@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.
Files changed (185) hide show
  1. package/dist/NOTICE.md +3 -3
  2. package/dist/bin/gezeld.js +8471 -5311
  3. package/dist/handboek-content/technical/building-connected-apps-with-gezel-app-sdk.md +78 -0
  4. package/dist/handboek-content/whats-new/{1.26250.md → 1.26251.md} +5 -5
  5. package/dist/index-store/static-index-worker.js +160 -51
  6. package/dist/index.d.ts +416 -71
  7. package/dist/index.js +8465 -5305
  8. package/dist/memory/embed-worker.js +132 -4
  9. package/dist/memory/image-embed-worker.js +14 -5
  10. package/dist/providers/mlx/python/cache_persist.py +52 -8
  11. package/dist/providers/mlx/python/gezel_mlx_server.py +44 -1
  12. package/dist/providers/mlx/python/qwen4_ple.py +159 -0
  13. package/dist/providers/mlx/python/spec_decode.py +73 -31
  14. package/dist/providers/mlx/python/tool_call_stream.py +10 -2
  15. package/dist/providers/mlx/python/tool_grammar.py +16 -0
  16. package/dist/ui/assets/{AmbientDashboardCard-DcVHxEdC.js → AmbientDashboardCard-_xnAQGnk.js} +1 -1
  17. package/dist/ui/assets/{AudioEngineSettings-BFM2S1mm.js → AudioEngineSettings-CgXgbX0i.js} +1 -1
  18. package/dist/ui/assets/{BenchmarksView-84-YeULA.js → BenchmarksView-BlExZpYA.js} +1 -1
  19. package/dist/ui/assets/CatalogBrowser-DYXUZQ_t.js +1 -0
  20. package/dist/ui/assets/{ChannelsSettings-7NAVUk4k.js → ChannelsSettings-EH27HcqZ.js} +1 -1
  21. package/dist/ui/assets/ChatTimelineView-Dn1TNyVn.js +7 -0
  22. package/dist/ui/assets/{ConnectedAppsPanel-CIgF4Q3R.js → ConnectedAppsPanel-BROry-Y0.js} +1 -1
  23. package/dist/ui/assets/CraftbookEditor-B2RNJnFf.js +1 -0
  24. package/dist/ui/assets/{CraftbookScriptEditorView-Ck5tzj3Y.js → CraftbookScriptEditorView-B-vySmHP.js} +1 -1
  25. package/dist/ui/assets/{CraftbookTabContent-BWg7FhK_.js → CraftbookTabContent-BW_2KC89.js} +1 -1
  26. package/dist/ui/assets/{CraftbookToolsetSetup-EuFOiUzR.js → CraftbookToolsetSetup-J7rEa835.js} +1 -1
  27. package/dist/ui/assets/{CraftbooksView-BIzQ1VVn.js → CraftbooksView-BjBUWPGF.js} +1 -1
  28. package/dist/ui/assets/DiffpackReviewView-CD4qJmgT.js +1 -0
  29. package/dist/ui/assets/DocumentDetail-SYozruTJ.js +1 -0
  30. package/dist/ui/assets/DocumentsView-DE7eL49Z.js +1 -0
  31. package/dist/ui/assets/{Ds4Settings-9soZCSeO.js → Ds4Settings-DGzc7JcD.js} +1 -1
  32. package/dist/ui/assets/{EmbeddedChat-Cce7nxXT.js → EmbeddedChat-D92TaJQ8.js} +1 -1
  33. package/dist/ui/assets/{FaceRecognitionCard-BVZyOwB8.js → FaceRecognitionCard-CB1Dt9X4.js} +1 -1
  34. package/dist/ui/assets/FileMapView-kVBG22FU.js +1 -0
  35. package/dist/ui/assets/FoldersSettings-BWFQU5B4.js +1 -0
  36. package/dist/ui/assets/GezelDetail-Br4v42Nv.js +1 -0
  37. package/dist/ui/assets/{GezelJsonEditor-DXXt165-.js → GezelJsonEditor-B9XEiW5Y.js} +1 -1
  38. package/dist/ui/assets/GezellenView-DheEBAy4.js +1 -0
  39. package/dist/ui/assets/{GildeUpdatesCard-CtY8mUTA.js → GildeUpdatesCard-BeIYv09f.js} +1 -1
  40. package/dist/ui/assets/{GithubSignInChip-DT3l6E0Q.js → GithubSignInChip-eEGCe9ar.js} +1 -1
  41. package/dist/ui/assets/{HandboekMediaProvider-ByJ4NAzz.js → HandboekMediaProvider-D0zcbbpf.js} +1 -1
  42. package/dist/ui/assets/HandboekView-p0BZT1rH.js +1 -0
  43. package/dist/ui/assets/{HistoryView-CkinzFEC.js → HistoryView-CKWcWW-Y.js} +1 -1
  44. package/dist/ui/assets/{HomeView-DNBrQnwy.js → HomeView-b_TT5oV3.js} +1 -1
  45. package/dist/ui/assets/{ImageEngineSettings-BfM9HSd_.js → ImageEngineSettings-CJfk4OJ4.js} +1 -1
  46. package/dist/ui/assets/{ImageRecognitionSettings-CaSQu5Br.js → ImageRecognitionSettings-DzbvZk5S.js} +1 -1
  47. package/dist/ui/assets/{IncompleteDownloads-C36lTCMG.js → IncompleteDownloads-C8_XyP8O.js} +1 -1
  48. package/dist/ui/assets/{KnowledgeCatalogsCard-CK9bqdf6.js → KnowledgeCatalogsCard-CHopG_j-.js} +1 -1
  49. package/dist/ui/assets/KnowledgeView-CXNKZUJq.js +1 -0
  50. package/dist/ui/assets/{LlamaCppSettings-CdNMHBbp.js → LlamaCppSettings-ohcM7kes.js} +1 -1
  51. package/dist/ui/assets/{MarkdownField-Dugmfr_e.js → MarkdownField-BX0qsaFq.js} +1 -1
  52. package/dist/ui/assets/{MemoriesTree-CgFqUNEr.js → MemoriesTree-BPj5Rod8.js} +1 -1
  53. package/dist/ui/assets/{MicrophoneSettings-DzDe9y1q.js → MicrophoneSettings-CWjeYnfI.js} +1 -1
  54. package/dist/ui/assets/MlxSettings-Dq6dRpcl.js +1 -0
  55. package/dist/ui/assets/{ModelPicker-BVkJhNAH.js → ModelPicker-0Ue-eEKj.js} +1 -1
  56. package/dist/ui/assets/NewPathDialog-BhAZm9dp.js +1 -0
  57. package/dist/ui/assets/{NewScriptDialog-TEAd0KLl.js → NewScriptDialog-DuryIe50.js} +1 -1
  58. package/dist/ui/assets/NewTaskDialog-BX24flMY.js +2 -0
  59. package/dist/ui/assets/{OllamaSettings-CPy2vxyZ.js → OllamaSettings-Boj8Nd1G.js} +1 -1
  60. package/dist/ui/assets/ProjectChat-Dhw_M5bq.js +5 -0
  61. package/dist/ui/assets/ProjectConnectionsTab-BwpMQNrg.js +1 -0
  62. package/dist/ui/assets/{ProjectGitStatusBar-BgHZ2ijN.js → ProjectGitStatusBar-BORGYx5l.js} +1 -1
  63. package/dist/ui/assets/{ProjectGithubView-BV2uTNU0.js → ProjectGithubView-CTP1BOMv.js} +1 -1
  64. package/dist/ui/assets/{ProjectMailTab-DLtJdXSL.js → ProjectMailTab-qFmAeV3M.js} +1 -1
  65. package/dist/ui/assets/{ProjectOverviewView-ZMs9nL5N.js → ProjectOverviewView-Cq1FsoaT.js} +1 -1
  66. package/dist/ui/assets/{ProjectTimeline-CTPcn4Kc.js → ProjectTimeline-Cqae2Z92.js} +1 -1
  67. package/dist/ui/assets/ProjectsView-D0uJjUB-.js +7 -0
  68. package/dist/ui/assets/{RecommendedBadge-iUoisQBi.js → RecommendedBadge-CN1jEmSn.js} +1 -1
  69. package/dist/ui/assets/{RemoteServersPanel-CTVJ0IRh.js → RemoteServersPanel-CMakvCCM.js} +1 -1
  70. package/dist/ui/assets/{ScriptEditorTabs-CCDFZjdC.js → ScriptEditorTabs-st6dJePd.js} +2 -2
  71. package/dist/ui/assets/{ScriptEditorView-CergLqKj.js → ScriptEditorView-BkySh57_.js} +2 -2
  72. package/dist/ui/assets/{ScriptsView-v7ckdhDi.js → ScriptsView-7uPKwjDB.js} +1 -1
  73. package/dist/ui/assets/{SecurityComplianceSettings-Bd0-66Gs.js → SecurityComplianceSettings-Tsv_pXfy.js} +1 -1
  74. package/dist/ui/assets/SessionSwitcher-D0fSeeHO.js +1 -0
  75. package/dist/ui/assets/SettingsView-cli_z8ZW.js +3 -0
  76. package/dist/ui/assets/{SquisqIntegration-C5l_OPvD.js → SquisqIntegration-BTZ1kBlg.js} +1 -1
  77. package/dist/ui/assets/{StorageCleanupDialog-3kv9-2mT.js → StorageCleanupDialog-CDBjl8JQ.js} +1 -1
  78. package/dist/ui/assets/{StorageUsageCard-7sWTrZFa.js → StorageUsageCard-DXY1j0dZ.js} +1 -1
  79. package/dist/ui/assets/TaskTabContent-C0P681SL.js +1 -0
  80. package/dist/ui/assets/TasksView-Ddwz10ri.js +1 -0
  81. package/dist/ui/assets/{TerminalCodeEditor-ChmdzmCz.js → TerminalCodeEditor-BkNQ6QoQ.js} +2 -2
  82. package/dist/ui/assets/ToolsetsEditor-KVigemfL.js +8 -0
  83. package/dist/ui/assets/{TransformToolbarButton-gzIxUBH7.js → TransformToolbarButton-8wfJR1bO.js} +2 -2
  84. package/dist/ui/assets/{UnrecognizedModels-0hptopv6.js → UnrecognizedModels-BzdU1clO.js} +1 -1
  85. package/dist/ui/assets/{VideoEngineSettings-BdNzCEdR.js → VideoEngineSettings-f79ff57u.js} +1 -1
  86. package/dist/ui/assets/{WorkspaceIndexPane-DnsOO916.js → WorkspaceIndexPane-fu5V6o1W.js} +1 -1
  87. package/dist/ui/assets/{api-C0I7spBl.js → api-CmrgM5Rf.js} +1 -1
  88. package/dist/ui/assets/chat-thread-memory-8MCtb17Q.js +1 -0
  89. package/dist/ui/assets/{chunk-6ECMNUIP-BvCy0HUI.js → chunk-6ECMNUIP-D5AA6ozp.js} +1 -1
  90. package/dist/ui/assets/{chunk-A6N6IN3I-ofeM4l8g.js → chunk-A6N6IN3I-BpxihS5H.js} +1 -1
  91. package/dist/ui/assets/{chunk-ATWVNF7D-CYuW1Yc6.js → chunk-ATWVNF7D-CKIWh7bN.js} +1 -1
  92. package/dist/ui/assets/{chunk-UBFT2CDQ-FexGDigd.js → chunk-CW24CH7I-BD0FIooX.js} +1 -1
  93. package/dist/ui/assets/{chunk-DXYWKZ52-zxe8pjH4.js → chunk-DXYWKZ52-DMKPZnpo.js} +1 -1
  94. package/dist/ui/assets/chunk-IIQYS2YH-BtDJt4Xr.js +1 -0
  95. package/dist/ui/assets/{chunk-KGWT454C-v5-l6U5m.js → chunk-KGWT454C-DsQOBuLg.js} +1 -1
  96. package/dist/ui/assets/{chunk-Q77KNJIN-BLuPdsQF.js → chunk-Q77KNJIN-BdWizq9s.js} +1 -1
  97. package/dist/ui/assets/{chunk-USU6HTKB-B_p-YcDp.js → chunk-USU6HTKB-DyGZplh4.js} +1 -1
  98. package/dist/ui/assets/{chunk-UXEANVBI-Bt0kX-0Z.js → chunk-UXEANVBI-BUBXvqyE.js} +1 -1
  99. package/dist/ui/assets/{chunk-O7JILDEF-CqcO1qaI.js → chunk-X7BNDUNI-D14WIvlD.js} +2 -2
  100. package/dist/ui/assets/{chunk-AE3IUKMM-mZjzzO8Z.js → chunk-ZSU5DJLX-CrjQf-vs.js} +1 -1
  101. package/dist/ui/assets/{container-BI8hxN1N.js → container-iFj1r6Hk.js} +1 -1
  102. package/dist/ui/assets/csv-Di411Mv-.js +1 -0
  103. package/dist/ui/assets/data-Q05qqAp4.js +1 -0
  104. package/dist/ui/assets/{dist-APSIK7H3.js → dist-1FNFiksd.js} +3 -3
  105. package/dist/ui/assets/dist-BMZhqfv7.js +2 -0
  106. package/dist/ui/assets/dist-CE5CbmDb.js +225 -0
  107. package/dist/ui/assets/doc-BHcGsJZd.js +587 -0
  108. package/dist/ui/assets/{document-import-DPK4r8Am.js → document-import-B2Ya6sbf.js} +1 -1
  109. package/dist/ui/assets/{docx-DRLuCTaC.js → docx-B8Pwz5Ih.js} +1 -1
  110. package/dist/ui/assets/{epub-a0p2Xb1b.js → epub-BQ4g8Q9j.js} +1 -1
  111. package/dist/ui/assets/{export-options-BqYFyzWx.js → export-options-Dylv69b3.js} +1 -1
  112. package/dist/ui/assets/file-browser-BLOPfnS0.js +5 -0
  113. package/dist/ui/assets/{html-BbQNmJ5X.js → html-BnA7qFwq.js} +1 -1
  114. package/dist/ui/assets/icons-CyM7Cg4E.js +1 -0
  115. package/dist/ui/assets/index-DW6qHqhU.css +1 -0
  116. package/dist/ui/assets/index-DivKnJyx.js +36 -0
  117. package/dist/ui/assets/{mail-link-CWfsP5Aq.js → mail-link-NtlcX5OE.js} +1 -1
  118. package/dist/ui/assets/{markdown-ryKA_OmY.js → markdown-CLKH_zzl.js} +1 -1
  119. package/dist/ui/assets/markdown-baseline-0dqv9qbV.js +1 -0
  120. package/dist/ui/assets/materialize-G4WC5UG3-xq2dcwS8.js +1 -0
  121. package/dist/ui/assets/{monaco-base-C0VTMpv-.js → monaco-base-BSvdAweA.js} +1 -1
  122. package/dist/ui/assets/{monaco-setup-CX8q88c5.js → monaco-setup-CT7LZ0o_.js} +1 -1
  123. package/dist/ui/assets/{new-project-meta-ZmDPGYzC.js → new-project-meta-5Y9Blozr.js} +1 -1
  124. package/dist/ui/assets/outside-in-Msmhxf_U.js +3 -0
  125. package/dist/ui/assets/{pdf-BHrygJa5.js → pdf-C4BhW3zg.js} +1 -1
  126. package/dist/ui/assets/{pending-drafts-27ujtQxX.js → pending-drafts-BD227X9H.js} +1 -1
  127. package/dist/ui/assets/{poppetje-CfaAvFkE.js → poppetje-DvCJO36y.js} +3 -3
  128. package/dist/ui/assets/{pptx-nDW64jAN.js → pptx-B6uaM2s7.js} +3 -3
  129. package/dist/ui/assets/{run-export-86KzLZ7R.js → run-export-TscWwR6y.js} +2 -2
  130. package/dist/ui/assets/{standalone-source-7QdiNsDW.js → standalone-source-Cw9SF7Zk.js} +1 -1
  131. package/dist/ui/assets/storage-Cmhlwx70.js +1 -0
  132. package/dist/ui/assets/styles-BjDaWeMA.css +1 -0
  133. package/dist/ui/assets/styles-CqO-rmOt.js +554 -0
  134. package/dist/ui/assets/{terminal-monaco-setup-Bar-sYKd.js → terminal-monaco-setup-me523-j-.js} +1 -1
  135. package/dist/ui/assets/{transform-CmAXy0Ck.js → transform-DxJCwK68.js} +1 -1
  136. package/dist/ui/assets/{use-local-model-manager-D1yiurrC.js → use-local-model-manager-8wvk-I-y.js} +1 -1
  137. package/dist/ui/assets/{useCompactLayout-BDtPQcDh.js → useCompactLayout-cm4E9Vja.js} +0 -0
  138. package/dist/ui/assets/{useCopilotAvailability-BHOfHrfT.js → useCopilotAvailability-D9hglSH_.js} +1 -1
  139. package/dist/ui/assets/{useDiffpacks-B0kYhlWQ.js → useDiffpacks-1BN2XJWg.js} +1 -1
  140. package/dist/ui/assets/{useGitSync-DOt-ODiw.js → useGitSync-7m9YA7h5.js} +1 -1
  141. package/dist/ui/assets/{useShowWorkInProgressFeatures-BtpredG7.js → useShowWorkInProgressFeatures-D6QOaTUT.js} +1 -1
  142. package/dist/ui/assets/{useTotalRamBytes-B8NFM27w.js → useTotalRamBytes-Durk383U.js} +1 -1
  143. package/dist/ui/assets/{xlsx-B_pu1ZvY.js → xlsx-BbHA9bxA.js} +1 -1
  144. package/dist/ui/index.html +15 -15
  145. package/package.json +12 -11
  146. package/dist/ui/assets/CatalogBrowser-7_jHy5Q3.js +0 -1
  147. package/dist/ui/assets/ChatTimelineView-Cg_kLK_U.js +0 -7
  148. package/dist/ui/assets/CraftbookEditor-BKAIsnXv.js +0 -1
  149. package/dist/ui/assets/DiffpackReviewView-B2a3zgE-.js +0 -1
  150. package/dist/ui/assets/DocumentDetail-GCYhwQqV.js +0 -1
  151. package/dist/ui/assets/DocumentsView-Cm3RaQ5N.js +0 -1
  152. package/dist/ui/assets/FileMapView-BKJovLcL.js +0 -1
  153. package/dist/ui/assets/FoldersSettings-CuJd2JdE.js +0 -1
  154. package/dist/ui/assets/GezelDetail-D_KIPDhQ.js +0 -1
  155. package/dist/ui/assets/GezellenView-BOOW1QQU.js +0 -1
  156. package/dist/ui/assets/HandboekView-gRzJcIbJ.js +0 -1
  157. package/dist/ui/assets/KnowledgeView-DJ3cJVHA.js +0 -1
  158. package/dist/ui/assets/MlxSettings-45mBFHbA.js +0 -1
  159. package/dist/ui/assets/NewTaskDialog-CIXVunZn.js +0 -2
  160. package/dist/ui/assets/ProjectChat-BiJRweob.js +0 -5
  161. package/dist/ui/assets/ProjectConnectionsTab-CQgaIzuv.js +0 -1
  162. package/dist/ui/assets/ProjectsView-BUdR76n6.js +0 -7
  163. package/dist/ui/assets/SessionSwitcher-BgZqyiRn.js +0 -1
  164. package/dist/ui/assets/SettingsView-DLhOYiR5.js +0 -3
  165. package/dist/ui/assets/TaskTabContent-CG2KmfwV.js +0 -1
  166. package/dist/ui/assets/TasksView-Dy5Ue4zS.js +0 -1
  167. package/dist/ui/assets/ToolsetsEditor-J9XxQ5Ms.js +0 -8
  168. package/dist/ui/assets/chat-thread-memory-CI2-giEq.js +0 -1
  169. package/dist/ui/assets/chunk-IIQYS2YH-DEkyBlHg.js +0 -1
  170. package/dist/ui/assets/csv-B0D9jJG2.js +0 -1
  171. package/dist/ui/assets/data-BIL84EaT.js +0 -1
  172. package/dist/ui/assets/dist-CJqyWK6E.js +0 -2
  173. package/dist/ui/assets/dist-DOqbRmFj.js +0 -225
  174. package/dist/ui/assets/doc-C2Ph2FWI.js +0 -584
  175. package/dist/ui/assets/document-companion-aDThLOwl.js +0 -1
  176. package/dist/ui/assets/file-browser-DVyWN0LD.js +0 -5
  177. package/dist/ui/assets/icons-DWaUNQbT.js +0 -1
  178. package/dist/ui/assets/index-DDu8nyO6.js +0 -34
  179. package/dist/ui/assets/index-DEDUSiCx.css +0 -1
  180. package/dist/ui/assets/markdown-baseline-9B52XlX2.js +0 -1
  181. package/dist/ui/assets/materialize-G4WC5UG3-BlZQe-88.js +0 -1
  182. package/dist/ui/assets/outside-in-BmIIeMid.js +0 -3
  183. package/dist/ui/assets/storage-B-vhjyV2.js +0 -1
  184. package/dist/ui/assets/styles-BvkZd-EV.js +0 -550
  185. package/dist/ui/assets/styles-IQ4adxWr.css +0 -1
@@ -0,0 +1,7 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/dist-BMZhqfv7.js","assets/rolldown-runtime-aKtaBQYM.js","assets/dist-CE5CbmDb.js"])))=>i.map(i=>d[i]);
2
+ import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{n as t,t as n}from"./jsx-runtime-CEpd2cAX.js";import{Ct as r,J as i,Rt as a,U as o,W as s,Y as c,an as l,ct as u,fn as d,on as f,st as p,yn as m,zt as h}from"./dist-CE5CbmDb.js";import{a as g}from"./dist-BMZhqfv7.js";import{t as _}from"./api-CmrgM5Rf.js";import{_ as v,g as y,o as ee,v as b}from"./primitives-CWrGZpPI.js";import{n as x,t as S}from"./relative-time-B2kBaekd.js";import{t as C}from"./preload-helper-Czpn1I53.js";import{a as w,i as T,l as E,o as D,r as O,s as te,t as k}from"./styles-CqO-rmOt.js";import{At as ne,Ct as A,Dt as j,E as re,Et as ie,F as ae,I as oe,L as se,M as ce,N as le,Ot as ue,P as de,Wt as fe,b as pe,bt as me,i as he,j as ge,jt as _e,kt as M,qt as ve}from"./index-DivKnJyx.js";import{c as ye,o as be,r as N}from"./SquisqIntegration-BTZ1kBlg.js";import{n as xe,t as P}from"./microphone-input-5gqW_NKf.js";import{r as Se,t as Ce}from"./composer-prefill-CbG_i1Rx.js";var F=e(t(),1),I=n();function we(e){return e.replace(/\.[^.]+$/,``).replace(/[-_]/g,` `)}function Te(e){return e.replace(/([\\\[\]])/g,`\\$1`)}function Ee(){return(0,I.jsxs)(`svg`,{width:`16`,height:`16`,viewBox:`0 0 16 16`,fill:`none`,"aria-hidden":`true`,children:[(0,I.jsx)(`rect`,{x:`2`,y:`2.5`,width:`12`,height:`11`,rx:`1.5`,stroke:`currentColor`,strokeWidth:`1.35`}),(0,I.jsx)(`circle`,{cx:`5.25`,cy:`5.75`,r:`1.1`,stroke:`currentColor`,strokeWidth:`1.2`}),(0,I.jsx)(`path`,{d:`m3.5 12 3.1-3.25 2.05 1.9 1.55-1.55 2.3 2.9`,stroke:`currentColor`,strokeWidth:`1.35`,strokeLinecap:`round`,strokeLinejoin:`round`})]})}function De(){return(0,I.jsx)(`svg`,{width:`16`,height:`16`,viewBox:`0 0 16 16`,fill:`none`,"aria-hidden":`true`,children:(0,I.jsx)(`path`,{d:`m5.25 8.7 4.2-4.2a2.1 2.1 0 0 1 2.97 2.97l-5.1 5.1a3.2 3.2 0 0 1-4.53-4.52l5-5`,stroke:`currentColor`,strokeWidth:`1.4`,strokeLinecap:`round`,strokeLinejoin:`round`})})}function Oe({mediaProvider:e,onError:t}){let{bumpMediaRevision:n,insertAtCursor:r}=E(),i=(0,F.useRef)(null),a=(0,F.useRef)(null),[o,s]=(0,F.useState)(null),c=(0,F.useCallback)(async(i,a)=>{s(a),t(null);try{let t=i.type||`application/octet-stream`,o=await e.addMedia(i.name,await i.arrayBuffer(),t);n();let s=Te(we(i.name));r(a===`image`?`![${s}](${o})`:`[${s}](${o})`)}catch(e){t(e instanceof Error?e.message:`Could not attach that file.`)}finally{s(null)}},[n,r,e,t]),l=(0,F.useCallback)((e,t)=>{let n=e.target.files?.[0];e.target.value=``,n&&c(n,t)},[c]);return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`div`,{className:`chat-composer-attachment-actions`,children:[(0,I.jsx)(`input`,{ref:i,type:`file`,accept:`image/*`,hidden:!0,onChange:e=>l(e,`image`)}),(0,I.jsx)(`input`,{ref:a,type:`file`,hidden:!0,onChange:e=>l(e,`file`)}),(0,I.jsx)(`button`,{type:`button`,className:`squisq-toolbar-button`,onClick:()=>i.current?.click(),disabled:o!==null,"aria-label":o===`image`?`Inserting image…`:`Insert image`,"aria-busy":o===`image`,title:`Insert image`,"data-tooltip":`Insert image`,children:(0,I.jsx)(Ee,{})}),(0,I.jsx)(`button`,{type:`button`,className:`squisq-toolbar-button`,onClick:()=>a.current?.click(),disabled:o!==null,"aria-label":o===`file`?`Attaching file…`:`Attach file`,"aria-busy":o===`file`,title:`Attach file`,"data-tooltip":`Attach file`,children:(0,I.jsx)(De,{})})]}),(0,I.jsx)(`span`,{className:`chat-composer-toolbar-spacer`,"aria-hidden":`true`})]})}var ke=50;function Ae(e){return typeof AudioContext>`u`?null:new L(e)}var L=class{stream;context=null;source=null;analyser=null;timer=null;samples=null;noiseFloor=.004;speaking=!1;constructor(e){this.stream=e}start(e){if(this.timer!==null)return;let t=new AudioContext;this.context=t;try{let e=t.createMediaStreamSource(this.stream),n=t.createAnalyser();n.fftSize=1024,n.smoothingTimeConstant=.15,e.connect(n),this.source=e,this.analyser=n,this.samples=new Float32Array(n.fftSize),t.resume().catch(()=>void 0)}catch(e){throw this.stop(),e}this.timer=setInterval(()=>{if(!this.analyser||!this.samples)return;this.analyser.getFloatTimeDomainData(this.samples);let t=je(this.samples),n=Math.max(.012,this.noiseFloor*2.8),r=Math.max(.008,this.noiseFloor*1.8);this.speaking=t>=(this.speaking?r:n),this.speaking||(this.noiseFloor=Math.min(.03,this.noiseFloor*.95+t*.05)),e(this.speaking,t)},ke)}stop(){this.timer!==null&&(clearInterval(this.timer),this.timer=null),this.source?.disconnect(),this.analyser?.disconnect(),this.source=null,this.analyser=null,this.samples=null;let e=this.context;this.context=null,e&&e.close().catch(()=>void 0)}};function je(e){if(e.length===0)return 0;let t=0;for(let n of e)t+=n*n;return Math.sqrt(t/e.length)}var Me=2500,Ne=350,Pe=650,Fe=1e4,Ie=1e3,R=class{stream;mimeType;segmentMs;speechPauseMs;minSegmentMs;longPauseMs;transcribe;onTranscript;onError;onLongPause;onAudioLevel;abortController=new AbortController;activityMonitor;activityMonitorStarted=!1;recorder=null;chunks=[];segmentTimer=null;transcriptionQueue=Promise.resolve();stopPromise=null;resolveStop=null;finalSegmentRequested=!1;segmentStartedAt=0;segmentHasSpeech=!1;currentlySpeaking=!1;lastSpeechAt=null;confirmedSilenceMs=0;recognitionPrompt=``;hasTranscript=!1;longPauseNotified=!1;disposed=!1;constructor(e){this.stream=e.stream,this.mimeType=e.mimeType??``,this.segmentMs=e.segmentMs??Me,this.speechPauseMs=e.speechPauseMs??Ne,this.minSegmentMs=e.minSegmentMs??Pe,this.longPauseMs=e.longPauseMs??Fe,this.activityMonitor=e.activityMonitor===void 0?Ae(e.stream):e.activityMonitor,this.transcribe=e.transcribe,this.onTranscript=e.onTranscript,this.onError=e.onError,this.onLongPause=e.onLongPause,this.onAudioLevel=e.onAudioLevel}start(){this.disposed||this.recorder||(this.startSegment(),this.startActivityMonitor())}stop(){if(this.stopPromise)return this.stopPromise;this.finalSegmentRequested=!0,this.stopActivityMonitor(),this.clearSegmentTimer(),this.stopPromise=new Promise(e=>{this.resolveStop=e});let e=this.recorder;return e?.state===`recording`?e.stop():e||this.finish(),this.stopPromise}cancel(){if(this.disposed)return;this.disposed=!0,this.abortController.abort(),this.stopActivityMonitor(),this.clearSegmentTimer();let e=this.recorder;if(this.recorder=null,e&&(e.ondataavailable=null,e.onstop=null,e.onerror=null,e.state!==`inactive`))try{e.stop()}catch{}this.releaseStream(),this.resolveStop?.(),this.resolveStop=null}startSegment(){if(this.disposed||this.finalSegmentRequested)return;let e=this.mimeType?{mimeType:this.mimeType}:void 0,t=new MediaRecorder(this.stream,e);this.recorder=t,this.chunks=[],this.segmentStartedAt=Date.now(),this.segmentHasSpeech=this.currentlySpeaking,t.ondataavailable=e=>{!this.disposed&&e.data.size>0&&this.chunks.push(e.data)},t.onerror=e=>{let t=e.error;this.onError(t??Error(`Microphone recording failed.`)),this.finalSegmentRequested=!0,this.clearSegmentTimer()},t.onstop=()=>{if(this.disposed||this.recorder!==t)return;this.recorder=null;let e=t.mimeType||this.mimeType||`audio/webm`,n=new Blob(this.chunks,{type:e}),r=Math.max(0,Date.now()-this.segmentStartedAt);this.chunks=[],this.finalSegmentRequested||this.startSegment(),n.size>0&&this.enqueueTranscription(n,e,r),this.finalSegmentRequested&&this.finish()},t.start(),this.segmentTimer=setTimeout(()=>{this.segmentTimer=null,!this.disposed&&!this.finalSegmentRequested&&t.state===`recording`&&t.stop()},this.segmentMs)}startActivityMonitor(){if(!(!this.activityMonitor||this.activityMonitorStarted))try{this.activityMonitor.start((e,t)=>{this.onAudioLevel?.(t),this.onSpeechActivity(e)}),this.activityMonitorStarted=!0}catch{this.activityMonitor.stop(),this.activityMonitor=null}}stopActivityMonitor(){this.activityMonitor?.stop()}onSpeechActivity(e){if(this.disposed||this.finalSegmentRequested)return;let t=Date.now();if(this.currentlySpeaking=e,e){this.segmentHasSpeech=!0,this.lastSpeechAt=t,this.longPauseNotified=!1;return}if(this.lastSpeechAt===null)return;let n=t-this.lastSpeechAt;this.segmentHasSpeech&&t-this.segmentStartedAt>=this.minSegmentMs&&n>=this.speechPauseMs&&this.flushCurrentSegment()}flushCurrentSegment(){let e=this.recorder;!e||e.state!==`recording`||(this.clearSegmentTimer(),e.stop())}enqueueTranscription(e,t,n){this.transcriptionQueue=this.transcriptionQueue.then(async()=>{if(!this.disposed)try{let r=Le(await this.transcribe(e,t,this.abortController.signal,this.recognitionPrompt));if(this.disposed)return;if(r){this.confirmedSilenceMs=0,this.hasTranscript=!0,this.longPauseNotified=!1,this.recognitionPrompt=Re(this.recognitionPrompt,r),this.onTranscript(r);return}this.confirmedSilenceMs+=n,!this.longPauseNotified&&this.onLongPause&&this.confirmedSilenceMs>=this.longPauseMs&&(this.longPauseNotified=!0,this.onLongPause(this.hasTranscript))}catch(e){if(this.disposed||this.abortController.signal.aborted)return;this.onError(e instanceof Error?e:Error(String(e)))}})}async finish(){this.clearSegmentTimer(),this.stopActivityMonitor(),this.releaseStream(),await this.transcriptionQueue,!this.disposed&&(this.disposed=!0,this.resolveStop?.(),this.resolveStop=null)}clearSegmentTimer(){this.segmentTimer!==null&&(clearTimeout(this.segmentTimer),this.segmentTimer=null)}releaseStream(){for(let e of this.stream.getTracks())e.stop()}};function Le(e){let t=e.trim();return/^\[\s*BLANK_AUDIO\s*\]$/i.test(t)?``:t}function Re(e,t){let n=`${e.trim()} ${t.trim()}`.trim();if(n.length<=Ie)return n;let r=n.slice(-1e3),i=r.search(/\s/);return(i>=0?r.slice(i+1):r).trim()}async function ze(e){if(/^audio\/(?:wav|wave|x-wav)(?:;|$)/i.test(e.type))return e;if(typeof AudioContext>`u`)throw Error(`This recording could not be prepared for speech-to-text.`);let t=new AudioContext;try{let n=await t.decodeAudioData(await e.arrayBuffer()),r=Be(Array.from({length:n.numberOfChannels},(e,t)=>n.getChannelData(t)),n.sampleRate);return new Blob([r.buffer],{type:`audio/wav`})}catch(e){let t=e instanceof Error&&e.message?` (${e.message})`:``;throw Error(`This recording could not be prepared for speech-to-text${t}`)}finally{await t.close().catch(()=>void 0)}}function Be(e,t){let n=e[0]?.length??0;if(e.length===0||n===0)throw Error(`The microphone recording was empty.`);if(!Number.isFinite(t)||t<=0)throw Error(`The microphone recording has an invalid sample rate.`);if(e.some(e=>e.length!==n))throw Error(`The microphone recording channels have different lengths.`);let r=n*2,i=new ArrayBuffer(44+r),a=new DataView(i);Ve(a,0,`RIFF`),a.setUint32(4,36+r,!0),Ve(a,8,`WAVE`),Ve(a,12,`fmt `),a.setUint32(16,16,!0),a.setUint16(20,1,!0),a.setUint16(22,1,!0),a.setUint32(24,Math.round(t),!0),a.setUint32(28,Math.round(t)*2,!0),a.setUint16(32,2,!0),a.setUint16(34,16,!0),Ve(a,36,`data`),a.setUint32(40,r,!0);for(let t=0;t<n;t+=1){let n=0;for(let r of e)n+=r[t]??0;n=Math.max(-1,Math.min(1,n/e.length));let r=Math.round(n<0?n*32768:n*32767);a.setInt16(44+t*2,r,!0)}return new Uint8Array(i)}function Ve(e,t,n){for(let r=0;r<n.length;r+=1)e.setUint8(t+r,n.charCodeAt(r))}var He=12;function Ue({projectId:e,disabled:t=!1,onTranscript:n,onError:r}){let[i,a]=(0,F.useState)(`idle`),[o,s]=(0,F.useState)(()=>We()),c=(0,F.useRef)(null),l=(0,F.useRef)(!0),u=(0,F.useRef)(!1),d=(0,F.useRef)(0),f=(0,F.useRef)(e),p=te()&&D();(0,F.useEffect)(()=>(l.current=!0,()=>{l.current=!1,d.current+=1,c.current?.cancel(),c.current=null}),[]),(0,F.useEffect)(()=>{f.current!==e&&(f.current=e,d.current+=1,c.current?.cancel(),c.current=null,u.current=!1,a(`idle`),s(We()))},[e]);let m=(0,F.useCallback)(async()=>{let e=c.current;if(e){a(`transcribing`);try{await e.stop()}finally{c.current===e&&(c.current=null),l.current&&a(`idle`)}}},[]),h=(0,F.useCallback)(async()=>{if(!p||t||u.current||c.current)return;u.current=!0;let i=d.current;a(`requesting`),s(We()),r(null);let o=null;try{let t=await _.getConfig().catch(()=>void 0),u={...t?.microphoneDeviceId?{deviceId:t.microphoneDeviceId}:{},...t?.microphoneDeviceLabel?{label:t.microphoneDeviceLabel}:{}},f=xe(u.deviceId||u.label?await P().catch(()=>[]):[],u),p=f?.deviceId??u.deviceId;if(o=await T({echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,...p?{deviceId:{exact:p}}:{}}),!l.current||i!==d.current){for(let e of o.getTracks())e.stop();return}let h=o.getAudioTracks?.()[0]?.label?.trim()||f?.label||u.label,g=w(`audio`),v=new R({stream:o,...g.mimeType?{mimeType:g.mimeType}:{},transcribe:async(t,n,i,a)=>{let o=await ze(t),s=Le((await _.transcribeAudio({audio:{data:await B(o),mimeType:o.type||n},projectId:e,signal:i,...a?{prompt:a}:{}})).text);return s?(r(null),s):``},onTranscript:n,onAudioLevel:e=>{if(!l.current||i!==d.current)return;let t=Ge(e);s(e=>[...e.slice(1),t])},onLongPause:e=>{e||r(`No speech detected${h?` from ${h}`:``}. Choose the microphone in Settings → Device Integration if this isn't the expected input.`),m()},onError:e=>{v.cancel(),c.current===v&&(c.current=null,l.current&&i===d.current&&(a(`idle`),r(Ke(e))))}});c.current=v,v.start(),o=null,a(`recording`)}catch(e){if(o)for(let e of o.getTracks())e.stop();l.current&&i===d.current&&(a(`idle`),r(Ke(e)))}finally{i===d.current&&(u.current=!1)}},[t,r,n,e,m,p]),g=i===`recording`,v=!p;return(0,I.jsxs)(`button`,{type:`button`,className:`chat-narrate-btn${g?` chat-narrate-btn-recording`:``}`,"data-testid":`chat-narrate`,onClick:g?()=>void m():()=>void h(),disabled:i===`requesting`||i===`transcribing`||i===`idle`&&(t||v),"aria-label":i===`requesting`?`Starting microphone…`:g?`Stop narrating`:i===`transcribing`?`Finishing transcription…`:`Narrate prompt`,"aria-pressed":g,"aria-busy":i===`requesting`||i===`transcribing`,title:v?`Voice input is unavailable in this browser`:g?`Listening — short pauses add speech; click to finish now`:i===`transcribing`?`Adding the remaining speech to this prompt`:`Narrate this prompt with your microphone`,children:[(0,I.jsx)(V,{}),g&&(0,I.jsx)(z,{levels:o}),g&&(0,I.jsx)(`span`,{className:`chat-narrate-live-dot`,"aria-hidden":`true`})]})}function We(){return Array.from({length:He},()=>0)}function Ge(e){return Math.min(1,Math.max(0,e*14))}function z({levels:e}){return(0,I.jsx)(`span`,{className:`chat-narrate-waveform`,"data-testid":`microphone-waveform`,"aria-hidden":`true`,children:e.map((e,t)=>(0,I.jsx)(`span`,{className:`chat-narrate-waveform-bar`,style:{height:`${2+e*14}px`}},t))})}async function B(e){let t=new Uint8Array(await e.arrayBuffer()),n=``,r=32768;for(let e=0;e<t.length;e+=r)n+=String.fromCharCode(...t.subarray(e,e+r));return btoa(n)}function Ke(e){let t=e instanceof Error?e:Error(String(e)),n=qe(t)??t.message;return t.name===`NotAllowedError`||/permission|not allowed|denied/i.test(n)?`Microphone access was not granted. Allow it in your system settings, then try again.`:t.name===`OverconstrainedError`||/constraint|selected microphone/i.test(n)?`The selected microphone is unavailable. Choose another in Settings → Device Integration.`:t.name===`NotFoundError`||/requested device not found|no microphone/i.test(n)?`No microphone is available.`:/speech_to_text_not_ready|no stt model|download one from settings|speech-to-text model/i.test(n)?`Speech-to-text is not ready. Download a model in Settings → Audio, then try again.`:/speech_to_text_failed/i.test(n)?`Speech-to-text could not transcribe this recording. Check Settings → Audio, then try again.`:`Could not narrate this prompt: ${n}`}function qe(e){let t=e.details;if(t&&typeof t==`object`&&`error`in t){let e=t.error;if(typeof e==`string`&&e.trim())return e.trim()}return typeof t==`string`&&t.trim()?t.trim():null}function V(){return(0,I.jsxs)(`svg`,{viewBox:`0 0 16 16`,fill:`none`,"aria-hidden":`true`,focusable:`false`,children:[(0,I.jsx)(`rect`,{x:`5.25`,y:`1.5`,width:`5.5`,height:`8`,rx:`2.75`,stroke:`currentColor`}),(0,I.jsx)(`path`,{d:`M3.5 7.5a4.5 4.5 0 0 0 9 0M8 12v2.5M5.75 14.5h4.5`,stroke:`currentColor`})]})}function Je({gezels:e,primaryGezelId:t,additionalRecipientIds:n,roleBasedNameOnlyMode:r,onSelectPrimary:i,onAddRecipient:a}){let[o,c]=(0,F.useState)(!1),[l,u]=(0,F.useState)(``),d=(0,F.useMemo)(()=>{let t=new Set;return e.filter(e=>t.has(e.id)?!1:(t.add(e.id),!0)).map(e=>({gezel:e,rendered:s({name:e.name,roleBasedName:e.roleBasedName},r)}))},[e,r]),f=d.length>8,p=l.trim().toLowerCase(),m=f&&p?d.filter(({gezel:e,rendered:t})=>t.toLowerCase().includes(p)||(e.role??``).toLowerCase().includes(p)):d,h=new Set(n);return(0,I.jsxs)(v,{open:o,onOpenChange:e=>{c(e),e||u(``)},children:[(0,I.jsx)(b,{asChild:!0,children:(0,I.jsx)(`button`,{type:`button`,className:`chat-composer-recipient-trigger`,"aria-label":`Choose recipients`,title:`Add or change recipients`,children:(0,I.jsx)(`span`,{className:`chat-recipient-plus-glyph`,"aria-hidden":`true`,children:`+`})})}),(0,I.jsxs)(y,{className:`chat-recipient-popover`,align:`end`,side:`top`,"aria-label":`Choose a gezel`,children:[(0,I.jsx)(`span`,{className:`chat-recipient-popover-label`,children:`Choose a gezel`}),f&&(0,I.jsx)(`input`,{className:`chat-recipient-search`,type:`search`,value:l,placeholder:`Search by name or role`,"aria-label":`Search gezels`,onChange:e=>u(e.target.value)}),(0,I.jsxs)(`div`,{className:`chat-recipient-list`,children:[m.map(({gezel:e,rendered:n})=>{let r=e.id===t,o=h.has(e.id);return(0,I.jsxs)(`div`,{className:`chat-recipient-option${r?` chat-recipient-option-primary`:``}`,children:[(0,I.jsxs)(`button`,{type:`button`,className:`chat-recipient-select`,"aria-current":r?`true`:void 0,"aria-label":`Talk to ${n}`,onClick:()=>{i(e.id),c(!1)},children:[(0,I.jsx)(fe,{svg:e.icon??null,poppetje:e.poppetje,iconOverride:e.iconOverride,name:n,size:26}),(0,I.jsxs)(`span`,{className:`chat-recipient-option-text`,children:[(0,I.jsx)(`span`,{className:`chat-recipient-option-name`,children:n}),e.role&&(0,I.jsx)(`span`,{className:`chat-recipient-option-role`,children:e.role})]})]}),r||o?(0,I.jsx)(`span`,{className:`chat-recipient-option-state`,children:r?`To`:`Added`}):(0,I.jsx)(`button`,{type:`button`,className:`chat-recipient-add`,"aria-label":`Add ${n} to recipients`,title:`Add ${n}`,onClick:()=>a(e.id),children:(0,I.jsx)(`span`,{className:`chat-recipient-plus-glyph`,"aria-hidden":`true`,children:`+`})})]},e.id)}),m.length===0&&(0,I.jsx)(`p`,{className:`muted small chat-recipient-empty`,children:`No matches.`})]})]})]})}var Ye=`Could not copy that image.`;function H(e){return e.closest(`img.squisq-image`)}async function U(e){if(e.complete||await e.decode(),e.naturalWidth<1||e.naturalHeight<1)throw Error(`image has no decoded pixels`);let t=document.createElement(`canvas`);t.width=e.naturalWidth,t.height=e.naturalHeight;let n=t.getContext(`2d`);if(!n)throw Error(`canvas is unavailable`);return n.drawImage(e,0,0),new Promise((e,n)=>{t.toBlob(t=>{t?e(t):n(Error(`image could not be encoded`))},`image/png`)})}async function Xe(e){let t=e.currentSrc||e.src;if(!t)throw Error(`image has no source`);let n=await fetch(t);if(!n.ok)throw Error(`image read failed (${n.status})`);let r=await n.blob();return r.type.toLowerCase()===`image/png`?r:U(e)}async function Ze(e){if(typeof ClipboardItem>`u`||!navigator.clipboard?.write)throw Error(`image clipboard is unavailable`);let t=new ClipboardItem({"image/png":Xe(e)});await navigator.clipboard.write([t])}function Qe({onError:e}){let{tiptapEditor:t}=E(),n=(0,F.useCallback)(async t=>{e(null);try{await Ze(t)}catch{e(Ye)}},[e]);return O((0,F.useMemo)(()=>[{id:`gezel.copy-composer-image`,label:`Copy image`,group:`image`,when:({target:e})=>H(e)!==null,onSelect:({target:e})=>{let t=H(e);if(t)return n(t)}}],[n])),(0,F.useEffect)(()=>{if(!t)return;let{view:e}=t,r=r=>{let{selection:i}=t.state;if((`node`in i?i.node:void 0)?.type?.name!==`image`)return;let a=e.nodeDOM(i.from),o=a instanceof HTMLImageElement?a:a instanceof Element?a.querySelector(`img.squisq-image`):null;o&&(r.preventDefault(),r.stopImmediatePropagation(),n(o))};return e.dom.addEventListener(`copy`,r,!0),()=>e.dom.removeEventListener(`copy`,r,!0)},[n,t]),null}var $e=new Map,W=`data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=`;function G(e){let t=e.trim();return/^(?:data|blob):/i.test(t)?!1:t.startsWith(`//`)||/^[a-z][a-z0-9+.-]*:/i.test(t)}function et(e,t){let n=`${e}:${t}`,r=$e.get(n);return r||(r=K({projectId:e,legacySessionId:t}),$e.set(n,r)),r}function K(e){let t=new Map,n=new Map,r=async(e,t)=>{if(e instanceof Blob)return e;let n=e instanceof Uint8Array?e:new Uint8Array(e),r=new Uint8Array(n.byteLength);return r.set(n),new Blob([r.buffer],{type:t})},i=e=>{let t=/^attachments\/([^/]+)$/.exec(e);if(t)return{scope:`attachments`,filename:t[1]};let n=/^images\/([^/]+)$/.exec(e);if(n)return{scope:`images`,filename:n[1]};let r=/^artifacts\/(.+)$/.exec(e);return r?{scope:`artifact`,path:r[1]}:/^generated\/[^/].*\.(png|jpe?g|gif|webp|svg)$/i.test(e)?{scope:`artifact`,path:e}:null};return{async addMedia(n,i,a){let o=await r(i,a),s=await _.uploadProjectAttachment(e.projectId,o,a,n);return t.set(s.relativePath,URL.createObjectURL(o)),s.relativePath},async resolveUrl(r){if(G(r))return W;if(/^(?:data|blob):/i.test(r.trim()))return r;let a=t.get(r);if(a)return a;let o=n.get(r);if(o)return o;let s=i(r);if(!s)return r;let c=(async()=>{try{let n;if(s.scope===`attachments`)n=await _.fetchProjectAttachment(e.projectId,s.filename);else if(s.scope===`artifact`)n=await _.fetchProjectArtifactBlob(e.projectId,s.path);else{if(!e.legacySessionId)return r;n=await _.fetchSessionImage(e.projectId,e.legacySessionId,s.filename)}let i=URL.createObjectURL(n);return t.set(r,i),i}finally{n.delete(r)}})();return n.set(r,c),c},async listMedia(){return(await _.listProjectAttachments(e.projectId)).attachments.map(e=>({name:`attachments/${e.filename}`,mimeType:e.mimeType,size:e.size}))},async removeMedia(n){let r=i(n);if(!r)return;r.scope===`attachments`?await _.deleteProjectAttachment(e.projectId,r.filename):r.scope===`images`&&e.legacySessionId&&await _.deleteSessionImage(e.projectId,e.legacySessionId,r.filename);let a=t.get(n);a&&(URL.revokeObjectURL(a),t.delete(n))},dispose(){for(let e of t.values())URL.revokeObjectURL(e);t.clear(),n.clear()}}}function tt(e){let t=e.trim();return/^(?:data|blob):/i.test(t)?!1:t.startsWith(`//`)||/^[a-z][a-z0-9+.-]*:/i.test(t)}function nt(e){let t=new Map,n=null,r=n=>{let r=t.get(n);return r||(r=be(N({projectId:e.projectId,root:`prompts/${n}/message_files`,client:_,referencePrefix:`message_files`}),`message_files`),t.set(n,r)),r},i=()=>(n??=K({projectId:e.projectId}),n);return{async addMedia(t,n,i){let a=await e.ensureDraftId();return r(a).addMedia(t,n,i)},async resolveUrl(t){if(tt(t))return W;if(/^(?:data|blob):/i.test(t.trim()))return t;let n=e.getDraftId(),a=t.replace(/^\.\//,``).replace(/^\/+/,``);return n&&a.startsWith(`message_files/`)?r(n).resolveUrl(t):i().resolveUrl(t)},async listMedia(){let t=e.getDraftId();return t?r(t).listMedia():[]},async removeMedia(t){let n=e.getDraftId(),a=t.replace(/^\.\//,``).replace(/^\/+/,``);if(n&&a.startsWith(`message_files/`)){await r(n).removeMedia(t);return}await i().removeMedia(t)},dispose(){for(let e of t.values())e.dispose();t.clear(),n?.dispose(),n=null}}}function rt(e){if(e.includes(`
3
+ `)||e.includes(`\r`))return null;let t=e.trim().match(/^\/open(?:[ \t]+(.*))?$/i);return t?(t[1]??``).trim():null}function it(e,t,n=8){let r=q(e),i=[`workspace`,`artifacts`].map(e=>({key:`folder:${e}`,label:e,description:`Open the project ${e} folder`,target:{type:`folder`,folder:e}})).filter(e=>ot(r,e.label)),a=new Set,o=[];for(let e of t){let t=`${e.projectId??``}:${e.kind}:${q(e.path)}`;if(!a.has(t)&&(a.add(t),!(!ot(r,e.path)&&!ot(r,st(e.path)))&&(o.push({key:`reference:${e.key}`,label:e.path,description:`Open recent ${e.kind}`,target:{type:`reference`,reference:e}}),o.length>=n)))break}return[...i,...o]}function at(e,t){let n=q(e);if(n===`workspace`||n===`artifacts`)return{type:`folder`,folder:n};if(!n)return null;let r=t.find(e=>q(e.path)===n);if(r)return{type:`reference`,reference:r};let i=t.filter(e=>q(st(e.path))===n);return i.length===1?{type:`reference`,reference:i[0]}:null}function q(e){return e.trim().replaceAll(`\\`,`/`).toLowerCase()}function ot(e,t){return!e||q(t).includes(e)}function st(e){let t=e.replaceAll(`\\`,`/`);return t.slice(t.lastIndexOf(`/`)+1)}var ct=new Set;function lt(e){for(let t of ct)t(e)}function ut(e){return ct.add(e),()=>{ct.delete(e)}}var dt=64,J=new Map,Y=new Map;function X(e){return[e.scope??`chat`,e.projectId,e.gezelId,e.taskRef??``,e.craftbookRef??``].join(`|`)}function ft(e){return`${X(e)}|${e.sessionId??`new`}`}function pt(e){return J.get(e)}function Z(e,t){if(!t){J.delete(e);return}for(J.delete(e),J.set(e,t);J.size>dt;){let e=J.keys().next();if(e.done)break;J.delete(e.value)}}var mt=new Set;function ht(e){return mt.add(e),()=>{mt.delete(e)}}function gt(){for(let e of mt)e()}function _t(e){return Y.get(e)}function Q(e,t){for(Y.delete(e),Y.set(e,t);Y.size>dt;){let e=Y.keys().next();if(e.done)break;Y.delete(e.value)}gt()}function $(e){Y.delete(e);for(let[t,n]of J)n===e&&J.delete(t);gt()}var vt=1e3;function yt(e){let{address:t,sessionId:n,draftId:r,onDraftIdChange:i,getText:a,onLoaded:o}=e,{scope:s,projectId:c,gezelId:l,taskRef:u,craftbookRef:d}=t,f=(0,F.useMemo)(()=>ft({...s?{scope:s}:{},projectId:c,gezelId:l,...u?{taskRef:u}:{},...d?{craftbookRef:d}:{},sessionId:n??null}),[s,c,l,u,d,n]),[p,m]=(0,F.useState)(()=>r??pt(f)??null),[h,g]=(0,F.useState)(null),[v,y]=(0,F.useState)({phase:`idle`,dirty:!1,error:null}),ee=(0,F.useRef)(p),b=(0,F.useRef)(f),x=(0,F.useRef)(!1),S=(0,F.useRef)(n===void 0),C=(0,F.useRef)(!1),w=(0,F.useRef)(null),T=(0,F.useRef)(!1),E=(0,F.useRef)(0),D=(0,F.useRef)(a);D.current=a;let O=(0,F.useRef)(o);O.current=o;let te=(0,F.useRef)(i);te.current=i;let k=(0,F.useRef)(t);k.current=t;let ne=(0,F.useRef)(n);ne.current=n;let A=(0,F.useCallback)(e=>{ee.current=e,m(e)},[]),j=(0,F.useRef)(null),ie=(0,F.useRef)(null),ae=(0,F.useCallback)(async e=>{let t=ee.current;if(!t)return;let n=k.current.projectId;if(!e.trim()&&!x.current){await _.deletePromptDraft(n,t).catch(()=>{}),$(t),Z(b.current,void 0),j.current=null,ie.current=null,A(null),g(null),te.current?.(void 0);return}try{let r=await _.writePromptDraftContent(n,t,e);if(r.deleted){$(t),Z(b.current,void 0),A(null),g(null),te.current?.(void 0);return}r.draft&&(g(r.draft),x.current=r.draft.hasFiles),Q(t,e)}catch(e){if(bt(e)){$(t),Z(b.current,void 0),A(null),g(null),te.current?.(void 0);return}throw e}},[A]),oe=(0,F.useCallback)(e=>{if(j.current&&ie.current===e)return j.current.configure(ae),j.current;let t=new re({resourceKey:`prompt-draft:${k.current.projectId}:${e}`,initialValue:_t(e)??``,save:ae,debounceMs:vt});return t.subscribe(e=>y(e)),j.current=t,ie.current=e,t},[ae]),se=(0,F.useCallback)(async()=>{let e=ee.current;if(e)return e;if(w.current)return w.current;let t=k.current.projectId,n=(async()=>{let e=await _.createPromptDraft(t,{gezelId:k.current.gezelId,sessionId:ne.current??null,content:D.current(),...k.current.taskRef?{taskRef:k.current.taskRef}:{},...k.current.craftbookRef?{craftbookRef:k.current.craftbookRef}:{},...k.current.scope?{scope:k.current.scope}:{}});if(T.current)throw await _.deletePromptDraft(t,e.id).catch(()=>{}),Error(`draft discarded while it was being created`);S.current=ne.current===void 0,x.current=e.hasFiles,Z(b.current,e.id),A(e.id),g(e),te.current?.(e.id),Q(e.id,e.content);let n=oe(e.id),r=D.current();return r!==e.content&&(Q(e.id,r),n.update(r)),e.id})();w.current=n;try{return await n}finally{w.current===n&&(w.current=null)}},[oe,A]),ce=(0,F.useCallback)(e=>{let t=ee.current;if(t){let n=oe(t);Q(t,e),n.update(e);return}e.trim()&&(T.current=!1,se().catch(()=>{}))},[se,oe]),le=(0,F.useCallback)(async()=>{w.current&&await w.current.catch(()=>{});let e=ee.current;!e||ie.current!==e||await j.current?.flush().catch(()=>{})},[]),ue=(0,F.useCallback)(()=>{let e=ee.current;e&&(j.current=null,ie.current=null,$(e),Z(b.current,void 0),x.current=!1,C.current=!1,A(null),g(null),y({phase:`idle`,dirty:!1,error:null}),te.current?.(void 0))},[A]),de=(0,F.useCallback)(async()=>{T.current=!0,w.current&&await w.current.catch(()=>{});let e=ee.current;j.current=null,ie.current=null,x.current=!1,C.current=!1,A(null),g(null),y({phase:`idle`,dirty:!1,error:null}),te.current?.(void 0),e&&($(e),Z(b.current,void 0),await _.deletePromptDraft(k.current.projectId,e).catch(()=>{}))},[A]),fe=(0,F.useCallback)(()=>{x.current=!0},[]),pe=(0,F.useCallback)(async()=>{await j.current?.retry().catch(()=>{})},[]),me=(0,F.useCallback)(async(e,t)=>{let n=_t(e);n!==void 0&&!D.current().trim()&&n!==D.current()&&O.current(n,{id:e});try{let n=await _.getPromptDraft(k.current.projectId,e);if(E.current!==t)return;x.current=n.hasFiles,C.current=n.sessionId===null,Q(e,n.content),g(n);let r=oe(e);if(r.getSnapshot().dirty)return;let i=r.hydrate(n.content);i!==D.current()&&O.current(i,n)}catch(n){if(E.current!==t)return;bt(n)&&($(e),Z(b.current,void 0),A(null),g(null),te.current?.(void 0))}},[oe,A]),he=(0,F.useRef)(f),ge=(0,F.useRef)(t.gezelId),_e=(0,F.useRef)(t.projectId),M=(0,F.useRef)(n),ve=(0,F.useRef)(r),ye=(0,F.useRef)(!1);(0,F.useEffect)(()=>{let e=he.current,i=ge.current!==t.gezelId,a=_e.current!==t.projectId,o=M.current===void 0&&n!==void 0,s=ve.current!==r,c=!ye.current,l=!c&&ve.current!==void 0&&r===void 0;b.current=f,he.current=f,ge.current=t.gezelId,_e.current=t.projectId,M.current=n,ve.current=r,ye.current=!0;let u=ee.current;if(!c&&u&&i&&!a&&!s){Z(e,void 0),Z(f,u),_.patchPromptDraft(t.projectId,u,{gezelId:t.gezelId,sessionId:n??null}).then(e=>g(e)).catch(()=>{});return}if(!c&&u&&o&&S.current&&!C.current&&!s){S.current=!1,Z(e,void 0),Z(f,u),_.patchPromptDraft(t.projectId,u,{sessionId:n??null}).then(e=>g(e)).catch(()=>{});return}if(!c&&!s&&e===f)return;l&&Z(f,void 0);let d=r??pt(f);if(d&&d===u){Z(f,d);return}let p=++E.current;if(j.current=null,ie.current=null,T.current=!1,S.current=n===void 0,y({phase:`idle`,dirty:!1,error:null}),d){Z(f,d),A(d),me(d,p);return}let m=u?``:D.current();A(null),g(null),x.current=!1,C.current=!1,!c&&!m.trim()&&O.current(``,{id:``}),n!==void 0&&(async()=>{try{let{drafts:e}=await _.listPromptDrafts(t.projectId,{gezelId:t.gezelId,sessionId:n,status:`draft`});if(E.current!==p)return;let r=e[0];if(!r)return;Z(f,r.id),A(r.id),await me(r.id,p)}catch{}})()},[f,r]),(0,F.useEffect)(()=>{let e=()=>{j.current?.flush().catch(()=>{})},t=()=>{document.visibilityState===`hidden`&&e()};return window.addEventListener(`pagehide`,e),document.addEventListener(`visibilitychange`,t),()=>{window.removeEventListener(`pagehide`,e),document.removeEventListener(`visibilitychange`,t),e()}},[]);let be=(0,F.useMemo)(()=>({...v,retry:pe}),[v,pe]);return{draftId:p,meta:h,isFreshThread:C.current||h?.sessionId===null&&n===void 0,autosave:be,update:ce,ensureDraft:se,flush:le,markSent:ue,discard:de,noteFileAdded:fe}}function bt(e){let t=e instanceof Error?e.message:String(e);return/\b404\b/.test(t)||/not found/i.test(t)}function xt(){return(0,I.jsx)(`svg`,{width:`16`,height:`16`,viewBox:`0 0 16 16`,fill:`none`,"aria-hidden":`true`,children:(0,I.jsx)(`path`,{d:`M5 6.4 8 3.4l3 3M11 9.6l-3 3-3-3`,stroke:`currentColor`,strokeWidth:`1.4`,strokeLinecap:`round`,strokeLinejoin:`round`})})}function St(){return(0,I.jsx)(`svg`,{width:`16`,height:`16`,viewBox:`0 0 16 16`,fill:`none`,"aria-hidden":`true`,children:(0,I.jsx)(`path`,{d:`M5 3.4l3 3 3-3M11 12.6l-3-3-3 3`,stroke:`currentColor`,strokeWidth:`1.4`,strokeLinecap:`round`,strokeLinejoin:`round`})})}function Ct(){return(0,I.jsxs)(`svg`,{width:`14`,height:`14`,viewBox:`0 0 14 14`,fill:`none`,"aria-hidden":`true`,children:[(0,I.jsx)(`path`,{d:`M7 1.75c.3 2.55 1.7 3.95 4.25 4.25C8.7 6.3 7.3 7.7 7 10.25 6.7 7.7 5.3 6.3 2.75 6 5.3 5.7 6.7 4.3 7 1.75Z`,stroke:`currentColor`,strokeWidth:`1.2`,strokeLinecap:`round`,strokeLinejoin:`round`}),(0,I.jsx)(`circle`,{cx:`10.75`,cy:`10.75`,r:`0.75`,fill:`currentColor`})]})}function wt(e){return(e.output?.label??e.specialist?.label??e.display.label).replace(/^Planned:\s*/i,``).replace(/\s*\([^)]*\)\s*$/,``)}var Tt={showFilesWhenNotEmpty:!0};function Et({projectId:e,disabled:t,onAppendTranscript:n,onError:r}){let{replaceAll:i}=E();return(0,I.jsx)(Ue,{projectId:e,disabled:t,onTranscript:(0,F.useCallback)(e=>{let t=n(e);t!==null&&i(t)},[n,i]),onError:r})}function Dt({gezelId:e,gezelName:t,gezelRoleBasedName:n,gezelRole:r,gezelIcon:a,gezelPoppetje:o,gezelIconOverride:l,focusRequestKey:u,recipientGezels:f,onPrimaryRecipientChange:p,projectId:m,sessionId:v,onSessionCreated:y,onToolActivity:b,recentReferences:x=[],onOpenReference:S,craftbookRef:C,onTurnStateChange:w,placeholder:T,taskRef:E,stepId:D,belowAddressLine:O,addressLineTrailing:te,onPivotToMention:ne,passiveCcGezelIds:j,onPassiveCcConsumed:re,onTerminalEscape:ie,draftScope:ae,draftId:oe,onDraftIdChange:se}){let ce=(0,F.useRef)(null);(0,F.useEffect)(()=>{if(!u)return;let e=window.requestAnimationFrame(()=>{ce.current?.querySelector(`.squisq-wysiwyg-editor`)?.focus({preventScroll:!0})});return()=>window.cancelAnimationFrame(e)},[u]);let le=A(),ue=ge(),de=s({name:t,roleBasedName:n},ue),[pe,me]=(0,F.useState)(!1),[he,_e]=(0,F.useState)(!1),[M,ve]=(0,F.useState)(!1),[be,N]=(0,F.useState)(null),xe=(0,F.useRef)(!1),[P,we]=(0,F.useState)(!1),[Te,Ee]=(0,F.useState)(null),[De,ke]=(0,F.useState)(null),Ae=(0,F.useMemo)(()=>({...ae?{scope:ae}:{},projectId:m,gezelId:e,...E?{taskRef:E}:{},...C?{craftbookRef:C}:{}}),[C,ae,e,m,E]),L=(0,F.useRef)((()=>{let e=ft({...Ae,sessionId:v??null}),t=oe??pt(e);return(t?_t(t):void 0)??``})()),je=(0,F.useRef)(0),Me=(0,F.useRef)(()=>{}),Ne=(0,F.useRef)(async()=>{}),Pe=(0,F.useRef)(async()=>``),Fe=(0,F.useRef)(()=>{}),Ie=(0,F.useRef)(!1),R=(0,F.useRef)(L.current.length),[Le,Re]=(0,F.useState)(()=>L.current.trim().length>0),[ze,Be]=(0,F.useState)(L.current),[Ve,He]=(0,F.useState)(null),[Ue,We]=(0,F.useState)(()=>rt(L.current)),[Ge,z]=(0,F.useState)(0),B=(0,F.useCallback)(()=>{let e=Se(m);if(!e)return;let t=L.current.trim(),n=t?`${t}\n\n${e}`:e;L.current=n,Me.current(n),je.current+=1,R.current=n.length,Re(n.trim().length>0),Be(n),We(rt(n)),z(e=>e+1)},[m]);(0,F.useEffect)(()=>{B();let e=e=>{e.detail?.projectId===m&&B()};return window.addEventListener(Ce,e),()=>window.removeEventListener(Ce,e)},[B,m]);let[Ke,qe]=(0,F.useState)(()=>i(L.current)),V=yt({address:Ae,sessionId:v,draftId:oe,onDraftIdChange:se,getText:()=>L.current,onLoaded:e=>{L.current=e,R.current=e.length,je.current+=1,Re(e.trim().length>0),Be(e),We(rt(e)),qe(i(e)),z(e=>e+1)}}),Ye=(0,F.useRef)(V.draftId);Ye.current=V.draftId,Me.current=V.update,Ne.current=V.discard,Pe.current=V.ensureDraft,Fe.current=V.noteFileAdded,Ie.current=V.isFreshThread;let[H,U]=(0,F.useState)([]);(0,F.useEffect)(()=>{U([])},[e,m]);let Xe=(0,F.useMemo)(()=>{let e=new Map((f??[]).map(e=>[e.id,e]));return H.flatMap(t=>{let n=e.get(t);return n?[n]:[]})},[H,f]),[Ze,$e]=(0,F.useState)(`proactive`);(0,F.useEffect)(()=>{_.getConfig().then(e=>$e(e.aiEngagementMode??`proactive`)).catch(()=>{});let e=e=>{let t=e.detail;t?.aiEngagementMode&&$e(t.aiEngagementMode)};return window.addEventListener(`gezel:config-updated`,e),()=>window.removeEventListener(`gezel:config-updated`,e)},[]);let W=Ze===`off`,G=(0,F.useRef)(null),et=(0,F.useRef)(0),K=(0,F.useRef)(v??null),[tt,q]=(0,F.useState)(v??null);(0,F.useEffect)(()=>{let e=v??null,t=K.current;if(K.current=e,q(e),t===e)return;let n=G.current;n&&n.sessionId!==e&&(G.current=null,n.controller.abort()),me(!1),ve(!1),Ee(null),ke(null)},[v]);let ot=(0,F.useRef)(0),st=(0,F.useRef)(`${e}\u0000${m}\u0000${tt??``}`);(0,F.useEffect)(()=>{let t=ze.trim(),n=++ot.current,r=`${e}\u0000${m}\u0000${tt??``}`,i=st.current!==r;if(st.current=r,t.length<8||rt(ze)!==null){He(null);return}i&&He(null);let a=window.setTimeout(()=>{_.previewTurnIntent({message:ze,gezelId:e,projectId:m,...tt?{sessionId:tt}:{}}).then(e=>{ot.current===n&&He(e.visible?e:null)}).catch(()=>{})},350);return()=>window.clearTimeout(a)},[e,ze,tt,m]);let ct=(0,F.useCallback)(async()=>{let t=await _.createChatSession({gezelId:e,projectId:m,...E?{taskRef:E}:{},...D?{stepId:D}:{},...C?{craftbookRef:C}:{}});return K.current=t.id,q(t.id),y?.(t.id),t.id},[e,m,E,D,C,y]),ut=(0,F.useCallback)(async()=>{if(K.current)return K.current;if(Ie.current)return ct();try{if(E){let t=h(E);if(t){let n=(await _.listTaskSessions(t.projectId,t.num)).sessions.find(t=>!t.archived&&t.gezelId===e);if(n)return K.current=n.id,q(n.id),y?.(n.id),n.id}}else{let t=(await _.listChatSessions({gezelId:e,projectId:m})).sessions.find(e=>!e.archived&&!e.taskRef);if(t)return K.current=t.id,q(t.id),y?.(t.id),t.id}}catch{}return ct()},[e,m,E,ct,y]),dt=(0,F.useMemo)(()=>nt({projectId:m,getDraftId:()=>Ye.current,ensureDraftId:async()=>{let e=await Pe.current();return Fe.current(),e}}),[m]);(0,F.useEffect)(()=>()=>{G.current?.controller.abort(),G.current=null,dt.dispose()},[dt]);let J=(0,F.useCallback)((e,t={})=>{let n=G.current;!n||n.id!==e||(G.current=null,t.abort&&n.controller.abort(),me(!1),Ee(null),t.serverIdle&&ve(!1))},[]),Y=(0,F.useCallback)(async(e,t)=>{let n=G.current,r=n?.sessionId===e&&n.accepted?n.id:null,i=await _.getChatSessionInflight(e);if(t&&!t()||K.current!==e||r!==null&&G.current?.id!==r)return;let a=i.inflight!==null;ve(a),!a&&r!==null&&J(r,{abort:!0,serverIdle:!0})},[J]);(0,F.useEffect)(()=>{if(!tt){ve(!1);return}let e=!1,t=async()=>{try{e||await Y(tt,()=>!e)}catch{}};t();let n=window.setInterval(()=>void t(),2e3);return()=>{e=!0,window.clearInterval(n)}},[tt,Y]);let X=pe||M,Z=(0,F.useRef)(X);Z.current=X;let mt=(0,F.useCallback)(async e=>{try{return(await _.listMentionCandidates({projectId:m,query:e})).candidates.map(e=>({id:e.id,label:ue&&e.roleBasedName?e.roleBasedName:e.label,scheme:`gezel`,...e.description?{description:e.description}:{},...e.group?{group:e.group}:{}}))}catch{return[]}},[m,ue]);(0,F.useEffect)(()=>{w?.(be?`error`:Te===null?X?`streaming`:`idle`:`queued`,be??void 0)},[X,Te,be,w]);let ht=(0,F.useCallback)(e=>{let t=R.current;R.current=e.length;let n=L.current!==e;if(L.current=e,Me.current(e),n&&(je.current+=1),Re(e.trim().length>0),Be(e),We(rt(e)),ie&&t<=2){let t=e.trimStart().match(/^>\s+([^\n]*)/);if(t){Ne.current(),ie((t[1]??``).trim());return}}let r=i(e);qe(e=>Ot(e,r)?e:r)},[ie]),gt=(0,F.useCallback)(e=>{let t=e.trim();if(!t)return null;let n=L.current,r=`${n}${n&&!/\s$/.test(n)?` `:``}${t}`;L.current=r,Me.current(r),je.current+=1,R.current=r.length,Re(!0),Be(r),We(rt(r));let a=i(r);return qe(e=>Ot(e,a)?e:a),r},[]),Q=(0,F.useCallback)(()=>{if(xe.current)return null;let e=L.current;return e.trim()?(xe.current=!0,we(!0),{source:e,editVersion:je.current}):null},[]),$=(0,F.useCallback)(()=>{xe.current=!1,we(!1)},[]),vt=(0,F.useCallback)(e=>{je.current!==e.editVersion||L.current!==e.source||(L.current=``,R.current=0,Re(!1),Be(``),We(null),z(e=>e+1),qe([]))},[]),bt=(0,F.useMemo)(()=>Ue===null?[]:it(Ue,x),[Ue,x]),Dt=(0,F.useCallback)(async e=>{let t=Q();if(!t)return;let n=rt(t.source),r=e??(n===null?null:at(n,x));if(!r){N(n?`No recent file matches “${n}”. Choose a suggestion or use workspace or artifacts.`:`Choose workspace, artifacts, or a recent file.`),$();return}N(null);try{if(r.type===`folder`)await _.revealProject(m,r.folder);else if(S)S(r.reference);else throw Error(`Recent file opening is unavailable in this chat.`);Ne.current(),vt(t)}catch(e){N(`Open failed: ${e instanceof Error?e.message:String(e)}`)}finally{$()}},[Q,vt,$,S,m,x]),At=(0,F.useRef)(null);(0,F.useEffect)(()=>{if(!ne){At.current=null;return}let t=Ke.find(t=>t.id!==e&&(!t.projectId||t.projectId===m));if(!t){At.current=null;return}At.current!==t.id&&(At.current=t.id,ne(t.id))},[Ke,e,m,ne]);let Nt=(0,F.useCallback)(async()=>{if(rt(L.current)!==null){await Dt();return}if(!e||X||W)return;let t=Q();if(!t)return;let n=t.source.trim();N(null),Ee(null);let r;try{await V.flush(),r=await V.ensureDraft()??void 0}catch{r=void 0}let i;try{i=await ut()}catch(e){N(Mt(e.message)),$();return}let a=++et.current,o=new AbortController;G.current={id:a,sessionId:i,controller:o,accepted:!1};let s=(async()=>{let e=0,t=0;for(;;){let n=0;try{for await(let e of g({url:_.sessionEventsUrl(i),headers:_.authHeader(),signal:o.signal,fetch:_.getFetch(),keepaliveTimeoutMs:1e4})){if(G.current?.id!==a)return;if(e.type===`tool`){if(n+=1,n<=t)continue;t=n;let r={name:e.name,durationMs:e.durationMs,success:e.success,...e.errorMessage?{errorMessage:e.errorMessage}:{},...e.path?{path:e.path}:{},...e.paths&&e.paths.length>0?{paths:e.paths}:{},...e.argsSummary?{argsSummary:e.argsSummary}:{},...e.argsFull?{argsFull:e.argsFull}:{},...e.resultText?{resultText:e.resultText}:{},...e.resultTruncated?{resultTruncated:!0}:{},...e.diff===void 0?{}:{diff:e.diff},...e.addedLines===void 0?{}:{addedLines:e.addedLines},...e.removedLines===void 0?{}:{removedLines:e.removedLines},...e.card?{card:e.card}:{},projectId:m};b?.(r)}else if(e.type===`error`)N(jt(e.error)),Ee(null);else if(e.type===`done`){J(a,{serverIdle:!0});return}else e.type===`queued`?Ee(e.aheadOf):e.type===`delta`&&Ee(null)}return}catch(t){if(t.name===`AbortError`){J(a);return}if(G.current?.id!==a)return;if(e+=1,e>5){console.warn(`[ChatComposer] chat event stream lost, giving up:`,t),N(Mt(t.message)),J(a);return}let n=Math.min(500*2**(e-1),5e3);if(console.warn(`[ChatComposer] chat event stream lost (reconnect ${e}/5 in ${n}ms):`,t),await new Promise(e=>setTimeout(e,n)),o.signal.aborted||G.current?.id!==a)return}}})();try{let o=[...new Set([...c(n),...H])].filter(t=>t!==e),s=(j??[]).filter(t=>t&&t!==e),l={message:n};o.length>0&&(l.mentions=o),s.length>0&&(l.passiveCcGezelIds=s),r&&(l.draftId=r),await _.sendToChatSession(i,l);let u=G.current;u?.id===a&&(u.accepted=!0,me(!0),Y(i).catch(()=>{})),r&&V.markSent(),vt(t),lt({sessionId:i,gezelId:e,projectId:m,content:r?d(n,r):n,at:new Date().toISOString()}),s.length>0&&re?.()}catch(e){o.abort(),J(a);let t=e.message??String(e);if(/already in flight/i.test(t))try{let{inflight:e}=await _.getChatSessionInflight(i);e?(ke({userText:e.userText,elapsedMs:e.elapsedMs,sessionId:i}),N(null)):N(jt(t))}catch{N(jt(t))}else N(Mt(t))}finally{$()}await s},[e,m,X,W,Q,vt,ut,$,J,Y,b,H,j,re,Dt,V]),Pt=(0,F.useCallback)(async()=>{if(De){try{await _.cancelChatSessionTurn(De.sessionId)}catch(e){N(`Cancel failed: ${e.message}`);return}ke(null),N(null)}},[De]),Ft=(0,F.useCallback)(async()=>{let e=K.current,t=G.current;if(t?(t.controller.abort(),J(t.id)):(me(!1),Ee(null)),!e){ve(!1);return}try{await _.cancelChatSessionTurn(e),ve(!1),N(null)}catch(e){N(`Cancel failed: ${e.message}`)}},[J]);(0,F.useEffect)(()=>{let e=e=>{!Z.current||xe.current||e.key!==`Escape`||e.defaultPrevented||(e.preventDefault(),Ft())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[Ft]);let It=(0,F.useCallback)(async()=>{let t=K.current;if(!e||!t||W)return;let n=Q();if(!n)return;let r=n.source.trim();N(null);let i;try{await V.flush(),i=await V.ensureDraft()??void 0}catch{i=void 0}try{await _.sendToChatSession(t,{message:r,nudge:!0,...i?{draftId:i}:{}}),i&&V.markSent(),vt(n)}catch(e){N(jt(e.message??String(e)))}finally{$()}},[e,W,Q,vt,$,V]),Lt=(0,F.useCallback)(async()=>{let t=K.current;if(!e||!t||W)return;let n=Q();if(!n)return;let r=n.source.trim();N(null),ve(!0);let i;try{await V.flush(),i=await V.ensureDraft()??void 0}catch{i=void 0}try{await _.interruptChatSession(t,{message:r,...i?{draftId:i}:{}}),i&&V.markSent(),vt(n),Y(t).catch(()=>{})}catch(e){N(jt(e.message??String(e)))}finally{$()}},[e,W,Q,vt,$,Y,V]),Rt=(0,F.useRef)(()=>{});return Rt.current=P?()=>{}:Ue===null?X?()=>void It():()=>void Nt():()=>void Dt(),(0,I.jsxs)(`div`,{ref:ce,className:`chat-composer`,"data-testid":`chat-composer`,"data-composer-expanded":he?`true`:void 0,children:[W&&(0,I.jsxs)(`div`,{className:`chat-composer-disabled-banner`,role:`alert`,children:[(0,I.jsx)(`span`,{children:`AI disabled in Settings → General. Chat is paused.`}),(0,I.jsx)(`button`,{type:`button`,onClick:()=>window.dispatchEvent(new CustomEvent(`gezel:navigate`,{detail:{view:`settings`}})),children:`Open Settings`})]}),De&&(0,I.jsxs)(`div`,{className:`chat-composer-wedged`,children:[(0,I.jsxs)(`div`,{className:`chat-composer-wedged-head`,children:[(0,I.jsx)(`strong`,{children:`Previous turn still running`}),(0,I.jsxs)(`span`,{className:`muted`,children:[` · `,kt(De.elapsedMs)]})]}),(0,I.jsx)(`div`,{className:`chat-composer-wedged-preview`,children:De.userText.length>180?`${De.userText.slice(0,177)}…`:De.userText}),(0,I.jsxs)(`div`,{className:`chat-composer-wedged-actions`,children:[(0,I.jsx)(`button`,{type:`button`,onClick:()=>void Pt(),children:`Cancel stuck turn`}),(0,I.jsx)(`button`,{type:`button`,className:`subtle`,onClick:()=>ke(null),children:`Dismiss`})]})]}),be&&(0,I.jsxs)(`div`,{className:`chat-composer-error`,role:`alert`,children:[(0,I.jsx)(`span`,{className:`chat-composer-error-mark`,"aria-hidden":`true`,children:`✗`}),(0,I.jsx)(`span`,{className:`chat-composer-error-text`,children:be})]}),(0,I.jsxs)(`div`,{className:`chat-composer-to`,children:[(0,I.jsx)(`span`,{className:`chat-composer-to-label muted`,children:`To:`}),(0,I.jsx)(fe,{svg:a??null,poppetje:o,iconOverride:l,name:de,size:18}),(0,I.jsxs)(`span`,{className:`chat-composer-to-text`,children:[(0,I.jsx)(`span`,{className:`chat-composer-to-name`,children:de}),!ue&&r&&(0,I.jsx)(`span`,{className:`chat-composer-to-role`,children:r})]}),Xe.map(e=>{let t=s({name:e.name,roleBasedName:e.roleBasedName},ue);return(0,I.jsxs)(`span`,{className:`chat-composer-to-recipient`,children:[(0,I.jsx)(fe,{svg:e.icon??null,poppetje:e.poppetje,iconOverride:e.iconOverride,name:t,size:18}),(0,I.jsxs)(`span`,{className:`chat-composer-to-text`,children:[(0,I.jsx)(`span`,{className:`chat-composer-to-name`,children:t}),!ue&&e.role&&(0,I.jsx)(`span`,{className:`chat-composer-to-role`,children:e.role})]}),(0,I.jsx)(`button`,{type:`button`,className:`chat-composer-recipient-remove`,"aria-label":`Remove ${t} from recipients`,title:`Remove ${t}`,onClick:()=>U(t=>t.filter(t=>t!==e.id)),children:`×`})]},e.id)}),Ke.filter(t=>(t.id!==e||t.projectId!==void 0)&&!H.includes(t.id)).map(e=>(0,I.jsxs)(`span`,{className:`chat-composer-to-mention`,title:e.projectId?`@${e.label} re: ${e.projectId}`:`@${e.label}`,children:[`@`,e.label]},e.rawId)),f&&p&&f.length>0&&(0,I.jsx)(Je,{gezels:f,primaryGezelId:e,additionalRecipientIds:H,roleBasedNameOnlyMode:ue,onSelectPrimary:e=>{U([]),p(e)},onAddRecipient:t=>U(n=>t===e||n.includes(t)?n:[...n,t])}),(0,I.jsx)(`button`,{type:`button`,className:`chat-composer-expand-btn`,"data-testid":`chat-composer-expand`,onClick:()=>_e(e=>!e),"aria-pressed":he,"aria-label":he?`Collapse the draft`:`Expand the draft`,title:he?`Collapse the draft back to a few lines`:`Expand the draft to fill the chat window`,children:he?(0,I.jsx)(St,{}):(0,I.jsx)(xt,{})}),te]}),O,(0,I.jsxs)(`div`,{className:`chat-editor-wrap`,children:[Ue!==null&&(0,I.jsxs)(`div`,{className:`chat-open-command-menu`,role:`menu`,"aria-label":`Open targets`,children:[(0,I.jsxs)(`div`,{className:`chat-open-command-heading`,children:[(0,I.jsx)(`code`,{children:`/open`}),(0,I.jsx)(`span`,{children:`Project folders and recent chat files`})]}),bt.length>0?(0,I.jsx)(`div`,{className:`chat-open-command-items`,children:bt.map(e=>(0,I.jsxs)(`button`,{type:`button`,role:`menuitem`,className:`chat-open-command-item`,"aria-label":e.target.type===`folder`?`Open ${e.target.folder} folder`:`Open ${e.label}`,onMouseDown:e=>e.preventDefault(),onClick:()=>void Dt(e.target),children:[(0,I.jsx)(`code`,{children:e.label}),(0,I.jsx)(`span`,{children:e.description})]},e.key))}):(0,I.jsx)(`p`,{className:`chat-open-command-empty`,children:`No matching recent files.`})]}),(0,I.jsx)(k,{initialMarkdown:L.current,hostMode:`chat`,mediaProvider:dt,mentionProvider:mt,...T?{placeholder:T}:{},imageDisplayMode:`thumbnail`,onChange:ht,submitOnEnter:()=>Rt.current(),minHeight:he?`100%`:`120px`,maxHeight:he?`100%`:`50vh`,colorScheme:le,uxFont:`var(--font-ui)`,showPlayTab:!1,showStatusBar:!1,showFilesToggle:!0,...Tt,fullWidth:!0,thinMargins:!0,toolbarSlotAfterActions:(0,I.jsx)(Oe,{mediaProvider:dt,onError:N}),toolbarSlotRight:(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(Qe,{onError:N}),(0,I.jsx)(ye,{autosave:V.autosave,failuresOnly:!0}),Ve&&(0,I.jsxs)(`output`,{className:`chat-turn-intent-preview`,"aria-label":`${Ve.display.label}. ${Ve.display.detail??``}`.trim(),title:`${Ve.display.label}${Ve.display.detail?` — ${Ve.display.detail}`:``}. Gezel will add this route when you send.`,children:[(0,I.jsx)(Ct,{}),(0,I.jsx)(`span`,{children:wt(Ve)})]}),(0,I.jsx)(Et,{projectId:m,disabled:!e||W||P,onAppendTranscript:gt,onError:N}),Ue===null?X?(0,I.jsxs)(I.Fragment,{children:[Le&&!W&&(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`button`,{type:`button`,className:`chat-send-btn chat-nudge-btn`,"data-testid":`chat-nudge`,onClick:()=>void It(),disabled:P,title:`Queue for after this turn (Enter)`,children:`Nudge`}),(0,I.jsx)(`button`,{type:`button`,className:`chat-interrupt-btn`,"data-testid":`chat-interrupt`,onClick:()=>void Lt(),disabled:P,title:`Stop this turn and send now`,children:`Interrupt`})]}),(0,I.jsx)(`button`,{type:`button`,className:`chat-stop-btn`,onClick:()=>void Ft(),disabled:P,title:`Stop generating (Escape)`,children:`■ Stop`})]}):(0,I.jsx)(`button`,{type:`button`,className:`chat-send-btn chat-send-btn-icon`,"data-testid":`chat-send`,onClick:Nt,disabled:!e||W||P,"aria-label":P?`Sending…`:`Send`,"aria-busy":P,title:W?`AI is disabled in Settings → General`:`Enter to send, Shift+Enter for newline`,children:(0,I.jsx)(ee,{})}):(0,I.jsx)(`button`,{type:`button`,className:`chat-send-btn`,"data-testid":`chat-open`,onClick:()=>void Dt(),disabled:P,title:`Open this folder or recent file (Enter)`,children:P?`Opening…`:`Open`})]})},`${Ge}:${e}:${T??``}`)]})]})}function Ot(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++){let r=e[n],i=t[n];if(!r||!i||r.rawId!==i.rawId||r.label!==i.label)return!1}return!0}function kt(e){let t=Math.floor(e/1e3);return t<60?`${t}s elapsed`:`${Math.floor(t/60)}m ${t%60}s elapsed`}function At(e){let t=/"error"\s*:\s*"model_not_loaded"/.test(e)||/model_not_loaded/.test(e),n=/is not available locally for provider/i.test(e),r=/"error"\s*:\s*"model_not_found"/.test(e);if(!t&&!n&&!r)return;let i=/"model"\s*:\s*"([^"]+)"/.exec(e)?.[1],a=/Model\s+"([^"]+)"/i.exec(e)?.[1],o=i??a??``,s=o.indexOf(`:`);return s===-1?o:o.slice(s+1)}function jt(e){if(!e)return e;let t=At(e);return t===void 0?/Timeout\s+after\s+\d+ms\s+waiting\s+for\s+session\.idle/i.test(e)?`Copilot stalled without streaming a reply — this usually means the SDK lost its connection. Your message is saved; try Send again, or pick a different model in Settings → Defaults.`:/timed out after \d+s/i.test(e)?`The model didn't respond in time. Your message is saved — try Send again.`:e:`The model ${t?`"${t}" `:``}isn't available on this device — it may never have finished downloading. Pick a model that is installed, or download this one, in Settings → Artificial Intelligence.`}function Mt(e){return/network\s?error/i.test(e)||/failed to fetch/i.test(e)||/load failed/i.test(e)||/transport unavailable/i.test(e)||/SSE stream (stale|failed)/i.test(e)||/ended before a terminal event/i.test(e)?`Lost the connection to the gezel service and could not reconnect. Your message is saved — if no reply appears, check that the service is running and try Send again.`:jt(e)}function Nt(e){let t=Ft(e);return t===``?`/`:t.startsWith(`/`)||/^[A-Za-z]:[\\/]/.test(t)?t:`/${t}`}var Pt=/\x1b\[[0-9;?]*[ -/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b[@-_]|\uFFFD\[[0-9;?]*[ -/]*[@-~]/g;function Ft(e){let t=``;for(let n of e.replace(Pt,``)){let e=n.charCodeAt(0);e>=32&&e!==127&&(t+=n)}return t.trim()}function It(e){return e.replace(/!\[([^\]]*)\]\([^)]*\)/g,`$1`).replace(/@\[([^\]]+)\]\([^)]+\)/g,`@$1`).replace(/\[([^\]]+)\]\([^)]+\)/g,`$1`).replace(/\*\*([^*]+)\*\*/g,`$1`).replace(/__([^_]+)__/g,`$1`).replace(/(?<!\*)\*([^*]+)\*(?!\*)/g,`$1`).replace(/(?<!_)_([^_]+)_(?!_)/g,`$1`).replace(/~~([^~]+)~~/g,`$1`).replace(/`+([^`]+)`+/g,`$1`).replace(/^\s*#+\s+/gm,``).replace(/^\s*>\s+/gm,``).replace(/^\s*[-*+]\s+/gm,``).replace(/^\s*\d+\.\s+/gm,``).replace(/\s+/g,` `).trim()}function Lt({payload:e,gezels:t}){let{userMsg:n,assistantInfo:r}=e,i=r.kind===`live`,o=i?r.slot:null,c=se(i?o?.startedAt??null:null),l=i?r.sessionId:r.msg.gezelId,d=t.get(i?o?.gezelId??``:r.msg.gezelId),f=ge(),m=d?s({name:d.name,roleBasedName:d.roleBasedName},f):`Gezel`,h=n.origin===`system`?a(n.content):null,g=h?p(h,m):It(n.content);return(0,I.jsxs)(`div`,{className:`chat-sticky-header`,"aria-live":`polite`,children:[(0,I.jsxs)(`div`,{className:`chat-sticky-header-user`,title:n.content,children:[(0,I.jsx)(`span`,{className:`chat-sticky-header-author`,children:h?u(h).toUpperCase():n.origin===`system`?`SYSTEM`:`YOU`}),(0,I.jsx)(`span`,{className:`chat-sticky-header-preview`,children:g})]}),(0,I.jsxs)(`div`,{className:`chat-sticky-header-assistant`,children:[(0,I.jsx)(fe,{svg:d?.icon??null,poppetje:d?.poppetje,iconOverride:d?.iconOverride,name:m,size:18}),(0,I.jsx)(`span`,{className:`chat-sticky-header-author`,children:m}),!f&&d?.role&&(0,I.jsx)(de,{role:d.role}),i&&o&&(0,I.jsx)(oe,{failed:!!o.error,queued:o.queueAhead!==void 0&&M(o.queuedAt,Date.now())&&!ne(o.segments),queueAhead:o.queueAhead,elapsedSeconds:c,toolCount:ie(o.segments),wirePulseCount:o.wirePulseCount,...ue(o)?{thinkingLabel:ue(o)}:{},...o.thinkingProgress===void 0?{}:{thinkingProgress:o.thinkingProgress},...o.thinkingDetail?{thinkingDetail:o.thinkingDetail}:{},...o.awaitingGezelName?{awaitingGezelName:o.awaitingGezelName}:{}})]},l)]})}var Rt=`gezel:timeline:indexing-receipts:v1:`;function zt(e){return`${Rt}${e}`}function Bt(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.id==`string`&&typeof t.gezelId==`string`&&typeof t.projectId==`string`&&typeof t.startedAt==`string`&&typeof t.completedAt==`string`&&Array.isArray(t.files)&&t.files.every(e=>typeof e==`string`&&e.length>0)}function Vt(e){if(typeof window>`u`)return[];try{let t=JSON.parse(window.localStorage.getItem(zt(e))??`[]`);return Array.isArray(t)?t.filter(Bt).slice(-20):[]}catch{return[]}}function Ht(e,t){if(!(typeof window>`u`))try{window.localStorage.setItem(zt(e),JSON.stringify(t.slice(-20)))}catch{}}function Ut(e){return/^Indexing\s+(.+)$/i.exec(e?.trim()??``)?.[1]?.trim()||null}function Wt(e,t){let n=Date.parse(t.completedAt),r=-1;for(let i=e.length-1;i>=0;i--){let a=e[i];if(a.gezelId!==t.gezelId||a.projectId!==t.projectId)continue;let o=Date.parse(a.completedAt);Number.isFinite(n)&&Number.isFinite(o)&&n-o<=3e5&&(r=i);break}if(r<0)return[...e,{id:`indexing:${t.sessionId}`,gezelId:t.gezelId,projectId:t.projectId,startedAt:t.startedAt,completedAt:t.completedAt,files:[t.path]}].slice(-20);let i=[...e],a=i[r];return a.files.includes(t.path)?e:(i[r]={...a,completedAt:t.completedAt,files:[...a.files,t.path]},i)}function Gt({receipt:e,gezels:t,projects:n,showProjectName:r,roleBasedNameOnlyMode:i,onOpenWorkspaceFile:a}){let[o,c]=(0,F.useState)(!1),l=t.get(e.gezelId),u=l?s({name:l.name,roleBasedName:l.roleBasedName},i):`Boekwachter`,d=r&&e.projectId!=="default"?n.get(e.projectId):void 0,f=e.files.length;return(0,I.jsxs)(`details`,{className:`timeline-indexing-receipt`,onToggle:e=>c(e.currentTarget.open),children:[(0,I.jsxs)(`summary`,{title:S(e.completedAt),children:[(0,I.jsx)(fe,{svg:l?.icon??null,poppetje:l?.poppetje,iconOverride:l?.iconOverride,name:u,size:16}),(0,I.jsxs)(`span`,{className:`timeline-indexing-receipt-label`,children:[(0,I.jsx)(`strong`,{children:u}),` has indexed `,(0,I.jsx)(`strong`,{children:f}),` `,f===1?`file`:`files`,d&&(0,I.jsxs)(I.Fragment,{children:[` in `,d.name]}),` · `,x(e.completedAt)]})]}),o&&(0,I.jsx)(`ul`,{className:`timeline-indexing-file-list`,children:e.files.map(t=>(0,I.jsx)(`li`,{children:a?(0,I.jsx)(`button`,{type:`button`,className:`timeline-indexing-file-link`,title:`Open ${t}`,"aria-label":`Open ${t}`,onClick:()=>a(t,e.projectId),children:t}):(0,I.jsx)(`span`,{className:`timeline-indexing-file-path`,children:t})},t))})]})}function Kt(e){return e===`dispatching`?`Starting`:e===`night-shift`||e===`night-quota`?`Scheduled`:e===`engagement-off`||e===`engagement-paused`?`On hold`:`In the queue`}function qt(e,t){switch(e){case`dispatching`:return`${t} is picking it up now.`;case`provider-busy`:return`Waiting for a free slot — other work is using the model right now.`;case`night-shift`:return`Parked for Night Shift — it starts when tonight's window opens.`;case`night-quota`:return`Held back by the cloud quota reserve — it starts once the quota frees up.`;case`engagement-off`:return`Held because AI engagement is off. Turn it back on in Settings to let it start.`;case`engagement-paused`:return`Held because AI work is paused. Resume to let it start.`;default:return`Waiting its turn — it starts as soon as ${t} is free.`}}function Jt({task:e,wait:t,gezel:n,onTaskReference:r}){let i=ge(),a=n?s({name:n.name,roleBasedName:n.roleBasedName},i):`the assigned gezel`,o=x(t.since,{style:`long`,fallback:t.since});return(0,I.jsx)(`div`,{className:`msg msg-user msg-system msg-queued-task`,"data-task-ref":e.ref,children:(0,I.jsxs)(`div`,{className:`msg-queued-task-card`,children:[(0,I.jsxs)(`div`,{className:`msg-queued-task-head`,children:[(0,I.jsx)(pe,{area:`tasks`,size:12,className:`msg-queued-task-icon`}),(0,I.jsx)(`span`,{className:`msg-queued-task-kind`,children:Kt(t.reason)}),(0,I.jsxs)(`span`,{className:`msg-role-time`,title:S(t.since),children:[`· `,o]})]}),(0,I.jsxs)(`p`,{className:`msg-queued-task-headline`,children:[(0,I.jsxs)(`span`,{className:`msg-queued-task-number`,children:[`#`,e.num]}),` `,e.title]}),(0,I.jsxs)(`p`,{className:`msg-queued-task-context`,children:[n&&(0,I.jsx)(fe,{svg:n.icon??null,poppetje:n.poppetje,iconOverride:n.iconOverride,name:a,size:14}),qt(t.reason,a)]}),(0,I.jsx)(`div`,{className:`msg-queued-task-actions`,children:r?(0,I.jsxs)(`button`,{type:`button`,className:`msg-ref-chip`,onClick:()=>r(e.ref),title:`Open this task`,children:[`Task `,e.ref]}):(0,I.jsxs)(`span`,{className:`msg-queued-task-ref`,children:[`Task `,e.ref]})})]})})}var Yt=[`black`,`red`,`green`,`yellow`,`blue`,`magenta`,`cyan`,`white`,`bright-black`,`bright-red`,`bright-green`,`bright-yellow`,`bright-blue`,`bright-magenta`,`bright-cyan`,`bright-white`];function Xt(){return{fg:null,bg:null,bold:!1,dim:!1,italic:!1,underline:!1,reverse:!1,hidden:!1}}function Zt(e){let t=[],n=e.reverse?e.bg:e.fg,r=e.reverse?e.fg:e.bg;return n!==null&&t.push(`ansi-fg-${Yt[n]}`),r!==null&&t.push(`ansi-bg-${Yt[r]}`),e.bold&&t.push(`ansi-bold`),e.dim&&t.push(`ansi-dim`),e.italic&&t.push(`ansi-italic`),e.underline&&t.push(`ansi-underline`),e.reverse&&t.push(`ansi-reverse`),e.hidden&&t.push(`ansi-hidden`),t.join(` `)}function Qt(e,t){if(t+1>=e.length)return null;let n=e[t+1];if(n===`[`){let n=t+2;for(;n<e.length;){let t=e.charCodeAt(n);if(t>=48&&t<=63)n++;else break}for(;n<e.length;){let t=e.charCodeAt(n);if(t>=32&&t<=47)n++;else break}if(n>=e.length)return null;let r=e.charCodeAt(n);if(r<64||r>126)return{end:t+1};if(e[n]===`m`){let r=e.slice(t+2,n),i=r===``?[0]:r.split(`;`).map(e=>{let t=Number.parseInt(e,10);return Number.isFinite(t)?t:0});return{end:n+1,sgrParams:i}}if(e[n]===`H`||e[n]===`f`){let r=e.slice(t+2,n).split(`;`).map(e=>Number.parseInt(e,10)),i=Number.isFinite(r[0])&&r[0]>0?r[0]:1,a=Number.isFinite(r[1])&&r[1]>0?r[1]:1;return{end:n+1,transcriptLineBreak:i>1&&a===1}}return{end:n+1}}if(n===`]`){let n=t+2;for(;n<e.length;){let t=e[n];if(t===`\x07`)return{end:n+1};if(t===`\x1B`&&n+1<e.length&&e[n+1]===`\\`)return{end:n+2};n++}return null}return{end:t+2}}function $t(e,t){let n={...e},r=0;for(;r<t.length;){let e=t[r];e===0?(n.fg=null,n.bg=null,n.bold=!1,n.dim=!1,n.italic=!1,n.underline=!1,n.reverse=!1,n.hidden=!1):e===1?n.bold=!0:e===2?n.dim=!0:e===3?n.italic=!0:e===4?n.underline=!0:e===7?n.reverse=!0:e===8?n.hidden=!0:e===22?(n.bold=!1,n.dim=!1):e===23?n.italic=!1:e===24?n.underline=!1:e===27?n.reverse=!1:e===28?n.hidden=!1:e>=30&&e<=37?n.fg=e-30:e===38?t[r+1]===5?r+=2:t[r+1]===2&&(r+=4):e===39?n.fg=null:e>=40&&e<=47?n.bg=e-40:e===48?t[r+1]===5?r+=2:t[r+1]===2&&(r+=4):e===49?n.bg=null:e>=90&&e<=97?n.fg=e-90+8:e>=100&&e<=107&&(n.bg=e-100+8),r++}return n}function en(e){let t=Xt(),n=``,r=!1,i=0;return{feed(a){let o=n+a;n=``;let s=[],c=0,l=0,u=n=>{if(n<=l)return;let a=o.slice(l,n);if(a===``)return;r&&/\S/.test(a)&&(s.push(`
4
+
5
+ `),r=!1);let c=e?e(a):a,u=Zt(t);u===``?s.push(c):s.push((0,I.jsx)(`span`,{className:u,children:c},i++))};for(;c<o.length;){if(o.charCodeAt(c)!==27){c++;continue}let e=Qt(o,c);if(e===null)return u(c),n=o.slice(c),s;u(c),e.sgrParams&&(t=$t(t,e.sgrParams)),e.transcriptLineBreak&&tn(o,e.end)?(s.push(`
6
+
7
+ `),r=!1):e.transcriptLineBreak&&(r=!0),c=e.end,l=c}return u(o.length),s}}}function tn(e,t){let n=t;for(;n<e.length;){if(e.charCodeAt(n)===27){let t=Qt(e,n);if(t===null)return!1;n=t.end;continue}if(!/\s/.test(e[n]))return!0;n++}return!1}function nn({text:e,renderText:t}){return(0,I.jsx)(I.Fragment,{children:(0,F.useMemo)(()=>en(t).feed(e),[e,t])})}var rn={tabIndex:0};function an({entry:e,onOpenWorkspaceFile:t}){let n=Nt(e.cwd===void 0?e.workingDir:e.cwd);if(e.msgKind===`command`)return(0,I.jsxs)(`div`,{className:`msg msg-user terminal-group terminal-group-command`,"data-terminal-message-id":e.messageId,"data-terminal-thread-id":e.threadId,children:[(0,I.jsxs)(`div`,{className:`msg-header terminal-group-header`,children:[(0,I.jsx)(`span`,{className:`terminal-folder-pill`,title:`Working folder`,children:n}),(0,I.jsx)(`span`,{className:`msg-author`,children:`You · terminal`})]}),(0,I.jsxs)(`div`,{className:`msg-body terminal-cmd-body`,children:[(0,I.jsx)(`span`,{className:`terminal-prompt-sigil`,children:`>`}),` `,(0,I.jsx)(`code`,{className:`terminal-cmd-code`,children:e.content})]}),e.resolvedFrom&&e.resolvedFrom!==e.content&&(0,I.jsxs)(`div`,{className:`terminal-resolved-hint`,children:[`from: `,e.resolvedFrom]})]});let r=e.exitCode!==void 0&&e.exitCode!==0,i=e.exitCode===void 0?null:e.exitCode===0?`exit 0`:`exit ${e.exitCode}`,a=n=>on(n,e.fileReferences??[],t);return(0,I.jsxs)(`div`,{className:`msg msg-assistant terminal-group terminal-group-output`,"data-terminal-message-id":e.messageId,"data-terminal-thread-id":e.threadId,children:[(0,I.jsxs)(`div`,{className:`msg-header terminal-group-header`,children:[(0,I.jsx)(`span`,{className:`terminal-folder-pill`,title:`Working folder`,children:n}),(0,I.jsx)(`span`,{className:`msg-author`,children:`Terminal output`}),i&&(0,I.jsx)(`span`,{className:`terminal-exit-pill ${r?`terminal-exit-fail`:`terminal-exit-ok`}`,children:i}),typeof e.durationMs==`number`&&(0,I.jsx)(`span`,{className:`terminal-duration`,children:cn(e.durationMs)}),e.truncated&&(0,I.jsx)(`span`,{className:`terminal-truncated-pill`,title:`200KB output cap reached`,children:`truncated`})]}),e.errorMessage&&e.exitCode===-1&&(0,I.jsx)(`div`,{className:`terminal-error-banner`,children:e.errorMessage}),(0,I.jsx)(`section`,{className:`terminal-output-viewport`,"aria-label":`Terminal output`,...rn,children:(0,I.jsx)(`pre`,{className:`terminal-output-body`,children:e.content?(0,I.jsx)(nn,{text:e.content,renderText:a}):r?`(no output)`:``})})]})}function on(e,t,n){if(!n||t.length===0||!e)return e;let r=[...t].sort((e,t)=>t.label.length-e.label.length),i=e.toLowerCase(),a=[],o=0,s=0;for(;o<e.length;){let t=null;for(let n of r){let r=n.label.toLowerCase(),a=i.indexOf(r,o);for(;a>=0&&!sn(e,a,n.label.length);)a=i.indexOf(r,a+Math.max(1,r.length));a>=0&&(!t||a<t.at)&&(t={at:a,reference:n})}if(!t)break;t.at>o&&a.push(e.slice(o,t.at));let c=e.slice(t.at,t.at+t.reference.label.length);a.push((0,I.jsx)(`button`,{type:`button`,className:`terminal-file-link`,title:`Preview ${t.reference.path}`,onClick:()=>n(t.reference.path),children:c},`${t.reference.path}:${s++}`)),o=t.at+t.reference.label.length}return o===0?e:(o<e.length&&a.push(e.slice(o)),a)}function sn(e,t,n){let r=t===0?``:e[t-1],i=t+n,a=i>=e.length?``:e[i];return(r===``||/[\s"'([{<]/.test(r))&&(a===``||/[\s"')\]}>:,;]/.test(a))}function cn(e){if(e<1e3)return`${e}ms`;let t=e/1e3;if(t<60)return`${t.toFixed(1)}s`;let n=Math.floor(t/60);return`${n}m${Math.round(t-n*60).toString().padStart(2,`0`)}s`}var ln=24,un={tabIndex:0};function dn({content:e,cwd:t,startedAt:n,onCancel:r,awaitingInput:i,onSendInput:a}){let o=Nt(t),s=(0,F.useRef)(null),c=(0,F.useRef)(!0);(0,F.useLayoutEffect)(()=>{let e=s.current;!e||!c.current||(e.scrollTop=e.scrollHeight)},[e]);let l=()=>{let e=s.current;if(!e)return;let t=e.scrollHeight-e.clientHeight-e.scrollTop;c.current=t<=ln};return(0,I.jsxs)(`div`,{className:`msg msg-assistant terminal-group terminal-group-output terminal-group-streaming`,children:[(0,I.jsxs)(`div`,{className:`msg-header terminal-group-header`,children:[(0,I.jsx)(`span`,{className:`terminal-folder-pill`,title:`Working folder`,children:o}),(0,I.jsx)(`span`,{className:`msg-author`,children:`Terminal output`}),(0,I.jsx)(pn,{startedAt:n}),r&&(0,I.jsx)(`button`,{type:`button`,className:`terminal-cancel-btn`,onClick:r,title:`Stop the running command (Ctrl+C)`,children:`■ Stop`})]}),(0,I.jsx)(`section`,{ref:s,className:`terminal-output-viewport`,"aria-label":`Live terminal output`,"aria-busy":`true`,...un,onScroll:l,children:(0,I.jsx)(`pre`,{className:`terminal-output-body`,children:(0,I.jsx)(nn,{text:e})})}),i&&a&&(0,I.jsx)(fn,{awaitingInput:i,onSubmit:a})]})}function fn({awaitingInput:e,onSubmit:t}){let[n,r]=(0,F.useState)(``),i=e=>{t(e),r(``)},a=e=>{e.key===`Enter`&&(e.preventDefault(),i(n))};if(e.mode===`yes-no`)return(0,I.jsxs)(`div`,{className:`terminal-input-prompt`,children:[(0,I.jsx)(`div`,{className:`terminal-input-prompt-line`,children:e.promptLine}),(0,I.jsxs)(`div`,{className:`terminal-input-prompt-row`,children:[(0,I.jsx)(`button`,{type:`button`,className:`terminal-input-yesno-btn`,onClick:()=>i(`y`),children:`Yes`}),(0,I.jsx)(`button`,{type:`button`,className:`terminal-input-yesno-btn`,onClick:()=>i(`n`),children:`No`}),(0,I.jsx)(`input`,{type:`text`,className:`terminal-input-reply`,value:n,onChange:e=>r(e.target.value),onKeyDown:a,placeholder:`or type a custom reply`,autoCapitalize:`off`,autoComplete:`off`,autoCorrect:`off`,spellCheck:!1})]})]});let o=e.mode===`password`;return(0,I.jsxs)(`div`,{className:`terminal-input-prompt`,children:[(0,I.jsx)(`div`,{className:`terminal-input-prompt-line`,children:e.promptLine}),(0,I.jsxs)(`div`,{className:`terminal-input-prompt-row`,children:[(0,I.jsx)(`input`,{type:o?`password`:`text`,className:`terminal-input-reply`,value:n,onChange:e=>r(e.target.value),onKeyDown:a,placeholder:o?`password (not echoed or saved)`:`reply…`,autoFocus:!0,autoCapitalize:`off`,autoComplete:`off`,autoCorrect:`off`,spellCheck:!1}),(0,I.jsx)(`button`,{type:`button`,className:`terminal-input-send-btn`,onClick:()=>i(n),children:`Send`})]}),o&&(0,I.jsx)(`div`,{className:`terminal-input-hint`,children:`Your input is hidden and isn't kept in the timeline.`})]})}function pn({startedAt:e}){let[,t]=(0,F.useState)(0);(0,F.useEffect)(()=>{let e=setInterval(()=>t(e=>e+1),1e3);return()=>clearInterval(e)},[]);let n=(0,F.useMemo)(()=>new Date(e).getTime(),[e]);return(0,I.jsxs)(`span`,{className:`terminal-running-pill`,title:`Running…`,children:[`running `,mn(Math.max(0,Date.now()-n))]})}function mn(e){if(e<1e3)return`${e}ms`;let t=Math.floor(e/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m${(t%60).toString().padStart(2,`0`)}s`}var hn=1440*60*1e3;function gn(e,t){if(!e)return!1;let n=Date.parse(e);return Number.isFinite(n)&&t-n<=864e5}var _n=300*1e3;function vn(e){let t=Date.parse(e);return Number.isFinite(t)?t+_n:void 0}function yn(e,t){let n;for(let r of e){let e=vn(r.at);e===void 0||e<t||(n===void 0||e<n)&&(n=e)}return n}function bn(e,t){if(e.kind===`terminal-streaming`)return!0;if(e.kind!==`terminal`)return!1;let n=vn(e.at);return n!==void 0&&t<=n}function xn(e,t){return bn(e,t)?2:+(e.kind===`streaming`)}function Sn(e,t,n){let r=xn(e,n)-xn(t,n);return r===0?e.at<t.at?-1:+(e.at>t.at):r}function Cn(e){let t=-1/0,n=e.root?[e.root,...e.replies]:e.replies;for(let e of n){let n=Date.parse(e.at);Number.isFinite(n)&&n>t&&(t=n)}return t}function wn(e,t,n){if(!t)return e;let r=-1;for(let n=e.length-1;n>=0;n--){let i=e[n];if(i?.kind===`thread`&&i.sessionId===t){r=n;break}}if(r===-1)return e;let i=e[r],a=Cn(i);if(!Number.isFinite(a)||n-a>864e5)return e;let o=e.length;for(;o>0;){let t=e[o-1];if(!t||!bn(t,n))break;o--}let s=o-1;if(s<=r)return e;let c=[...e];return c.splice(r,1),c.splice(s,0,i),c}var Tn=280;function En(e,t){t?.current&&(t.current.abort(),t.current=null);let n=e.current;if(n){try{n.pause(),n.removeAttribute(`src`),n.load()}catch{}e.current=null}}function Dn(e){let t=e.trim();if(t.length<=Tn)return t;let n=t.slice(0,Tn),r=Math.max(n.lastIndexOf(`. `),n.lastIndexOf(`! `),n.lastIndexOf(`? `));return r>=Tn/2?n.slice(0,r+1).trim():`${n.trim()}…`}async function On(e,t,n,r,i){En(r,i);let a=new AbortController;i.current=a;let o=Dn(e);console.debug(`[narrate] synth start chars=${o.length} (of ${e.length}) gezelId=${t}`);let s;try{s=await _.synthesizeSpeech({text:o,gezelId:t,projectId:n,inline:!0,signal:a.signal})}catch(e){if(a.signal.aborted){console.debug(`[narrate] synth aborted (superseded by newer turn)`);return}console.warn(`[narrate] synth failed:`,e);return}if(a.signal.aborted){console.debug(`[narrate] synth resolved but aborted — dropping`);return}if(console.debug(`[narrate] synth ok b64Len=${s.b64Wav?.length??0} meta=`,s.meta),!s.b64Wav){console.warn(`[narrate] synth returned no b64Wav — narration skipped`);return}let c=new Audio(`data:audio/wav;base64,${s.b64Wav}`);r.current=c,c.addEventListener(`ended`,()=>{console.debug(`[narrate] playback ended`),r.current===c&&(r.current=null),i.current===a&&(i.current=null)});try{await c.play(),console.debug(`[narrate] playback started`)}catch(e){console.warn(`[narrate] playback rejected:`,e),r.current===c&&(r.current=null),i.current===a&&(i.current=null)}}function kn(e){let{branch:t,phase:n}=e,r=t.ancestorContinuationLevels.filter(e=>e>=2&&e<=4);return(0,I.jsxs)(I.Fragment,{children:[(n===`thread`&&t.hasFollowingSibling?[1,...r]:r).map(e=>(0,I.jsx)(`span`,{className:`timeline-tree-guide timeline-tree-guide-${n} timeline-tree-guide-up-${e}`,"aria-hidden":`true`},`${n}:${e}`)),n===`divider`&&(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`span`,{className:`timeline-tree-parent-line timeline-tree-guide-up-1${t.hasFollowingSibling?` timeline-tree-parent-line-continues`:``}`,"aria-hidden":`true`}),(0,I.jsx)(`span`,{className:`timeline-tree-elbow timeline-tree-guide-up-1`,"aria-hidden":`true`})]})]})}function An(e){let{row:t,gezels:n,projects:r,showProjectName:i,activeSessionId:a,onFocusSession:o,continuing:c,depth:l=0,treeBranch:u,key:d,roleBasedNameOnlyMode:f}=e,p=t.kind===`streaming`?t.sessionId:t.msg.sessionId,m=t.kind===`streaming`?t.slot.gezelId:t.msg.gezelId,h=t.kind===`streaming`?t.slot.projectId:t.msg.projectId,g=n.get(m),_=i&&h!=="default"?r.get(h):void 0,v=p===a,y=t.kind===`message`?t.msg.sessionCreatedAt:t.slot.sessionCreatedAt??new Date(t.slot.startedAt).toISOString(),ee=t.kind===`message`?t.msg.taskRef:t.slot.taskRef,b=t.kind===`message`?t.msg.sessionSource:t.slot.sessionSource,C=t.kind===`message`?t.msg.parentSession:t.slot.parentSession,w=t.kind===`message`?t.msg.handoffFrom:t.slot.handoffFrom,T=C??(w?{...w,kind:`task-handoff`}:void 0),E=T?(()=>{let e=n.get(T.gezelId);return e?s({name:e.name,roleBasedName:e.roleBasedName},f):void 0})():void 0,D=w?(()=>{let e=n.get(w.gezelId);return e?s({name:e.name,roleBasedName:e.roleBasedName},f):void 0})():void 0,O=g?s({name:g.name,roleBasedName:g.roleBasedName},f):`Gezel`;if(t.kind===`streaming`&&p.startsWith(`one-shot:`)){let e=t.slot.activity?.trim()||`Background work`;return(0,I.jsxs)(`output`,{className:`timeline-session-divider timeline-session-divider-activity`,children:[(0,I.jsx)(fe,{svg:g?.icon??null,poppetje:g?.poppetje,iconOverride:g?.iconOverride,name:O,size:16}),(0,I.jsxs)(`span`,{className:`timeline-divider-meta`,title:S(y),children:[O,` · `,e,_&&(0,I.jsxs)(I.Fragment,{children:[` · in `,_.name]}),` · `,`started `,x(y)]})]},d)}return(0,I.jsxs)(`button`,{type:`button`,className:`timeline-session-divider${v?` timeline-session-divider-active`:``}${c?` timeline-session-divider-continuing`:``}${l>0?` timeline-session-divider-child timeline-session-depth-${Math.min(l,4)}`:``}`,onClick:()=>o?.(p,m,h),title:b?`View this read-only thread from ${b.appName}`:`Focus this thread — composer will post here`,children:[l>0&&u&&(0,I.jsx)(kn,{branch:u,phase:`divider`}),(0,I.jsx)(fe,{svg:g?.icon??null,poppetje:g?.poppetje,iconOverride:g?.iconOverride,name:O,size:16}),(0,I.jsxs)(`span`,{className:`timeline-divider-meta`,title:S(y),children:[c?(0,I.jsxs)(I.Fragment,{children:[`↩ continuing with `,O,_&&(0,I.jsxs)(I.Fragment,{children:[` · in `,_.name]}),b&&(0,I.jsxs)(I.Fragment,{children:[` · from `,b.appName,` · read-only`]})]}):b?(0,I.jsxs)(I.Fragment,{children:[`external thread with `,O,` · from `,b.appName,` · read-only`,_&&(0,I.jsxs)(I.Fragment,{children:[` · in `,_.name]}),` · `,`started `,x(y)]}):T?(0,I.jsxs)(I.Fragment,{children:[T.kind===`consultation`?`consultation with ${O}`:T.kind===`task-handoff`?`task hand-off to ${O}`:`delegated to ${O}`,_&&(0,I.jsxs)(I.Fragment,{children:[` · in `,_.name]}),` · `,`started `,x(y)]}):(0,I.jsxs)(I.Fragment,{children:[`new thread with `,O,_&&(0,I.jsxs)(I.Fragment,{children:[` · in `,_.name]}),` · `,`started `,x(y)]}),ee&&(0,I.jsxs)(I.Fragment,{children:[` · task `,ee]})]}),T&&(T.kind===`task-handoff`?D??E:E)&&(0,I.jsxs)(`span`,{className:`timeline-divider-handoff`,children:[(0,I.jsxs)(`svg`,{className:`timeline-divider-handoff-icon`,viewBox:`0 0 16 16`,fill:`none`,"aria-hidden":`true`,focusable:`false`,children:[(0,I.jsx)(`path`,{d:`M2.5 4.25v2.1a4.4 4.4 0 0 0 4.4 4.4H13`}),(0,I.jsx)(`path`,{d:`m10.5 8.25 2.75 2.5-2.75 2.5`})]}),T.kind===`task-handoff`?`from`:`by`,` `,T.kind===`task-handoff`?D??E:E]})]},d)}function jn(e){let{entry:t,key:n}=e;return(0,I.jsxs)(`div`,{className:`timeline-session-divider timeline-terminal-session-divider`,children:[(0,I.jsx)(`span`,{className:`terminal-folder-pill`,title:`Working folder`,children:t.workingDir===``?`/`:t.workingDir}),(0,I.jsxs)(`span`,{className:`timeline-divider-meta`,title:S(t.at),children:[`terminal session · started `,x(t.at)]})]},n)}function Mn(e){return e.replace(/["\\]/g,`\\$&`)}function Nn(e,t){let n=new Map((e??[]).map(e=>[e.messageId,e]));for(let e of t)n.set(e.messageId,e);return[...n.values()].sort((e,t)=>e.at<t.at?-1:+(e.at>t.at))}function Pn(e,t){let n=t.filter(e=>e.role===`user`),r=e.filter(e=>{if(!e.optimistic)return!0;let t=Date.parse(e.at);return!n.some(n=>{if(n.sessionId!==e.sessionId||n.content!==e.content)return!1;let r=Date.parse(n.at);return Number.isFinite(t)&&Number.isFinite(r)?Math.abs(r-t)<2*6e4:!0})}),i=new Set,a=[];for(let e of[...t,...r]){let t=`${e.sessionId}:${e.at}:${e.role}`;i.has(t)||(i.add(t),a.push(e))}return a.sort((e,t)=>e.at<t.at?-1:+(e.at>t.at)),a}function Fn(e,t){for(let n=e.length-1;n>=0;n--)if(e[n].sessionId===t)return e[n];return null}function In(e){return/model\s+.*\bnot available\b/i.test(e)||/\bunknown model\b/i.test(e)}function Ln(e){return e?.code===`capacity-denied`||e?.code===`engine-busy`}function Rn(e,t){return r(e)||In(e)||/\bdo not retry\b|\bcannot run on this machine\b/i.test(e)?!1:t?.code===`engine-busy`||t?.code===`capacity-denied`||t?.code===`native-engine-crash`||/\bretry the turn\b|\bsend (?:the )?message again\b|\bretry \(the cache is warm now\)|\btry a shorter prompt, retry\b/i.test(e)}var zn=[];function Bn(e){return e.referencedFiles?.length?e.referencedFiles:e.referencedArtifacts?.length?e.referencedArtifacts.map(e=>({kind:`artifact`,path:e})):zn}function Vn(e,t){if(!e)return!1;try{let n=new Date(e).getTime();return Date.now()-n<=t}catch{return!1}}function Hn(e){switch(e){case`copilot`:return`Copilot`;case`openai`:return`OpenAI`;case`anthropic`:return`Claude`;case`anthropic-cli`:return`Claude CLI`;case`codex-cli`:return`Codex CLI`;case`ollama`:return`Ollama`;case`llama-cpp`:return`On-device`;case`mlx`:return`MLX`;case`ds4`:return`DwarfStar`;case`remote`:return`Remote`}}function Un({store:e,itemKey:t,render:n,onRendered:r}){let i=(0,F.useCallback)(n=>e.subscribeItem(t,n),[e,t]),a=(0,F.useCallback)(()=>e.getItemSnapshot(t),[e,t]),o=(0,F.useSyncExternalStore)(i,a,a),s=e.items.get(t);return(0,F.useLayoutEffect)(()=>{s&&r?.()},[s,r,o]),s?(0,I.jsx)(I.Fragment,{children:n(s)}):null}function Wn({store:e,sessionId:t,userMsg:n,gezels:r}){return(0,I.jsx)(Un,{store:e,itemKey:t,render:e=>(0,I.jsx)(Lt,{payload:{userMsg:n,assistantInfo:{kind:`live`,sessionId:t,slot:e}},gezels:r})})}var Gn={request(e){return typeof requestAnimationFrame==`function`?requestAnimationFrame(e):window.setTimeout(()=>e(performance.now()),16)},cancel(e){typeof cancelAnimationFrame==`function`?cancelAnimationFrame(e):window.clearTimeout(e)}},Kn=class{scheduler;items=new Map;structureVersion=0;itemVersions=new Map;structureListeners=new Set;itemListeners=new Map;pendingItems=new Set;pendingStructure=!1;frameHandle=null;constructor(e=Gn){this.scheduler=e}getStructureSnapshot=()=>this.structureVersion;subscribeStructure=e=>(this.structureListeners.add(e),()=>this.structureListeners.delete(e));getItemSnapshot(e){return this.itemVersions.get(e)??0}subscribeItem(e,t){let n=this.itemListeners.get(e);return n||(n=new Set,this.itemListeners.set(e,n)),n.add(t),()=>{n?.delete(t),n?.size===0&&this.itemListeners.delete(e)}}markItemChanged(e){this.pendingItems.add(e),this.scheduleFlush()}markStructureChanged(){this.pendingStructure=!0,this.scheduleFlush()}scheduleFlush(){this.frameHandle===null&&(this.frameHandle=this.scheduler.request(()=>this.flush()))}flush(){this.frameHandle=null;let e=this.pendingStructure,t=[...this.pendingItems];if(this.pendingStructure=!1,this.pendingItems.clear(),e){this.structureVersion+=1;for(let e of this.structureListeners)e()}for(let e of t){this.itemVersions.set(e,(this.itemVersions.get(e)??0)+1);for(let t of this.itemListeners.get(e)??[])t()}}dispose(){this.frameHandle!==null&&this.scheduler.cancel(this.frameHandle),this.frameHandle=null,this.pendingStructure=!1,this.pendingItems.clear(),this.structureListeners.clear(),this.itemListeners.clear()}};function qn(e){let t=e.root?[e.root,...e.replies]:e.replies;for(let e of t)if(e.kind===`message`&&e.msg.parentSession?.sessionId)return e.msg.parentSession.sessionId}function Jn(e){let t=new Map,n=new Map,r=new Map;for(let i=0;i<e.length;i++){let a=e[i];if(!a||a.kind!==`thread`)continue;let o=t.get(a.sessionId)??[];o.push(a),t.set(a.sessionId,o),n.has(a.sessionId)||n.set(a.sessionId,i);let s=qn(a);s&&s!==a.sessionId&&r.set(a.sessionId,s)}let i=new Set(t.keys()),a=new Map;for(let[e,t]of r){if(!i.has(t))continue;let n=a.get(t)??[];n.push(e),a.set(t,n)}for(let e of a.values())e.sort((e,t)=>(n.get(e)??0)-(n.get(t)??0));let o=new Map;for(let e of a.values())for(let t=0;t<e.length;t++){let n=e[t];n&&o.set(n,t<e.length-1)}let s=new Map,c=(e,t=new Set)=>{let n=s.get(e);if(n!==void 0)return n;if(t.has(e))return 0;let a=r.get(e);if(!a||!i.has(a))return s.set(e,0),0;let o=new Set(t);o.add(e);let l=Math.min(4,c(a,o)+1);return s.set(e,l),l};for(let e of i)c(e);let l=new Map;for(let e of i){let t=[];if((s.get(e)??0)>0){let n=r.get(e),i=2;for(;n&&r.has(n);)o.get(n)===!0&&t.push(i),n=r.get(n),i+=1}l.set(e,{hasChildren:(a.get(e)?.length??0)>0,hasFollowingSibling:o.get(e)===!0,ancestorContinuationLevels:t})}let u=new Set;for(let[e,t]of r)i.has(t)&&(s.get(e)??0)>0&&u.add(e);let d=[],f=new Set,p=(e,n=new Set)=>{if(f.has(e)||n.has(e))return;f.add(e);for(let n of t.get(e)??[])d.push(n);let r=new Set(n);r.add(e);for(let t of a.get(e)??[])p(t,r)},m=new Map;for(let t=0;t<e.length;t++){let n=e[t];n?.kind===`thread`&&!u.has(n.sessionId)&&m.set(n.sessionId,t)}for(let t=0;t<e.length;t++){let n=e[t];if(n){if(n.kind!==`thread`){d.push(n);continue}if(!u.has(n.sessionId)&&(d.push(n),m.get(n.sessionId)===t)){f.add(n.sessionId);for(let e of a.get(n.sessionId)??[])p(e)}}}for(let e of i)f.has(e)||p(e);return{items:d,depthBySession:s,branchBySession:l}}function Yn(e){let t=new Map,n=new Map;for(let r of e){if(r.role!==`user`)continue;let e=r.content.trim(),i=Date.parse(r.at),a=t.get(e);if(a&&a.sessionId!==r.sessionId&&i-a.atMs<=5e3){n.set(r,a.row);continue}t.set(e,{atMs:i,sessionId:r.sessionId,row:r})}return n}function Xn(e){let t=Yn(e.flatMap(e=>e.kind===`message`&&e.msg.role===`user`?[{at:e.msg.at,role:e.msg.role,content:e.msg.content,sessionId:e.msg.sessionId,ref:e}]:[])),n=new Map;for(let[e,r]of t)n.set(e.ref,r.ref);let r=[],i=new Map,a=new Map;for(let t of e){if(t.kind===`indexing`||t.kind===`terminal`||t.kind===`terminal-streaming`){r.push(t);continue}if(t.kind===`message`&&t.msg.role===`user`){let e=n.get(t);if(e){let n=a.get(e);if(n){i.set(t.msg.sessionId,n);continue}}let o={kind:`thread`,sessionId:t.msg.sessionId,at:t.at,root:t,replies:[]};r.push(o),i.set(t.msg.sessionId,o),a.set(t,o);continue}let e=t.kind===`message`?t.msg.sessionId:t.sessionId,o=i.get(e);o||(o={kind:`thread`,sessionId:e,at:t.kind===`streaming`?t.threadAt??t.at:t.at,replies:[]},r.push(o),i.set(e,o)),o.replies.push(t);let s=r.indexOf(o);s>=0&&s!==r.length-1&&(r.splice(s,1),r.push(o))}return r}function Zn(){let[e,t]=(0,F.useState)(!1);return(0,F.useEffect)(()=>{let e=!1;_.getConfig().then(n=>{e||t(n.narrateAssistantReplies??!1)}).catch(()=>{});let n=e=>{let n=e.detail;n&&typeof n.narrateAssistantReplies==`boolean`&&t(n.narrateAssistantReplies)};return window.addEventListener(`gezel:config-updated`,n),()=>{e=!0,window.removeEventListener(`gezel:config-updated`,n)}},[]),e}var Qn=100,$n=new Set([`ollama`,`llama-cpp`,`mlx`,`ds4`]),er=180*1e3,tr=80,nr=80,rr=700,ir=300,ar=2e3,or=7200*1e3,sr=4,cr=1e4;function lr(e){return e.role===`assistant`&&e.toolCalls?.some(e=>e.success&&m(e.name).replace(/^gezel-/,``)===`ask_user_question`)===!0}var ur={starting:`Starting engine`,loading_model:`Loading model`,prefill:`Thinking it through`,generating:`Generating`,ready:`Ready`};function dr({scopeKey:e,activeSessionId:t,onFocusSession:n,onToolActivity:i,onArtifactReference:a,onArtifactSeen:c,onWorkspaceReference:u,onWorkspaceSeen:d,onOpenReference:p,onTaskReference:m,queuedTasks:h,emptyPlaceholder:g,emptyContent:v,loadTimeline:y,streamUrl:ee,terminalStreamUrl:b,terminalRefreshKey:S,terminalSubmission:w,terminalFocusRequest:T,sessionFocusRequest:E,onTerminalWorkingDirChanged:D,showProjectName:O,inflightScope:te,scopedSessionIds:k,onUnknownSession:ne}){let A=ge(),re=(0,F.useRef)(k);re.current=k;let ie=(0,F.useRef)(ne);ie.current=ne;let oe=Zn(),se=(0,F.useRef)(oe);se.current=oe;let de=(0,F.useRef)(null),fe=(0,F.useRef)(null),pe=(0,F.useRef)(new Map);(0,F.useEffect)(()=>()=>{En(de,fe)},[]);let[M,ye]=(0,F.useState)([]),be=(0,F.useRef)([]),N=(0,F.useRef)(new Set);(0,F.useEffect)(()=>{be.current=M},[M]),(0,F.useEffect)(()=>{if(m)for(let e of M){if(e.taskRef){let n=!!t&&e.sessionId===t;m(e.taskRef,{scoped:n})}if(e.referencedTasks)for(let t of e.referencedTasks)m(t)}},[M,t,m]),(0,F.useEffect)(()=>{if(!(!c&&!d))for(let e of M){let t=`${e.sessionId}\u0000${e.at}\u0000${e.role}`,n=(n,r)=>{let i=n===`workspace`?d:c;if(!i)return;let a=`${t}\u0000${n}\u0000${r}`;N.current.has(a)||(N.current.add(a),i(r,e.projectId))};for(let t of Bn(e))n(t.kind,t.path);for(let t of e.toolCalls??[]){if(!t.success)continue;for(let e of[...t.images??[],...t.audios??[],...t.videos??[]])n(`artifact`,e.path);let e=t.paths?.length?t.paths:t.path?[t.path]:[];for(let r of e)t.name===`read_artifact`||t.name===`write_artifact`?n(`artifact`,r):(t.name===`read_file`||t.name===`read_files`||t.name===`write_file`)&&n(`workspace`,r)}}},[M,c,d]);let[xe,P]=(0,F.useState)([]),[Se,Ce]=(0,F.useState)([]),[we,Te]=(0,F.useState)(0),[Ee,De]=(0,F.useState)(!1),[Oe,ke]=(0,F.useState)();(0,F.useEffect)(()=>{let e=yn(xe,Date.now());if(e===void 0)return;let t=window.setTimeout(()=>Te(e=>e+1),Math.max(0,e-Date.now()+1));return()=>window.clearTimeout(t)},[xe,we]),(0,F.useEffect)(()=>{t&&_.warmSessionCache(t).catch(()=>{})},[t]);let[Ae,L]=(0,F.useState)(!0),[je,Me]=(0,F.useState)(null),[Ne,Pe]=(0,F.useState)(new Map),[Fe,Ie]=(0,F.useState)(new Set),[R,Le]=(0,F.useState)(new Map),Re=(0,F.useRef)(R);Re.current=R;let[ze,Be]=(0,F.useState)(new Map),[Ve,He]=(0,F.useState)(new Map),Ue=(0,F.useRef)(new Set),We=(0,F.useRef)(e);We.current=e;let Ge=(0,F.useRef)(null);Ge.current||=new Kn;let z=Ge.current,B=(0,F.useRef)(z.items),Ke=(0,F.useSyncExternalStore)(z.subscribeStructure,z.getStructureSnapshot,z.getStructureSnapshot),qe=(0,F.useRef)(null);qe.current||=new Kn;let V=qe.current;(0,F.useEffect)(()=>{let e=e=>{let t=e.detail?.projectId;if(typeof t!=`string`||t.length===0)return;Ie(e=>{let n=new Set(e);return n.add(t),n}),ye(e=>e.map(e=>e.projectId===t?{...e,sessionLastTurnError:void 0,sessionLastTurnErrorDetail:void 0}:e));let n=!1;for(let[e,r]of B.current)r.projectId!==t||!r.error||(B.current.delete(e),n=!0);n&&z.markStructureChanged(),Pe(e=>{let n=new Map(e);for(let e of be.current)e.projectId===t&&n.delete(e.sessionId);return n})};return window.addEventListener(`gezel:session-error-cleared`,e),()=>window.removeEventListener(`gezel:session-error-cleared`,e)},[z]);let Je=(0,F.useRef)(V.items),Ye=(0,F.useSyncExternalStore)(V.subscribeStructure,V.getStructureSnapshot,V.getStructureSnapshot),H=(0,F.useRef)(new Map),U=(0,F.useRef)(null),Xe=(0,F.useRef)(null),Ze=(0,F.useRef)(null),[Qe,$e]=(0,F.useState)(!0),W=(0,F.useRef)(!0);W.current=Qe;let[G,K]=(0,F.useState)(null),[tt,nt]=(0,F.useState)(null),rt=(0,F.useRef)(null),it=(0,F.useRef)(null),at=(0,F.useRef)(!1),[q,ot]=(0,F.useState)(null),st=(0,F.useRef)(null),ct=(0,F.useRef)(60),lt=(0,F.useRef)(0),dt=(0,F.useRef)(0),J=(0,F.useRef)(null),Y=te?.projectId,X=te?.gezelId;(0,F.useEffect)(()=>{let t=!1;return L(!0),Me(null),Pe(new Map),ye([]),P([]),Ce(Vt(e)),De(!1),ke(void 0),Ie(new Set),N.current.clear(),Ue.current.clear(),B.current.clear(),z.markStructureChanged(),Je.current.clear(),V.markStructureChanged(),H.current.clear(),W.current=!0,$e(!0),K(null),nt(null),lt.current=0,dt.current=0,(async()=>{try{let e=await y({limit:Qn});if(t)return;ye(e.messages),De(e.hasMore),ke(e.nextCursor),P(t=>Nn(e.terminalEntries,t));try{let n=await _.listInflightTurns({...Y===void 0?{}:{projectId:Y},...X===void 0?{}:{gezelId:X}});if(t)return;for(let t of n.inflight){if(B.current.has(t.sessionId)||re.current&&!re.current.has(t.sessionId))continue;let n=Fn(e.messages,t.sessionId);B.current.set(t.sessionId,{gezelId:t.gezelId,projectId:t.projectId,segments:[],startedAt:t.startedAt,lastActivityAt:t.lastProgressAgoMs==null?t.startedAt:Date.now()-t.lastProgressAgoMs,hasProgress:t.lastProgressAgoMs!=null,...n?{sessionTitle:n.sessionTitle,sessionCreatedAt:n.sessionCreatedAt,sessionProviderName:n.sessionProviderName,...n.sessionModel?{sessionModel:n.sessionModel}:{},...n.taskRef?{taskRef:n.taskRef}:{}}:{}})}n.inflight.length>0&&z.markStructureChanged()}catch{}try{let e=await _.getQueueStatus();if(t)return;for(let t of e.sessions)re.current&&!re.current.has(t.sessionId)||H.current.set(t.sessionId,t.entries.map(e=>({id:e.queueId,preview:e.preview,enqueuedAt:e.enqueuedAt,...e.nudge?{nudge:!0}:{}})));e.sessions.length>0&&z.markStructureChanged()}catch{}try{let e=await y({limit:Qn});if(t)return;ye(t=>Pn(t,e.messages)),P(t=>Nn(e.terminalEntries,t))}catch{}}catch(e){t||Me(e.message)}finally{t||L(!1)}})(),()=>{t=!0}},[e,y,Y,X]);let[ft,pt]=(0,F.useState)(`copilot`),[Z,mt]=(0,F.useState)({}),[ht,gt]=(0,F.useState)(!1);(0,F.useEffect)(()=>{let e=!1;return(async()=>{try{let t=await _.getConfig();if(e)return;pt(t.provider),mt(t.defaultModel??{}),gt(t.debugMode===!0)}catch{}})(),()=>{e=!0}},[]);let _t=(0,F.useCallback)((e,t,n=!1)=>{let r=Fn(e,t.sessionId);return{sessionId:t.sessionId,gezelId:t.gezelId,projectId:t.projectId,sessionTitle:r?.sessionTitle??o(t.content),sessionCreatedAt:r?.sessionCreatedAt??t.at,sessionLastActivityAt:t.at,sessionProviderName:r?.sessionProviderName??ft,...r?.sessionModel?{sessionModel:r.sessionModel}:{},...r?.taskRef?{taskRef:r.taskRef}:{},...r?.stepId?{stepId:r.stepId}:{},role:`user`,content:t.content,at:t.at,...t.from?{from:t.from}:{},...n?{optimistic:!0}:{}}},[ft]),Q=(0,F.useCallback)(e=>R.get(e)?.provider??ft,[R,ft]),$=(0,F.useCallback)(e=>{let t=R.get(e),n=Q(e),r=t?.model;return r?`Provider: ${Hn(n)} (${r})`:`Provider: ${Hn(n)}`},[R,Q]),vt=(0,F.useCallback)((e,t)=>{let n=Z[ft],r=$n.has(e);if(e!==ft)return t&&!r?`${Hn(e)} · ${t}`:Hn(e);if(!r&&t&&n&&t!==n)return t},[ft,Z]),yt=(0,F.useRef)(null),bt=(0,F.useCallback)(()=>{if(yt.current)return yt.current;let e=(async()=>{try{let e=await _.listGezels(),t=new Map;for(let n of e.gezels)t.set(n.id,n);Le(t)}catch{}finally{yt.current=null}})();return yt.current=e,e},[]);(0,F.useEffect)(()=>{bt()},[bt]),(0,F.useEffect)(()=>{let e=e=>{let t=e.detail;t?.id&&Le(e=>{let n=new Map(e);return n.set(t.id,{...n.get(t.id),...t}),n})};return window.addEventListener(`gezel:gezel-updated`,e),()=>window.removeEventListener(`gezel:gezel-updated`,e)},[]),(0,F.useEffect)(()=>{if(!O)return;let e=!1;return(async()=>{try{let t=await _.listProjects();if(e)return;let n=new Map;for(let e of t.projects)n.set(e.id,e);Be(n)}catch{}})(),()=>{e=!0}},[O]);let xt=(0,F.useCallback)(async()=>{try{let e=await _.listQuestions({pending:!0});He(t=>{let n=new Map(t);for(let[e,t]of n)t.answer||n.delete(e);for(let t of e.questions)n.set(t.id,t);return n})}catch{}},[]);(0,F.useEffect)(()=>{xt()},[e,xt]),(0,F.useEffect)(()=>{let t=new Set;for(let e of M)!e.pendingQuestionId&&!lr(e)||Ue.current.has(e.projectId)||t.add(e.projectId);if(t.size===0)return;let n=[...t],r=e;for(let e of n)Ue.current.add(e);Promise.allSettled(n.map(e=>_.listQuestions({projectId:e}))).then(e=>{if(We.current!==r)return;let t=[];e.forEach((e,r)=>{e.status===`fulfilled`?t.push(...e.value.questions):Ue.current.delete(n[r])}),t.length!==0&&He(e=>{let n=new Map(e);for(let e of t)n.set(e.id,e);return n})})},[M,e]),(0,F.useEffect)(()=>{let e=new AbortController,t=!1,n=250;return(async()=>{for(;!t;){try{let r={url:ee(),headers:_.authHeader(),signal:e.signal,fetch:_.getFetch()};for await(let e of ve(r)){if(t)return;Ct(e),n=250}}catch(e){if(t||e.name===`AbortError`)return;console.warn(`[ChatTimelineView] envelope stream error (reconnecting in ${n}ms):`,e)}if(t)return;await new Promise(e=>setTimeout(e,n)),n=Math.min(n*2,5e3)}})(),()=>{t=!0,e.abort()}},[e,ee]),(0,F.useEffect)(()=>{if(!b)return;let e=new AbortController,t=!1,n=250;return(async()=>{let{streamTerminalEvents:r}=await C(async()=>{let{streamTerminalEvents:e}=await import(`./dist-BMZhqfv7.js`).then(e=>e.r);return{streamTerminalEvents:e}},__vite__mapDeps([0,1,2]));for(;!t;){try{for await(let i of r({url:b(),headers:_.authHeader(),signal:e.signal,fetch:_.getFetch()})){if(t)return;if(i.kind===`workingDirChanged`){D?.(i.threadId,i.newWorkingDir),n=250;continue}if(i.kind===`openFile`){u?.(i.path,i.projectId),n=250;continue}if(i.kind===`runStarted`){Je.current.set(i.runId,{projectId:i.projectId,threadId:i.threadId,commandMessageId:i.commandMessageId,startedAt:i.at,cwd:i.cwd,content:``}),V.markStructureChanged(),n=250;continue}if(i.kind===`outputChunk`){let e=Je.current.get(i.runId);e&&(e.content+=i.chunk,e.awaitingInput&&delete e.awaitingInput,V.markItemChanged(i.runId)),n=250;continue}if(i.kind===`inputRequested`){let e=Je.current.get(i.runId);e&&(e.awaitingInput={promptLine:i.promptLine,mode:i.mode},V.markItemChanged(i.runId)),n=250;continue}i.runId&&(Je.current.delete(i.runId),V.markStructureChanged()),P(e=>{if(e.some(e=>e.messageId===i.message.id))return e;let t={threadId:i.threadId,projectId:i.projectId,workingDir:i.workingDir,threadCreatedAt:i.message.at,threadLastActivityAt:i.message.at,messageId:i.message.id,msgKind:i.message.kind,content:i.message.content,at:i.message.at,...i.message.resolvedFrom?{resolvedFrom:i.message.resolvedFrom}:{},...i.message.stdout===void 0?{}:{stdout:i.message.stdout},...i.message.stderr===void 0?{}:{stderr:i.message.stderr},...i.message.exitCode===void 0?{}:{exitCode:i.message.exitCode},...i.message.durationMs===void 0?{}:{durationMs:i.message.durationMs},...i.message.truncated?{truncated:!0}:{},...i.message.errorMessage?{errorMessage:i.message.errorMessage}:{},...i.message.fileReferences?{fileReferences:i.message.fileReferences}:{},...i.message.cwd===void 0?{}:{cwd:i.message.cwd}},n=[...e,t];return n.sort((e,t)=>e.at<t.at?-1:+(e.at>t.at)),n}),n=250}}catch(e){if(t||e.name===`AbortError`)return;console.warn(`[ChatTimelineView] terminal stream error (reconnecting in ${n}ms):`,e)}if(t)return;await new Promise(e=>setTimeout(e,n)),n=Math.min(n*2,5e3)}})(),()=>{t=!0,e.abort()}},[e,b,u]),(0,F.useEffect)(()=>{if(!S)return;let e=!1;return y({limit:Qn}).then(t=>{e||P(e=>Nn(t.terminalEntries,e))}).catch(()=>{}),()=>{e=!0}},[S,y]),(0,F.useEffect)(()=>{w&&(K({kind:`terminal`,key:`terminal:${w.runId}`,runId:w.runId,threadId:w.threadId,input:w.input}),nt(null))},[w]);let St=(0,F.useCallback)(async()=>{try{let e=await y({limit:Qn});ye(t=>Pn(t,e.messages));let t=j(B.current,e.messages);for(let e of t)B.current.delete(e);t.length>0&&z.markStructureChanged()}catch{}},[y,z.markStructureChanged]);(0,F.useEffect)(()=>{let e=!1,t=!1,n=async()=>{if(t||B.current.size===0)return;t=!0;let n=new Map(B.current);try{let t=await _.listInflightTurns({...Y===void 0?{}:{projectId:Y},...X===void 0?{}:{gezelId:X}});if(e)return;let r=new Set(t.inflight.map(e=>e.sessionId)),i=_e(B.current,n,r);if(i.length===0)return;for(let e of i)B.current.delete(e),pe.current.delete(e);z.markStructureChanged(),St()}catch{}finally{t=!1}},r=window.setInterval(()=>{n()},5e3);return()=>{e=!0,window.clearInterval(r)}},[Y,X,St,z.markStructureChanged]),(0,F.useEffect)(()=>ut(e=>{if(Y!==void 0&&e.projectId!==Y||X!==void 0&&e.gezelId!==X||re.current&&!re.current.has(e.sessionId))return;let t=Date.parse(e.at);if(ye(n=>{if(n.some(n=>{if(n.sessionId!==e.sessionId||n.role!==`user`||n.content!==e.content)return!1;let r=Date.parse(n.at);return Number.isFinite(t)&&Number.isFinite(r)?Math.abs(r-t)<2*6e4:!0}))return n;let r=[...n,_t(n,e,!0)];return r.sort((e,t)=>e.at<t.at?-1:+(e.at>t.at)),r}),!B.current.has(e.sessionId)){let n=Fn(be.current,e.sessionId),r=Number.isFinite(t)?t:Date.now();B.current.set(e.sessionId,{gezelId:e.gezelId,projectId:e.projectId,segments:[],startedAt:r,lastActivityAt:r,hasProgress:!1,...n?{sessionTitle:n.sessionTitle}:{sessionTitle:o(e.content)},...n?{sessionCreatedAt:n.sessionCreatedAt}:{sessionCreatedAt:e.at},...n?{sessionProviderName:n.sessionProviderName,...n.sessionModel?{sessionModel:n.sessionModel}:{}}:{},...n?.taskRef?{taskRef:n.taskRef}:{},...n?.stepId?{stepId:n.stepId}:{}}),z.markStructureChanged()}K({kind:`chat`,key:`chat:${e.sessionId}:${e.at}`,sessionId:e.sessionId,content:e.content,at:e.at}),nt(null)}),[Y,X,_t,z.markStructureChanged]);let Ct=(0,F.useCallback)(t=>{let{sessionId:n,gezelId:r,projectId:a,event:s}=t;if(Y!==void 0&&a!==Y||X!==void 0&&r!==X)return;let c=re.current;if(c&&!c.has(n)){ie.current?.(n);return}if(Re.current.has(r)||bt(),s.type===`user_message`){!s.message.hidden&&!s.message.from&&(En(de,fe),pe.current.delete(n));let e=Fn(M,n),i={sessionId:n,gezelId:r,projectId:a,sessionTitle:e?.sessionTitle??o(s.message.content),sessionCreatedAt:e?.sessionCreatedAt??s.message.at,sessionLastActivityAt:s.message.at,sessionProviderName:e?.sessionProviderName??ft,...e?.sessionSource?{sessionSource:e.sessionSource}:t.sessionSource?{sessionSource:t.sessionSource}:{},...e?.sessionModel?{sessionModel:e.sessionModel}:{},...e?.taskRef?{taskRef:e.taskRef}:{},...e?.stepId?{stepId:e.stepId}:{},...e?.parentSession?{parentSession:e.parentSession}:t.parentSession?{parentSession:t.parentSession}:{},...e?.handoffFrom?{handoffFrom:e.handoffFrom}:t.handoffFrom?{handoffFrom:t.handoffFrom}:{},role:s.message.role,content:s.message.content,at:s.message.at,...s.message.from?{from:s.message.from}:{},...s.message.nudge?{nudge:!0}:{},...s.message.origin===`system`?{origin:`system`}:{}},c=`${n}:${s.message.at}:${s.message.role}`;if(ye(e=>{if(s.message.hidden)return e;let t=e.filter(e=>!e.optimistic||!(e.sessionId===n&&e.role===s.message.role&&e.content===s.message.content));if(t.some(e=>`${e.sessionId}:${e.at}:${e.role}`===c))return t;let r=[...t,i];return r.sort((e,t)=>e.at<t.at?-1:+(e.at>t.at)),r}),s.message.role===`user`&&B.current.get(n)?.error&&B.current.delete(n),s.message.role===`user`&&!B.current.has(n)){let o=Date.parse(s.message.at),c=Number.isFinite(o)?o:Date.now();B.current.set(n,{gezelId:r,projectId:a,segments:[],startedAt:c,lastActivityAt:c,hasProgress:!1,...e?{sessionTitle:e.sessionTitle}:{sessionTitle:i.sessionTitle},...e?{sessionCreatedAt:e.sessionCreatedAt}:{sessionCreatedAt:i.sessionCreatedAt},...e?{sessionProviderName:e.sessionProviderName,...e.sessionModel?{sessionModel:e.sessionModel}:{}}:{},...e?.sessionSource?{sessionSource:e.sessionSource}:t.sessionSource?{sessionSource:t.sessionSource}:{},...e?.taskRef?{taskRef:e.taskRef}:{},...e?.parentSession?{parentSession:e.parentSession}:t.parentSession?{parentSession:t.parentSession}:{},...e?.handoffFrom?{handoffFrom:e.handoffFrom}:t.handoffFrom?{handoffFrom:t.handoffFrom}:{}}),z.markStructureChanged()}}else if(s.type===`delta`){let e=B.current.get(n)??l(r,a,n),t=e.segments[e.segments.length-1],i=Date.now(),o=i-e.lastActivityAt<5e3;t?.kind===`text`&&o?t.content+=s.content:e.segments.push({kind:`text`,content:s.content}),e.lastActivityAt=i,e.hasProgress=!0,delete e.queueAhead,delete e.queuedAt,e.wirePulseCount=0,e.thinkingLabel=void 0,delete e.thinkingProgress,delete e.thinkingDetail,delete e.liveToolArgs,B.current.set(n,e),z.markItemChanged(n)}else if(s.type===`reasoning_delta`){let e=B.current.get(n)??l(r,a,n),t=e.segments[e.segments.length-1];t?.kind===`reasoning`?t.content+=s.content:e.segments.push({kind:`reasoning`,content:s.content}),e.lastActivityAt=Date.now(),e.hasProgress=!0,delete e.queueAhead,delete e.queuedAt,e.wirePulseCount=0,delete e.thinkingProgress,delete e.thinkingDetail,B.current.set(n,e),z.markItemChanged(n)}else if(s.type===`tool_args_delta`){let e=B.current.get(n)??l(r,a,n),t=e.liveToolArgs,i=s.name.length>0?s.name:t?.name??``,o=((t?.head??``)+s.content).slice(0,400),c=((t?.tail??``)+s.content).slice(-2e3);e.liveToolArgs={name:i,chars:(t?.chars??0)+s.content.length,head:o,tail:c},e.lastActivityAt=Date.now(),e.hasProgress=!0,delete e.queueAhead,delete e.queuedAt,B.current.set(n,e),z.markItemChanged(n)}else if(s.type===`wire_pulse`){let e=B.current.get(n)??l(r,a,n);e.wirePulseCount=(e.wirePulseCount??0)+1,e.lastActivityAt=Date.now(),e.hasProgress=!0,B.current.set(n,e),z.markItemChanged(n)}else if(s.type===`intent`){let e=B.current.get(n)??l(r,a,n);e.segments.push({kind:`intent`,label:s.label}),e.lastActivityAt=Date.now(),e.hasProgress=!0,e.wirePulseCount=0,delete e.queueAhead,delete e.queuedAt,B.current.set(n,e),z.markItemChanged(n)}else if(s.type===`heartbeat`){let e=B.current.get(n)??l(r,a,n);e.lastActivityAt=Date.now(),e.hasProgress=!0,e.wirePulseCount=0,e.thinkingLabel=s.label,B.current.set(n,e),z.markItemChanged(n)}else if(s.type===`warning`){let e=B.current.get(n)??l(r,a,n);e.warnings=[...e.warnings??[],s],B.current.set(n,e),z.markItemChanged(n)}else if(s.type===`queued`){let e=B.current.get(n)??l(r,a,n);e.queueAhead=s.aheadOf,e.queuedAt=Date.now(),B.current.set(n,e),z.markItemChanged(n)}else if(s.type===`queue_enqueued`){let e=H.current.get(n)??[],t={id:s.queueId,preview:s.preview,enqueuedAt:s.enqueuedAt,...s.nudge?{nudge:!0}:{}},r=e.findIndex(e=>e.id===s.queueId);r>=0?e[r]=t:e.push(t),H.current.set(n,e),z.markStructureChanged()}else if(s.type===`queue_removed`){let e=H.current.get(n);if(e){let t=e.filter(e=>e.id!==s.queueId);t.length===0?H.current.delete(n):H.current.set(n,t),z.markStructureChanged()}}else if(s.type===`tool`){let e=B.current.get(n)??l(r,a,n),t={name:s.name,durationMs:s.durationMs,success:s.success,...s.errorMessage?{errorMessage:s.errorMessage}:{},...s.path?{path:s.path}:{},...s.paths&&s.paths.length>0?{paths:s.paths}:{},...s.argsSummary?{argsSummary:s.argsSummary}:{},...s.argsFull?{argsFull:s.argsFull}:{},...s.resultText?{resultText:s.resultText}:{},...s.resultTruncated?{resultTruncated:!0}:{},...s.images&&s.images.length>0?{images:s.images}:{},...s.diff===void 0?{}:{diff:s.diff},...s.addedLines===void 0?{}:{addedLines:s.addedLines},...s.removedLines===void 0?{}:{removedLines:s.removedLines},...s.card?{card:s.card}:{},projectId:a};e.segments.push({kind:`tool`,tool:t}),e.lastActivityAt=Date.now(),e.hasProgress=!0,e.wirePulseCount=0,delete e.liveToolArgs,delete e.queueAhead,delete e.queuedAt,B.current.set(n,e),z.markItemChanged(n),i?.(t)}else if(s.type===`complete`){ye(e=>e.map(e=>e.sessionId===n?{...e,sessionLastTurnError:void 0,sessionLastTurnErrorDetail:void 0}:e)),Pe(e=>{if(!e.has(n))return e;let t=new Map(e);return t.delete(n),t});let e=B.current.get(n);e&&(e.segments=[],e.lastActivityAt=Date.now(),e.hasProgress=!0,e.wirePulseCount=0,delete e.liveToolArgs,delete e.queueAhead,delete e.error,B.current.set(n,e)),z.markItemChanged(n),St();let t=s.message.content.trim().length;console.debug(`[narrate] complete event — contentLen=${t} gezelId=${r} projectId=${a} sessionId=${n} (buffering for done)`),t>0&&pe.current.set(n,{content:s.message.content,gezelId:r,projectId:a})}else if(s.type===`error`){Ie(e=>{if(!e.has(a))return e;let t=new Set(e);return t.delete(a),t}),ye(e=>e.map(e=>e.sessionId===n?{...e,sessionLastTurnError:s.error,sessionLastTurnErrorDetail:s.errorDetail}:e)),Pe(e=>{if(!e.has(n))return e;let t=new Map(e);return t.delete(n),t});let e=B.current.get(n);e&&(e.error=s.error,e.errorDetail=s.errorDetail,B.current.set(n,e),z.markItemChanged(n))}else if(s.type===`cancelled`)B.current.delete(n)&&z.markStructureChanged(),St();else if(s.type===`done`){let t=B.current.get(n),r=Ut(t?.activity);if(t&&!t.error&&r){let i=new Date().toISOString();Ce(a=>{let o=Wt(a,{sessionId:n,gezelId:t.gezelId,projectId:t.projectId,path:r,startedAt:new Date(t.startedAt).toISOString(),completedAt:i});return o===a?a:(Ht(e,o),o)})}t&&!t.error&&(B.current.delete(n),z.markStructureChanged());let i=pe.current.get(n);i&&(pe.current.delete(n),se.current&&(console.debug(`[narrate] done event — playing buffered narration chars=${i.content.length} sessionId=${n}`),On(i.content,i.gezelId,i.projectId,de,fe))),St()}else if(s.type===`engine_phase`){let t=B.current.get(n)??l(r,a,n);if(t.lastActivityAt=Date.now(),t.hasProgress=!0,s.activity?.trim()&&(t.activity=s.activity.trim()),s.phase===`ready`)delete t.thinkingLabel,delete t.thinkingProgress,delete t.thinkingDetail,delete t.thinkingPhase;else{let e=ur[s.phase];s.progress===void 0?(t.thinkingLabel=s.detail??e,t.thinkingPhase!==s.phase&&(delete t.thinkingProgress,delete t.thinkingDetail)):(t.thinkingLabel=e,t.thinkingProgress=s.progress,s.detail?t.thinkingDetail=s.detail:delete t.thinkingDetail),t.thinkingPhase=s.phase}B.current.set(n,t),z.markItemChanged(n);let i=Ut(s.activity);if(i){let r=new Date().toISOString();Ce(a=>{let o=Wt(a,{sessionId:n,gezelId:t.gezelId,projectId:t.projectId,path:i,startedAt:new Date(t.startedAt).toISOString(),completedAt:r});return o===a?a:(Ht(e,o),o)})}}else if(s.type===`gpu_swap`){let e=B.current.get(n)??l(r,a,n);e.lastActivityAt=Date.now(),s.state===`ended`?(delete e.gpuSwapTask,delete e.gpuSwapDetail,delete e.gpuSwapPrompt,delete e.gpuSwapProgress,delete e.gpuSwapStep,delete e.gpuSwapTotalSteps,delete e.gpuSwapSecondsPerStep):(e.gpuSwapTask=s.task,s.detail?e.gpuSwapDetail=s.detail:s.state===`started`&&delete e.gpuSwapDetail,s.prompt&&(e.gpuSwapPrompt=s.prompt),typeof s.progress==`number`&&(e.gpuSwapProgress=s.progress),typeof s.step==`number`&&(e.gpuSwapStep=s.step),typeof s.totalSteps==`number`&&(e.gpuSwapTotalSteps=s.totalSteps),typeof s.secondsPerStep==`number`&&(e.gpuSwapSecondsPerStep=s.secondsPerStep)),B.current.set(n,e),z.markItemChanged(n)}else if(s.type===`awaiting_gezel`){let e=B.current.get(n)??l(r,a,n);e.lastActivityAt=Date.now(),s.state===`ended`?delete e.awaitingGezelName:e.awaitingGezelName=s.targetGezelName,B.current.set(n,e),z.markItemChanged(n)}else s.type===`context_compacted`?(s.mode!==`mid-turn`&&St(),z.markStructureChanged()):(s.type===`question_asked`||s.type===`question_answered`)&&(He(e=>{let t=new Map(e);return s.type===`question_answered`&&!s.question.answer?t.delete(s.question.id):t.set(s.question.id,s.question),t}),s.type===`question_asked`&&St());function l(e,n,r){let i=Fn(M,r);z.markStructureChanged();let a=Date.now();return{gezelId:e,projectId:n,segments:[],startedAt:a,lastActivityAt:a,hasProgress:!1,...i?{sessionTitle:i.sessionTitle}:{},...i?{sessionCreatedAt:i.sessionCreatedAt}:{},...i?.taskRef?{taskRef:i.taskRef}:{},...i?.parentSession?{parentSession:i.parentSession}:t.parentSession?{parentSession:t.parentSession}:{},...i?.handoffFrom?{handoffFrom:i.handoffFrom}:t.handoffFrom?{handoffFrom:t.handoffFrom}:{},...i?.sessionSource?{sessionSource:i.sessionSource}:t.sessionSource?{sessionSource:t.sessionSource}:{}}}},[M,i,St,bt,ft,Y,X,e,z.markItemChanged,z.markStructureChanged]),wt=(0,F.useMemo)(()=>{let e=[];for(let[t,n]of B.current.entries())e.push({kind:`streaming`,sessionId:t,slot:n});let t=M.map(e=>({kind:`message`,msg:e,at:e.at})),n=e.map(e=>({kind:`streaming`,sessionId:e.sessionId,slot:e.slot,at:new Date(e.slot.lastActivityAt).toISOString(),threadAt:new Date(e.slot.startedAt).toISOString()})),r=xe.map(e=>({kind:`terminal`,entry:e,at:e.at})),i=[];for(let[e,t]of Je.current.entries())i.push({kind:`terminal-streaming`,runId:e,slot:t,at:t.startedAt});let a=Se.map(e=>({kind:`indexing`,entry:e,at:e.completedAt})),o=[...t,...n,...a,...r,...i],s=Date.now();return o.sort((e,t)=>Sn(e,t,s)),o},[M,Se,xe,Ke,Ye,we]),Tt=(0,F.useMemo)(()=>Jn(wn(Xn(wt),t,Date.now())),[wt,t,we]),Et=Tt.items,Dt=Tt.depthBySession,Ot=Tt.branchBySession,kt=(0,F.useMemo)(()=>{if(!h?.length)return[];let e=new Set;for(let[t,n]of B.current.entries()){let r=n.taskRef??Fn(M,t)?.taskRef;r&&e.add(r)}return h.filter(t=>{if(e.has(t.task.ref))return!1;let n=t.wait.sessionId;return!n||!B.current.has(n)&&!M.some(e=>e.sessionId===n)})},[h,M,Ke]);(0,F.useEffect)(()=>{let e=U.current;if(!e)return;let t=wt.length>lt.current,n=e.scrollHeight>dt.current;lt.current=wt.length,dt.current=e.scrollHeight,!(!t&&!n)&&Qe&&e.scrollTo({top:e.scrollHeight,behavior:`instant`})},[wt,Qe]);let At=(0,F.useCallback)(()=>{J.current===null&&(J.current=requestAnimationFrame(()=>{J.current=null;let e=U.current;if(!e)return;let t=e.scrollHeight,n=t>dt.current;dt.current=t,!(!n||!W.current)&&e.scrollTo({top:t,behavior:`instant`})}))},[]);(0,F.useLayoutEffect)(()=>{let e=U.current,t=Xe.current;if(!e||!t)return;let n=()=>{let n=Number.parseFloat(getComputedStyle(e).rowGap)||0,r=0,i=new Set,a=e.querySelectorAll(`[data-msg-id^="live:"], .terminal-group-streaming`);for(let e of a){if(i.has(e))continue;i.add(e),r+=e.getBoundingClientRect().height;let t=e.closest(`.timeline-thread-rootless`)?.previousElementSibling;t?.classList.contains(`timeline-session-divider-activity`)&&(r+=t.getBoundingClientRect().height+n);let a=e.closest(`.timeline-thread-replies`),o=a&&Number.parseFloat(getComputedStyle(a).rowGap)||n;r+=o}t.style.blockSize=`${Math.max(0,ir-r)}px`};if(n(),typeof ResizeObserver>`u`)return;let r=new ResizeObserver(n);for(let t of e.querySelectorAll(`[data-msg-id^="live:"], .terminal-group-streaming`))r.observe(t);return()=>r.disconnect()},[Ae,Ke,Ye]),(0,F.useEffect)(()=>{let e=U.current;if(!e||!G||tt===G.key)return;let t=null;if(G.kind===`chat`){let n=Date.parse(G.at),r=M.filter(e=>e.sessionId===G.sessionId&&e.role===`user`&&e.content===G.content).sort((e,t)=>Math.abs(Date.parse(e.at)-n)-Math.abs(Date.parse(t.at)-n))[0];if(r){let n=Mn(`msg:${r.sessionId}:${r.at}:${r.role}`);t=e.querySelector(`[data-msg-id="${n}"]`)}}else{let n=[...xe].reverse().find(e=>e.threadId===G.threadId&&e.msgKind===`command`&&(e.content===G.input||e.resolvedFrom===G.input));if(n){let r=Mn(n.messageId);t=e.querySelector(`[data-terminal-message-id="${r}"]`)}}if(!t)return;let n=e.getBoundingClientRect(),r=t.getBoundingClientRect(),i=Math.max(0,e.scrollTop+r.top-n.top-12);W.current=!0,$e(!0),e.scrollTo({top:i}),nt(G.key)},[M,xe,G,tt]),(0,F.useEffect)(()=>{if(!T||rt.current===T.requestKey)return;let e=U.current;if(!e)return;let t=Mn(T.threadId),n=e.querySelectorAll(`[data-terminal-thread-id="${t}"]`),r=n[n.length-1];r&&(rt.current=T.requestKey,W.current=!1,$e(!1),typeof r.scrollIntoView==`function`&&r.scrollIntoView({block:`center`}),r.classList.add(`timeline-focus-flash`),window.setTimeout(()=>r.classList.remove(`timeline-focus-flash`),ar))},[T,xe]);let jt=(0,F.useCallback)((e,t)=>{let r=U.current;if(!r)return!1;let i=Mn(e),a=r.querySelector(`[data-session-error="${i}"]`),o=r.querySelectorAll(`[data-session-id="${i}"]`),s=null;if(t?.messageIndex!==void 0){let n=be.current.filter(t=>t.sessionId===e),i=n[Math.max(0,Math.min(t.messageIndex-1,n.length-1))];i&&(s=r.querySelector(`[data-msg-id="${Mn(`msg:${i.sessionId}:${i.at}:${i.role}`)}"]`))}let c=s??a??o[o.length-1]??null;if(!c)return!1;if(W.current=!1,$e(!1),typeof c.scrollIntoView==`function`&&c.scrollIntoView({block:`center`}),c.classList.add(`timeline-focus-flash`),window.setTimeout(()=>c.classList.remove(`timeline-focus-flash`),ar),t?.notifyParent!==!1){let t=be.current.find(t=>t.sessionId===e);t&&n?.(e,t.gezelId,t.projectId)}return!0},[n]),Mt=(0,F.useRef)(null),[Nt,Pt]=(0,F.useState)(0),Ft=(0,F.useCallback)((e,t)=>{Mt.current={sessionId:e,notifyParent:t?.notifyParent!==!1,...t?.messageIndex===void 0?{}:{messageIndex:t.messageIndex}},Pt(e=>e+1)},[]);(0,F.useEffect)(()=>{let e=Mt.current;if(e){if(jt(e.sessionId,{notifyParent:e.notifyParent,...e.messageIndex===void 0?{}:{messageIndex:e.messageIndex}})){Mt.current=null;return}if(!(Ae||at.current)){if(!Ee||!Oe){Mt.current=null;return}at.current=!0,(async()=>{try{let t=await y({limit:Qn,before:Oe});if(Mt.current!==e)return;ye(e=>[...t.messages,...e]),De(t.hasMore),ke(t.nextCursor)}catch{Mt.current===e&&(Mt.current=null)}finally{at.current=!1,Pt(e=>e+1)}})()}}},[wt,Nt,jt,Ae,Ee,Oe,y]),(0,F.useEffect)(()=>{let e=e=>{let t=e.detail;t?.sessionId&&t.projectId===Y&&(Y&&he(Y),Ft(t.sessionId))};return window.addEventListener(`gezel:focus-session-error`,e),()=>window.removeEventListener(`gezel:focus-session-error`,e)},[Y,Ft]);let It=(0,F.useRef)(void 0);(0,F.useEffect)(()=>{if(It.current!==Y&&(It.current=Y,Mt.current=null),!Y)return;let e=he(Y);e&&Ft(e.sessionId)},[Y,Ft]),(0,F.useEffect)(()=>{E&&it.current!==E.requestKey&&(it.current=E.requestKey,Ft(E.sessionId,{notifyParent:!1,...E.messageIndex===void 0?{}:{messageIndex:E.messageIndex}}))},[E,Ft]);let Rt=(0,F.useCallback)(()=>{let e=U.current;if(!e){ot(e=>e===null?e:null);return}let t=e.getBoundingClientRect(),n=e.parentElement;if(n){let t=e.offsetWidth-e.clientWidth;n.style.setProperty(`--chat-timeline-sb-width`,`${t}px`)}let r=e.parentElement?.querySelector(`.chat-sticky-header`);if(r){let e=r.getBoundingClientRect().height;e>0&&(ct.current=e)}let i=ct.current,a=t.top,o=t.top+i,s=null,c=0,l=null,u=null,d=null,f=e.querySelectorAll(`[data-msg-id]`);for(let e of f){let t=e.dataset.msgId,n=e.dataset.sessionId;if(!t)continue;let r=e.getBoundingClientRect(),i=r.top<a&&r.bottom>o,d=e.classList.contains(`msg-assistant`)||e.classList.contains(`msg-from-gezel`);i&&d&&(s=t,c=r.top,l=n??null,u=r)}if(n&&u){let e=n.getBoundingClientRect(),t=u.left-e.left;n.style.setProperty(`--chat-sticky-left`,`${t}px`),n.style.setProperty(`--chat-sticky-width`,`${u.width}px`)}if(s&&l)for(let e of f){let t=e.dataset.msgId,n=e.dataset.sessionId;!t||n!==l||e.classList.contains(`msg-user`)&&e.getBoundingClientRect().bottom<=c&&(d=t)}let p=s&&d?{userMessageId:d,assistantMessageId:s}:null;ot(e=>e===p||e&&p&&e.userMessageId===p.userMessageId&&e.assistantMessageId===p.assistantMessageId?e:p)},[]),zt=(0,F.useCallback)(()=>{st.current===null&&(st.current=requestAnimationFrame(()=>{st.current=null,Rt()}))},[Rt]);(0,F.useEffect)(()=>{zt()},[wt,zt]),(0,F.useEffect)(()=>{let e=U.current;if(!e||typeof ResizeObserver>`u`)return;let t=new ResizeObserver(zt);return t.observe(e),()=>t.disconnect()},[zt]),(0,F.useEffect)(()=>()=>{st.current!==null&&(cancelAnimationFrame(st.current),st.current=null),J.current!==null&&(cancelAnimationFrame(J.current),J.current=null),Ze.current!==null&&(window.clearTimeout(Ze.current),Ze.current=null)},[]);let Bt=(0,F.useCallback)(()=>{zt();let e=U.current;if(!e)return;e.classList.add(`chat-timeline-scrolling`),Ze.current!==null&&window.clearTimeout(Ze.current),Ze.current=window.setTimeout(()=>{U.current?.classList.remove(`chat-timeline-scrolling`),Ze.current=null},rr);let t=e.scrollHeight-(e.scrollTop+e.clientHeight)<=tr;if(W.current=t,$e(e=>e===t?e:t),e.scrollTop<=nr&&Ee&&!Ae&&!at.current&&Oe){at.current=!0;let t=e.scrollHeight,n=e.scrollTop;(async()=>{try{let e=await y({limit:Qn,before:Oe});ye(t=>[...e.messages,...t]),De(e.hasMore),ke(e.nextCursor),requestAnimationFrame(()=>{let e=U.current;e&&e.scrollTo({top:e.scrollHeight-t+n,behavior:`instant`}),at.current=!1,Mt.current&&Pt(e=>e+1)})}catch{at.current=!1,Mt.current&&Pt(e=>e+1)}})()}},[Ee,Ae,Oe,y,zt]),Kt=(0,F.useCallback)(()=>{$e(e=>{let t=!e;if(W.current=t,t){let e=U.current;e&&e.scrollTo({top:e.scrollHeight,behavior:`instant`})}return t})},[]),qt=(0,F.useMemo)(()=>{if(!q)return null;let e=M.find(e=>`msg:${e.sessionId}:${e.at}:${e.role}`===q.userMessageId);if(!e)return null;let t=null;if(q.assistantMessageId.startsWith(`live:`)){let e=q.assistantMessageId.slice(5);B.current.has(e)&&(t={kind:`live`,sessionId:e})}else{let e=M.find(e=>`msg:${e.sessionId}:${e.at}:${e.role}`===q.assistantMessageId);e&&(t={kind:`message`,msg:e})}return t?{userMsg:e,assistantInfo:t}:null},[q,M,Ke]),Yt=kt.slice(0,sr),Xt=kt.length-Yt.length,Zt=(0,I.jsxs)(I.Fragment,{children:[Yt.map(e=>(0,I.jsx)(Jt,{task:e.task,wait:e.wait,gezel:R.get(e.wait.gezelId),onTaskReference:e=>window.dispatchEvent(new CustomEvent(`gezel:open-tab`,{detail:{kind:`task`,ref:e}}))},`queued-task:${e.task.ref}`)),Xt>0&&(0,I.jsxs)(`p`,{className:`msg-queued-task-overflow muted small`,children:[`+ `,Xt,` more task`,Xt===1?``:`s`,` waiting in the queue.`]})]}),Qt=(e,t)=>{Pe(n=>{let r=new Map(n);return t?r.set(e,t):r.delete(e),r})},$t=async(e,t)=>{Qt(e,{busy:`acknowledge`});let n=new AbortController,r=window.setTimeout(()=>n.abort(),cr);try{await _.clearProjectErrors(t,n.signal),window.dispatchEvent(new CustomEvent(`gezel:session-error-cleared`,{detail:{projectId:t}}))}catch{Qt(e,{error:n.signal.aborted?`Clearing the alert took too long. Check the connection and try again.`:`Could not clear the alert. Check the connection and try again.`})}finally{window.clearTimeout(r)}},en=async e=>{Qt(e,{busy:`retry`});try{await _.retryChatSessionTurn(e)}catch{Qt(e,{error:`Retry could not start. Check the connection or settings, then try again.`})}},tn=(e,t,n,i,a)=>{let o=Ne.get(e),s=o?.busy;return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`div`,{className:`timeline-session-error-actions`,"aria-label":`Failed turn actions`,children:[Rn(t,n)&&(0,I.jsx)(`button`,{type:`button`,className:`timeline-session-error-action timeline-session-error-action-primary`,disabled:s!==void 0,onClick:()=>void en(e),children:s===`retry`?`Retrying…`:`Retry`}),In(t)&&(0,I.jsx)(`button`,{type:`button`,className:`timeline-session-error-action secondary`,disabled:s!==void 0,onClick:()=>window.dispatchEvent(new CustomEvent(`gezel:navigate`,{detail:{view:`settings`,section:`defaults`}})),children:`Open Settings`}),i&&(0,I.jsx)(`button`,{type:`button`,className:`timeline-session-error-action secondary`,title:`Clear this project's failed-turn alerts without rerunning the work`,disabled:s!==void 0,onClick:()=>void $t(e,i),children:s===`acknowledge`?`Acknowledging…`:`Acknowledge`}),!r(t)&&!Ln(n)&&(0,I.jsx)(me,{className:`timeline-session-error-link`,report:{surface:a,message:t,detail:n}})]}),o?.error&&(0,I.jsx)(`p`,{className:`timeline-session-error-action-error`,role:`alert`,children:o.error})]})};if(Ae&&M.length===0)return(0,I.jsx)(`div`,{className:`chat-timeline chat-timeline-loading`,children:(0,I.jsx)(`p`,{className:`muted small`,children:`Loading…`})});if(je)return(0,I.jsx)(`div`,{className:`chat-timeline chat-timeline-error`,children:(0,I.jsx)(`p`,{className:`error`,children:je})});if(wt.length===0)return(0,I.jsxs)(`div`,{className:`chat-timeline`,ref:U,"data-testid":`chat-timeline`,children:[v??(g?(0,I.jsx)(`p`,{className:`placeholder`,children:g}):null),Zt]});let nn=null,rn=null,on,sn=null,cn=new Set,ln=new Map,un=new Set;for(let e of M)e.pendingQuestionId&&un.add(e.pendingQuestionId);let fn=new Map;for(let e of Ve.values()){if(un.has(e.id))continue;let t=fn.get(e.sessionId);(!t||e.createdAt>t.createdAt)&&fn.set(e.sessionId,e)}let pn=new Map;for(let e of M){if(e.role!==`assistant`||e.pendingQuestionId||!lr(e))continue;let t=`${e.sessionId}\u0000${e.at}\u0000${e.role}`,n=pn.get(e.sessionId);(!n||e.at>n.at)&&pn.set(e.sessionId,{key:t,at:e.at})}let mn=new Map,gn=new Map;for(let[e,t]of fn){let n=pn.get(e);n?mn.set(n.key,t):t.answer||gn.set(e,t)}let _n=[],vn=(e,t,n,r)=>{_n.push((0,I.jsxs)(`div`,{className:`timeline-session-error-banner`,"data-session-error":e,role:`alert`,children:[(0,I.jsxs)(`div`,{className:`timeline-session-error-body`,children:[(0,I.jsx)(`span`,{"aria-hidden":`true`,children:`✗`}),(0,I.jsxs)(`span`,{children:[(0,I.jsx)(`strong`,{children:`Last turn failed.`}),` `,t]})]}),tn(e,t,n,r,`session-error`)]},`session-error:${e}`))},bn=e=>{m?m(e,{focus:!0}):window.dispatchEvent(new CustomEvent(`gezel:open-tab`,{detail:{kind:`task`,ref:e}}))},xn=(e,n)=>{let r=R.get(e.gezelId),i=e.sessionId===t,o=Vn(e.sessionLastActivityAt,hn),c=!i&&!o,d=O&&e.projectId!=="default"?ze.get(e.projectId):void 0,m=e.from?e.from.gezelId:e.gezelId,h=R.get(m)?.font,g=l(h),_=f(h),v=Bn(e),y=(e.pendingQuestionId?Ve.get(e.pendingQuestionId):void 0)??mn.get(`${e.sessionId}\u0000${e.at}\u0000${e.role}`);return(0,I.jsx)(le,{dataMsgId:`msg:${e.sessionId}:${e.at}:${e.role}`,dataSessionId:e.sessionId,debugMode:ht,sessionId:e.sessionId,messageAt:e.at,role:e.role,content:e.content,authorLabel:r?s({name:r.name,roleBasedName:r.roleBasedName},A):`Gezel`,authorIcon:r?.icon??null,...r?.poppetje?{authorPoppetje:r.poppetje}:{},...r?.iconOverride?{authorIconOverride:!0}:{},authorTooltip:$(e.gezelId),...(()=>{let t=vt(e.sessionProviderName,e.sessionModel);return t?{driftLabel:t}:{}})(),...!A&&r?.role?{authorRole:r.role}:{},...e.from?{from:e.from}:{},...e.nudge?{nudge:!0}:{},...e.origin===`system`?{origin:`system`}:{},receiverLabel:r?s({name:r.name,roleBasedName:r.roleBasedName},A):`Gezel`,...g?{fontFamily:g}:{},..._===1?{}:{fontScale:_},...d?{projectLabel:d.name}:{},extraClass:c?`timeline-msg-faded`:void 0,projectId:e.projectId,mediaProvider:et(e.projectId,e.sessionId),...v.length>0?{referencedFiles:v}:{},...e.retrieval&&e.retrieval.hits.length>0?{retrieval:e.retrieval}:{},...e.referencedTasks?{referencedTasks:e.referencedTasks}:{},...e.toolCalls&&e.toolCalls.length>0?{toolCalls:e.toolCalls}:{},...p?{onOpenReference:p}:{},...e.reasoning?{reasoning:e.reasoning}:{},...e.reasoningDurationMs===void 0?{}:{reasoningDurationMs:e.reasoningDurationMs},...e.attemptedToolCalls&&e.attemptedToolCalls.length>0?{attemptedToolCalls:e.attemptedToolCalls}:{},...n?.recoveredInNextTurn?{recoveredInNextTurn:!0}:{},...n?.suppressHeader?{suppressHeader:!0}:{},...n?.timestampLabel?{timestampLabel:n.timestampLabel}:{},...e.intents&&e.intents.length>0?{intents:e.intents}:{},...e.warnings&&e.warnings.length>0?{warnings:e.warnings}:{},...e.synthetic?{synthetic:e.synthetic}:{},...e.contextCompaction?{contextCompaction:e.contextCompaction}:{},...y?{question:y,onQuestionAnswered:e=>He(t=>{let n=new Map(t);return n.set(e.id,e),n})}:{},...a||u?{onFileReference:t=>{t.kind===`workspace`?u?.(t.path,e.projectId):a?.(t.path,e.projectId)}}:{},onTaskReference:e=>window.dispatchEvent(new CustomEvent(`gezel:open-tab`,{detail:{kind:`task`,ref:e}})),onFocusTask:bn},`msg:${e.sessionId}:${e.at}:${e.role}`)},Cn=(e,t)=>{let n=[],r=R.get(t.gezelId),i=l(r?.font),a=f(r?.font);n.push((0,I.jsx)(ae,{dataMsgId:`live:${e}`,dataSessionId:e,authorLabel:r?s({name:r.name,roleBasedName:r.roleBasedName},A):`Gezel`,authorIcon:r?.icon??null,...r?.poppetje?{authorPoppetje:r.poppetje}:{},...r?.iconOverride?{authorIconOverride:!0}:{},authorTooltip:$(t.gezelId),...(()=>{if(!t.sessionProviderName)return{};let e=vt(t.sessionProviderName,t.sessionModel);return e?{driftLabel:e}:{}})(),...!A&&r?.role?{authorRole:r.role}:{},segments:t.segments,...p?{onOpenReference:p}:{},onFocusTask:bn,startedAt:t.startedAt,lastActivityAt:t.lastActivityAt,hasProgress:t.hasProgress,...Q(t.gezelId)===`ollama`?{onProbeOllama:()=>_.ollamaProbe()}:{},...Q(t.gezelId)===`ollama`?{localEngine:`ollama`}:Q(t.gezelId)===`llama-cpp`?{localEngine:`llama-cpp`}:Q(t.gezelId)===`ds4`?{localEngine:`ds4`}:{},...t.sessionSource||e.startsWith(`one-shot:`)?{}:{onCancel:async()=>{try{await _.cancelChatSessionTurn(e)}catch(e){console.warn(`[timeline] failed to cancel turn:`,e)}},onReEngage:async()=>{try{await _.cancelChatSessionTurn(e)}catch(e){console.warn(`[timeline] re-engage: cancel failed:`,e)}try{await _.sendToChatSession(e,{message:`Please continue where you left off and finish the work you started.`})}catch(e){console.warn(`[timeline] re-engage: send failed:`,e)}}},...i?{fontFamily:i}:{},...a===1?{}:{fontScale:a},...t.error?{error:t.error}:{},...t.errorDetail?{errorDetail:t.errorDetail}:{},...t.error?{errorActions:tn(e,t.error,t.errorDetail,t.projectId,`chat-turn`)}:{},...t.queueAhead===void 0?{}:{queueAhead:t.queueAhead},...t.queuedAt===void 0?{}:{queuedAt:t.queuedAt},...t.wirePulseCount&&t.wirePulseCount>0?{wirePulseCount:t.wirePulseCount}:{},...ue(t)?{thinkingLabel:ue(t)}:{},...t.thinkingProgress===void 0?{}:{thinkingProgress:t.thinkingProgress},...t.thinkingDetail?{thinkingDetail:t.thinkingDetail}:{},...t.liveToolArgs?{liveToolArgs:t.liveToolArgs}:{},...t.gpuSwapTask?{gpuSwapTask:t.gpuSwapTask}:{},...t.gpuSwapDetail?{gpuSwapDetail:t.gpuSwapDetail}:{},...t.gpuSwapPrompt?{gpuSwapPrompt:t.gpuSwapPrompt}:{},...t.gpuSwapProgress===void 0?{}:{gpuSwapProgress:t.gpuSwapProgress},...t.gpuSwapStep===void 0?{}:{gpuSwapStep:t.gpuSwapStep},...t.gpuSwapTotalSteps===void 0?{}:{gpuSwapTotalSteps:t.gpuSwapTotalSteps},...t.gpuSwapSecondsPerStep===void 0?{}:{gpuSwapSecondsPerStep:t.gpuSwapSecondsPerStep},...t.awaitingGezelName?{awaitingGezelName:t.awaitingGezelName}:{},...t.warnings&&t.warnings.length>0?{warnings:t.warnings}:{},...gn.get(e)?{question:gn.get(e),onQuestionAnswered:e=>He(t=>{let n=new Map(t);return n.set(e.id,e),n})}:{},debugMode:ht,sessionId:e},`live:${e}`));let o=H.current.get(e);if(o&&o.length>0)for(let r of o)n.push((0,I.jsx)(ce,{sessionId:e,queueId:r.id,preview:r.preview,enqueuedAt:r.enqueuedAt,mediaProvider:et(t.projectId,e),...r.nudge?{nudge:!0}:{},onDiscard:async()=>{try{await _.cancelQueuedMessage(e,r.id)}catch(e){console.warn(`[timeline] failed to discard queued message:`,e)}},onCancelCurrent:async()=>{try{await _.cancelChatSessionTurn(e)}catch(e){console.warn(`[timeline] failed to cancel current turn:`,e)}},onLoadText:async()=>{try{return(await _.listSessionQueue(e)).entries.find(e=>e.queueId===r.id)?.text??null}catch{return null}},onSaveEdit:async t=>{try{return await _.updateQueuedMessage(e,r.id,{message:t}),!0}catch(e){if(/not found/i.test(e.message??``))return!1;throw e}}},`ghost:${r.id}`));return n};for(let e of Et){if(e.kind===`indexing`){_n.push((0,I.jsx)(Gt,{receipt:e.entry,gezels:R,projects:ze,showProjectName:O,roleBasedNameOnlyMode:A,...u?{onOpenWorkspaceFile:u}:{}},e.entry.id));continue}if(e.kind===`terminal`){let t=e.entry,n=ln.get(t.threadId),r=!n,i=n?Math.max(0,new Date(t.at).getTime()-new Date(n.at).getTime()):0;(r||i>or)&&_n.push(jn({entry:t,key:`terminal-divider:${t.threadId}:${t.messageId}`})),_n.push((0,I.jsx)(an,{entry:t,...u?{onOpenWorkspaceFile:e=>u(e,t.projectId)}:{}},`terminal:${t.threadId}:${t.messageId}`)),ln.set(t.threadId,t);continue}if(e.kind===`terminal-streaming`){let t=e.slot.projectId,n=e.runId;_n.push((0,I.jsx)(Un,{store:V,itemKey:n,onRendered:At,render:e=>(0,I.jsx)(dn,{content:e.content,cwd:e.cwd,startedAt:e.startedAt,...e.awaitingInput?{awaitingInput:e.awaitingInput}:{},onCancel:()=>{_.cancelTerminalRun(t,n).catch(()=>{})},onSendInput:e=>{let r=Je.current.get(n);r&&(delete r.awaitingInput,V.markItemChanged(n)),_.sendTerminalInput(t,n,e).catch(e=>{console.warn(`[ChatTimelineView] sendTerminalInput failed`,e)})}})},`terminal-streaming:${n}`));continue}let r=e.sessionId,i=Dt.get(r)??0,a=Ot.get(r),o=e.root??e.replies[0];if(!o)continue;if(r!==nn){nn&&rn&&!B.current.has(nn)&&vn(nn,rn,on,sn);let s=cn.has(r);_n.push(An({row:o,gezels:R,projects:ze,showProjectName:O,activeSessionId:t,onFocusSession:n,continuing:s,depth:i,...a?{treeBranch:a}:{},key:`divider:${r}:${e.at}`,roleBasedNameOnlyMode:A})),cn.add(r),nn=r,rn=null,on=void 0,sn=null}let s=e.root??e.replies.find(e=>e.kind===`message`);s&&s.kind===`message`&&s.msg.sessionLastTurnError&&!Fe.has(s.msg.projectId)&&(rn=s.msg.sessionLastTurnError,on=s.msg.sessionLastTurnErrorDetail,sn=s.msg.projectId);let c=[];if(e.root&&c.push(xn(e.root.msg,{timestampLabel:x(e.root.at)})),e.replies.length>0){let t=[];for(let n=0;n<e.replies.length;n++){let r=e.replies[n];if(r.kind===`streaming`){t.push((0,I.jsx)(Un,{store:z,itemKey:r.sessionId,onRendered:At,render:e=>Cn(r.sessionId,e)},`live-slot:${r.sessionId}`));continue}let i=r.msg,a=n>0?e.replies[n-1]:void 0,o=a?a.at:e.root?.at,s=(o?Math.max(0,Date.parse(i.at)-Date.parse(o)):0)>er,c=a?.kind===`message`&&a.msg.gezelId===i.gezelId,l=e.replies[n+1],u=i.role===`assistant`&&i.content.trim().length===0&&!!i.toolCalls&&i.toolCalls.length>0&&l!==void 0&&l.kind===`message`&&l.msg.sessionId===i.sessionId&&l.msg.role===`assistant`&&l.msg.content.trim().length>0;t.push(xn(i,{...c&&!s?{suppressHeader:!0}:{},...s?{timestampLabel:x(i.at)}:{},...u?{recoveredInNextTurn:!0}:{}}))}c.push((0,I.jsx)(`div`,{className:`timeline-thread-replies`,children:t},`replies`))}let l=a?.hasChildren===!0||i===0&&e.replies.length>0&&(!e.root||!e.root.msg.from);_n.push((0,I.jsxs)(`div`,{className:`timeline-thread${i>0?` timeline-session-subthread timeline-session-depth-${Math.min(i,4)}`:``}${a?.hasChildren?` timeline-session-parent`:``}${e.root?``:` timeline-thread-rootless`}${l?` timeline-thread-railed`:``}`,children:[i>0&&a&&(0,I.jsx)(kn,{branch:a,phase:`thread`}),c]},`thread:${r}:${e.at}`))}return nn&&rn&&!B.current.has(nn)&&vn(nn,rn,on,sn),(0,I.jsxs)(`div`,{className:`chat-timeline-viewport`,children:[qt&&(qt.assistantInfo.kind===`live`?(0,I.jsx)(Wn,{store:z,sessionId:qt.assistantInfo.sessionId,userMsg:qt.userMsg,gezels:R}):(0,I.jsx)(Lt,{payload:{userMsg:qt.userMsg,assistantInfo:{kind:`message`,msg:qt.assistantInfo.msg}},gezels:R})),(0,I.jsxs)(`div`,{className:`chat-timeline`,ref:U,onScroll:Bt,"data-testid":`chat-timeline`,children:[Ee&&(0,I.jsx)(`div`,{className:`timeline-loading-pill muted small`,children:at.current?`Loading older messages…`:`Scroll up for older messages`}),_n.length===0?v??(g?(0,I.jsx)(`p`,{className:`placeholder`,children:g}):null):_n,Zt,(0,I.jsx)(`div`,{ref:Xe,className:`timeline-response-runway`,"aria-hidden":`true`})]}),!Qe&&(0,I.jsx)(`button`,{type:`button`,className:`chat-timeline-pin-toggle`,onClick:Kt,title:`Jump to newest and follow`,"aria-label":`Jump to newest and follow`,children:(0,I.jsxs)(`svg`,{className:`chat-timeline-pin-glyph`,width:`16`,height:`16`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.5`,strokeLinecap:`round`,strokeLinejoin:`round`,role:`img`,"aria-hidden":!0,children:[(0,I.jsx)(`title`,{children:`Jump to newest`}),(0,I.jsx)(`line`,{x1:`12`,y1:`4`,x2:`12`,y2:`15`}),(0,I.jsx)(`polyline`,{points:`6 10 12 16 18 10`}),(0,I.jsx)(`line`,{x1:`5`,y1:`20`,x2:`19`,y2:`20`})]})})]})}export{_t as a,Dt as i,gn as n,ht as o,Nt as r,dr as t};
@@ -1 +1 @@
1
- import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{n as t,t as n}from"./jsx-runtime-CEpd2cAX.js";import{t as r}from"./api-C0I7spBl.js";import{c as i,d as a,f as o,l as s,m as c,p as l,s as u,u as d}from"./primitives-CWrGZpPI.js";import{n as f,t as p}from"./relative-time-B2kBaekd.js";import{t as m}from"./ConfirmDialog-Dt1ed4Fh.js";import{At as h,Ot as g,kt as _}from"./index-DDu8nyO6.js";import"./provider-default-BLsHrgzI.js";var v=e(t(),1);function y(e){let t=(0,v.useRef)(null),[n,r]=(0,v.useState)(null),[i,a]=(0,v.useState)(``),[o,s]=(0,v.useState)(null),[c,l]=(0,v.useState)(null),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(!1),[m,h]=(0,v.useState)(!1),g=(0,v.useRef)(e);g.current=e;let _=(0,v.useCallback)(e=>{r(e);let t=g.current.backupNotice?.(e);t&&l(t),a(t=>{let n=new Set(e.models.map(e=>e.id));return t&&n.has(t)?t:e.configuredModel&&n.has(e.configuredModel)?e.configuredModel:e.recommendedModel&&n.has(e.recommendedModel)?e.recommendedModel:e.models[0]?.id??``})},[]),y=(0,v.useCallback)(async()=>{s(null);try{_(await g.current.fetchStatus())}catch(e){s(`Could not check the ${g.current.label} setup — ${S(e)}`)}},[_]);(0,v.useEffect)(()=>(y(),()=>{t.current!==null&&window.clearTimeout(t.current)}),[y]);let b=window.__GEZEL__?.mode,x=b===`local-adopt`||b===`local-spawn-packaged`||b===`local-spawn-dev`||b===`embedded`,C=b===`remote`,w=n?.state===`configured`||n?.state===`update-needed`,T=n?.state===`configured`&&n.bridge.listening&&e.endpointsEnabled&&x,E=e.modelSelection!==!1,D=E&&w&&i!==n?.configuredModel,O=n?.state===`conflict`&&n.canRepair,k=n?.state===`not-configured`||n?.state===`update-needed`||D||O,A=n?.state===`conflict`?n.canRepair:n?.canConfigure??!1,j=f||!x||!e.endpointsEnabled||!A||E&&!i,M=f||!x||!e.endpointsEnabled||!A;return{status:n,model:i,setModel:a,error:o,setError:s,notice:c,confirmation:u,setConfirmation:d,busy:f,copied:m,refresh:y,runConfirmedAction:(0,v.useCallback)(async()=>{if(!(!u||f)){p(!0),s(null),l(null);try{_(await g.current.runAction(u,i)),d(null),Promise.resolve(g.current.onChanged?.()).catch(()=>{})}catch(e){d(null),s(`${g.current.errorPrefix(u,n?.state)} — ${S(e)}`)}finally{p(!1)}}},[_,f,u,i,n?.state]),copyLaunchCommand:(0,v.useCallback)(async()=>{if(n?.launchCommand){s(null);try{if(!navigator.clipboard?.writeText)throw Error(`clipboard access is unavailable`);await navigator.clipboard.writeText(n.launchCommand),h(!0),t.current!==null&&window.clearTimeout(t.current),t.current=window.setTimeout(()=>{t.current=null,h(!1)},2e3)}catch(e){s(`Could not copy the ${g.current.label} command — ${S(e)}`)}}},[n?.launchCommand]),localDesktopMode:x,remoteMode:C,configured:w,canLaunch:T,modelChanged:D,repairable:O,needsConfigure:k,configureDisabled:j,selectionDisabled:M}}function b(e){switch(e){case`not-configured`:return`Not configured`;case`configured`:return`Configured`;case`update-needed`:return`Update needed`;case`conflict`:return`Needs attention`;case`unavailable`:return`Unavailable`}}function x(e){return e.kind===`gezel`||e.id.startsWith(`gezel:`)}function S(e){if(e&&typeof e==`object`&&`details`in e){let t=e.details;if(typeof t==`string`&&t)return t;if(t&&typeof t==`object`){let e=t;if(typeof e.message==`string`&&e.message)return e.message;if(typeof e.error==`string`&&e.error)return e.error}}return e instanceof Error?e.message:String(e)}var C=n();function w({headingId:e,title:t,status:n,intro:r,notInstalledNote:f,repairExplainer:p,notice:m,reasonsIntro:h,configuredNote:g,commandRow:_,modelRow:y,extraRows:S,actions:w,error:E,emptyModelsNote:D,remoteMode:O,localDesktopMode:k,endpointsEnabled:A,repairable:j,children:M}){let N=(0,v.useId)(),P=n?b(n.state):`Checking…`,F=n?.models.filter(x)??[],I=n?.models.filter(e=>!x(e))??[];return(0,C.jsxs)(`section`,{className:`settings-subsection provider-card harness-setup-card`,"aria-labelledby":e,children:[(0,C.jsxs)(`div`,{className:`settings-card-header`,children:[(0,C.jsx)(`h3`,{id:e,children:t}),(0,C.jsx)(`span`,{className:`harness-setup-state harness-setup-state--${n?.state??`checking`}`,"aria-live":`polite`,children:P})]}),(0,C.jsx)(`p`,{className:`muted small harness-setup-intro`,children:r}),!n&&!E&&(0,C.jsx)(`p`,{className:`muted small`,children:`Checking the setup…`}),n&&(0,C.jsxs)(C.Fragment,{children:[n.message&&(0,C.jsx)(`p`,{className:n.state===`conflict`||n.state===`unavailable`?`harness-setup-caution small`:`muted small`,children:n.message}),j&&p&&(0,C.jsx)(`p`,{className:`muted small`,children:p}),m&&(0,C.jsx)(`p`,{className:`muted small`,children:m}),f&&n.state!==`unavailable`&&(0,C.jsx)(`p`,{className:`muted small`,children:f}),O&&(0,C.jsx)(`p`,{className:`harness-setup-caution small`,children:`One-click setup is unavailable while this app is connected to a remote Gezel service. Set it up on the computer where you plan to run it.`}),!O&&!k&&(0,C.jsx)(`p`,{className:`harness-setup-caution small`,children:`One-click setup is available in the Gezel desktop app when it is connected to your user service on this computer.`}),!A&&(0,C.jsxs)(`p`,{className:`harness-setup-caution small`,children:[`Turn on `,(0,C.jsx)(`strong`,{children:`Allow apps to connect`}),` above before setting up or updating this.`]}),n.state===`update-needed`&&n.reasons.length>0&&(0,C.jsxs)(`div`,{className:`harness-setup-reasons`,children:[(0,C.jsx)(`span`,{className:`small`,children:h}),(0,C.jsx)(`ul`,{className:`muted small`,children:n.reasons.map(e=>(0,C.jsx)(`li`,{children:e},e))})]}),g&&(0,C.jsx)(`p`,{className:`muted small`,children:g}),_,y&&n.models.length>0&&(n.state!==`conflict`||j)&&(0,C.jsxs)(`div`,{className:`harness-setup-model-row`,children:[(0,C.jsx)(`span`,{id:N,children:y.label}),(0,C.jsxs)(a,{value:y.value,onValueChange:y.onChange,disabled:y.disabled,children:[(0,C.jsx)(l,{"aria-labelledby":N,children:(0,C.jsx)(c,{})}),(0,C.jsxs)(u,{children:[F.length>0&&(0,C.jsxs)(i,{children:[(0,C.jsx)(d,{children:`Gezels`}),F.map(e=>(0,C.jsx)(s,{value:e.id,children:T(e)},e.id))]}),F.length>0&&I.length>0&&(0,C.jsx)(o,{}),I.length>0&&(0,C.jsxs)(i,{children:[(0,C.jsx)(d,{children:`Raw models`}),I.map(e=>(0,C.jsx)(s,{value:e.id,children:T(e)},e.id))]})]})]})]}),n.models.length===0&&n.state!==`conflict`&&(0,C.jsx)(`p`,{className:`harness-setup-caution small`,children:D}),S,(0,C.jsx)(`div`,{className:`harness-setup-actions`,children:w})]}),E&&(0,C.jsx)(`p`,{className:`error small harness-setup-error`,role:`alert`,children:E}),M]})}function T(e){return e.description?`${e.label} — ${e.description}`:e.label}function E({endpointsEnabled:e,onChanged:t}){let n=y({label:`Codex`,endpointsEnabled:e,fetchStatus:()=>r.getCodexSetupStatus(),runAction:(0,v.useCallback)((e,t)=>e===`remove`?r.removeCodexSetup():r.configureCodex({model:t,...e===`repair`?{backupConflictingProfile:!0}:{}}),[]),errorPrefix:D,backupNotice:e=>e.profileBackupPath?`The previous file was saved as ${e.profileBackupPath}.`:null,...t?{onChanged:t}:{}}),{status:i,confirmation:a,setConfirmation:o,setError:s,busy:c,copied:l}=n,u=i?.models.find(e=>e.id===n.model),d=i?.models.find(e=>e.id===i.configuredModel),f=n.repairable?`Repair Codex setup…`:i?.state===`not-configured`?`Set up Codex…`:`Update Codex…`;return(0,C.jsxs)(w,{headingId:`codex-setup-heading`,title:`Use Gezel in Codex`,status:i,remoteMode:n.remoteMode,localDesktopMode:n.localDesktopMode,endpointsEnabled:e,repairable:!!n.repairable,notice:n.notice,error:n.error,reasonsIntro:`The managed setup needs an update:`,emptyModelsNote:`No gezels or inference models compatible with the Codex tool loop are available yet.`,intro:(0,C.jsx)(C.Fragment,{children:`Codex keeps its coding tools, sandbox, approvals, and conversation loop while a gezel supplies the character, model, and tuning. Your whole eligible crew is offered to Codex — the gezel you pick here is the one it starts with, and you can switch to any other from Codex's own model picker. Raw local models remain available when you want inference without a gezel persona.`}),...i?{repairExplainer:(0,C.jsxs)(C.Fragment,{children:[`Repair writes a fresh `,(0,C.jsx)(`code`,{children:i.profileName}),` profile for this Gezel and keeps a copy of the existing file next to it.`]})}:{},...i&&!i.codexInstalled?{notInstalledNote:`Codex was not found on this computer. You can prepare the setup now and use it after installing Codex.`}:{},...n.configured&&d&&!n.modelChanged?{configuredNote:(0,C.jsxs)(C.Fragment,{children:[`Codex starts with `,(0,C.jsx)(`strong`,{children:d.label}),`.`,i?.codexVersion?` Codex ${i.codexVersion} was found.`:``]})}:{},...n.canLaunch&&i?{commandRow:(0,C.jsxs)(`div`,{className:`harness-setup-command-row`,children:[(0,C.jsx)(`span`,{className:`muted small`,children:`Start it with`}),(0,C.jsx)(`code`,{children:i.launchCommand}),(0,C.jsx)(`button`,{type:`button`,onClick:()=>void n.copyLaunchCommand(),children:l?`Copied`:`Copy command`}),(0,C.jsx)(`output`,{className:`sr-only`,"aria-live":`polite`,children:l?`Codex launch command copied.`:``}),(0,C.jsx)(`span`,{className:`muted small`,children:`Keep Gezel running while you use Codex.`})]})}:{},modelRow:{label:`Default gezel`,value:n.model,onChange:n.setModel,disabled:n.selectionDisabled},actions:(0,C.jsxs)(C.Fragment,{children:[n.needsConfigure&&(0,C.jsx)(`button`,{type:`button`,className:`primary`,disabled:n.configureDisabled,onClick:()=>{s(null),o(n.repairable?`repair`:`configure`)},children:f}),i?.canRemove&&(0,C.jsx)(`button`,{type:`button`,disabled:c||!n.localDesktopMode,onClick:()=>{s(null),o(`remove`)},children:i.state===`conflict`?`Clear Gezel setup…`:`Remove setup…`}),n.error&&(0,C.jsx)(`button`,{type:`button`,onClick:()=>void n.refresh(),disabled:c,children:`Try again`})]}),children:[(0,C.jsx)(m,{open:a===`configure`,title:i?.state===`not-configured`?`Set up Codex with Gezel?`:`Update Codex setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will `,i?.state===`not-configured`?`create`:`update`,` its managed Codex profile for `,(0,C.jsx)(`strong`,{children:u?.label??n.model}),`.`,` `,u&&x(u)?(0,C.jsxs)(C.Fragment,{children:[`This gezel's character, `,u.modelLabel??`model`,`, and tuning will guide Codex.`,` `]}):(0,C.jsx)(C.Fragment,{children:`Codex will use it as a raw inference model without a gezel persona. `}),`The profile includes the local connection and app-scoped credential`,i?.profilePath?(0,C.jsxs)(C.Fragment,{children:[` `,`at `,(0,C.jsx)(`code`,{children:i.profilePath})]}):null,`. Your other Codex settings and conversations stay untouched.`]}),confirmLabel:i?.state===`not-configured`?`Set up Codex`:`Update Codex`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`repair`,title:`Repair the Codex setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will write a working `,(0,C.jsx)(`code`,{children:i?.profileName}),` profile for`,` `,(0,C.jsx)(`strong`,{children:u?.label??n.model}),`, connected to this copy of Gezel.`,i?.profilePath?(0,C.jsxs)(C.Fragment,{children:[` `,`The file now at `,(0,C.jsx)(`code`,{children:i.profilePath}),` is kept as a `,(0,C.jsx)(`code`,{children:`.backup`}),` `,`copy beside it, so nothing is lost.`]}):(0,C.jsx)(C.Fragment,{children:` The file it replaces is kept as a .backup copy beside it, so nothing is lost.`}),` `,`Your other Codex settings and conversations stay untouched.`]}),confirmLabel:`Repair setup`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`remove`,title:i?.state===`conflict`?`Clear Gezel setup for Codex?`:`Remove Gezel setup from Codex?`,message:(0,C.jsxs)(C.Fragment,{children:[`This removes only Gezel's managed Codex profile, catalog, state, and credential. It does not uninstall Codex or delete your other settings and conversations.`,i?.state===`conflict`?` Any Codex profile not managed by Gezel will be preserved.`:``]}),confirmLabel:i?.state===`conflict`?`Clear Gezel setup`:`Remove setup`,danger:!0,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)})]})}function D(e,t){switch(e){case`remove`:return`Could not remove the Codex setup`;case`repair`:return`Could not repair the Codex setup`;default:return t===`not-configured`?`Could not set up the Codex setup`:`Could not update the Codex setup`}}function O({endpointsEnabled:e,onChanged:t}){let n=y({label:`OpenCode`,endpointsEnabled:e,fetchStatus:()=>r.getOpenCodeSetupStatus(),runAction:(0,v.useCallback)((e,t)=>{switch(e){case`remove`:return r.removeOpenCodeSetup();case`install-plugin`:return r.installOpenCodePlugin();case`replace-plugin`:return r.installOpenCodePlugin({backupConflictingPlugin:!0});case`remove-plugin`:return r.removeOpenCodePlugin();default:return r.configureOpenCode({model:t,...e===`repair`?{backupConflictingConfig:!0}:{}})}},[]),errorPrefix:k,backupNotice:e=>e.pluginBackupPath?`The previous plugin file was saved as ${e.pluginBackupPath}.`:e.configBackupPath?`The previous file was saved as ${e.configBackupPath}.`:null,...t?{onChanged:t}:{}}),{status:i,confirmation:a,setConfirmation:o,setError:s,busy:c,copied:l}=n,u=i?.models.find(e=>e.id===n.model),d=i?.models.find(e=>e.id===i.configuredModel),f=n.configured&&n.localDesktopMode&&i?.state!==`conflict`&&i?.plugin.state!==`unsupported`,p=n.repairable?`Repair OpenCode setup…`:i?.state===`not-configured`?`Set up OpenCode…`:`Update OpenCode…`;return(0,C.jsxs)(w,{headingId:`opencode-setup-heading`,title:`Use Gezel in OpenCode`,status:i,remoteMode:n.remoteMode,localDesktopMode:n.localDesktopMode,endpointsEnabled:e,repairable:!!n.repairable,notice:n.notice,error:n.error,reasonsIntro:`The managed setup needs an update:`,emptyModelsNote:`No gezels or inference models compatible with the OpenCode tool loop are available yet.`,intro:(0,C.jsx)(C.Fragment,{children:`OpenCode keeps its own tools, permissions, and conversation loop while a gezel supplies the character, model, and tuning. Gezel writes its own settings file and points OpenCode at it with one command. You can also let Gezel add a small plugin of its own to OpenCode, so the gezel provider is simply there in every session. Either way, your own OpenCode settings, conversations, and permissions are never edited. Your whole eligible crew is offered, so you can switch between them from OpenCode's model picker.`}),repairExplainer:`Repair writes a fresh settings file for this Gezel and keeps a copy of the existing one next to it.`,...i&&!i.opencodeInstalled?{notInstalledNote:`OpenCode was not found on this computer. You can prepare the setup now and use it after installing OpenCode.`}:{},...n.configured&&d&&!n.modelChanged?{configuredNote:(0,C.jsxs)(C.Fragment,{children:[`OpenCode starts with `,(0,C.jsx)(`strong`,{children:d.label}),`.`,i?.opencodeVersion?` OpenCode ${i.opencodeVersion} was found.`:``]})}:{},...n.canLaunch&&i?{commandRow:(0,C.jsxs)(`div`,{className:`harness-setup-command-row`,children:[(0,C.jsx)(`span`,{className:`muted small`,children:`Start it with`}),(0,C.jsx)(`code`,{children:i.launchCommand}),(0,C.jsx)(`button`,{type:`button`,onClick:()=>void n.copyLaunchCommand(),children:l?`Copied`:`Copy command`}),(0,C.jsx)(`output`,{className:`sr-only`,"aria-live":`polite`,children:l?`OpenCode launch command copied.`:``}),(0,C.jsx)(`span`,{className:`muted small`,children:`Keep Gezel running while you use OpenCode.`})]})}:{},modelRow:{label:`Default gezel`,value:n.model,onChange:n.setModel,disabled:n.selectionDisabled},...f&&i?{extraRows:(0,C.jsx)(`p`,{className:`muted small`,children:i.plugin.state===`installed`||i.plugin.state===`stale`?(0,C.jsxs)(C.Fragment,{children:[`Gezel is in OpenCode's provider list without the command, through`,` `,(0,C.jsx)(`code`,{children:i.plugin.path}),`.`]}):i.plugin.state===`conflict`?i.plugin.message:(0,C.jsx)(C.Fragment,{children:`Rather not use the command every time? Gezel can add its own plugin file to OpenCode so the crew shows up in every session.`})})}:{},actions:(0,C.jsxs)(C.Fragment,{children:[n.needsConfigure&&(0,C.jsx)(`button`,{type:`button`,className:`primary`,disabled:n.configureDisabled,onClick:()=>{s(null),o(n.repairable?`repair`:`configure`)},children:p}),f&&i&&(i.plugin.canInstall||i.plugin.canReplace)&&(0,C.jsx)(`button`,{type:`button`,disabled:c||!n.localDesktopMode,onClick:()=>{s(null),o(i.plugin.canReplace?`replace-plugin`:`install-plugin`)},children:i.plugin.canReplace?`Replace OpenCode plugin…`:`Add to OpenCode…`}),f&&i?.plugin.canRemove&&(0,C.jsx)(`button`,{type:`button`,disabled:c||!n.localDesktopMode,onClick:()=>{s(null),o(`remove-plugin`)},children:`Remove from OpenCode…`}),i?.canRemove&&(0,C.jsx)(`button`,{type:`button`,disabled:c||!n.localDesktopMode,onClick:()=>{s(null),o(`remove`)},children:i.state===`conflict`?`Clear Gezel setup…`:`Remove setup…`}),n.error&&(0,C.jsx)(`button`,{type:`button`,onClick:()=>void n.refresh(),disabled:c,children:`Try again`})]}),children:[(0,C.jsx)(m,{open:a===`configure`,title:i?.state===`not-configured`?`Set up OpenCode with Gezel?`:`Update OpenCode setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will `,i?.state===`not-configured`?`create`:`update`,` its own OpenCode settings file for `,(0,C.jsx)(`strong`,{children:u?.label??n.model}),`.`,` `,u&&x(u)?(0,C.jsxs)(C.Fragment,{children:[`This gezel's character, `,u.modelLabel??`model`,`, and tuning will guide OpenCode.`,` `]}):(0,C.jsx)(C.Fragment,{children:`OpenCode will use it as a raw inference model without a gezel persona. `}),`The file holds the local connection and app-scoped credential`,i?.configPath?(0,C.jsxs)(C.Fragment,{children:[` `,`at `,(0,C.jsx)(`code`,{children:i.configPath})]}):null,`. Your own OpenCode configuration, sessions, and permissions stay untouched.`]}),confirmLabel:i?.state===`not-configured`?`Set up OpenCode`:`Update OpenCode`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`repair`,title:`Repair the OpenCode setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will write a working settings file for`,` `,(0,C.jsx)(`strong`,{children:u?.label??n.model}),`, connected to this copy of Gezel.`,i?.configPath?(0,C.jsxs)(C.Fragment,{children:[` `,`The file now at `,(0,C.jsx)(`code`,{children:i.configPath}),` is kept as a `,(0,C.jsx)(`code`,{children:`.backup`}),` `,`copy beside it, so nothing is lost.`]}):(0,C.jsx)(C.Fragment,{children:` The file it replaces is kept as a .backup copy beside it, so nothing is lost.`}),` `,`Your own OpenCode configuration stays untouched.`]}),confirmLabel:`Repair setup`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`remove`,title:i?.state===`conflict`?`Clear Gezel setup for OpenCode?`:`Remove Gezel setup from OpenCode?`,message:(0,C.jsxs)(C.Fragment,{children:[`This removes only Gezel's own OpenCode settings file, state, and credential`,i?.plugin.canRemove?(0,C.jsxs)(C.Fragment,{children:[`, along with the plugin file Gezel added at `,(0,C.jsx)(`code`,{children:i.plugin.path})]}):null,`. It does not uninstall OpenCode or touch your own configuration and sessions.`]}),confirmLabel:i?.state===`conflict`?`Clear Gezel setup`:`Remove setup`,danger:!0,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`install-plugin`||a===`replace-plugin`,title:a===`replace-plugin`?`Replace the plugin file in OpenCode?`:`Add Gezel to OpenCode?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will add one file of its own`,i?.plugin.path?(0,C.jsxs)(C.Fragment,{children:[` `,`at `,(0,C.jsx)(`code`,{children:i.plugin.path})]}):null,`, so every OpenCode session on this computer offers the `,(0,C.jsx)(`strong`,{children:`gezel`}),` provider without the command above. It holds no password — it reads Gezel's own settings when OpenCode starts, and does nothing at all when Gezel is not running. It does not change which model OpenCode starts with; pick a gezel from OpenCode's own model picker. Your own OpenCode configuration, sessions, and permissions stay untouched, and`,` `,(0,C.jsx)(`code`,{children:`opencode --pure`}),` always starts without it.`,a===`replace-plugin`?(0,C.jsx)(C.Fragment,{children:` The file it replaces is kept as a .backup copy beside it, so nothing is lost.`}):null]}),confirmLabel:a===`replace-plugin`?`Replace plugin`:`Add to OpenCode`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`remove-plugin`,title:`Remove Gezel from OpenCode?`,message:(0,C.jsxs)(C.Fragment,{children:[`This deletes the plugin file Gezel added`,i?.plugin.path?(0,C.jsxs)(C.Fragment,{children:[` `,`at `,(0,C.jsx)(`code`,{children:i.plugin.path})]}):null,`. OpenCode stops offering the gezel provider unless you start it with the command on this card. The rest of the setup, and everything of your own, stays as it is.`]}),confirmLabel:`Remove from OpenCode`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)})]})}function k(e,t){switch(e){case`remove`:return`Could not remove the OpenCode setup`;case`repair`:return`Could not repair the OpenCode setup`;case`install-plugin`:case`replace-plugin`:return`Could not add Gezel to OpenCode`;case`remove-plugin`:return`Could not remove Gezel from OpenCode`;default:return t===`not-configured`?`Could not set up the OpenCode setup`:`Could not update the OpenCode setup`}}function A({endpointsEnabled:e,onChanged:t}){let n=y({label:`pi`,endpointsEnabled:e,fetchStatus:()=>r.getPiSetupStatus(),runAction:(0,v.useCallback)((e,t)=>{switch(e){case`remove`:return r.removePiSetup();case`install-extension`:return r.installPiExtension();case`replace-extension`:return r.installPiExtension({backupConflictingExtension:!0});case`remove-extension`:return r.removePiExtension();default:return r.configurePi({model:t,...e===`repair`?{backupConflictingConfig:!0}:{}})}},[]),errorPrefix:j,backupNotice:e=>e.extensionBackupPath?`The previous extension file was saved as ${e.extensionBackupPath}.`:e.configBackupPath?`The previous file was saved as ${e.configBackupPath}.`:null,...t?{onChanged:t}:{}}),{status:i,confirmation:a,setConfirmation:o,setError:s,busy:c,copied:l}=n,u=i?.models.find(e=>e.id===n.model),d=i?.models.find(e=>e.id===i.configuredModel),f=n.configured&&n.localDesktopMode&&i?.state!==`conflict`&&i?.extension.state!==`unsupported`,p=n.repairable?`Repair pi setup…`:i?.state===`not-configured`?`Set up pi…`:`Update pi…`;return(0,C.jsxs)(w,{headingId:`pi-setup-heading`,title:`Use Gezel in pi`,status:i,remoteMode:n.remoteMode,localDesktopMode:n.localDesktopMode,endpointsEnabled:e,repairable:!!n.repairable,notice:n.notice,error:n.error,reasonsIntro:`The managed setup needs an update:`,emptyModelsNote:`No gezels or inference models compatible with the pi tool loop are available yet.`,intro:(0,C.jsx)(C.Fragment,{children:`pi keeps its own tools, permissions, and conversation loop while a gezel supplies the character, model, and tuning. Gezel writes an extension of its own and hands you a command that loads it for that run. You can also let Gezel add that same file to pi, so the gezel provider is simply there in every session. Either way, your own pi settings, sessions, and models are never edited.`}),repairExplainer:`Repair writes a fresh model list for this Gezel and keeps a copy of the existing one next to it.`,...i&&!i.piInstalled?{notInstalledNote:`pi was not found on this computer. You can prepare the setup now and use it after installing pi.`}:{},...n.configured&&d&&!n.modelChanged?{configuredNote:(0,C.jsxs)(C.Fragment,{children:[`pi starts with `,(0,C.jsx)(`strong`,{children:d.label}),`, and offers the whole crew in its own model picker.`,i?.piVersion?` pi ${i.piVersion} was found.`:``]})}:{},...n.canLaunch&&i?{commandRow:(0,C.jsxs)(`div`,{className:`harness-setup-command-row`,children:[(0,C.jsx)(`span`,{className:`muted small`,children:`Start it with`}),(0,C.jsx)(`code`,{children:i.launchCommand}),(0,C.jsx)(`button`,{type:`button`,onClick:()=>void n.copyLaunchCommand(),children:l?`Copied`:`Copy command`}),(0,C.jsx)(`output`,{className:`sr-only`,"aria-live":`polite`,children:l?`pi launch command copied.`:``}),(0,C.jsx)(`span`,{className:`muted small`,children:`Keep Gezel running while you use pi.`})]})}:{},modelRow:{label:`Default gezel`,value:n.model,onChange:n.setModel,disabled:n.selectionDisabled},...f&&i?{extraRows:(0,C.jsx)(`p`,{className:`muted small`,children:i.extension.state===`installed`||i.extension.state===`stale`?(0,C.jsxs)(C.Fragment,{children:[`Gezel is in pi's provider list without the command, through`,` `,(0,C.jsx)(`code`,{children:i.extension.path}),`.`]}):i.extension.state===`conflict`?i.extension.message:(0,C.jsx)(C.Fragment,{children:`Rather not use the command every time? Gezel can add the same extension to pi so the crew shows up in every session.`})})}:{},actions:(0,C.jsxs)(C.Fragment,{children:[n.needsConfigure&&(0,C.jsx)(`button`,{type:`button`,className:`primary`,disabled:n.configureDisabled,onClick:()=>{s(null),o(n.repairable?`repair`:`configure`)},children:p}),f&&i&&(i.extension.canInstall||i.extension.canReplace)&&(0,C.jsx)(`button`,{type:`button`,disabled:c||!n.localDesktopMode,onClick:()=>{s(null),o(i.extension.canReplace?`replace-extension`:`install-extension`)},children:i.extension.canReplace?`Replace pi extension…`:`Add to pi…`}),f&&i?.extension.canRemove&&(0,C.jsx)(`button`,{type:`button`,disabled:c||!n.localDesktopMode,onClick:()=>{s(null),o(`remove-extension`)},children:`Remove from pi…`}),i?.canRemove&&(0,C.jsx)(`button`,{type:`button`,disabled:c||!n.localDesktopMode,onClick:()=>{s(null),o(`remove`)},children:i.state===`conflict`?`Clear Gezel setup…`:`Remove setup…`}),n.error&&(0,C.jsx)(`button`,{type:`button`,onClick:()=>void n.refresh(),disabled:c,children:`Try again`})]}),children:[(0,C.jsx)(m,{open:a===`configure`,title:i?.state===`not-configured`?`Set up pi with Gezel?`:`Update pi setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will `,i?.state===`not-configured`?`create`:`update`,` its own pi extension and model list for `,(0,C.jsx)(`strong`,{children:u?.label??n.model}),`.`,` `,u&&x(u)?(0,C.jsxs)(C.Fragment,{children:[`This gezel's character, `,u.modelLabel??`model`,`, and tuning will guide pi.`,` `]}):(0,C.jsx)(C.Fragment,{children:`pi will use it as a raw inference model without a gezel persona. `}),`Both files live in Gezel's own folder`,i?.extensionPath?(0,C.jsxs)(C.Fragment,{children:[`, at `,(0,C.jsx)(`code`,{children:i.extensionPath})]}):null,`, and the command above points pi at them for that run. Your own pi settings, sessions, and models stay untouched.`]}),confirmLabel:i?.state===`not-configured`?`Set up pi`:`Update pi`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`repair`,title:`Repair the pi setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will write a working model list for`,` `,(0,C.jsx)(`strong`,{children:u?.label??n.model}),`, connected to this copy of Gezel.`,i?.configPath?(0,C.jsxs)(C.Fragment,{children:[` `,`The file now at `,(0,C.jsx)(`code`,{children:i.configPath}),` is kept as a `,(0,C.jsx)(`code`,{children:`.backup`}),` `,`copy beside it, so nothing is lost.`]}):(0,C.jsx)(C.Fragment,{children:` The file it replaces is kept as a .backup copy beside it, so nothing is lost.`}),` `,`Your own pi configuration stays untouched.`]}),confirmLabel:`Repair setup`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`remove`,title:i?.state===`conflict`?`Clear Gezel setup for pi?`:`Remove Gezel setup from pi?`,message:(0,C.jsxs)(C.Fragment,{children:[`This removes only Gezel's own pi extension, model list, state, and credential`,i?.extension.canRemove?(0,C.jsxs)(C.Fragment,{children:[`, along with the copy Gezel added at `,(0,C.jsx)(`code`,{children:i.extension.path})]}):null,`. It does not uninstall pi or touch your own settings and sessions.`]}),confirmLabel:i?.state===`conflict`?`Clear Gezel setup`:`Remove setup`,danger:!0,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`install-extension`||a===`replace-extension`,title:a===`replace-extension`?`Replace the extension file in pi?`:`Add Gezel to pi?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will add its extension`,i?.extension.path?(0,C.jsxs)(C.Fragment,{children:[` `,`at `,(0,C.jsx)(`code`,{children:i.extension.path})]}):null,`, so every pi session on this computer offers the `,(0,C.jsx)(`strong`,{children:`gezel`}),` provider without the command above. It holds no password — it reads Gezel's own model list when pi starts, and does nothing at all when Gezel is not running. It does not change which model pi starts with; pick a gezel from pi's own model picker. Your own pi settings, sessions, and models stay untouched, and `,(0,C.jsx)(`code`,{children:`pi -ne`}),` always starts without it.`,i?.extension.agentDirSource==="default"?(0,C.jsxs)(C.Fragment,{children:[` `,`Gezel found pi's folder in its usual place. If you point pi elsewhere with`,` `,(0,C.jsx)(`code`,{children:`PI_CODING_AGENT_DIR`}),` in your shell, it will not be picked up.`]}):null,a===`replace-extension`?(0,C.jsx)(C.Fragment,{children:` The file it replaces is kept as a .backup copy beside it, so nothing is lost.`}):null]}),confirmLabel:a===`replace-extension`?`Replace extension`:`Add to pi`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`remove-extension`,title:`Remove Gezel from pi?`,message:(0,C.jsxs)(C.Fragment,{children:[`This deletes the extension Gezel added`,i?.extension.path?(0,C.jsxs)(C.Fragment,{children:[` `,`at `,(0,C.jsx)(`code`,{children:i.extension.path})]}):null,`. pi stops offering the gezel provider unless you start it with the command on this card. The rest of the setup, and everything of your own, stays as it is.`]}),confirmLabel:`Remove from pi`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)})]})}function j(e,t){switch(e){case`remove`:return`Could not remove the pi setup`;case`repair`:return`Could not repair the pi setup`;case`install-extension`:case`replace-extension`:return`Could not add Gezel to pi`;case`remove-extension`:return`Could not remove Gezel from pi`;default:return t===`not-configured`?`Could not set up pi`:`Could not update the pi setup`}}function M({endpointsEnabled:e,onChanged:t}){let[n,i]=(0,v.useState)(``),o=(0,v.useId)(),d=y({label:`VS Code`,endpointsEnabled:e,fetchStatus:()=>r.getVSCodeSetupStatus(),runAction:(0,v.useCallback)(e=>e===`remove`?r.removeVSCodeSetup():r.configureVSCode({profileId:n,...e===`repair`?{backupConflictingConfig:!0}:{}}),[n]),modelSelection:!1,errorPrefix:N,backupNotice:e=>e.configBackupPath?`The previous file was saved as ${e.configBackupPath}.`:null,...t?{onChanged:t}:{}}),{status:f,confirmation:p,setConfirmation:h,setError:g,busy:_}=d;(0,v.useEffect)(()=>{f&&i(e=>f.profiles.some(t=>t.id===e)?e:f.configuredProfileId??f.profiles[0]?.id??``)},[f]);let b=f?.profiles.find(e=>e.id===n),x=P(f?.vscodeVersion),S=!!f?.configuredProfileId,T=d.repairable?`Repair VS Code setup…`:f?.state===`not-configured`?`Set up VS Code…`:`Update VS Code…`;return(0,C.jsxs)(w,{headingId:`vscode-setup-heading`,title:`Use Gezel in VS Code`,status:f,remoteMode:d.remoteMode,localDesktopMode:d.localDesktopMode,endpointsEnabled:e,repairable:!!d.repairable,notice:d.notice,error:d.error,reasonsIntro:`The managed setup needs an update:`,emptyModelsNote:`No gezels or inference models compatible with VS Code's agent tool loop are available yet.`,intro:(0,C.jsx)(C.Fragment,{children:`VS Code keeps its native agent tools, permissions, and conversation loop. Gezel adds your eligible crew and raw local models through VS Code's built-in custom endpoint — no extension is installed. Setup edits only the Gezel provider in the selected profile.`}),repairExplainer:(0,C.jsxs)(C.Fragment,{children:[`Repair keeps a copy of `,(0,C.jsx)(`code`,{children:f?.configPath}),`, then replaces only the conflicting Gezel provider entry. Other providers stay in place.`]}),...f&&!f.vscodeInstalled?{notInstalledNote:`VS Code was not found on PATH. You can prepare its conventional profile now and use it after installing VS Code.`}:{},...d.configured&&b?{configuredNote:(0,C.jsxs)(C.Fragment,{children:[`Gezel is available in `,(0,C.jsx)(`strong`,{children:b.label}),`.`,x?` VS Code ${x} was found.`:``,` Keep Gezel running while you use the models.`]})}:{},extraRows:f&&(f.state!==`conflict`||d.repairable)?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`div`,{className:`harness-setup-model-row`,children:[(0,C.jsx)(`span`,{id:o,children:`VS Code profile`}),(0,C.jsxs)(a,{value:n,onValueChange:i,disabled:_||!d.localDesktopMode||!e||S,children:[(0,C.jsx)(l,{"aria-labelledby":o,children:(0,C.jsx)(c,{})}),(0,C.jsx)(u,{children:f.profiles.map(e=>(0,C.jsx)(s,{value:e.id,children:e.label},e.id))})]})]}),S&&(0,C.jsx)(`p`,{className:`muted small`,children:`Clear this setup before choosing a different profile.`}),(0,C.jsxs)(`p`,{className:`muted small`,children:[`If VS Code is already open, you may need to run`,` `,(0,C.jsx)(`strong`,{children:`Developer: Reload Window`}),` or restart VS Code after setup before the models work.`]})]}):null,actions:(0,C.jsxs)(C.Fragment,{children:[d.needsConfigure&&(0,C.jsx)(`button`,{type:`button`,className:`primary`,disabled:d.configureDisabled||!n,onClick:()=>{g(null),h(d.repairable?`repair`:`configure`)},children:T}),f?.canRemove&&(0,C.jsx)(`button`,{type:`button`,disabled:_||!d.localDesktopMode,onClick:()=>{g(null),h(`remove`)},children:f.state===`conflict`?`Clear Gezel setup…`:`Remove setup…`}),d.error&&(0,C.jsx)(`button`,{type:`button`,onClick:()=>void d.refresh(),disabled:_,children:`Try again`})]}),children:[(0,C.jsx)(m,{open:p===`configure`,title:f?.state===`not-configured`?`Set up VS Code with Gezel?`:`Update VS Code setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will add or update one provider in `,(0,C.jsx)(`code`,{children:b?.configPath}),`. VS Code will show every eligible gezel and raw local model in its native model picker and keep control of agent tools and permissions. Other custom endpoint providers are preserved.`,(0,C.jsx)(`br`,{}),(0,C.jsx)(`br`,{}),`Because no extension is involved, the dedicated inference-only credential is stored as plain text in this profile file. It works only through Gezel's loopback inference bridge and can be revoked by clearing this setup. If VS Code is already open, reload its window or restart it after setup so it picks up the new credential.`]}),confirmLabel:f?.state===`not-configured`?`Set up VS Code`:`Update VS Code`,onConfirm:d.runConfirmedAction,onCancel:()=>h(null)}),(0,C.jsx)(m,{open:p===`repair`,title:`Repair the VS Code setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will save the current `,(0,C.jsx)(`code`,{children:f?.configPath}),` beside it as a backup, then publish a working Gezel provider for this installation. Providers that are not named Gezel remain untouched. The replacement contains a new plain-text, inference-only loopback credential.`]}),confirmLabel:`Repair setup`,onConfirm:d.runConfirmedAction,onCancel:()=>h(null)}),(0,C.jsx)(m,{open:p===`remove`,title:`Remove Gezel setup from VS Code?`,message:(0,C.jsx)(C.Fragment,{children:`This removes only the Gezel provider entry, setup state, and dedicated credential. It does not uninstall VS Code, touch other endpoint providers, or delete conversations. A Gezel entry changed outside this setup is preserved, but its credential is revoked.`}),confirmLabel:`Remove setup`,danger:!0,onConfirm:d.runConfirmedAction,onCancel:()=>h(null)})]})}function N(e,t){return e===`remove`?`Could not remove the VS Code setup`:e===`repair`?`Could not repair the VS Code setup`:t===`not-configured`?`Could not set up the VS Code setup`:`Could not update the VS Code setup`}function P(e){if(!e)return;let t=e.split(/\s+/).filter(e=>e&&!/^[a-f\d]{40}$/i.test(e));return t.length>0?t.join(` `):void 0}function F(e){return e?f(e):`never`}var I=`__AUTOMATIC__`,L=new Set([`copilot`,`anthropic-cli`,`codex-cli`]);function R(){let[e,t]=(0,v.useState)(null),[n,i]=(0,v.useState)(null),[o,d]=(0,v.useState)(null),[f,y]=(0,v.useState)(null),[b,x]=(0,v.useState)({}),[S,w]=(0,v.useState)({}),[T,D]=(0,v.useState)([]),[k,j]=(0,v.useState)(null),[N,P]=(0,v.useState)(0),[R,z]=(0,v.useState)(`copilot`),[B,V]=(0,v.useState)(),H=(0,v.useCallback)(async()=>{try{let e=await fetch(`${r.getBaseUrl()}/v1/apps`,{headers:r.authHeader()});if(!e.ok){i(`Failed to load apps: HTTP ${e.status}`);return}i(null),t(await e.json())}catch(e){i(e instanceof Error?e.message:String(e))}},[]);(0,v.useEffect)(()=>{H();let e=window.setInterval(()=>void H(),4e3);return()=>window.clearInterval(e)},[H]),(0,v.useEffect)(()=>{r.getConfig().then(e=>{w(e.openaiEndpoints??{}),z(e.provider??`llama-cpp`),V(e.meesterGezelId)}).catch(()=>{}),r.listGezels().then(e=>D(e.gezels.map(({id:e,name:t,role:n,provider:r})=>({id:e,name:t,role:n,provider:r})))).catch(()=>{})},[]);let U=(0,v.useCallback)(async e=>{let t=S,n=e.emulateOllama===t.emulateOllama?`endpoints`:`ollama`;w(e),j({scope:n,text:`saving…`});try{let t=await r.updateConfig({openaiEndpoints:e});w(t.openaiEndpoints??{}),P(e=>e+1),j(null)}catch(e){w(t);let r=e&&typeof e==`object`&&`details`in e?e.details?.message:void 0;j({scope:n,text:`save failed: ${r??(e instanceof Error?e.message:String(e))}`})}},[S]),W=S.enabled!==!1,G=T.find(e=>e.id===S.servingGezelId),K=T.find(e=>e.id===B)??T[0],q=G??K,J=e=>e.provider??R,Y=q!==void 0&&L.has(J(q)),X=(0,v.useCallback)(async(t,n)=>{if(o)return;let a=e?.grants.find(e=>e.id===t),s=b[t]??``;d(`${n}:${t}`);try{let e=await fetch(`${r.getBaseUrl()}/v1/apps/grant/${encodeURIComponent(t)}/${n}`,{method:`POST`,headers:{...r.authHeader(),...n===`approve`&&a?.verificationRequired?{"Content-Type":`application/json`}:{}},...n===`approve`&&a?.verificationRequired?{body:JSON.stringify({verificationCode:s})}:{}});if(!e.ok){i(await g(e,`Failed to ${n} grant`));return}x(e=>{let n={...e};return delete n[t],n}),await H()}catch(e){i(e instanceof Error?e.message:String(e))}finally{d(null)}},[o,H,e?.grants,b]),Z=(0,v.useCallback)(async()=>{if(f){d(`revoke:${f.appId}`);try{let e=await fetch(`${r.getBaseUrl()}/v1/apps/${encodeURIComponent(f.appId)}/token`,{method:`DELETE`,headers:r.authHeader()});if(!e.ok){i(`Failed to revoke ${f.appId}: HTTP ${e.status}`);return}y(null),await H(),P(e=>e+1)}finally{d(null)}}},[f,H]),Q=(e?.grants??[]).filter(e=>e.status===`pending`),$=e?.apps??[];return(0,C.jsxs)(`section`,{className:`settings-section`,children:[(0,C.jsx)(`h2`,{children:`Connected Apps`}),(0,C.jsx)(`p`,{className:`muted small`,children:`Apps and command-line clients that have asked for access to your Gezel service. Each client is granted only the scopes it requested. Revoke any time.`}),n&&(0,C.jsx)(`p`,{className:`settings-error`,role:`alert`,children:n}),(0,C.jsxs)(`div`,{className:`settings-subsection`,children:[(0,C.jsx)(`h3`,{children:`OpenAI-compatible endpoints`}),(0,C.jsx)(`p`,{className:`muted small`,children:`Other apps (editors, browser tools) can use your gezellen and models through standard OpenAI-style endpoints. Each app still needs your approval below before it gets access.`}),(0,C.jsxs)(`label`,{className:`debug-toggle`,children:[(0,C.jsx)(`input`,{type:`checkbox`,checked:W,onChange:e=>void U({...S,enabled:e.target.checked?void 0:!1})}),(0,C.jsx)(`span`,{children:`Allow apps to connect`})]}),W?(0,C.jsxs)(`p`,{className:`muted small`,children:[`Point apps at `,(0,C.jsxs)(`code`,{children:[r.getBaseUrl(),`/v1`]})]}):(0,C.jsx)(`p`,{className:`muted small`,children:`Turned off — connected apps are refused and new apps cannot ask for access until this is back on.`}),(0,C.jsxs)(`div`,{className:`connected-apps-serving`,children:[(0,C.jsx)(`span`,{id:`serving-gezel-label`,children:`Fallback gezel`}),(0,C.jsxs)(a,{value:G?G.id:I,onValueChange:e=>void U({...S,servingGezelId:e===I?void 0:e}),disabled:!W,children:[(0,C.jsx)(l,{"aria-labelledby":`serving-gezel-label`,children:(0,C.jsx)(c,{})}),(0,C.jsxs)(u,{children:[(0,C.jsxs)(s,{value:I,children:[`Automatic`,K?` — ${K.name}`:``]}),T.map(e=>(0,C.jsxs)(s,{value:e.id,children:[e.name,e.role?` — ${e.role}`:``,` (${J(e)})`]},e.id))]})]})]}),(0,C.jsxs)(`p`,{className:`muted small`,children:[`Apps receive your gezellen as model choices, including their names and roles. If an app asks for something else, `,q?.name??`your default gezel`,` answers with their character and model settings.`]}),q&&Y&&(0,C.jsxs)(`p`,{className:`small connected-apps-caution`,children:[q.name,` runs on `,J(q),`, which can't accept tools sent by apps — editors that use tools will get an error. For full compatibility, pick a gezel on a local model or a direct API provider.`]}),(0,C.jsxs)(`label`,{className:`debug-toggle`,children:[(0,C.jsx)(`input`,{type:`checkbox`,checked:S.supportingBehaviors!==!1,onChange:e=>void U({...S,supportingBehaviors:e.target.checked?void 0:!1}),disabled:!W}),(0,C.jsx)(`span`,{children:`Supporting behaviors`})]}),(0,C.jsx)(`p`,{className:`muted small`,children:`Gezel knows how to get the best out of each model — catching runaway rambling, folding leaked reasoning, and applying model-specific fixes. Turn this off for plain serving: apps still get the gezel's character and each model's tuned settings (sampling, thinking mode), but no runtime interventions.`}),k?.scope===`endpoints`&&(0,C.jsx)(`output`,{className:`muted small`,children:k.text})]}),(0,C.jsx)(E,{endpointsEnabled:W,onChanged:H},`codex-${N}`),(0,C.jsx)(M,{endpointsEnabled:W,onChanged:H},`vscode-${N}`),(0,C.jsx)(O,{endpointsEnabled:W,onChanged:H},`opencode-${N}`),(0,C.jsx)(A,{endpointsEnabled:W,onChanged:H},`pi-${N}`),(0,C.jsxs)(`div`,{className:`settings-subsection`,children:[(0,C.jsx)(`h3`,{children:`Ollama emulation`}),(0,C.jsxs)(`label`,{className:`debug-toggle`,children:[(0,C.jsx)(`input`,{type:`checkbox`,checked:S.emulateOllama===!0,onChange:e=>void U({...S,emulateOllama:e.target.checked?!0:void 0}),disabled:!W}),(0,C.jsx)(`span`,{children:`Emulate Ollama (port 11434)`})]}),(0,C.jsx)(`p`,{className:`muted small`,children:`Apps that auto-discover Ollama will find gezel instead — no setup needed in each app. Security note: Ollama's convention is no password, so while this is on, any program on this computer can use your models without asking first. Gezel refuses to take the port if Ollama itself is already running.`}),k?.scope===`ollama`&&(0,C.jsx)(`output`,{className:`muted small`,children:k.text})]}),Q.length>0&&(0,C.jsxs)(`div`,{className:`settings-subsection`,children:[(0,C.jsx)(`h3`,{children:`Pending requests`}),(0,C.jsx)(`ul`,{className:`settings-list`,children:Q.map(e=>(0,C.jsxs)(`li`,{className:`connected-app-row connected-app-row--pending`,children:[(0,C.jsxs)(`div`,{className:`connected-app-meta`,children:[(0,C.jsxs)(`div`,{className:`connected-app-name`,children:[e.appName,e.kind===`device`&&(0,C.jsx)(`span`,{className:`badge`,children:` device`})]}),(0,C.jsx)(`div`,{className:`muted small`,children:e.kind===`device`?`wants to run models on this device`:e.scopes.includes(`cli`)?`${e.appId} — wants command-line control of this Gezel service`:e.scopes.includes(`product`)?`${e.appId} — wants access to Gezel features and data`:`${e.appId} — wants: ${e.scopes.join(`, `)}`})]}),(0,C.jsxs)(`div`,{className:`connected-app-actions`,children:[e.verificationRequired&&(0,C.jsxs)(`label`,{className:`connected-app-code`,children:[(0,C.jsx)(`span`,{children:`Connection code`}),(0,C.jsx)(`input`,{value:b[e.id]??``,onChange:t=>{let n=_(t.currentTarget.value);x(t=>({...t,[e.id]:n}))},placeholder:`___-___`,maxLength:7,autoComplete:`off`,autoCapitalize:`characters`,spellCheck:!1,"aria-label":`Connection code for ${e.appName}`})]}),(0,C.jsx)(`button`,{type:`button`,onClick:()=>void X(e.id,`deny`),disabled:o!==null,children:`Deny`}),(0,C.jsx)(`button`,{type:`button`,className:`primary`,onClick:()=>void X(e.id,`approve`),disabled:o!==null||e.verificationRequired&&!h(b[e.id]??``),children:o===`approve:${e.id}`?`Approving…`:`Approve`})]})]},e.id))})]}),(0,C.jsxs)(`div`,{className:`settings-subsection`,children:[(0,C.jsx)(`h3`,{children:`Connected`}),$.length===0?(0,C.jsx)(`p`,{className:`muted small`,children:`No apps connected. Apps that use the gezel SDK appear here after you approve them.`}):(0,C.jsx)(`div`,{className:`connected-apps-table-wrap`,children:(0,C.jsxs)(`table`,{className:`connected-apps-table`,"aria-label":`Connected apps`,children:[(0,C.jsx)(`thead`,{children:(0,C.jsxs)(`tr`,{children:[(0,C.jsx)(`th`,{scope:`col`,children:`App`}),(0,C.jsx)(`th`,{scope:`col`,children:`Scopes`}),(0,C.jsx)(`th`,{scope:`col`,children:`Last used`}),(0,C.jsx)(`th`,{scope:`col`,children:(0,C.jsx)(`span`,{className:`sr-only`,children:`Actions`})})]})}),(0,C.jsx)(`tbody`,{children:$.map(e=>(0,C.jsxs)(`tr`,{children:[(0,C.jsxs)(`td`,{"data-label":`App`,children:[(0,C.jsxs)(`div`,{className:`connected-apps-identity`,children:[(0,C.jsx)(`span`,{className:`connected-apps-name`,children:e.appName}),e.kind===`device`&&(0,C.jsx)(`span`,{className:`connected-apps-kind`,children:`Device`})]}),(0,C.jsx)(`span`,{className:`connected-apps-id`,children:e.appId})]}),(0,C.jsx)(`td`,{"data-label":`Scopes`,children:e.scopes.length>0?(0,C.jsx)(`ul`,{className:`connected-apps-scopes`,children:e.scopes.map(e=>(0,C.jsx)(`li`,{children:e},e))}):(0,C.jsx)(`span`,{className:`connected-apps-empty`,children:`None`})}),(0,C.jsx)(`td`,{"data-label":`Last used`,children:(0,C.jsx)(`span`,{className:`connected-apps-last-used`,title:e.lastUsedAt?p(e.lastUsedAt):void 0,children:F(e.lastUsedAt)})}),(0,C.jsx)(`td`,{className:`connected-apps-action`,children:(0,C.jsx)(`button`,{type:`button`,className:`connected-apps-revoke`,"aria-label":`Revoke ${e.appName}`,onClick:()=>y(e),disabled:o!==null,children:`Revoke`})})]},e.appId))})]})})]}),(0,C.jsx)(m,{open:f!==null,title:f?`Revoke ${f.appName}?`:`Revoke app`,message:f?(0,C.jsxs)(C.Fragment,{children:[`The next time `,(0,C.jsx)(`strong`,{children:f.appName}),` tries to use gezel it will be denied. The app can reconnect later by going through the consent flow again.`]}):null,confirmLabel:`Revoke`,danger:!0,onConfirm:Z,onCancel:()=>y(null)})]})}export{R as ConnectedAppsPanel};
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{c as i,d as a,f as o,l as s,m as c,p as l,s as u,u as d}from"./primitives-CWrGZpPI.js";import{n as f,t as p}from"./relative-time-B2kBaekd.js";import{t as m}from"./ConfirmDialog-Dt1ed4Fh.js";import{It as h,Lt as g,Rt as _}from"./index-DivKnJyx.js";import"./provider-default-BLsHrgzI.js";var v=e(t(),1);function y(e){let t=(0,v.useRef)(null),[n,r]=(0,v.useState)(null),[i,a]=(0,v.useState)(``),[o,s]=(0,v.useState)(null),[c,l]=(0,v.useState)(null),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(!1),[m,h]=(0,v.useState)(!1),g=(0,v.useRef)(e);g.current=e;let _=(0,v.useCallback)(e=>{r(e);let t=g.current.backupNotice?.(e);t&&l(t),a(t=>{let n=new Set(e.models.map(e=>e.id));return t&&n.has(t)?t:e.configuredModel&&n.has(e.configuredModel)?e.configuredModel:e.recommendedModel&&n.has(e.recommendedModel)?e.recommendedModel:e.models[0]?.id??``})},[]),y=(0,v.useCallback)(async()=>{s(null);try{_(await g.current.fetchStatus())}catch(e){s(`Could not check the ${g.current.label} setup — ${S(e)}`)}},[_]);(0,v.useEffect)(()=>(y(),()=>{t.current!==null&&window.clearTimeout(t.current)}),[y]);let b=window.__GEZEL__?.mode,x=b===`local-adopt`||b===`local-spawn-packaged`||b===`local-spawn-dev`||b===`embedded`,C=b===`remote`,w=n?.state===`configured`||n?.state===`update-needed`,T=n?.state===`configured`&&n.bridge.listening&&e.endpointsEnabled&&x,E=e.modelSelection!==!1,D=E&&w&&i!==n?.configuredModel,O=n?.state===`conflict`&&n.canRepair,k=n?.state===`not-configured`||n?.state===`update-needed`||D||O,A=n?.state===`conflict`?n.canRepair:n?.canConfigure??!1,j=f||!x||!e.endpointsEnabled||!A||E&&!i,M=f||!x||!e.endpointsEnabled||!A;return{status:n,model:i,setModel:a,error:o,setError:s,notice:c,confirmation:u,setConfirmation:d,busy:f,copied:m,refresh:y,runConfirmedAction:(0,v.useCallback)(async()=>{if(!(!u||f)){p(!0),s(null),l(null);try{_(await g.current.runAction(u,i)),d(null),Promise.resolve(g.current.onChanged?.()).catch(()=>{})}catch(e){d(null),s(`${g.current.errorPrefix(u,n?.state)} — ${S(e)}`)}finally{p(!1)}}},[_,f,u,i,n?.state]),copyLaunchCommand:(0,v.useCallback)(async()=>{if(n?.launchCommand){s(null);try{if(!navigator.clipboard?.writeText)throw Error(`clipboard access is unavailable`);await navigator.clipboard.writeText(n.launchCommand),h(!0),t.current!==null&&window.clearTimeout(t.current),t.current=window.setTimeout(()=>{t.current=null,h(!1)},2e3)}catch(e){s(`Could not copy the ${g.current.label} command — ${S(e)}`)}}},[n?.launchCommand]),localDesktopMode:x,remoteMode:C,configured:w,canLaunch:T,modelChanged:D,repairable:O,needsConfigure:k,configureDisabled:j,selectionDisabled:M}}function b(e){switch(e){case`not-configured`:return`Not configured`;case`configured`:return`Configured`;case`update-needed`:return`Update needed`;case`conflict`:return`Needs attention`;case`unavailable`:return`Unavailable`}}function x(e){return e.kind===`gezel`||e.id.startsWith(`gezel:`)}function S(e){if(e&&typeof e==`object`&&`details`in e){let t=e.details;if(typeof t==`string`&&t)return t;if(t&&typeof t==`object`){let e=t;if(typeof e.message==`string`&&e.message)return e.message;if(typeof e.error==`string`&&e.error)return e.error}}return e instanceof Error?e.message:String(e)}var C=n();function w({headingId:e,title:t,status:n,intro:r,notInstalledNote:f,repairExplainer:p,notice:m,reasonsIntro:h,configuredNote:g,commandRow:_,modelRow:y,extraRows:S,actions:w,error:E,emptyModelsNote:D,remoteMode:O,localDesktopMode:k,endpointsEnabled:A,repairable:j,children:M}){let N=(0,v.useId)(),P=n?b(n.state):`Checking…`,F=n?.models.filter(x)??[],I=n?.models.filter(e=>!x(e))??[];return(0,C.jsxs)(`section`,{className:`settings-subsection provider-card harness-setup-card`,"aria-labelledby":e,children:[(0,C.jsxs)(`div`,{className:`settings-card-header`,children:[(0,C.jsx)(`h3`,{id:e,children:t}),(0,C.jsx)(`span`,{className:`harness-setup-state harness-setup-state--${n?.state??`checking`}`,"aria-live":`polite`,children:P})]}),(0,C.jsx)(`p`,{className:`muted small harness-setup-intro`,children:r}),!n&&!E&&(0,C.jsx)(`p`,{className:`muted small`,children:`Checking the setup…`}),n&&(0,C.jsxs)(C.Fragment,{children:[n.message&&(0,C.jsx)(`p`,{className:n.state===`conflict`||n.state===`unavailable`?`harness-setup-caution small`:`muted small`,children:n.message}),j&&p&&(0,C.jsx)(`p`,{className:`muted small`,children:p}),m&&(0,C.jsx)(`p`,{className:`muted small`,children:m}),f&&n.state!==`unavailable`&&(0,C.jsx)(`p`,{className:`muted small`,children:f}),O&&(0,C.jsx)(`p`,{className:`harness-setup-caution small`,children:`One-click setup is unavailable while this app is connected to a remote Gezel service. Set it up on the computer where you plan to run it.`}),!O&&!k&&(0,C.jsx)(`p`,{className:`harness-setup-caution small`,children:`One-click setup is available in the Gezel desktop app when it is connected to your user service on this computer.`}),!A&&(0,C.jsxs)(`p`,{className:`harness-setup-caution small`,children:[`Turn on `,(0,C.jsx)(`strong`,{children:`Allow apps to connect`}),` above before setting up or updating this.`]}),n.state===`update-needed`&&n.reasons.length>0&&(0,C.jsxs)(`div`,{className:`harness-setup-reasons`,children:[(0,C.jsx)(`span`,{className:`small`,children:h}),(0,C.jsx)(`ul`,{className:`muted small`,children:n.reasons.map(e=>(0,C.jsx)(`li`,{children:e},e))})]}),g&&(0,C.jsx)(`p`,{className:`muted small`,children:g}),_,y&&n.models.length>0&&(n.state!==`conflict`||j)&&(0,C.jsxs)(`div`,{className:`harness-setup-model-row`,children:[(0,C.jsx)(`span`,{id:N,children:y.label}),(0,C.jsxs)(a,{value:y.value,onValueChange:y.onChange,disabled:y.disabled,children:[(0,C.jsx)(l,{"aria-labelledby":N,children:(0,C.jsx)(c,{})}),(0,C.jsxs)(u,{children:[F.length>0&&(0,C.jsxs)(i,{children:[(0,C.jsx)(d,{children:`Gezels`}),F.map(e=>(0,C.jsx)(s,{value:e.id,children:T(e)},e.id))]}),F.length>0&&I.length>0&&(0,C.jsx)(o,{}),I.length>0&&(0,C.jsxs)(i,{children:[(0,C.jsx)(d,{children:`Raw models`}),I.map(e=>(0,C.jsx)(s,{value:e.id,children:T(e)},e.id))]})]})]})]}),n.models.length===0&&n.state!==`conflict`&&(0,C.jsx)(`p`,{className:`harness-setup-caution small`,children:D}),S,(0,C.jsx)(`div`,{className:`harness-setup-actions`,children:w})]}),E&&(0,C.jsx)(`p`,{className:`error small harness-setup-error`,role:`alert`,children:E}),M]})}function T(e){return e.description?`${e.label} — ${e.description}`:e.label}function E({endpointsEnabled:e,onChanged:t}){let n=y({label:`Codex`,endpointsEnabled:e,fetchStatus:()=>r.getCodexSetupStatus(),runAction:(0,v.useCallback)((e,t)=>e===`remove`?r.removeCodexSetup():r.configureCodex({model:t,...e===`repair`?{backupConflictingProfile:!0}:{}}),[]),errorPrefix:D,backupNotice:e=>e.profileBackupPath?`The previous file was saved as ${e.profileBackupPath}.`:null,...t?{onChanged:t}:{}}),{status:i,confirmation:a,setConfirmation:o,setError:s,busy:c,copied:l}=n,u=i?.models.find(e=>e.id===n.model),d=i?.models.find(e=>e.id===i.configuredModel),f=n.repairable?`Repair Codex setup…`:i?.state===`not-configured`?`Set up Codex…`:`Update Codex…`;return(0,C.jsxs)(w,{headingId:`codex-setup-heading`,title:`Use Gezel in Codex`,status:i,remoteMode:n.remoteMode,localDesktopMode:n.localDesktopMode,endpointsEnabled:e,repairable:!!n.repairable,notice:n.notice,error:n.error,reasonsIntro:`The managed setup needs an update:`,emptyModelsNote:`No gezels or inference models compatible with the Codex tool loop are available yet.`,intro:(0,C.jsx)(C.Fragment,{children:`Codex keeps its coding tools, sandbox, approvals, and conversation loop while a gezel supplies the character, model, and tuning. Your whole eligible crew is offered to Codex — the gezel you pick here is the one it starts with, and you can switch to any other from Codex's own model picker. Raw local models remain available when you want inference without a gezel persona.`}),...i?{repairExplainer:(0,C.jsxs)(C.Fragment,{children:[`Repair writes a fresh `,(0,C.jsx)(`code`,{children:i.profileName}),` profile for this Gezel and keeps a copy of the existing file next to it.`]})}:{},...i&&!i.codexInstalled?{notInstalledNote:`Codex was not found on this computer. You can prepare the setup now and use it after installing Codex.`}:{},...n.configured&&d&&!n.modelChanged?{configuredNote:(0,C.jsxs)(C.Fragment,{children:[`Codex starts with `,(0,C.jsx)(`strong`,{children:d.label}),`.`,i?.codexVersion?` Codex ${i.codexVersion} was found.`:``]})}:{},...n.canLaunch&&i?{commandRow:(0,C.jsxs)(`div`,{className:`harness-setup-command-row`,children:[(0,C.jsx)(`span`,{className:`muted small`,children:`Start it with`}),(0,C.jsx)(`code`,{children:i.launchCommand}),(0,C.jsx)(`button`,{type:`button`,onClick:()=>void n.copyLaunchCommand(),children:l?`Copied`:`Copy command`}),(0,C.jsx)(`output`,{className:`sr-only`,"aria-live":`polite`,children:l?`Codex launch command copied.`:``}),(0,C.jsx)(`span`,{className:`muted small`,children:`Keep Gezel running while you use Codex.`})]})}:{},modelRow:{label:`Default gezel`,value:n.model,onChange:n.setModel,disabled:n.selectionDisabled},actions:(0,C.jsxs)(C.Fragment,{children:[n.needsConfigure&&(0,C.jsx)(`button`,{type:`button`,className:`primary`,disabled:n.configureDisabled,onClick:()=>{s(null),o(n.repairable?`repair`:`configure`)},children:f}),i?.canRemove&&(0,C.jsx)(`button`,{type:`button`,disabled:c||!n.localDesktopMode,onClick:()=>{s(null),o(`remove`)},children:i.state===`conflict`?`Clear Gezel setup…`:`Remove setup…`}),n.error&&(0,C.jsx)(`button`,{type:`button`,onClick:()=>void n.refresh(),disabled:c,children:`Try again`})]}),children:[(0,C.jsx)(m,{open:a===`configure`,title:i?.state===`not-configured`?`Set up Codex with Gezel?`:`Update Codex setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will `,i?.state===`not-configured`?`create`:`update`,` its managed Codex profile for `,(0,C.jsx)(`strong`,{children:u?.label??n.model}),`.`,` `,u&&x(u)?(0,C.jsxs)(C.Fragment,{children:[`This gezel's character, `,u.modelLabel??`model`,`, and tuning will guide Codex.`,` `]}):(0,C.jsx)(C.Fragment,{children:`Codex will use it as a raw inference model without a gezel persona. `}),`The profile includes the local connection and app-scoped credential`,i?.profilePath?(0,C.jsxs)(C.Fragment,{children:[` `,`at `,(0,C.jsx)(`code`,{children:i.profilePath})]}):null,`. Your other Codex settings and conversations stay untouched.`]}),confirmLabel:i?.state===`not-configured`?`Set up Codex`:`Update Codex`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`repair`,title:`Repair the Codex setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will write a working `,(0,C.jsx)(`code`,{children:i?.profileName}),` profile for`,` `,(0,C.jsx)(`strong`,{children:u?.label??n.model}),`, connected to this copy of Gezel.`,i?.profilePath?(0,C.jsxs)(C.Fragment,{children:[` `,`The file now at `,(0,C.jsx)(`code`,{children:i.profilePath}),` is kept as a `,(0,C.jsx)(`code`,{children:`.backup`}),` `,`copy beside it, so nothing is lost.`]}):(0,C.jsx)(C.Fragment,{children:` The file it replaces is kept as a .backup copy beside it, so nothing is lost.`}),` `,`Your other Codex settings and conversations stay untouched.`]}),confirmLabel:`Repair setup`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`remove`,title:i?.state===`conflict`?`Clear Gezel setup for Codex?`:`Remove Gezel setup from Codex?`,message:(0,C.jsxs)(C.Fragment,{children:[`This removes only Gezel's managed Codex profile, catalog, state, and credential. It does not uninstall Codex or delete your other settings and conversations.`,i?.state===`conflict`?` Any Codex profile not managed by Gezel will be preserved.`:``]}),confirmLabel:i?.state===`conflict`?`Clear Gezel setup`:`Remove setup`,danger:!0,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)})]})}function D(e,t){switch(e){case`remove`:return`Could not remove the Codex setup`;case`repair`:return`Could not repair the Codex setup`;default:return t===`not-configured`?`Could not set up the Codex setup`:`Could not update the Codex setup`}}function O({endpointsEnabled:e,onChanged:t}){let n=y({label:`OpenCode`,endpointsEnabled:e,fetchStatus:()=>r.getOpenCodeSetupStatus(),runAction:(0,v.useCallback)((e,t)=>{switch(e){case`remove`:return r.removeOpenCodeSetup();case`install-plugin`:return r.installOpenCodePlugin();case`replace-plugin`:return r.installOpenCodePlugin({backupConflictingPlugin:!0});case`remove-plugin`:return r.removeOpenCodePlugin();default:return r.configureOpenCode({model:t,...e===`repair`?{backupConflictingConfig:!0}:{}})}},[]),errorPrefix:k,backupNotice:e=>e.pluginBackupPath?`The previous plugin file was saved as ${e.pluginBackupPath}.`:e.configBackupPath?`The previous file was saved as ${e.configBackupPath}.`:null,...t?{onChanged:t}:{}}),{status:i,confirmation:a,setConfirmation:o,setError:s,busy:c,copied:l}=n,u=i?.models.find(e=>e.id===n.model),d=i?.models.find(e=>e.id===i.configuredModel),f=n.configured&&n.localDesktopMode&&i?.state!==`conflict`&&i?.plugin.state!==`unsupported`,p=n.repairable?`Repair OpenCode setup…`:i?.state===`not-configured`?`Set up OpenCode…`:`Update OpenCode…`;return(0,C.jsxs)(w,{headingId:`opencode-setup-heading`,title:`Use Gezel in OpenCode`,status:i,remoteMode:n.remoteMode,localDesktopMode:n.localDesktopMode,endpointsEnabled:e,repairable:!!n.repairable,notice:n.notice,error:n.error,reasonsIntro:`The managed setup needs an update:`,emptyModelsNote:`No gezels or inference models compatible with the OpenCode tool loop are available yet.`,intro:(0,C.jsx)(C.Fragment,{children:`OpenCode keeps its own tools, permissions, and conversation loop while a gezel supplies the character, model, and tuning. Gezel writes its own settings file and points OpenCode at it with one command. You can also let Gezel add a small plugin of its own to OpenCode, so the gezel provider is simply there in every session. Either way, your own OpenCode settings, conversations, and permissions are never edited. Your whole eligible crew is offered, so you can switch between them from OpenCode's model picker.`}),repairExplainer:`Repair writes a fresh settings file for this Gezel and keeps a copy of the existing one next to it.`,...i&&!i.opencodeInstalled?{notInstalledNote:`OpenCode was not found on this computer. You can prepare the setup now and use it after installing OpenCode.`}:{},...n.configured&&d&&!n.modelChanged?{configuredNote:(0,C.jsxs)(C.Fragment,{children:[`OpenCode starts with `,(0,C.jsx)(`strong`,{children:d.label}),`.`,i?.opencodeVersion?` OpenCode ${i.opencodeVersion} was found.`:``]})}:{},...n.canLaunch&&i?{commandRow:(0,C.jsxs)(`div`,{className:`harness-setup-command-row`,children:[(0,C.jsx)(`span`,{className:`muted small`,children:`Start it with`}),(0,C.jsx)(`code`,{children:i.launchCommand}),(0,C.jsx)(`button`,{type:`button`,onClick:()=>void n.copyLaunchCommand(),children:l?`Copied`:`Copy command`}),(0,C.jsx)(`output`,{className:`sr-only`,"aria-live":`polite`,children:l?`OpenCode launch command copied.`:``}),(0,C.jsx)(`span`,{className:`muted small`,children:`Keep Gezel running while you use OpenCode.`})]})}:{},modelRow:{label:`Default gezel`,value:n.model,onChange:n.setModel,disabled:n.selectionDisabled},...f&&i?{extraRows:(0,C.jsx)(`p`,{className:`muted small`,children:i.plugin.state===`installed`||i.plugin.state===`stale`?(0,C.jsxs)(C.Fragment,{children:[`Gezel is in OpenCode's provider list without the command, through`,` `,(0,C.jsx)(`code`,{children:i.plugin.path}),`.`]}):i.plugin.state===`conflict`?i.plugin.message:(0,C.jsx)(C.Fragment,{children:`Rather not use the command every time? Gezel can add its own plugin file to OpenCode so the crew shows up in every session.`})})}:{},actions:(0,C.jsxs)(C.Fragment,{children:[n.needsConfigure&&(0,C.jsx)(`button`,{type:`button`,className:`primary`,disabled:n.configureDisabled,onClick:()=>{s(null),o(n.repairable?`repair`:`configure`)},children:p}),f&&i&&(i.plugin.canInstall||i.plugin.canReplace)&&(0,C.jsx)(`button`,{type:`button`,disabled:c||!n.localDesktopMode,onClick:()=>{s(null),o(i.plugin.canReplace?`replace-plugin`:`install-plugin`)},children:i.plugin.canReplace?`Replace OpenCode plugin…`:`Add to OpenCode…`}),f&&i?.plugin.canRemove&&(0,C.jsx)(`button`,{type:`button`,disabled:c||!n.localDesktopMode,onClick:()=>{s(null),o(`remove-plugin`)},children:`Remove from OpenCode…`}),i?.canRemove&&(0,C.jsx)(`button`,{type:`button`,disabled:c||!n.localDesktopMode,onClick:()=>{s(null),o(`remove`)},children:i.state===`conflict`?`Clear Gezel setup…`:`Remove setup…`}),n.error&&(0,C.jsx)(`button`,{type:`button`,onClick:()=>void n.refresh(),disabled:c,children:`Try again`})]}),children:[(0,C.jsx)(m,{open:a===`configure`,title:i?.state===`not-configured`?`Set up OpenCode with Gezel?`:`Update OpenCode setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will `,i?.state===`not-configured`?`create`:`update`,` its own OpenCode settings file for `,(0,C.jsx)(`strong`,{children:u?.label??n.model}),`.`,` `,u&&x(u)?(0,C.jsxs)(C.Fragment,{children:[`This gezel's character, `,u.modelLabel??`model`,`, and tuning will guide OpenCode.`,` `]}):(0,C.jsx)(C.Fragment,{children:`OpenCode will use it as a raw inference model without a gezel persona. `}),`The file holds the local connection and app-scoped credential`,i?.configPath?(0,C.jsxs)(C.Fragment,{children:[` `,`at `,(0,C.jsx)(`code`,{children:i.configPath})]}):null,`. Your own OpenCode configuration, sessions, and permissions stay untouched.`]}),confirmLabel:i?.state===`not-configured`?`Set up OpenCode`:`Update OpenCode`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`repair`,title:`Repair the OpenCode setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will write a working settings file for`,` `,(0,C.jsx)(`strong`,{children:u?.label??n.model}),`, connected to this copy of Gezel.`,i?.configPath?(0,C.jsxs)(C.Fragment,{children:[` `,`The file now at `,(0,C.jsx)(`code`,{children:i.configPath}),` is kept as a `,(0,C.jsx)(`code`,{children:`.backup`}),` `,`copy beside it, so nothing is lost.`]}):(0,C.jsx)(C.Fragment,{children:` The file it replaces is kept as a .backup copy beside it, so nothing is lost.`}),` `,`Your own OpenCode configuration stays untouched.`]}),confirmLabel:`Repair setup`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`remove`,title:i?.state===`conflict`?`Clear Gezel setup for OpenCode?`:`Remove Gezel setup from OpenCode?`,message:(0,C.jsxs)(C.Fragment,{children:[`This removes only Gezel's own OpenCode settings file, state, and credential`,i?.plugin.canRemove?(0,C.jsxs)(C.Fragment,{children:[`, along with the plugin file Gezel added at `,(0,C.jsx)(`code`,{children:i.plugin.path})]}):null,`. It does not uninstall OpenCode or touch your own configuration and sessions.`]}),confirmLabel:i?.state===`conflict`?`Clear Gezel setup`:`Remove setup`,danger:!0,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`install-plugin`||a===`replace-plugin`,title:a===`replace-plugin`?`Replace the plugin file in OpenCode?`:`Add Gezel to OpenCode?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will add one file of its own`,i?.plugin.path?(0,C.jsxs)(C.Fragment,{children:[` `,`at `,(0,C.jsx)(`code`,{children:i.plugin.path})]}):null,`, so every OpenCode session on this computer offers the `,(0,C.jsx)(`strong`,{children:`gezel`}),` provider without the command above. It holds no password — it reads Gezel's own settings when OpenCode starts, and does nothing at all when Gezel is not running. It does not change which model OpenCode starts with; pick a gezel from OpenCode's own model picker. Your own OpenCode configuration, sessions, and permissions stay untouched, and`,` `,(0,C.jsx)(`code`,{children:`opencode --pure`}),` always starts without it.`,a===`replace-plugin`?(0,C.jsx)(C.Fragment,{children:` The file it replaces is kept as a .backup copy beside it, so nothing is lost.`}):null]}),confirmLabel:a===`replace-plugin`?`Replace plugin`:`Add to OpenCode`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`remove-plugin`,title:`Remove Gezel from OpenCode?`,message:(0,C.jsxs)(C.Fragment,{children:[`This deletes the plugin file Gezel added`,i?.plugin.path?(0,C.jsxs)(C.Fragment,{children:[` `,`at `,(0,C.jsx)(`code`,{children:i.plugin.path})]}):null,`. OpenCode stops offering the gezel provider unless you start it with the command on this card. The rest of the setup, and everything of your own, stays as it is.`]}),confirmLabel:`Remove from OpenCode`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)})]})}function k(e,t){switch(e){case`remove`:return`Could not remove the OpenCode setup`;case`repair`:return`Could not repair the OpenCode setup`;case`install-plugin`:case`replace-plugin`:return`Could not add Gezel to OpenCode`;case`remove-plugin`:return`Could not remove Gezel from OpenCode`;default:return t===`not-configured`?`Could not set up the OpenCode setup`:`Could not update the OpenCode setup`}}function A({endpointsEnabled:e,onChanged:t}){let n=y({label:`pi`,endpointsEnabled:e,fetchStatus:()=>r.getPiSetupStatus(),runAction:(0,v.useCallback)((e,t)=>{switch(e){case`remove`:return r.removePiSetup();case`install-extension`:return r.installPiExtension();case`replace-extension`:return r.installPiExtension({backupConflictingExtension:!0});case`remove-extension`:return r.removePiExtension();default:return r.configurePi({model:t,...e===`repair`?{backupConflictingConfig:!0}:{}})}},[]),errorPrefix:j,backupNotice:e=>e.extensionBackupPath?`The previous extension file was saved as ${e.extensionBackupPath}.`:e.configBackupPath?`The previous file was saved as ${e.configBackupPath}.`:null,...t?{onChanged:t}:{}}),{status:i,confirmation:a,setConfirmation:o,setError:s,busy:c,copied:l}=n,u=i?.models.find(e=>e.id===n.model),d=i?.models.find(e=>e.id===i.configuredModel),f=n.configured&&n.localDesktopMode&&i?.state!==`conflict`&&i?.extension.state!==`unsupported`,p=n.repairable?`Repair pi setup…`:i?.state===`not-configured`?`Set up pi…`:`Update pi…`;return(0,C.jsxs)(w,{headingId:`pi-setup-heading`,title:`Use Gezel in pi`,status:i,remoteMode:n.remoteMode,localDesktopMode:n.localDesktopMode,endpointsEnabled:e,repairable:!!n.repairable,notice:n.notice,error:n.error,reasonsIntro:`The managed setup needs an update:`,emptyModelsNote:`No gezels or inference models compatible with the pi tool loop are available yet.`,intro:(0,C.jsx)(C.Fragment,{children:`pi keeps its own tools, permissions, and conversation loop while a gezel supplies the character, model, and tuning. Gezel writes an extension of its own and hands you a command that loads it for that run. You can also let Gezel add that same file to pi, so the gezel provider is simply there in every session. Either way, your own pi settings, sessions, and models are never edited.`}),repairExplainer:`Repair writes a fresh model list for this Gezel and keeps a copy of the existing one next to it.`,...i&&!i.piInstalled?{notInstalledNote:`pi was not found on this computer. You can prepare the setup now and use it after installing pi.`}:{},...n.configured&&d&&!n.modelChanged?{configuredNote:(0,C.jsxs)(C.Fragment,{children:[`pi starts with `,(0,C.jsx)(`strong`,{children:d.label}),`, and offers the whole crew in its own model picker.`,i?.piVersion?` pi ${i.piVersion} was found.`:``]})}:{},...n.canLaunch&&i?{commandRow:(0,C.jsxs)(`div`,{className:`harness-setup-command-row`,children:[(0,C.jsx)(`span`,{className:`muted small`,children:`Start it with`}),(0,C.jsx)(`code`,{children:i.launchCommand}),(0,C.jsx)(`button`,{type:`button`,onClick:()=>void n.copyLaunchCommand(),children:l?`Copied`:`Copy command`}),(0,C.jsx)(`output`,{className:`sr-only`,"aria-live":`polite`,children:l?`pi launch command copied.`:``}),(0,C.jsx)(`span`,{className:`muted small`,children:`Keep Gezel running while you use pi.`})]})}:{},modelRow:{label:`Default gezel`,value:n.model,onChange:n.setModel,disabled:n.selectionDisabled},...f&&i?{extraRows:(0,C.jsx)(`p`,{className:`muted small`,children:i.extension.state===`installed`||i.extension.state===`stale`?(0,C.jsxs)(C.Fragment,{children:[`Gezel is in pi's provider list without the command, through`,` `,(0,C.jsx)(`code`,{children:i.extension.path}),`.`]}):i.extension.state===`conflict`?i.extension.message:(0,C.jsx)(C.Fragment,{children:`Rather not use the command every time? Gezel can add the same extension to pi so the crew shows up in every session.`})})}:{},actions:(0,C.jsxs)(C.Fragment,{children:[n.needsConfigure&&(0,C.jsx)(`button`,{type:`button`,className:`primary`,disabled:n.configureDisabled,onClick:()=>{s(null),o(n.repairable?`repair`:`configure`)},children:p}),f&&i&&(i.extension.canInstall||i.extension.canReplace)&&(0,C.jsx)(`button`,{type:`button`,disabled:c||!n.localDesktopMode,onClick:()=>{s(null),o(i.extension.canReplace?`replace-extension`:`install-extension`)},children:i.extension.canReplace?`Replace pi extension…`:`Add to pi…`}),f&&i?.extension.canRemove&&(0,C.jsx)(`button`,{type:`button`,disabled:c||!n.localDesktopMode,onClick:()=>{s(null),o(`remove-extension`)},children:`Remove from pi…`}),i?.canRemove&&(0,C.jsx)(`button`,{type:`button`,disabled:c||!n.localDesktopMode,onClick:()=>{s(null),o(`remove`)},children:i.state===`conflict`?`Clear Gezel setup…`:`Remove setup…`}),n.error&&(0,C.jsx)(`button`,{type:`button`,onClick:()=>void n.refresh(),disabled:c,children:`Try again`})]}),children:[(0,C.jsx)(m,{open:a===`configure`,title:i?.state===`not-configured`?`Set up pi with Gezel?`:`Update pi setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will `,i?.state===`not-configured`?`create`:`update`,` its own pi extension and model list for `,(0,C.jsx)(`strong`,{children:u?.label??n.model}),`.`,` `,u&&x(u)?(0,C.jsxs)(C.Fragment,{children:[`This gezel's character, `,u.modelLabel??`model`,`, and tuning will guide pi.`,` `]}):(0,C.jsx)(C.Fragment,{children:`pi will use it as a raw inference model without a gezel persona. `}),`Both files live in Gezel's own folder`,i?.extensionPath?(0,C.jsxs)(C.Fragment,{children:[`, at `,(0,C.jsx)(`code`,{children:i.extensionPath})]}):null,`, and the command above points pi at them for that run. Your own pi settings, sessions, and models stay untouched.`]}),confirmLabel:i?.state===`not-configured`?`Set up pi`:`Update pi`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`repair`,title:`Repair the pi setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will write a working model list for`,` `,(0,C.jsx)(`strong`,{children:u?.label??n.model}),`, connected to this copy of Gezel.`,i?.configPath?(0,C.jsxs)(C.Fragment,{children:[` `,`The file now at `,(0,C.jsx)(`code`,{children:i.configPath}),` is kept as a `,(0,C.jsx)(`code`,{children:`.backup`}),` `,`copy beside it, so nothing is lost.`]}):(0,C.jsx)(C.Fragment,{children:` The file it replaces is kept as a .backup copy beside it, so nothing is lost.`}),` `,`Your own pi configuration stays untouched.`]}),confirmLabel:`Repair setup`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`remove`,title:i?.state===`conflict`?`Clear Gezel setup for pi?`:`Remove Gezel setup from pi?`,message:(0,C.jsxs)(C.Fragment,{children:[`This removes only Gezel's own pi extension, model list, state, and credential`,i?.extension.canRemove?(0,C.jsxs)(C.Fragment,{children:[`, along with the copy Gezel added at `,(0,C.jsx)(`code`,{children:i.extension.path})]}):null,`. It does not uninstall pi or touch your own settings and sessions.`]}),confirmLabel:i?.state===`conflict`?`Clear Gezel setup`:`Remove setup`,danger:!0,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`install-extension`||a===`replace-extension`,title:a===`replace-extension`?`Replace the extension file in pi?`:`Add Gezel to pi?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will add its extension`,i?.extension.path?(0,C.jsxs)(C.Fragment,{children:[` `,`at `,(0,C.jsx)(`code`,{children:i.extension.path})]}):null,`, so every pi session on this computer offers the `,(0,C.jsx)(`strong`,{children:`gezel`}),` provider without the command above. It holds no password — it reads Gezel's own model list when pi starts, and does nothing at all when Gezel is not running. It does not change which model pi starts with; pick a gezel from pi's own model picker. Your own pi settings, sessions, and models stay untouched, and `,(0,C.jsx)(`code`,{children:`pi -ne`}),` always starts without it.`,i?.extension.agentDirSource==="default"?(0,C.jsxs)(C.Fragment,{children:[` `,`Gezel found pi's folder in its usual place. If you point pi elsewhere with`,` `,(0,C.jsx)(`code`,{children:`PI_CODING_AGENT_DIR`}),` in your shell, it will not be picked up.`]}):null,a===`replace-extension`?(0,C.jsx)(C.Fragment,{children:` The file it replaces is kept as a .backup copy beside it, so nothing is lost.`}):null]}),confirmLabel:a===`replace-extension`?`Replace extension`:`Add to pi`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)}),(0,C.jsx)(m,{open:a===`remove-extension`,title:`Remove Gezel from pi?`,message:(0,C.jsxs)(C.Fragment,{children:[`This deletes the extension Gezel added`,i?.extension.path?(0,C.jsxs)(C.Fragment,{children:[` `,`at `,(0,C.jsx)(`code`,{children:i.extension.path})]}):null,`. pi stops offering the gezel provider unless you start it with the command on this card. The rest of the setup, and everything of your own, stays as it is.`]}),confirmLabel:`Remove from pi`,onConfirm:n.runConfirmedAction,onCancel:()=>o(null)})]})}function j(e,t){switch(e){case`remove`:return`Could not remove the pi setup`;case`repair`:return`Could not repair the pi setup`;case`install-extension`:case`replace-extension`:return`Could not add Gezel to pi`;case`remove-extension`:return`Could not remove Gezel from pi`;default:return t===`not-configured`?`Could not set up pi`:`Could not update the pi setup`}}function M({endpointsEnabled:e,onChanged:t}){let[n,i]=(0,v.useState)(``),o=(0,v.useId)(),d=y({label:`VS Code`,endpointsEnabled:e,fetchStatus:()=>r.getVSCodeSetupStatus(),runAction:(0,v.useCallback)(e=>e===`remove`?r.removeVSCodeSetup():r.configureVSCode({profileId:n,...e===`repair`?{backupConflictingConfig:!0}:{}}),[n]),modelSelection:!1,errorPrefix:N,backupNotice:e=>e.configBackupPath?`The previous file was saved as ${e.configBackupPath}.`:null,...t?{onChanged:t}:{}}),{status:f,confirmation:p,setConfirmation:h,setError:g,busy:_}=d;(0,v.useEffect)(()=>{f&&i(e=>f.profiles.some(t=>t.id===e)?e:f.configuredProfileId??f.profiles[0]?.id??``)},[f]);let b=f?.profiles.find(e=>e.id===n),x=P(f?.vscodeVersion),S=!!f?.configuredProfileId,T=d.repairable?`Repair VS Code setup…`:f?.state===`not-configured`?`Set up VS Code…`:`Update VS Code…`;return(0,C.jsxs)(w,{headingId:`vscode-setup-heading`,title:`Use Gezel in VS Code`,status:f,remoteMode:d.remoteMode,localDesktopMode:d.localDesktopMode,endpointsEnabled:e,repairable:!!d.repairable,notice:d.notice,error:d.error,reasonsIntro:`The managed setup needs an update:`,emptyModelsNote:`No gezels or inference models compatible with VS Code's agent tool loop are available yet.`,intro:(0,C.jsx)(C.Fragment,{children:`VS Code keeps its native agent tools, permissions, and conversation loop. Gezel adds your eligible crew and raw local models through VS Code's built-in custom endpoint — no extension is installed. Setup edits only the Gezel provider in the selected profile.`}),repairExplainer:(0,C.jsxs)(C.Fragment,{children:[`Repair keeps a copy of `,(0,C.jsx)(`code`,{children:f?.configPath}),`, then replaces only the conflicting Gezel provider entry. Other providers stay in place.`]}),...f&&!f.vscodeInstalled?{notInstalledNote:`VS Code was not found on PATH. You can prepare its conventional profile now and use it after installing VS Code.`}:{},...d.configured&&b?{configuredNote:(0,C.jsxs)(C.Fragment,{children:[`Gezel is available in `,(0,C.jsx)(`strong`,{children:b.label}),`.`,x?` VS Code ${x} was found.`:``,` Keep Gezel running while you use the models.`]})}:{},extraRows:f&&(f.state!==`conflict`||d.repairable)?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`div`,{className:`harness-setup-model-row`,children:[(0,C.jsx)(`span`,{id:o,children:`VS Code profile`}),(0,C.jsxs)(a,{value:n,onValueChange:i,disabled:_||!d.localDesktopMode||!e||S,children:[(0,C.jsx)(l,{"aria-labelledby":o,children:(0,C.jsx)(c,{})}),(0,C.jsx)(u,{children:f.profiles.map(e=>(0,C.jsx)(s,{value:e.id,children:e.label},e.id))})]})]}),S&&(0,C.jsx)(`p`,{className:`muted small`,children:`Clear this setup before choosing a different profile.`}),(0,C.jsxs)(`p`,{className:`muted small`,children:[`If VS Code is already open, you may need to run`,` `,(0,C.jsx)(`strong`,{children:`Developer: Reload Window`}),` or restart VS Code after setup before the models work.`]})]}):null,actions:(0,C.jsxs)(C.Fragment,{children:[d.needsConfigure&&(0,C.jsx)(`button`,{type:`button`,className:`primary`,disabled:d.configureDisabled||!n,onClick:()=>{g(null),h(d.repairable?`repair`:`configure`)},children:T}),f?.canRemove&&(0,C.jsx)(`button`,{type:`button`,disabled:_||!d.localDesktopMode,onClick:()=>{g(null),h(`remove`)},children:f.state===`conflict`?`Clear Gezel setup…`:`Remove setup…`}),d.error&&(0,C.jsx)(`button`,{type:`button`,onClick:()=>void d.refresh(),disabled:_,children:`Try again`})]}),children:[(0,C.jsx)(m,{open:p===`configure`,title:f?.state===`not-configured`?`Set up VS Code with Gezel?`:`Update VS Code setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will add or update one provider in `,(0,C.jsx)(`code`,{children:b?.configPath}),`. VS Code will show every eligible gezel and raw local model in its native model picker and keep control of agent tools and permissions. Other custom endpoint providers are preserved.`,(0,C.jsx)(`br`,{}),(0,C.jsx)(`br`,{}),`Because no extension is involved, the dedicated inference-only credential is stored as plain text in this profile file. It works only through Gezel's loopback inference bridge and can be revoked by clearing this setup. If VS Code is already open, reload its window or restart it after setup so it picks up the new credential.`]}),confirmLabel:f?.state===`not-configured`?`Set up VS Code`:`Update VS Code`,onConfirm:d.runConfirmedAction,onCancel:()=>h(null)}),(0,C.jsx)(m,{open:p===`repair`,title:`Repair the VS Code setup?`,message:(0,C.jsxs)(C.Fragment,{children:[`Gezel will save the current `,(0,C.jsx)(`code`,{children:f?.configPath}),` beside it as a backup, then publish a working Gezel provider for this installation. Providers that are not named Gezel remain untouched. The replacement contains a new plain-text, inference-only loopback credential.`]}),confirmLabel:`Repair setup`,onConfirm:d.runConfirmedAction,onCancel:()=>h(null)}),(0,C.jsx)(m,{open:p===`remove`,title:`Remove Gezel setup from VS Code?`,message:(0,C.jsx)(C.Fragment,{children:`This removes only the Gezel provider entry, setup state, and dedicated credential. It does not uninstall VS Code, touch other endpoint providers, or delete conversations. A Gezel entry changed outside this setup is preserved, but its credential is revoked.`}),confirmLabel:`Remove setup`,danger:!0,onConfirm:d.runConfirmedAction,onCancel:()=>h(null)})]})}function N(e,t){return e===`remove`?`Could not remove the VS Code setup`:e===`repair`?`Could not repair the VS Code setup`:t===`not-configured`?`Could not set up the VS Code setup`:`Could not update the VS Code setup`}function P(e){if(!e)return;let t=e.split(/\s+/).filter(e=>e&&!/^[a-f\d]{40}$/i.test(e));return t.length>0?t.join(` `):void 0}function F(e){return e?f(e):`never`}var I=`__AUTOMATIC__`,L=new Set([`copilot`,`anthropic-cli`,`codex-cli`]);function R(){let[e,t]=(0,v.useState)(null),[n,i]=(0,v.useState)(null),[o,d]=(0,v.useState)(null),[f,y]=(0,v.useState)(null),[b,x]=(0,v.useState)({}),[S,w]=(0,v.useState)({}),[T,D]=(0,v.useState)([]),[k,j]=(0,v.useState)(null),[N,P]=(0,v.useState)(0),[R,z]=(0,v.useState)(`copilot`),[B,V]=(0,v.useState)(),H=(0,v.useCallback)(async()=>{try{let e=await fetch(`${r.getBaseUrl()}/v1/apps`,{headers:r.authHeader()});if(!e.ok){i(`Failed to load apps: HTTP ${e.status}`);return}i(null),t(await e.json())}catch(e){i(e instanceof Error?e.message:String(e))}},[]);(0,v.useEffect)(()=>{H();let e=window.setInterval(()=>void H(),4e3);return()=>window.clearInterval(e)},[H]),(0,v.useEffect)(()=>{r.getConfig().then(e=>{w(e.openaiEndpoints??{}),z(e.provider??`llama-cpp`),V(e.meesterGezelId)}).catch(()=>{}),r.listGezels().then(e=>D(e.gezels.map(({id:e,name:t,role:n,provider:r})=>({id:e,name:t,role:n,provider:r})))).catch(()=>{})},[]);let U=(0,v.useCallback)(async e=>{let t=S,n=e.emulateOllama===t.emulateOllama?`endpoints`:`ollama`;w(e),j({scope:n,text:`saving…`});try{let t=await r.updateConfig({openaiEndpoints:e});w(t.openaiEndpoints??{}),P(e=>e+1),j(null)}catch(e){w(t);let r=e&&typeof e==`object`&&`details`in e?e.details?.message:void 0;j({scope:n,text:`save failed: ${r??(e instanceof Error?e.message:String(e))}`})}},[S]),W=S.enabled!==!1,G=T.find(e=>e.id===S.servingGezelId),K=T.find(e=>e.id===B)??T[0],q=G??K,J=e=>e.provider??R,Y=q!==void 0&&L.has(J(q)),X=(0,v.useCallback)(async(t,n)=>{if(o)return;let a=e?.grants.find(e=>e.id===t),s=b[t]??``;d(`${n}:${t}`);try{let e=await fetch(`${r.getBaseUrl()}/v1/apps/grant/${encodeURIComponent(t)}/${n}`,{method:`POST`,headers:{...r.authHeader(),...n===`approve`&&a?.verificationRequired?{"Content-Type":`application/json`}:{}},...n===`approve`&&a?.verificationRequired?{body:JSON.stringify({verificationCode:s})}:{}});if(!e.ok){i(await h(e,`Failed to ${n} grant`));return}x(e=>{let n={...e};return delete n[t],n}),await H()}catch(e){i(e instanceof Error?e.message:String(e))}finally{d(null)}},[o,H,e?.grants,b]),Z=(0,v.useCallback)(async()=>{if(f){d(`revoke:${f.appId}`);try{let e=await fetch(`${r.getBaseUrl()}/v1/apps/${encodeURIComponent(f.appId)}/token`,{method:`DELETE`,headers:r.authHeader()});if(!e.ok){i(`Failed to revoke ${f.appId}: HTTP ${e.status}`);return}y(null),await H(),P(e=>e+1)}finally{d(null)}}},[f,H]),Q=(e?.grants??[]).filter(e=>e.status===`pending`),$=e?.apps??[];return(0,C.jsxs)(`section`,{className:`settings-section`,children:[(0,C.jsx)(`h2`,{children:`Connected Apps`}),(0,C.jsx)(`p`,{className:`muted small`,children:`Apps and command-line clients that have asked for access to your Gezel service. Each client is granted only the scopes it requested. Revoke any time.`}),n&&(0,C.jsx)(`p`,{className:`settings-error`,role:`alert`,children:n}),(0,C.jsxs)(`div`,{className:`settings-subsection`,children:[(0,C.jsx)(`h3`,{children:`OpenAI-compatible endpoints`}),(0,C.jsx)(`p`,{className:`muted small`,children:`Other apps (editors, browser tools) can use your gezellen and models through standard OpenAI-style endpoints. Each app still needs your approval below before it gets access.`}),(0,C.jsxs)(`label`,{className:`debug-toggle`,children:[(0,C.jsx)(`input`,{type:`checkbox`,checked:W,onChange:e=>void U({...S,enabled:e.target.checked?void 0:!1})}),(0,C.jsx)(`span`,{children:`Allow apps to connect`})]}),W?(0,C.jsxs)(`p`,{className:`muted small`,children:[`Point apps at `,(0,C.jsxs)(`code`,{children:[r.getBaseUrl(),`/v1`]})]}):(0,C.jsx)(`p`,{className:`muted small`,children:`Turned off — connected apps are refused and new apps cannot ask for access until this is back on.`}),(0,C.jsxs)(`div`,{className:`connected-apps-serving`,children:[(0,C.jsx)(`span`,{id:`serving-gezel-label`,children:`Fallback gezel`}),(0,C.jsxs)(a,{value:G?G.id:I,onValueChange:e=>void U({...S,servingGezelId:e===I?void 0:e}),disabled:!W,children:[(0,C.jsx)(l,{"aria-labelledby":`serving-gezel-label`,children:(0,C.jsx)(c,{})}),(0,C.jsxs)(u,{children:[(0,C.jsxs)(s,{value:I,children:[`Automatic`,K?` — ${K.name}`:``]}),T.map(e=>(0,C.jsxs)(s,{value:e.id,children:[e.name,e.role?` — ${e.role}`:``,` (${J(e)})`]},e.id))]})]})]}),(0,C.jsxs)(`p`,{className:`muted small`,children:[`Apps receive your gezellen as model choices, including their names and roles. If an app asks for something else, `,q?.name??`your default gezel`,` answers with their character and model settings.`]}),q&&Y&&(0,C.jsxs)(`p`,{className:`small connected-apps-caution`,children:[q.name,` runs on `,J(q),`, which can't accept tools sent by apps — editors that use tools will get an error. For full compatibility, pick a gezel on a local model or a direct API provider.`]}),(0,C.jsxs)(`label`,{className:`debug-toggle`,children:[(0,C.jsx)(`input`,{type:`checkbox`,checked:S.supportingBehaviors!==!1,onChange:e=>void U({...S,supportingBehaviors:e.target.checked?void 0:!1}),disabled:!W}),(0,C.jsx)(`span`,{children:`Supporting behaviors`})]}),(0,C.jsx)(`p`,{className:`muted small`,children:`Gezel knows how to get the best out of each model — catching runaway rambling, folding leaked reasoning, and applying model-specific fixes. Turn this off for plain serving: apps still get the gezel's character and each model's tuned settings (sampling, thinking mode), but no runtime interventions.`}),k?.scope===`endpoints`&&(0,C.jsx)(`output`,{className:`muted small`,children:k.text})]}),(0,C.jsx)(E,{endpointsEnabled:W,onChanged:H},`codex-${N}`),(0,C.jsx)(M,{endpointsEnabled:W,onChanged:H},`vscode-${N}`),(0,C.jsx)(O,{endpointsEnabled:W,onChanged:H},`opencode-${N}`),(0,C.jsx)(A,{endpointsEnabled:W,onChanged:H},`pi-${N}`),(0,C.jsxs)(`div`,{className:`settings-subsection`,children:[(0,C.jsx)(`h3`,{children:`Ollama emulation`}),(0,C.jsxs)(`label`,{className:`debug-toggle`,children:[(0,C.jsx)(`input`,{type:`checkbox`,checked:S.emulateOllama===!0,onChange:e=>void U({...S,emulateOllama:e.target.checked?!0:void 0}),disabled:!W}),(0,C.jsx)(`span`,{children:`Emulate Ollama (port 11434)`})]}),(0,C.jsx)(`p`,{className:`muted small`,children:`Apps that auto-discover Ollama will find gezel instead — no setup needed in each app. Security note: Ollama's convention is no password, so while this is on, any program on this computer can use your models without asking first. Gezel refuses to take the port if Ollama itself is already running.`}),k?.scope===`ollama`&&(0,C.jsx)(`output`,{className:`muted small`,children:k.text})]}),Q.length>0&&(0,C.jsxs)(`div`,{className:`settings-subsection`,children:[(0,C.jsx)(`h3`,{children:`Pending requests`}),(0,C.jsx)(`ul`,{className:`settings-list`,children:Q.map(e=>(0,C.jsxs)(`li`,{className:`connected-app-row connected-app-row--pending`,children:[(0,C.jsxs)(`div`,{className:`connected-app-meta`,children:[(0,C.jsxs)(`div`,{className:`connected-app-name`,children:[e.appName,e.kind===`device`&&(0,C.jsx)(`span`,{className:`badge`,children:` device`})]}),(0,C.jsx)(`div`,{className:`muted small`,children:e.kind===`device`?`wants to run models on this device`:e.scopes.includes(`cli`)?`${e.appId} — wants command-line control of this Gezel service`:e.scopes.includes(`product`)?`${e.appId} — wants access to Gezel features and data`:`${e.appId} — wants: ${e.scopes.join(`, `)}`})]}),(0,C.jsxs)(`div`,{className:`connected-app-actions`,children:[e.verificationRequired&&(0,C.jsxs)(`label`,{className:`connected-app-code`,children:[(0,C.jsx)(`span`,{children:`Connection code`}),(0,C.jsx)(`input`,{value:b[e.id]??``,onChange:t=>{let n=g(t.currentTarget.value);x(t=>({...t,[e.id]:n}))},placeholder:`___-___`,maxLength:7,autoComplete:`off`,autoCapitalize:`characters`,spellCheck:!1,"aria-label":`Connection code for ${e.appName}`})]}),(0,C.jsx)(`button`,{type:`button`,onClick:()=>void X(e.id,`deny`),disabled:o!==null,children:`Deny`}),(0,C.jsx)(`button`,{type:`button`,className:`primary`,onClick:()=>void X(e.id,`approve`),disabled:o!==null||e.verificationRequired&&!_(b[e.id]??``),children:o===`approve:${e.id}`?`Approving…`:`Approve`})]})]},e.id))})]}),(0,C.jsxs)(`div`,{className:`settings-subsection`,children:[(0,C.jsx)(`h3`,{children:`Connected`}),$.length===0?(0,C.jsx)(`p`,{className:`muted small`,children:`No apps connected. Apps that use the gezel SDK appear here after you approve them.`}):(0,C.jsx)(`div`,{className:`connected-apps-table-wrap`,children:(0,C.jsxs)(`table`,{className:`connected-apps-table`,"aria-label":`Connected apps`,children:[(0,C.jsx)(`thead`,{children:(0,C.jsxs)(`tr`,{children:[(0,C.jsx)(`th`,{scope:`col`,children:`App`}),(0,C.jsx)(`th`,{scope:`col`,children:`Scopes`}),(0,C.jsx)(`th`,{scope:`col`,children:`Last used`}),(0,C.jsx)(`th`,{scope:`col`,children:(0,C.jsx)(`span`,{className:`sr-only`,children:`Actions`})})]})}),(0,C.jsx)(`tbody`,{children:$.map(e=>(0,C.jsxs)(`tr`,{children:[(0,C.jsxs)(`td`,{"data-label":`App`,children:[(0,C.jsxs)(`div`,{className:`connected-apps-identity`,children:[(0,C.jsx)(`span`,{className:`connected-apps-name`,children:e.appName}),e.kind===`device`&&(0,C.jsx)(`span`,{className:`connected-apps-kind`,children:`Device`})]}),(0,C.jsx)(`span`,{className:`connected-apps-id`,children:e.appId})]}),(0,C.jsx)(`td`,{"data-label":`Scopes`,children:e.scopes.length>0?(0,C.jsx)(`ul`,{className:`connected-apps-scopes`,children:e.scopes.map(e=>(0,C.jsx)(`li`,{children:e},e))}):(0,C.jsx)(`span`,{className:`connected-apps-empty`,children:`None`})}),(0,C.jsx)(`td`,{"data-label":`Last used`,children:(0,C.jsx)(`span`,{className:`connected-apps-last-used`,title:e.lastUsedAt?p(e.lastUsedAt):void 0,children:F(e.lastUsedAt)})}),(0,C.jsx)(`td`,{className:`connected-apps-action`,children:(0,C.jsx)(`button`,{type:`button`,className:`connected-apps-revoke`,"aria-label":`Revoke ${e.appName}`,onClick:()=>y(e),disabled:o!==null,children:`Revoke`})})]},e.appId))})]})})]}),(0,C.jsx)(m,{open:f!==null,title:f?`Revoke ${f.appName}?`:`Revoke app`,message:f?(0,C.jsxs)(C.Fragment,{children:[`The next time `,(0,C.jsx)(`strong`,{children:f.appName}),` tries to use gezel it will be denied. The app can reconnect later by going through the consent flow again.`]}):null,confirmLabel:`Revoke`,danger:!0,onConfirm:Z,onCancel:()=>y(null)})]})}export{R as ConnectedAppsPanel};
@@ -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{M as r,Mt as i,Nt as a,Sn as o,W as s,en as c,nn as l}from"./dist-CE5CbmDb.js";import{t as u}from"./api-CmrgM5Rf.js";import{i as d,n as f,r as p}from"./Tabs-jE0Z5Tzd.js";import{d as m,l as h,m as g,p as _,s as v}from"./primitives-CWrGZpPI.js";import{it as y,j as b}from"./index-DivKnJyx.js";import{i as x}from"./ChatTimelineView-Dn1TNyVn.js";import{t as S}from"./ProjectTimeline-Cqae2Z92.js";import{t as C}from"./MarkdownField-BX0qsaFq.js";var w=e(t(),1),T=n(),E=`default`;function D({craftbookId:e,craftbookName:t,readOnly:n}){let r=b(),[i,a]=(0,w.useState)([]),[o,c]=(0,w.useState)(``);(0,w.useEffect)(()=>{u.listGezels().then(e=>a(e.gezels)).catch(()=>{})},[]),(0,w.useEffect)(()=>{c(``)},[e]);let l=(0,w.useMemo)(()=>i.find(e=>e.role===`voorman`)??i.find(e=>e.role===`meester`)??i[0],[i]),d=t=>{t?.startsWith(`craftbook_`)&&window.dispatchEvent(new CustomEvent(`gezel:craftbook-edited`,{detail:{id:e}}))};if(n)return(0,T.jsx)(`div`,{className:`craftbook-chat-pane muted small`,children:`This craftbook is read-only — fork it to a local copy to edit it with AI.`});if(!l)return(0,T.jsx)(`div`,{className:`craftbook-chat-pane muted small`,children:`No gezel available yet. Create a voorman or the Meester first, then come back.`});let f=s(l,r);return(0,T.jsxs)(`div`,{className:`craftbook-chat-pane task-detail-chat`,children:[(0,T.jsx)(S,{projectId:E,activeSessionId:o||void 0,onFocusSession:(e,t)=>{t===l.id&&c(e)},onToolActivity:e=>d(e.name)}),(0,T.jsx)(x,{gezelId:l.id,gezelName:l.name,gezelRoleBasedName:l.roleBasedName,gezelRole:l.role,gezelIcon:l.icon??null,...l.poppetje?{gezelPoppetje:l.poppetje}:{},...l.iconOverride?{gezelIconOverride:l.iconOverride}:{},projectId:E,sessionId:o||void 0,onSessionCreated:e=>c(e),onToolActivity:e=>d(e.name),craftbookRef:e,placeholder:`Ask ${f} to shape “${t}” — add steps, set roles, wire gates…`})]})}function O(e){window.dispatchEvent(new CustomEvent(`gezel:open-tab`,{detail:e}))}function k({craftbookId:e,steps:t,stepId:n,entryStepId:r,gezels:o,readOnly:s,busy:c,onPatch:l,onRemove:u,onSetEntry:d}){let f=n?t.find(e=>e.id===n)??null:null,[p,y]=(0,w.useState)(n),b=(0,w.useRef)(f?.name??``),x=(0,w.useRef)(f?.description??``),S=(0,w.useRef)(f?.prompt??``),E=(0,w.useRef)(f?.suggestedRole??``);if((0,w.useEffect)(()=>{b.current=f?.name??``,x.current=f?.description??``,S.current=f?.prompt??``,E.current=f?.suggestedRole??``,y(f?.id??null)},[f?.id,f?.name,f?.description,f?.prompt,f?.suggestedRole]),!f)return(0,T.jsx)(`section`,{className:`task-step-panel empty`,children:(0,T.jsx)(`p`,{className:`muted small`,children:t.length===0?`No steps yet — add one with the + button to begin.`:`Select a step above to view and edit it.`})});let D=f.id===r,k=e=>{s||l(f.id,e)},A=()=>{let e=b.current.trim();!e||e===f.name||k({name:e})},j=()=>{x.current!==(f.description??``)&&k({description:x.current})},M=()=>{S.current!==(f.prompt??``)&&k({prompt:S.current})},N=()=>{let e=E.current.trim();e!==(f.suggestedRole??``)&&k({suggestedRole:e||null})},P=f.assignee?f.assignee.kind===`user`?`__user`:f.assignee.gezelId:f.suggestedGezelId?f.suggestedGezelId:`__none`,F=e=>{k(e===`__user`?{assignee:{kind:`user`},suggestedGezelId:null}:e===`__none`?{assignee:null,suggestedGezelId:null}:{assignee:null,suggestedGezelId:e})},I=f.terminal?`__terminal`:f.next??`__linear`,L=e=>{k(e===`__terminal`?{terminal:!0,next:null}:e===`__linear`?{terminal:!1,next:null}:{terminal:!1,next:e})},R=t=>{let n=i(t===`enter`?f.onEnter:f.onExit),r=t===`enter`?`onEnter`:`onExit`,a=e=>k({[r]:e.length>0?e:null});return(0,T.jsxs)(`div`,{className:`step-script-row`,children:[(0,T.jsx)(`span`,{className:`step-script-moment muted small`,children:t===`enter`?`when it starts`:`when it finishes`}),n.length===0&&s&&(0,T.jsx)(`span`,{className:`muted small`,children:`—`}),n.map((t,r)=>(0,T.jsxs)(`span`,{className:`step-script-chip`,children:[(0,T.jsxs)(`button`,{type:`button`,className:`link-button`,onClick:()=>{(t.scope===void 0||t.scope===`craftbook`)&&O({kind:`craftbook-script`,craftbookId:e,name:t.name})},title:t.scope?`${t.scope} script`:`Open this script in the editor`,children:[`⚙ `,t.name,t.scope&&t.scope!==`craftbook`?` (${t.scope})`:``]}),!s&&(0,T.jsx)(`button`,{type:`button`,className:`link-button muted`,onClick:()=>a(n.filter((e,t)=>t!==r)),children:`detach`})]},`${t.scope??`craftbook`}:${t.name}:${r}`)),!s&&(0,T.jsx)(`button`,{type:`button`,className:`link-button`,onClick:()=>{let r=`${f.id}-${t}${n.length>0?`-${n.length+1}`:``}`;a([...n,{name:r}]),O({kind:`craftbook-script`,craftbookId:e,name:r})},children:`+ attach script`})]})},z=[];if(f.gate){let e=a(f.gate),t=[...e.checks.length>0?[`${e.checks.length} check(s)`]:[],...e.scripts.length>0?[`${e.scripts.length} script(s)`]:[]];z.push(`gate at ${e.at}: ${t.join(` + `)||`empty`}`)}return f.advanceWhen&&z.push(`auto-advance on ${f.advanceWhen.file}`),f.branches&&f.branches.length>0&&z.push(`${f.branches.length} branch(es)`),(0,T.jsxs)(`section`,{className:`task-step-panel`,children:[(0,T.jsxs)(`header`,{className:`task-step-panel-header`,children:[(0,T.jsxs)(`div`,{className:`task-step-panel-title`,children:[(0,T.jsx)(`h4`,{children:f.name}),D&&(0,T.jsx)(`span`,{className:`step-status-pill status-active`,children:`Entry`})]}),!s&&(0,T.jsxs)(`div`,{className:`task-step-panel-actions`,children:[(0,T.jsx)(`button`,{type:`button`,className:`secondary`,onClick:()=>void d(f.id),disabled:c||D,title:`Make this the craftbook's entry step`,children:`Set as entry`}),(0,T.jsx)(`button`,{type:`button`,className:`danger`,onClick:()=>void u(f.id),disabled:c||t.length<=1,title:t.length<=1?`A craftbook needs at least one step`:`Delete this step`,children:`Delete`})]})]}),(0,T.jsxs)(`div`,{className:`task-step-panel-grid`,children:[(0,T.jsxs)(`label`,{className:`task-step-field`,children:[(0,T.jsx)(`span`,{className:`task-step-field-label`,children:`Name`}),(0,T.jsx)(`input`,{defaultValue:f.name,disabled:s,onChange:e=>{b.current=e.target.value},onBlur:A},`name-${p}`)]}),(0,T.jsxs)(`label`,{className:`task-step-field`,children:[(0,T.jsx)(`span`,{className:`task-step-field-label`,children:`Indexed context`}),(0,T.jsxs)(m,{value:f.retrieval?.mode??`__inherit`,disabled:s||c,onValueChange:e=>k(e===`__inherit`?{retrieval:null}:{retrieval:{mode:e,...f.retrieval?.maxTokens?{maxTokens:f.retrieval.maxTokens}:{},...f.retrieval?.sources?{sources:f.retrieval.sources}:{}}}),children:[(0,T.jsx)(_,{children:(0,T.jsx)(g,{})}),(0,T.jsxs)(v,{children:[(0,T.jsx)(h,{value:`__inherit`,children:`Inherit from gezel`}),(0,T.jsx)(h,{value:`off`,children:`Off — tools only`}),(0,T.jsx)(h,{value:`lean`,children:`Lean — paths and hints`}),(0,T.jsx)(h,{value:`balanced`,children:`Balanced — a few excerpts`}),(0,T.jsx)(h,{value:`deep`,children:`Deep — broad evidence`})]})]})]}),(0,T.jsxs)(`label`,{className:`task-step-field`,children:[(0,T.jsx)(`span`,{className:`task-step-field-label`,children:`Context token cap`}),(0,T.jsx)(`input`,{type:`number`,min:0,max:16e3,defaultValue:f.retrieval?.maxTokens??``,disabled:s||c||!f.retrieval||f.retrieval.mode===`off`,placeholder:`Mode default`,onBlur:e=>{if(!f.retrieval)return;let t=e.currentTarget.value.trim(),n=t?Number.parseInt(t,10):void 0;if(n!==void 0&&!Number.isFinite(n)||n===f.retrieval.maxTokens)return;let{maxTokens:r,...i}=f.retrieval;k({retrieval:n===void 0?i:{...i,maxTokens:n}})}},`retrieval-budget-${p}`)]}),(0,T.jsxs)(`label`,{className:`task-step-field`,children:[(0,T.jsx)(`span`,{className:`task-step-field-label`,children:`Suggested role`}),(0,T.jsx)(`input`,{defaultValue:f.suggestedRole??``,disabled:s,placeholder:`developer, reviewer, designer…`,onChange:e=>{E.current=e.target.value},onBlur:N},`role-${p}`)]}),(0,T.jsxs)(`label`,{className:`task-step-field`,children:[(0,T.jsx)(`span`,{className:`task-step-field-label`,children:`Assignee (override)`}),(0,T.jsxs)(m,{value:P,disabled:s||c,onValueChange:F,children:[(0,T.jsx)(_,{children:(0,T.jsx)(g,{})}),(0,T.jsxs)(v,{children:[(0,T.jsx)(h,{value:`__none`,children:`— by role —`}),(0,T.jsx)(h,{value:`__user`,children:`→ You`}),o.map(e=>(0,T.jsxs)(h,{value:e.id,children:[`→ `,e.name]},e.id))]})]})]}),(0,T.jsxs)(`label`,{className:`task-step-field`,children:[(0,T.jsx)(`span`,{className:`task-step-field-label`,children:`Next step`}),(0,T.jsxs)(m,{value:I,disabled:s||c,onValueChange:L,children:[(0,T.jsx)(_,{children:(0,T.jsx)(g,{})}),(0,T.jsxs)(v,{children:[(0,T.jsx)(h,{value:`__linear`,children:`→ next in order`}),(0,T.jsx)(h,{value:`__terminal`,children:`■ terminal (ends here)`}),t.filter(e=>e.id!==f.id).map(e=>(0,T.jsxs)(h,{value:e.id,children:[`→ `,e.name]},e.id))]})]})]}),(0,T.jsxs)(`div`,{className:`task-step-field full-width`,children:[(0,T.jsx)(`span`,{className:`task-step-field-label`,children:`Description`}),(0,T.jsx)(C,{value:f.description??``,readOnly:s,placeholder:`What this step produces, who it's for, what 'done' looks like.`,onCommit:e=>{x.current=e,j()}},`desc-${p}`)]}),(0,T.jsxs)(`div`,{className:`task-step-field full-width`,children:[(0,T.jsxs)(`span`,{className:`task-step-field-label`,children:[`Prompt `,(0,T.jsx)(`span`,{className:`muted small`,children:`— step-specific guidance for the assignee`})]}),(0,T.jsx)(C,{value:f.prompt??``,readOnly:s,placeholder:`Instructions the assignee can lean on for this step.`,onCommit:e=>{S.current=e,M()}},`prompt-${p}`)]}),(0,T.jsxs)(`div`,{className:`task-step-field full-width`,children:[(0,T.jsx)(`span`,{className:`task-step-field-label`,children:`Scripts`}),(0,T.jsxs)(`div`,{className:`step-scripts`,children:[R(`enter`),R(`exit`)]})]}),z.length>0&&(0,T.jsxs)(`div`,{className:`task-step-field full-width`,children:[(0,T.jsx)(`span`,{className:`task-step-field-label`,children:`Routing`}),(0,T.jsxs)(`p`,{className:`muted small`,children:[z.join(` · `),` — edit gates/branches/auto-advance via the AI assist.`]})]})]})]})}function A(e){window.dispatchEvent(new CustomEvent(`gezel:open-tab`,{detail:e}))}function j(e){return{name:e.name,description:e.description??null,plan:e.plan??null,defaultAssignee:e.defaultAssignee??null,steps:e.steps,entryStepId:e.entryStepId}}function M({craftbookId:e,source:t,onChanged:n}){let[i,a]=(0,w.useState)(null),[s,m]=(0,w.useState)(t??`local`),[h,g]=(0,w.useState)([]),[_,v]=(0,w.useState)(null),[b,x]=(0,w.useState)(`editor`),[S,E]=(0,w.useState)(!1),[O,M]=(0,w.useState)(null),N=(0,w.useRef)(``),P=(0,w.useRef)(``),F=s!==`local`,I=(0,w.useCallback)(async()=>{try{let n=await u.getCraftbook(e,t?{source:t}:{});a(n.craftbook),N.current=n.craftbook.name,P.current=n.craftbook.description??``,v(e=>e&&n.craftbook.steps.some(t=>t.id===e)?e:n.craftbook.entryStepId??n.craftbook.steps[0]?.id??null)}catch(e){M(e.message)}},[e,t]);(0,w.useEffect)(()=>{I()},[I]),(0,w.useEffect)(()=>{u.listGezels().then(e=>g(e.gezels)).catch(()=>{})},[]),(0,w.useEffect)(()=>{if(t){m(t);return}u.listCraftbooks({source:`all`}).then(t=>{let n=t.craftbooks.find(t=>t.id===e);n&&m(n.source)}).catch(()=>{})},[e,t]),(0,w.useEffect)(()=>{let t=t=>{let n=t.detail;(!n?.id||n.id===e)&&I()};return window.addEventListener(`gezel:craftbook-edited`,t),()=>window.removeEventListener(`gezel:craftbook-edited`,t)},[e,I]);let L=(0,w.useCallback)(async e=>{if(a(e),!F){E(!0),M(null);try{let t=await u.updateCraftbook(e.id,j(e));a(t.craftbook),n?.()}catch(e){M(e.message),await I()}finally{E(!1)}}},[F,n,I]);if(O&&!i)return(0,T.jsx)(`p`,{className:`error`,children:O});if(!i)return(0,T.jsx)(`p`,{className:`placeholder`,children:`Loading…`});let R=(e,t)=>{L({...i,steps:i.steps.map(n=>n.id===e?r(n,t):n)})},z=e=>{L({...i,steps:l(i.steps,e)})},B=e=>{try{let t=c(i.steps,e),n=i.entryStepId===e?t[0].id:i.entryStepId;_===e&&v(n),L({...i,steps:t,entryStepId:n})}catch(e){M(e.message)}},V=e=>{L({...i,entryStepId:e})},H=()=>{let e=o(i.steps,`New step`),t={id:e,name:`New step`};v(e),L({...i,steps:[...i.steps,t]})},U=()=>{let e=N.current.trim();!e||e===i.name||L({...i,name:e})},W=()=>{P.current!==(i.description??``)&&L({...i,description:P.current||void 0})},G=async()=>{E(!0),M(null);try{A({kind:`craftbook`,id:(await u.createCraftbook({name:`${i.name} (copy)`,...i.description?{description:i.description}:{},...i.plan?{plan:i.plan}:{},steps:i.steps,entryStepId:i.entryStepId})).craftbook.id,source:`local`})}catch(e){M(e.message)}finally{E(!1)}};return(0,T.jsxs)(`div`,{className:`craftbook-editor`,"data-testid":`craftbook-editor`,children:[(0,T.jsxs)(`header`,{className:`craftbook-editor-header`,children:[(0,T.jsxs)(`div`,{className:`craftbook-editor-title`,children:[F?(0,T.jsx)(`h3`,{children:i.name}):(0,T.jsx)(`input`,{className:`craftbook-name-input`,defaultValue:i.name,onChange:e=>{N.current=e.target.value},onBlur:U,"aria-label":`Craftbook name`}),(0,T.jsx)(`span`,{className:`task-ref`,children:i.id}),(0,T.jsx)(`span`,{className:`task-badge task-badge-${s}`,children:s}),F&&(0,T.jsx)(`button`,{type:`button`,className:`primary`,onClick:()=>void G(),disabled:S,children:`Copy to edit`})]}),O&&(0,T.jsx)(`p`,{className:`error small`,children:O})]}),(0,T.jsx)(`div`,{className:`task-bench-row craftbook-bench-row${_===null?``:` has-docked-panel has-selected-step`}`,children:(0,T.jsx)(y,{steps:i.steps,selectedStepId:_,onSelect:v,entryStepId:i.entryStepId,busy:S,ariaLabel:`Craftbook steps`,addLabel:`Add step`,variant:`bench`,...F?{}:{onAddStep:H,onReorder:z}})}),(0,T.jsx)(k,{craftbookId:i.id,steps:i.steps,stepId:_,entryStepId:i.entryStepId,gezels:h,readOnly:F,busy:S,onPatch:R,onRemove:B,onSetEntry:V}),(0,T.jsx)(`div`,{className:`craftbook-editor-tabs`,children:(0,T.jsx)(p,{value:b,onValueChange:e=>x(e),children:(0,T.jsxs)(f,{children:[(0,T.jsx)(d,{value:`editor`,children:`Overview`}),(0,T.jsx)(d,{value:`chat`,children:`AI assist`})]})})}),b===`editor`&&(0,T.jsxs)(`div`,{className:`craftbook-overview`,children:[(0,T.jsxs)(`div`,{className:`task-step-field full-width`,children:[(0,T.jsx)(`span`,{className:`task-step-field-label`,children:`Description`}),(0,T.jsx)(C,{value:i.description??``,readOnly:F,placeholder:`What this craftbook is for and when to reach for it.`,onCommit:e=>{P.current=e,W()}},`cbdesc-${i.id}`)]}),i.plan&&(0,T.jsxs)(`div`,{className:`task-step-field full-width`,children:[(0,T.jsx)(`span`,{className:`task-step-field-label`,children:`Plan`}),(0,T.jsx)(`p`,{className:`muted small`,children:i.plan})]})]}),b===`chat`&&(0,T.jsx)(D,{craftbookId:i.id,craftbookName:i.name,readOnly:F})]})}export{M as t};
@@ -1 +1 @@
1
- import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{n as t,t as n}from"./jsx-runtime-CEpd2cAX.js";import{t as r}from"./api-C0I7spBl.js";import{t as i}from"./ScriptEditorTabs-CCDFZjdC.js";var a=e(t(),1),o=n();function s({craftbookId:e,scriptName:t}){let n=(0,a.useRef)(null),[s,c]=(0,a.useState)(null),[l,u]=(0,a.useState)([]),[d,f]=(0,a.useState)(!1),[p,m]=(0,a.useState)(!1),[h,g]=(0,a.useState)(null);(0,a.useEffect)(()=>{let n=!1;return(async()=>{try{let i=await r.getCraftbookScriptSource(e,t).catch(()=>null);i||=(await r.createCraftbookScript(e,{name:t}),await r.getCraftbookScriptSource(e,t)),n||c(i)}catch(e){n||g(e.message)}})(),()=>{n=!0}},[e,t]);let _=(0,a.useCallback)(async()=>{let i=n.current?.getValue();if(!(i==null||!s)){m(!0),g(null);try{let a=await r.saveCraftbookScriptSource(e,{name:t,source:i,baseHash:s.hash});if(a.status===`conflict`){g(`The script changed on disk — reopen the tab to get the latest.`);return}c({...s,source:i,hash:a.hash}),f(!1),n.current?.setServerDiagnostics(a.diagnostics)}catch(e){g(e.message)}finally{m(!1)}}},[e,t,s]);if(h&&!s)return(0,o.jsx)(`p`,{className:`error`,children:h});if(!s)return(0,o.jsx)(`p`,{className:`placeholder`,children:`Loading…`});let v=l.filter(e=>e.severity===`error`).length;return(0,o.jsxs)(`div`,{className:`script-editor-view`,children:[(0,o.jsxs)(`header`,{className:`script-editor-header`,children:[(0,o.jsxs)(`div`,{className:`script-editor-title`,children:[(0,o.jsx)(`span`,{className:`task-ref`,children:e}),(0,o.jsx)(`h3`,{children:t}),d&&(0,o.jsx)(`span`,{className:`muted small`,children:`• unsaved`})]}),(0,o.jsx)(`div`,{className:`script-editor-actions`,children:(0,o.jsx)(`button`,{type:`button`,className:`primary`,onClick:()=>void _(),disabled:p||!d,children:p?`Saving…`:`Save`})})]}),h&&(0,o.jsx)(`p`,{className:`error small`,children:h}),(0,o.jsx)(`div`,{className:`script-editor-body`,children:(0,o.jsx)(i,{ref:n,projectId:`craftbook:${e}`,scriptName:t,initialSource:s.source,initialMeta:s.meta,onChangeContent:()=>f(!0),onSave:()=>void _(),onProblems:u})}),v>0&&(0,o.jsxs)(`div`,{className:`script-editor-problems small`,children:[v,` problem`,v===1?``:`s`,` — hover the red marks in the editor.`]})]})}export{s as CraftbookScriptEditorView};
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"./ScriptEditorTabs-st6dJePd.js";var a=e(t(),1),o=n();function s({craftbookId:e,scriptName:t}){let n=(0,a.useRef)(null),[s,c]=(0,a.useState)(null),[l,u]=(0,a.useState)([]),[d,f]=(0,a.useState)(!1),[p,m]=(0,a.useState)(!1),[h,g]=(0,a.useState)(null);(0,a.useEffect)(()=>{let n=!1;return(async()=>{try{let i=await r.getCraftbookScriptSource(e,t).catch(()=>null);i||=(await r.createCraftbookScript(e,{name:t}),await r.getCraftbookScriptSource(e,t)),n||c(i)}catch(e){n||g(e.message)}})(),()=>{n=!0}},[e,t]);let _=(0,a.useCallback)(async()=>{let i=n.current?.getValue();if(!(i==null||!s)){m(!0),g(null);try{let a=await r.saveCraftbookScriptSource(e,{name:t,source:i,baseHash:s.hash});if(a.status===`conflict`){g(`The script changed on disk — reopen the tab to get the latest.`);return}c({...s,source:i,hash:a.hash}),f(!1),n.current?.setServerDiagnostics(a.diagnostics)}catch(e){g(e.message)}finally{m(!1)}}},[e,t,s]);if(h&&!s)return(0,o.jsx)(`p`,{className:`error`,children:h});if(!s)return(0,o.jsx)(`p`,{className:`placeholder`,children:`Loading…`});let v=l.filter(e=>e.severity===`error`).length;return(0,o.jsxs)(`div`,{className:`script-editor-view`,children:[(0,o.jsxs)(`header`,{className:`script-editor-header`,children:[(0,o.jsxs)(`div`,{className:`script-editor-title`,children:[(0,o.jsx)(`span`,{className:`task-ref`,children:e}),(0,o.jsx)(`h3`,{children:t}),d&&(0,o.jsx)(`span`,{className:`muted small`,children:`• unsaved`})]}),(0,o.jsx)(`div`,{className:`script-editor-actions`,children:(0,o.jsx)(`button`,{type:`button`,className:`primary`,onClick:()=>void _(),disabled:p||!d,children:p?`Saving…`:`Save`})})]}),h&&(0,o.jsx)(`p`,{className:`error small`,children:h}),(0,o.jsx)(`div`,{className:`script-editor-body`,children:(0,o.jsx)(i,{ref:n,projectId:`craftbook:${e}`,scriptName:t,initialSource:s.source,initialMeta:s.meta,onChangeContent:()=>f(!0),onSave:()=>void _(),onProblems:u})}),v>0&&(0,o.jsxs)(`div`,{className:`script-editor-problems small`,children:[v,` problem`,v===1?``:`s`,` — hover the red marks in the editor.`]})]})}export{s as CraftbookScriptEditorView};
@@ -1 +1 @@
1
- import{t as e}from"./jsx-runtime-CEpd2cAX.js";import{t}from"./CraftbookEditor-BKAIsnXv.js";var n=e();function r({craftbookId:e,source:r,onChanged:i}){return(0,n.jsx)(`div`,{className:`craftbook-tab`,children:(0,n.jsx)(t,{craftbookId:e,...r?{source:r}:{},...i?{onChanged:i}:{}},e)})}export{r as CraftbookTabContent};
1
+ import{t as e}from"./jsx-runtime-CEpd2cAX.js";import{t}from"./CraftbookEditor-B2RNJnFf.js";var n=e();function r({craftbookId:e,source:r,onChanged:i}){return(0,n.jsx)(`div`,{className:`craftbook-tab`,children:(0,n.jsx)(t,{craftbookId:e,...r?{source:r}:{},...i?{onChanged:i}:{}},e)})}export{r as CraftbookTabContent};