@openpalm/ui 0.11.0-rc.11 → 0.11.0-rc.13

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 (239) hide show
  1. package/build/.openpalm-ui-version +1 -1
  2. package/build/client/_app/immutable/assets/0.nenI9xO9.css +1 -0
  3. package/build/client/_app/immutable/assets/0.nenI9xO9.css.br +0 -0
  4. package/build/client/_app/immutable/assets/0.nenI9xO9.css.gz +0 -0
  5. package/build/client/_app/immutable/assets/4.j3F-W7h_.css +1 -0
  6. package/build/client/_app/immutable/assets/4.j3F-W7h_.css.br +0 -0
  7. package/build/client/_app/immutable/assets/4.j3F-W7h_.css.gz +0 -0
  8. package/build/client/_app/immutable/assets/7.CzC8JVIO.css +1 -0
  9. package/build/client/_app/immutable/assets/7.CzC8JVIO.css.br +0 -0
  10. package/build/client/_app/immutable/assets/7.CzC8JVIO.css.gz +0 -0
  11. package/build/client/_app/immutable/assets/8.cpz_TytB.css +1 -0
  12. package/build/client/_app/immutable/assets/8.cpz_TytB.css.br +0 -0
  13. package/build/client/_app/immutable/assets/8.cpz_TytB.css.gz +0 -0
  14. package/build/client/_app/immutable/assets/AuthGate._tqG1OIX.css +1 -0
  15. package/build/client/_app/immutable/assets/AuthGate._tqG1OIX.css.br +0 -0
  16. package/build/client/_app/immutable/assets/AuthGate._tqG1OIX.css.gz +0 -0
  17. package/build/client/_app/immutable/assets/ModeSwitch.DVIv_V4C.css +1 -0
  18. package/build/client/_app/immutable/assets/ModeSwitch.DVIv_V4C.css.br +0 -0
  19. package/build/client/_app/immutable/assets/ModeSwitch.DVIv_V4C.css.gz +0 -0
  20. package/build/client/_app/immutable/assets/Spinner.BtzHSsat.css +1 -0
  21. package/build/client/_app/immutable/assets/Spinner.BtzHSsat.css.br +2 -0
  22. package/build/client/_app/immutable/assets/Spinner.BtzHSsat.css.gz +0 -0
  23. package/build/client/_app/immutable/assets/VoiceProfileSelector.B8FTffwl.css +1 -0
  24. package/build/client/_app/immutable/assets/VoiceProfileSelector.B8FTffwl.css.br +0 -0
  25. package/build/client/_app/immutable/assets/VoiceProfileSelector.B8FTffwl.css.gz +0 -0
  26. package/build/client/_app/immutable/chunks/0swOyi-5.js +3 -0
  27. package/build/client/_app/immutable/chunks/0swOyi-5.js.br +0 -0
  28. package/build/client/_app/immutable/chunks/0swOyi-5.js.gz +0 -0
  29. package/build/client/_app/immutable/chunks/B1uQvvlv.js +5 -0
  30. package/build/client/_app/immutable/chunks/B1uQvvlv.js.br +0 -0
  31. package/build/client/_app/immutable/chunks/B1uQvvlv.js.gz +0 -0
  32. package/build/client/_app/immutable/chunks/{DpdFx-ph.js → BBdT9Cjm.js} +1 -1
  33. package/build/client/_app/immutable/chunks/BBdT9Cjm.js.br +0 -0
  34. package/build/client/_app/immutable/chunks/BBdT9Cjm.js.gz +0 -0
  35. package/build/client/_app/immutable/chunks/{BxZ6a55y.js → BPh8tqAg.js} +1 -1
  36. package/build/client/_app/immutable/chunks/BPh8tqAg.js.br +2 -0
  37. package/build/client/_app/immutable/chunks/BPh8tqAg.js.gz +0 -0
  38. package/build/client/_app/immutable/chunks/BQ0vnNWj.js +1 -0
  39. package/build/client/_app/immutable/chunks/BQ0vnNWj.js.br +1 -0
  40. package/build/client/_app/immutable/chunks/BQ0vnNWj.js.gz +0 -0
  41. package/build/client/_app/immutable/chunks/{CJkMgfFh.js → BQrb5YOM.js} +1 -1
  42. package/build/client/_app/immutable/chunks/BQrb5YOM.js.br +0 -0
  43. package/build/client/_app/immutable/chunks/BQrb5YOM.js.gz +0 -0
  44. package/build/client/_app/immutable/chunks/Bmfn2m9N.js +1 -0
  45. package/build/client/_app/immutable/chunks/Bmfn2m9N.js.br +1 -0
  46. package/build/client/_app/immutable/chunks/Bmfn2m9N.js.gz +0 -0
  47. package/build/client/_app/immutable/chunks/CrcMJfbz.js +1 -0
  48. package/build/client/_app/immutable/chunks/CrcMJfbz.js.br +0 -0
  49. package/build/client/_app/immutable/chunks/CrcMJfbz.js.gz +0 -0
  50. package/build/client/_app/immutable/chunks/E7W0MQkU.js +1 -0
  51. package/build/client/_app/immutable/chunks/E7W0MQkU.js.br +0 -0
  52. package/build/client/_app/immutable/chunks/E7W0MQkU.js.gz +0 -0
  53. package/build/client/_app/immutable/entry/app.9wfmQKXa.js +2 -0
  54. package/build/client/_app/immutable/entry/app.9wfmQKXa.js.br +0 -0
  55. package/build/client/_app/immutable/entry/app.9wfmQKXa.js.gz +0 -0
  56. package/build/client/_app/immutable/entry/start.BzWuQgSn.js +1 -0
  57. package/build/client/_app/immutable/entry/start.BzWuQgSn.js.br +0 -0
  58. package/build/client/_app/immutable/entry/start.BzWuQgSn.js.gz +0 -0
  59. package/build/client/_app/immutable/nodes/0.DxAGOZgx.js +1 -0
  60. package/build/client/_app/immutable/nodes/0.DxAGOZgx.js.br +0 -0
  61. package/build/client/_app/immutable/nodes/0.DxAGOZgx.js.gz +0 -0
  62. package/build/client/_app/immutable/nodes/1.B-z3blIe.js +1 -0
  63. package/build/client/_app/immutable/nodes/1.B-z3blIe.js.br +1 -0
  64. package/build/client/_app/immutable/nodes/1.B-z3blIe.js.gz +0 -0
  65. package/build/client/_app/immutable/nodes/2.B-8ehRO1.js +1 -0
  66. package/build/client/_app/immutable/nodes/2.B-8ehRO1.js.br +0 -0
  67. package/build/client/_app/immutable/nodes/2.B-8ehRO1.js.gz +0 -0
  68. package/build/client/_app/immutable/nodes/3.DHPuQEyR.js +1 -0
  69. package/build/client/_app/immutable/nodes/3.DHPuQEyR.js.br +0 -0
  70. package/build/client/_app/immutable/nodes/3.DHPuQEyR.js.gz +0 -0
  71. package/build/client/_app/immutable/nodes/4.DOO_QIq1.js +18 -0
  72. package/build/client/_app/immutable/nodes/4.DOO_QIq1.js.br +0 -0
  73. package/build/client/_app/immutable/nodes/4.DOO_QIq1.js.gz +0 -0
  74. package/build/client/_app/immutable/nodes/5.BrAtimvQ.js +4 -0
  75. package/build/client/_app/immutable/nodes/5.BrAtimvQ.js.br +0 -0
  76. package/build/client/_app/immutable/nodes/5.BrAtimvQ.js.gz +0 -0
  77. package/build/client/_app/immutable/nodes/6.CDpI1TrW.js +1 -0
  78. package/build/client/_app/immutable/nodes/6.CDpI1TrW.js.br +0 -0
  79. package/build/client/_app/immutable/nodes/6.CDpI1TrW.js.gz +0 -0
  80. package/build/client/_app/immutable/nodes/{7.fFA0e6kz.js → 7.B5KYnWwU.js} +7 -7
  81. package/build/client/_app/immutable/nodes/7.B5KYnWwU.js.br +0 -0
  82. package/build/client/_app/immutable/nodes/7.B5KYnWwU.js.gz +0 -0
  83. package/build/client/_app/immutable/nodes/8.2jRmEBBC.js +2 -0
  84. package/build/client/_app/immutable/nodes/8.2jRmEBBC.js.br +0 -0
  85. package/build/client/_app/immutable/nodes/8.2jRmEBBC.js.gz +0 -0
  86. package/build/client/_app/version.json +1 -1
  87. package/build/client/_app/version.json.br +1 -1
  88. package/build/client/_app/version.json.gz +0 -0
  89. package/build/server/chunks/0-CP9GcQBP.js +9 -0
  90. package/build/server/chunks/{0-TTdZdv8o.js.map → 0-CP9GcQBP.js.map} +1 -1
  91. package/build/server/chunks/1-BDxTrwG3.js +9 -0
  92. package/build/server/chunks/{1-BhLqDyOn.js.map → 1-BDxTrwG3.js.map} +1 -1
  93. package/build/server/chunks/2-DQWoUtW1.js +9 -0
  94. package/build/server/chunks/{2-C2y4ydWU.js.map → 2-DQWoUtW1.js.map} +1 -1
  95. package/build/server/chunks/{3-BgeGdVvT.js → 3-gylRjzeN.js} +2 -2
  96. package/build/server/chunks/{3-BgeGdVvT.js.map → 3-gylRjzeN.js.map} +1 -1
  97. package/build/server/chunks/4-CBgm4iSo.js +9 -0
  98. package/build/server/chunks/4-CBgm4iSo.js.map +1 -0
  99. package/build/server/chunks/5-CD1fuYOe.js +9 -0
  100. package/build/server/chunks/5-CD1fuYOe.js.map +1 -0
  101. package/build/server/chunks/6-B6tmbcQ8.js +9 -0
  102. package/build/server/chunks/6-B6tmbcQ8.js.map +1 -0
  103. package/build/server/chunks/7-m4KLf_Gx.js +9 -0
  104. package/build/server/chunks/7-m4KLf_Gx.js.map +1 -0
  105. package/build/server/chunks/8-CmPpxrjv.js +9 -0
  106. package/build/server/chunks/8-CmPpxrjv.js.map +1 -0
  107. package/build/server/chunks/{AuthGate-C3ZisQbA.js → AuthGate-BcB49fE5.js} +44 -41
  108. package/build/server/chunks/AuthGate-BcB49fE5.js.map +1 -0
  109. package/build/server/chunks/ModeSwitch-D26evPMy.js +15 -0
  110. package/build/server/chunks/ModeSwitch-D26evPMy.js.map +1 -0
  111. package/build/server/chunks/Spinner-Bk6e83RX.js +12 -0
  112. package/build/server/chunks/Spinner-Bk6e83RX.js.map +1 -0
  113. package/build/server/chunks/VoiceProfileSelector-CbOV_v5A.js +306 -0
  114. package/build/server/chunks/VoiceProfileSelector-CbOV_v5A.js.map +1 -0
  115. package/build/server/chunks/{_layout.svelte-B93aaRP_.js → _layout.svelte-BV7A7zff.js} +2 -2
  116. package/build/server/chunks/{_layout.svelte-B93aaRP_.js.map → _layout.svelte-BV7A7zff.js.map} +1 -1
  117. package/build/server/chunks/{_layout.svelte-CcloHuB_.js → _layout.svelte-C8ggVfth.js} +8 -8
  118. package/build/server/chunks/_layout.svelte-C8ggVfth.js.map +1 -0
  119. package/build/server/chunks/_page.svelte-CEjRvc8B.js +2579 -0
  120. package/build/server/chunks/_page.svelte-CEjRvc8B.js.map +1 -0
  121. package/build/server/chunks/{_page.svelte-C6H2En_w.js → _page.svelte-Cy4kcLwu.js} +7 -6
  122. package/build/server/chunks/{_page.svelte-C6H2En_w.js.map → _page.svelte-Cy4kcLwu.js.map} +1 -1
  123. package/build/server/chunks/{_page.svelte-D0gMlmzQ.js → _page.svelte-DLAHj-kk.js} +6 -14
  124. package/build/server/chunks/_page.svelte-DLAHj-kk.js.map +1 -0
  125. package/build/server/chunks/{_page.svelte-DA9eUO0x.js → _page.svelte-DrWHHwCU.js} +8 -7
  126. package/build/server/chunks/{_page.svelte-DA9eUO0x.js.map → _page.svelte-DrWHHwCU.js.map} +1 -1
  127. package/build/server/chunks/{_page.svelte-Arw4vnr_.js → _page.svelte-WWZsjJuR.js} +25 -22
  128. package/build/server/chunks/_page.svelte-WWZsjJuR.js.map +1 -0
  129. package/build/server/chunks/{dev-DjANv7AF.js → dev-B6xUe35c.js} +23 -2
  130. package/build/server/chunks/{dev-DjANv7AF.js.map → dev-B6xUe35c.js.map} +1 -1
  131. package/build/server/chunks/{error.svelte-CEMlYvrw.js → error.svelte-CcHm-30A.js} +4 -4
  132. package/build/server/chunks/{error.svelte-CEMlYvrw.js.map → error.svelte-CcHm-30A.js.map} +1 -1
  133. package/build/server/chunks/{internal-CStLdOSk.js → internal-B08Y9iTe.js} +3 -3
  134. package/build/server/chunks/{internal-CStLdOSk.js.map → internal-B08Y9iTe.js.map} +1 -1
  135. package/build/server/chunks/{state-BCMZi_P3.js → state-CFHLgqLs.js} +3 -3
  136. package/build/server/chunks/{state-BCMZi_P3.js.map → state-CFHLgqLs.js.map} +1 -1
  137. package/build/server/chunks/{theme-state.svelte-PtPMmKGN.js → theme-state.svelte-y-mfJax7.js} +9 -2
  138. package/build/server/chunks/theme-state.svelte-y-mfJax7.js.map +1 -0
  139. package/build/server/index.js +2 -2
  140. package/build/server/index.js.map +1 -1
  141. package/build/server/manifest.js +10 -10
  142. package/build/server/manifest.js.map +1 -1
  143. package/package.json +1 -1
  144. package/build/client/_app/immutable/assets/0.p3iHeEvq.css +0 -1
  145. package/build/client/_app/immutable/assets/0.p3iHeEvq.css.br +0 -0
  146. package/build/client/_app/immutable/assets/0.p3iHeEvq.css.gz +0 -0
  147. package/build/client/_app/immutable/assets/4.DhrSl6jB.css +0 -1
  148. package/build/client/_app/immutable/assets/4.DhrSl6jB.css.br +0 -0
  149. package/build/client/_app/immutable/assets/4.DhrSl6jB.css.gz +0 -0
  150. package/build/client/_app/immutable/assets/7.Cucah5cY.css +0 -1
  151. package/build/client/_app/immutable/assets/7.Cucah5cY.css.br +0 -0
  152. package/build/client/_app/immutable/assets/7.Cucah5cY.css.gz +0 -0
  153. package/build/client/_app/immutable/assets/8.DjrHy5wu.css +0 -1
  154. package/build/client/_app/immutable/assets/8.DjrHy5wu.css.br +0 -0
  155. package/build/client/_app/immutable/assets/8.DjrHy5wu.css.gz +0 -0
  156. package/build/client/_app/immutable/assets/AuthGate.B8fOC_pJ.css +0 -1
  157. package/build/client/_app/immutable/assets/AuthGate.B8fOC_pJ.css.br +0 -0
  158. package/build/client/_app/immutable/assets/AuthGate.B8fOC_pJ.css.gz +0 -0
  159. package/build/client/_app/immutable/assets/ModeSwitch.RmRIDur-.css +0 -1
  160. package/build/client/_app/immutable/assets/ModeSwitch.RmRIDur-.css.br +0 -0
  161. package/build/client/_app/immutable/assets/ModeSwitch.RmRIDur-.css.gz +0 -0
  162. package/build/client/_app/immutable/assets/VoiceProfileSelector.CM_o2XIa.css +0 -1
  163. package/build/client/_app/immutable/assets/VoiceProfileSelector.CM_o2XIa.css.br +0 -0
  164. package/build/client/_app/immutable/assets/VoiceProfileSelector.CM_o2XIa.css.gz +0 -0
  165. package/build/client/_app/immutable/chunks/7rWcSIlt.js +0 -1
  166. package/build/client/_app/immutable/chunks/7rWcSIlt.js.br +0 -0
  167. package/build/client/_app/immutable/chunks/7rWcSIlt.js.gz +0 -0
  168. package/build/client/_app/immutable/chunks/B7ArSvo1.js +0 -1
  169. package/build/client/_app/immutable/chunks/B7ArSvo1.js.br +0 -0
  170. package/build/client/_app/immutable/chunks/B7ArSvo1.js.gz +0 -0
  171. package/build/client/_app/immutable/chunks/BwTF6U35.js +0 -3
  172. package/build/client/_app/immutable/chunks/BwTF6U35.js.br +0 -0
  173. package/build/client/_app/immutable/chunks/BwTF6U35.js.gz +0 -0
  174. package/build/client/_app/immutable/chunks/BxZ6a55y.js.br +0 -0
  175. package/build/client/_app/immutable/chunks/BxZ6a55y.js.gz +0 -0
  176. package/build/client/_app/immutable/chunks/CJkMgfFh.js.br +0 -0
  177. package/build/client/_app/immutable/chunks/CJkMgfFh.js.gz +0 -0
  178. package/build/client/_app/immutable/chunks/CaNTMSit.js +0 -5
  179. package/build/client/_app/immutable/chunks/CaNTMSit.js.br +0 -0
  180. package/build/client/_app/immutable/chunks/CaNTMSit.js.gz +0 -0
  181. package/build/client/_app/immutable/chunks/DpdFx-ph.js.br +0 -0
  182. package/build/client/_app/immutable/chunks/DpdFx-ph.js.gz +0 -0
  183. package/build/client/_app/immutable/chunks/os2NZ37U.js +0 -1
  184. package/build/client/_app/immutable/chunks/os2NZ37U.js.br +0 -1
  185. package/build/client/_app/immutable/chunks/os2NZ37U.js.gz +0 -0
  186. package/build/client/_app/immutable/entry/app.CzMd4RbT.js +0 -2
  187. package/build/client/_app/immutable/entry/app.CzMd4RbT.js.br +0 -0
  188. package/build/client/_app/immutable/entry/app.CzMd4RbT.js.gz +0 -0
  189. package/build/client/_app/immutable/entry/start.QaKTVCwD.js +0 -1
  190. package/build/client/_app/immutable/entry/start.QaKTVCwD.js.br +0 -0
  191. package/build/client/_app/immutable/entry/start.QaKTVCwD.js.gz +0 -0
  192. package/build/client/_app/immutable/nodes/0.BUaVTC13.js +0 -1
  193. package/build/client/_app/immutable/nodes/0.BUaVTC13.js.br +0 -0
  194. package/build/client/_app/immutable/nodes/0.BUaVTC13.js.gz +0 -0
  195. package/build/client/_app/immutable/nodes/1.D9TRUzbv.js +0 -1
  196. package/build/client/_app/immutable/nodes/1.D9TRUzbv.js.br +0 -2
  197. package/build/client/_app/immutable/nodes/1.D9TRUzbv.js.gz +0 -0
  198. package/build/client/_app/immutable/nodes/2.ojh8oE7F.js +0 -1
  199. package/build/client/_app/immutable/nodes/2.ojh8oE7F.js.br +0 -0
  200. package/build/client/_app/immutable/nodes/2.ojh8oE7F.js.gz +0 -0
  201. package/build/client/_app/immutable/nodes/3.DeAC3yVJ.js +0 -1
  202. package/build/client/_app/immutable/nodes/3.DeAC3yVJ.js.br +0 -0
  203. package/build/client/_app/immutable/nodes/3.DeAC3yVJ.js.gz +0 -0
  204. package/build/client/_app/immutable/nodes/4.5fL8qHix.js +0 -18
  205. package/build/client/_app/immutable/nodes/4.5fL8qHix.js.br +0 -0
  206. package/build/client/_app/immutable/nodes/4.5fL8qHix.js.gz +0 -0
  207. package/build/client/_app/immutable/nodes/5.DAAeB39N.js +0 -4
  208. package/build/client/_app/immutable/nodes/5.DAAeB39N.js.br +0 -0
  209. package/build/client/_app/immutable/nodes/5.DAAeB39N.js.gz +0 -0
  210. package/build/client/_app/immutable/nodes/6.CmMKgobq.js +0 -1
  211. package/build/client/_app/immutable/nodes/6.CmMKgobq.js.br +0 -0
  212. package/build/client/_app/immutable/nodes/6.CmMKgobq.js.gz +0 -0
  213. package/build/client/_app/immutable/nodes/7.fFA0e6kz.js.br +0 -0
  214. package/build/client/_app/immutable/nodes/7.fFA0e6kz.js.gz +0 -0
  215. package/build/client/_app/immutable/nodes/8.Rc3xcFgu.js +0 -2
  216. package/build/client/_app/immutable/nodes/8.Rc3xcFgu.js.br +0 -0
  217. package/build/client/_app/immutable/nodes/8.Rc3xcFgu.js.gz +0 -0
  218. package/build/server/chunks/0-TTdZdv8o.js +0 -9
  219. package/build/server/chunks/1-BhLqDyOn.js +0 -9
  220. package/build/server/chunks/2-C2y4ydWU.js +0 -9
  221. package/build/server/chunks/4-D6mAJO8F.js +0 -9
  222. package/build/server/chunks/4-D6mAJO8F.js.map +0 -1
  223. package/build/server/chunks/5-D5Apamdo.js +0 -9
  224. package/build/server/chunks/5-D5Apamdo.js.map +0 -1
  225. package/build/server/chunks/6-aCBWYjjQ.js +0 -9
  226. package/build/server/chunks/6-aCBWYjjQ.js.map +0 -1
  227. package/build/server/chunks/7-NlChqFlW.js +0 -9
  228. package/build/server/chunks/7-NlChqFlW.js.map +0 -1
  229. package/build/server/chunks/8-EJHw3wqt.js +0 -9
  230. package/build/server/chunks/8-EJHw3wqt.js.map +0 -1
  231. package/build/server/chunks/AuthGate-C3ZisQbA.js.map +0 -1
  232. package/build/server/chunks/ModeSwitch-B9a33ugm.js +0 -15
  233. package/build/server/chunks/ModeSwitch-B9a33ugm.js.map +0 -1
  234. package/build/server/chunks/_layout.svelte-CcloHuB_.js.map +0 -1
  235. package/build/server/chunks/_page.svelte-4WHOZ298.js +0 -408
  236. package/build/server/chunks/_page.svelte-4WHOZ298.js.map +0 -1
  237. package/build/server/chunks/_page.svelte-Arw4vnr_.js.map +0 -1
  238. package/build/server/chunks/_page.svelte-D0gMlmzQ.js.map +0 -1
  239. package/build/server/chunks/theme-state.svelte-PtPMmKGN.js.map +0 -1
@@ -0,0 +1,2579 @@
1
+ import { E as head, p as ensure_array_like, e as attr_class, d as attr, r as escape_html, a8 as stringify, F as html, o as derived, g as bind_props } from './dev-B6xUe35c.js';
2
+ import { o as onDestroy } from './state-CFHLgqLs.js';
3
+ import { g as fetchHealth, a as fetchContainers, f as fetchAutomations, k as fetchVersions, h as fetchReleases, j as fetchUiVersions, v as voiceState, b as buildHeaders, i as fetchServiceLogs } from './theme-state.svelte-y-mfJax7.js';
4
+ import { A as AuthGate, N as Navbar } from './AuthGate-BcB49fE5.js';
5
+ import { S as Spinner } from './Spinner-Bk6e83RX.js';
6
+ import { V as VoiceEngineSelector, a as VoiceProfileSelector } from './VoiceProfileSelector-CbOV_v5A.js';
7
+ import './internal-B08Y9iTe.js';
8
+ import './utils-BSRjJDrZ.js';
9
+ import 'node:module';
10
+ import './chunk-CLZ62Ad-.js';
11
+
12
+ //#region src/lib/components/chrome/TabBar.svelte
13
+ function TabBar($$renderer, $$props) {
14
+ $$renderer.component(($$renderer) => {
15
+ let { active} = $$props;
16
+ const ICONS = {
17
+ overview: `<rect x="3" y="3" width="7" height="7" /><rect x="14" y="3" width="7" height="7" /><rect x="14" y="14" width="7" height="7" /><rect x="3" y="14" width="7" height="7" />`,
18
+ containers: `<rect x="2" y="2" width="20" height="8" rx="2" ry="2" /><rect x="2" y="14" width="20" height="8" rx="2" ry="2" /><line x1="6" y1="6" x2="6.01" y2="6" /><line x1="6" y1="18" x2="6.01" y2="18" />`,
19
+ logs: `<polyline points="4 17 10 11 4 5" /><line x1="12" y1="19" x2="20" y2="19" />`,
20
+ connections: `<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" /><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />`,
21
+ akm: `<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />`,
22
+ "host-sharing": `<circle cx="18" cy="5" r="3" /><circle cx="6" cy="12" r="3" /><circle cx="18" cy="19" r="3" /><line x1="8.59" y1="13.51" x2="15.42" y2="17.49" /><line x1="15.41" y1="6.51" x2="8.59" y2="10.49" />`,
23
+ voice: `<path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" /><path d="M19 10v2a7 7 0 0 1-14 0v-2" /><line x1="12" y1="19" x2="12" y2="23" /><line x1="8" y1="23" x2="16" y2="23" />`,
24
+ addons: `<path d="M12 2L2 7l10 5 10-5-10-5z" /><path d="M2 17l10 5 10-5" /><path d="M2 12l10 5 10-5" />`,
25
+ automations: `<circle cx="12" cy="12" r="10" /><polyline points="12 6 12 12 16 14" />`,
26
+ secrets: `<rect x="3" y="11" width="18" height="11" rx="2" ry="2" /><path d="M7 11V7a5 5 0 0 1 10 0v4" />`,
27
+ updates: `<polyline points="8 17 12 21 16 17" /><line x1="12" y1="12" x2="12" y2="21" /><path d="M20.88 18.09A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.29" />`
28
+ };
29
+ const SECTIONS = [
30
+ {
31
+ id: "health",
32
+ label: "Health",
33
+ tabs: [
34
+ {
35
+ id: "overview",
36
+ label: "Overview",
37
+ icon: ICONS.overview
38
+ },
39
+ {
40
+ id: "containers",
41
+ label: "Systems",
42
+ icon: ICONS.containers
43
+ },
44
+ {
45
+ id: "logs",
46
+ label: "Journal",
47
+ icon: ICONS.logs
48
+ },
49
+ {
50
+ id: "updates",
51
+ label: "Check-up",
52
+ icon: ICONS.updates
53
+ }
54
+ ]
55
+ },
56
+ {
57
+ id: "mind",
58
+ label: "Mind",
59
+ tabs: [{
60
+ id: "connections",
61
+ label: "AI Providers",
62
+ icon: ICONS.connections
63
+ }]
64
+ },
65
+ {
66
+ id: "voice",
67
+ label: "Voice",
68
+ tabs: [{
69
+ id: "voice",
70
+ label: "Voice",
71
+ icon: ICONS.voice
72
+ }]
73
+ },
74
+ {
75
+ id: "routines",
76
+ label: "Routines",
77
+ tabs: [{
78
+ id: "automations",
79
+ label: "Automations",
80
+ icon: ICONS.automations
81
+ }]
82
+ },
83
+ {
84
+ id: "capabilities",
85
+ label: "Capabilities",
86
+ tabs: [{
87
+ id: "addons",
88
+ label: "Add-ons",
89
+ icon: ICONS.addons
90
+ }]
91
+ },
92
+ {
93
+ id: "knowledge",
94
+ label: "Knowledge",
95
+ tabs: [
96
+ {
97
+ id: "akm",
98
+ label: "Memory",
99
+ icon: ICONS.akm
100
+ },
101
+ {
102
+ id: "secrets",
103
+ label: "Secrets",
104
+ icon: ICONS.secrets
105
+ },
106
+ {
107
+ id: "host-sharing",
108
+ label: "Sharing",
109
+ icon: ICONS["host-sharing"]
110
+ }
111
+ ]
112
+ }
113
+ ];
114
+ let activeSection = derived(() => SECTIONS.find((s) => s.tabs.some((t) => t.id === active)) ?? SECTIONS[0]);
115
+ $$renderer.push(`<nav class="nav-shell svelte-7673iv" aria-label="Admin sections"><div class="section-strip svelte-7673iv" role="tablist" aria-label="Sections"><!--[-->`);
116
+ const each_array = ensure_array_like(SECTIONS);
117
+ for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
118
+ let section = each_array[$$index];
119
+ $$renderer.push(`<button${attr_class("section-tab svelte-7673iv", void 0, { "section-tab-active": activeSection().id === section.id })} role="tab"${attr("aria-selected", activeSection().id === section.id)}>${escape_html(section.label)}</button>`);
120
+ }
121
+ $$renderer.push(`<!--]--></div> `);
122
+ if (activeSection().tabs.length > 1) {
123
+ $$renderer.push("<!--[0-->");
124
+ $$renderer.push(`<div class="subtab-row svelte-7673iv"><div class="tabs svelte-7673iv" role="tablist"${attr("aria-label", `${stringify(activeSection().label)} tabs`)}><!--[-->`);
125
+ const each_array_1 = ensure_array_like(activeSection().tabs);
126
+ for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
127
+ let tab = each_array_1[$$index_1];
128
+ $$renderer.push(`<button${attr_class("tab svelte-7673iv", void 0, { "tab-active": active === tab.id })} role="tab"${attr("aria-selected", active === tab.id)}><svg aria-hidden="true" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${html(tab.icon)}</svg> ${escape_html(tab.label)}</button>`);
129
+ }
130
+ $$renderer.push(`<!--]--></div></div>`);
131
+ } else $$renderer.push("<!--[-1-->");
132
+ $$renderer.push(`<!--]--></nav>`);
133
+ });
134
+ }
135
+ //#endregion
136
+ //#region src/lib/components/admin/overview/StatusHero.svelte
137
+ function StatusHero($$renderer, $$props) {
138
+ $$renderer.component(($$renderer) => {
139
+ let { status, title, detail, healthLoading, anyDangerousLoading} = $$props;
140
+ $$renderer.push(`<section${attr_class(`hero hero--${stringify(status)}`, "svelte-10n23hu")} role="status" aria-live="polite"><span class="hero-icon svelte-10n23hu" aria-hidden="true">`);
141
+ if (status === "warning") {
142
+ $$renderer.push("<!--[0-->");
143
+ $$renderer.push(`<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"></path><line x1="12" y1="9" x2="12" y2="13"></line><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>`);
144
+ } else if (status === "ok") {
145
+ $$renderer.push("<!--[1-->");
146
+ $$renderer.push(`<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>`);
147
+ } else {
148
+ $$renderer.push("<!--[-1-->");
149
+ $$renderer.push(`<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line></svg>`);
150
+ }
151
+ $$renderer.push(`<!--]--></span> <div class="hero-text svelte-10n23hu"><h2 class="hero-title svelte-10n23hu">${escape_html(title)}</h2> <p class="hero-detail svelte-10n23hu">${escape_html(detail)}</p></div> <div class="hero-actions svelte-10n23hu"><button class="btn btn-secondary"${attr("disabled", healthLoading, true)}>${escape_html(healthLoading ? "Checking…" : "Re-check")}</button> `);
152
+ if (status === "warning") {
153
+ $$renderer.push("<!--[0-->");
154
+ $$renderer.push(`<button class="btn btn-secondary">View containers</button>`);
155
+ } else $$renderer.push("<!--[-1-->");
156
+ $$renderer.push(`<!--]--> <button class="btn btn-secondary"${attr("disabled", anyDangerousLoading || false, true)}>${escape_html("Apply config & restart")}</button></div></section>`);
157
+ });
158
+ }
159
+ //#endregion
160
+ //#region src/lib/components/admin/overview/OperationOutput.svelte
161
+ function OperationOutput($$renderer, $$props) {
162
+ $$renderer.push("<!--[-1-->");
163
+ $$renderer.push(`<!--]-->`);
164
+ }
165
+ //#endregion
166
+ //#region src/lib/components/admin/overview/MetricTile.svelte
167
+ function MetricTile($$renderer, $$props) {
168
+ /** Primary metric value (rendered when no icon snippet is supplied). */
169
+ /** Secondary "/total" fragment shown next to the value. */
170
+ /** Whether enough data has loaded to show value/sub (else shows an em dash). */
171
+ /** Decorative icon, mutually exclusive with value. */
172
+ let { label, onClick, value = null, sub = null, loaded = true, icon } = $$props;
173
+ $$renderer.push(`<button class="tile svelte-19hpfg">`);
174
+ if (icon) {
175
+ $$renderer.push("<!--[0-->");
176
+ $$renderer.push(`<span class="tile-metric tile-metric--icon svelte-19hpfg" aria-hidden="true">`);
177
+ icon($$renderer);
178
+ $$renderer.push(`<!----></span>`);
179
+ } else {
180
+ $$renderer.push("<!--[-1-->");
181
+ $$renderer.push(`<span class="tile-metric svelte-19hpfg">`);
182
+ if (loaded) {
183
+ $$renderer.push("<!--[0-->");
184
+ $$renderer.push(`${escape_html(value)}`);
185
+ if (sub) {
186
+ $$renderer.push("<!--[0-->");
187
+ $$renderer.push(`<span class="tile-metric-sub svelte-19hpfg">${escape_html(sub)}</span>`);
188
+ } else $$renderer.push("<!--[-1-->");
189
+ $$renderer.push(`<!--]-->`);
190
+ } else {
191
+ $$renderer.push("<!--[-1-->");
192
+ $$renderer.push(`—`);
193
+ }
194
+ $$renderer.push(`<!--]--></span>`);
195
+ }
196
+ $$renderer.push(`<!--]--> <span class="tile-label svelte-19hpfg">${escape_html(label)}</span></button>`);
197
+ }
198
+ //#endregion
199
+ //#region src/lib/components/admin/overview/AkmHealthCard.svelte
200
+ function AkmHealthCard($$renderer, $$props) {
201
+ $$renderer.component(($$renderer) => {
202
+ let { badge} = $$props;
203
+ $$renderer.push(`<button class="akm-card svelte-dcgqe1" aria-label="AKM health — open Knowledge settings"><div class="akm-head svelte-dcgqe1"><span class="akm-title svelte-dcgqe1">AKM runtime health</span> <span${attr_class(`badge ${stringify(badge.cls)}`, "svelte-dcgqe1")}>${escape_html(badge.label)}</span></div> `);
204
+ {
205
+ $$renderer.push("<!--[-1-->");
206
+ $$renderer.push(`<p class="akm-unavailable svelte-dcgqe1">Metrics unavailable — the akm CLI isn't reachable from the admin host.</p>`);
207
+ }
208
+ $$renderer.push(`<!--]--></button>`);
209
+ });
210
+ }
211
+ //#endregion
212
+ //#region src/lib/components/admin/overview/ConfigureShortcuts.svelte
213
+ function ConfigureShortcuts($$renderer, $$props) {
214
+ $$renderer.component(($$renderer) => {
215
+ $$renderer.push(`<div class="shortcut-grid svelte-8y2vdf"><button class="shortcut svelte-8y2vdf"><span class="shortcut-name svelte-8y2vdf">AI Providers</span> <span class="shortcut-desc svelte-8y2vdf">Models &amp; provider credentials</span></button> <button class="shortcut svelte-8y2vdf"><span class="shortcut-name svelte-8y2vdf">Knowledge</span> <span class="shortcut-desc svelte-8y2vdf">Assistant memory &amp; behavior</span></button> <button class="shortcut svelte-8y2vdf"><span class="shortcut-name svelte-8y2vdf">Voice</span> <span class="shortcut-desc svelte-8y2vdf">Speech-to-text &amp; text-to-speech</span></button> <button class="shortcut svelte-8y2vdf"><span class="shortcut-name svelte-8y2vdf">Channels &amp; add-ons</span> <span class="shortcut-desc svelte-8y2vdf">Discord, Slack, API &amp; more</span></button> <button class="shortcut svelte-8y2vdf"><span class="shortcut-name svelte-8y2vdf">Secrets</span> <span class="shortcut-desc svelte-8y2vdf">Stack &amp; channel credentials</span></button> <a class="shortcut svelte-8y2vdf" href="/setup?rerun=1"><span class="shortcut-name svelte-8y2vdf">Re-run setup</span> <span class="shortcut-desc svelte-8y2vdf">Walk through the setup wizard again</span></a></div>`);
216
+ });
217
+ }
218
+ //#endregion
219
+ //#region src/lib/components/admin/overview/OverviewTab.svelte
220
+ function OverviewTab($$renderer, $$props) {
221
+ $$renderer.component(($$renderer) => {
222
+ let { healthLoading, anyDangerousLoading, mergedServices, onNavigate } = $$props;
223
+ let akmBadge = derived(() => {
224
+ return {
225
+ label: "Unavailable",
226
+ cls: "badge-neutral"
227
+ };
228
+ });
229
+ let akmCheckTotal = derived(() => 0);
230
+ let containerCounts = derived(() => {
231
+ if (mergedServices.size === 0) return null;
232
+ return {
233
+ total: mergedServices.size,
234
+ running: [...mergedServices.values()].filter((s) => s === "running").length
235
+ };
236
+ });
237
+ let downServices = derived(() => {
238
+ const out = [];
239
+ for (const [name, status] of mergedServices) if (status !== "running") out.push(name);
240
+ return out;
241
+ });
242
+ let health = derived(() => {
243
+ if (!containerCounts()) return {
244
+ status: "unknown",
245
+ title: "Checking services…",
246
+ detail: "Fetching the latest status from Docker."
247
+ };
248
+ if (containerCounts().running === containerCounts().total && containerCounts().total > 0) return {
249
+ status: "ok",
250
+ title: "All systems operational",
251
+ detail: `${containerCounts().total} of ${containerCounts().total} services are running normally.`
252
+ };
253
+ const down = containerCounts().total - containerCounts().running;
254
+ const names = downServices().map((n) => n.charAt(0).toUpperCase() + n.slice(1)).join(", ");
255
+ return {
256
+ status: "warning",
257
+ title: `${down} of ${containerCounts().total} services not running`,
258
+ detail: names ? `Not running: ${names}.` : "One or more services need attention."
259
+ };
260
+ });
261
+ if (health().status !== "ok") {
262
+ $$renderer.push("<!--[0-->");
263
+ StatusHero($$renderer, {
264
+ status: health().status,
265
+ title: health().title,
266
+ detail: health().detail,
267
+ healthLoading,
268
+ anyDangerousLoading});
269
+ } else $$renderer.push("<!--[-1-->");
270
+ $$renderer.push(`<!--]--> `);
271
+ OperationOutput($$renderer);
272
+ $$renderer.push(`<!----> <div class="tile-grid svelte-xz862u">`);
273
+ MetricTile($$renderer, {
274
+ label: "Services running",
275
+ onClick: () => onNavigate("containers"),
276
+ value: containerCounts()?.running,
277
+ sub: containerCounts() ? `/${containerCounts().total}` : null,
278
+ loaded: !!containerCounts()
279
+ });
280
+ $$renderer.push(`<!----> `);
281
+ {
282
+ function icon($$renderer) {
283
+ $$renderer.push(`<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5"></polyline><line x1="12" y1="19" x2="20" y2="19"></line></svg>`);
284
+ }
285
+ MetricTile($$renderer, {
286
+ label: "View logs",
287
+ onClick: () => onNavigate("logs"),
288
+ icon});
289
+ }
290
+ $$renderer.push(`<!----> `);
291
+ {
292
+ function icon($$renderer) {
293
+ $$renderer.push(`<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="8 17 12 21 16 17"></polyline><line x1="12" y1="12" x2="12" y2="21"></line><path d="M20.88 18.09A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.29"></path></svg>`);
294
+ }
295
+ MetricTile($$renderer, {
296
+ label: "Check for updates",
297
+ onClick: () => onNavigate("updates"),
298
+ icon});
299
+ }
300
+ $$renderer.push(`<!----></div> <h3 class="section-heading svelte-xz862u">Knowledge base (AKM)</h3> `);
301
+ AkmHealthCard($$renderer, {
302
+ badge: akmBadge(),
303
+ checkTotal: akmCheckTotal()});
304
+ $$renderer.push(`<!----> <h3 class="section-heading svelte-xz862u">Configure</h3> `);
305
+ ConfigureShortcuts($$renderer);
306
+ $$renderer.push(`<!---->`);
307
+ });
308
+ }
309
+ //#endregion
310
+ //#region src/lib/components/admin/updates/UpdatesTab.svelte
311
+ function UpdatesTab($$renderer, $$props) {
312
+ $$renderer.component(($$renderer) => {
313
+ let { currentImageTag, selectedImageTag, tagChangeLoading, anyDangerousLoading, inElectron, uiVersions, uiVersionsLoading, selectedUiTag, uiDownloadLoading, releases, releasesLoading, onSelectedImageTagChange, onSelectedUiTagChange} = $$props;
314
+ function uiVersionLabel(v) {
315
+ const tags = [];
316
+ if (v.distTag) tags.push(v.distTag);
317
+ else if (v.prerelease) tags.push("pre-release");
318
+ return tags.length ? `${v.version} (${tags.join(", ")})` : v.version;
319
+ }
320
+ $$renderer.push(`<div class="panel svelte-7mkeya" role="tabpanel"><div class="panel-header svelte-7mkeya"><div class="svelte-7mkeya"><h2 class="svelte-7mkeya">Updates</h2> <p class="panel-subtitle svelte-7mkeya">Pull new stack images, upgrade to the latest release, and update the UI.</p></div></div> <div class="panel-body svelte-7mkeya"><div class="version-section svelte-7mkeya"><div class="version-row svelte-7mkeya"><span class="version-label svelte-7mkeya">Stack images</span> <code class="version-value svelte-7mkeya">${escape_html(currentImageTag || "—")}</code></div> <div class="version-input-row svelte-7mkeya">`);
321
+ if (releasesLoading) {
322
+ $$renderer.push("<!--[0-->");
323
+ $$renderer.push(`<div class="version-select-skeleton svelte-7mkeya"></div>`);
324
+ } else if (releases.length > 0) {
325
+ $$renderer.push("<!--[1-->");
326
+ $$renderer.select({
327
+ class: "version-select",
328
+ value: selectedImageTag,
329
+ onchange: (e) => onSelectedImageTagChange(e.currentTarget.value),
330
+ disabled: tagChangeLoading || anyDangerousLoading
331
+ }, ($$renderer) => {
332
+ $$renderer.option({
333
+ value: "latest",
334
+ class: ""
335
+ }, ($$renderer) => {
336
+ $$renderer.push(`latest`);
337
+ }, "svelte-7mkeya");
338
+ $$renderer.push(`<!--[-->`);
339
+ const each_array = ensure_array_like(releases);
340
+ for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
341
+ let r = each_array[$$index];
342
+ $$renderer.option({
343
+ value: r.tag,
344
+ class: ""
345
+ }, ($$renderer) => {
346
+ $$renderer.push(`${escape_html(r.tag)}${escape_html(r.prerelease ? " (pre-release)" : "")}`);
347
+ }, "svelte-7mkeya");
348
+ }
349
+ $$renderer.push(`<!--]-->`);
350
+ }, "svelte-7mkeya");
351
+ } else {
352
+ $$renderer.push("<!--[-1-->");
353
+ $$renderer.push(`<input class="version-input svelte-7mkeya" type="text" placeholder="e.g. 0.11.0 or latest"${attr("value", selectedImageTag)}${attr("disabled", tagChangeLoading || anyDangerousLoading, true)}/>`);
354
+ }
355
+ $$renderer.push(`<!--]--> <button class="btn btn-sm btn-primary svelte-7mkeya"${attr("disabled", !selectedImageTag.trim() || tagChangeLoading || anyDangerousLoading, true)}>`);
356
+ if (tagChangeLoading) {
357
+ $$renderer.push("<!--[0-->");
358
+ Spinner($$renderer, {});
359
+ $$renderer.push(`<!----> Applying…`);
360
+ } else {
361
+ $$renderer.push("<!--[-1-->");
362
+ $$renderer.push(`Pull &amp; Restart`);
363
+ }
364
+ $$renderer.push(`<!--]--></button></div> <p class="version-hint svelte-7mkeya">Pulls the selected images and restarts services.</p></div> <div class="version-divider svelte-7mkeya"></div> <div class="version-section svelte-7mkeya"><div class="version-row svelte-7mkeya"><span class="version-label svelte-7mkeya">Upgrade Stack</span></div> <div class="version-input-row svelte-7mkeya"><button class="btn btn-sm btn-secondary svelte-7mkeya"${attr("disabled", anyDangerousLoading || false, true)}>`);
365
+ {
366
+ $$renderer.push("<!--[-1-->");
367
+ $$renderer.push(`Upgrade to Latest`);
368
+ }
369
+ $$renderer.push(`<!--]--></button></div> <p class="version-hint svelte-7mkeya">Downloads the latest assets, pulls images, and restarts services. Backs up current config first.</p></div> `);
370
+ if (inElectron) {
371
+ $$renderer.push("<!--[0-->");
372
+ $$renderer.push(`<div class="version-divider svelte-7mkeya"></div> <div class="version-section svelte-7mkeya"><div class="version-row svelte-7mkeya"><span class="version-label svelte-7mkeya">UI Version</span></div> <div class="version-input-row svelte-7mkeya">`);
373
+ if (uiVersionsLoading) {
374
+ $$renderer.push("<!--[0-->");
375
+ $$renderer.push(`<div class="version-select-skeleton svelte-7mkeya"></div>`);
376
+ } else if (uiVersions.length > 0) {
377
+ $$renderer.push("<!--[1-->");
378
+ $$renderer.select({
379
+ class: "version-select",
380
+ value: selectedUiTag,
381
+ onchange: (e) => onSelectedUiTagChange(e.currentTarget.value),
382
+ disabled: uiDownloadLoading
383
+ }, ($$renderer) => {
384
+ $$renderer.push(`<!--[-->`);
385
+ const each_array_1 = ensure_array_like(uiVersions);
386
+ for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
387
+ let v = each_array_1[$$index_1];
388
+ $$renderer.option({
389
+ value: v.version,
390
+ class: ""
391
+ }, ($$renderer) => {
392
+ $$renderer.push(`${escape_html(uiVersionLabel(v))}`);
393
+ }, "svelte-7mkeya");
394
+ }
395
+ $$renderer.push(`<!--]-->`);
396
+ }, "svelte-7mkeya");
397
+ } else {
398
+ $$renderer.push("<!--[-1-->");
399
+ $$renderer.push(`<input class="version-input svelte-7mkeya" type="text" placeholder="e.g. 0.11.0-beta.7"${attr("value", selectedUiTag)}${attr("disabled", uiDownloadLoading, true)}/>`);
400
+ }
401
+ $$renderer.push(`<!--]--> <button class="btn btn-sm svelte-7mkeya"${attr("disabled", !selectedUiTag.trim() || uiDownloadLoading, true)}>`);
402
+ if (uiDownloadLoading) {
403
+ $$renderer.push("<!--[0-->");
404
+ Spinner($$renderer, {});
405
+ $$renderer.push(`<!----> Downloading…`);
406
+ } else {
407
+ $$renderer.push("<!--[-1-->");
408
+ $$renderer.push(`Download`);
409
+ }
410
+ $$renderer.push(`<!--]--></button></div> `);
411
+ {
412
+ $$renderer.push("<!--[-1-->");
413
+ $$renderer.push(`<p class="version-hint svelte-7mkeya">Downloads and replaces the UI from GitHub. Takes effect on restart.</p>`);
414
+ }
415
+ $$renderer.push(`<!--]--></div>`);
416
+ } else $$renderer.push("<!--[-1-->");
417
+ $$renderer.push(`<!--]--></div></div>`);
418
+ });
419
+ }
420
+ //#endregion
421
+ //#region src/lib/components/common/EmptyState.svelte
422
+ function EmptyState($$renderer, $$props) {
423
+ /** Icon markup (typically an inline SVG). */
424
+ /** Message body (paragraphs, hints, etc.). */
425
+ /** Optional action(s) — buttons/links shown below the message. */
426
+ let { icon, children, action } = $$props;
427
+ $$renderer.push(`<div class="empty-state svelte-1dv4ads">`);
428
+ if (icon) {
429
+ $$renderer.push("<!--[0-->");
430
+ icon($$renderer);
431
+ $$renderer.push(`<!---->`);
432
+ } else $$renderer.push("<!--[-1-->");
433
+ $$renderer.push(`<!--]--> `);
434
+ children($$renderer);
435
+ $$renderer.push(`<!----> `);
436
+ if (action) {
437
+ $$renderer.push("<!--[0-->");
438
+ action($$renderer);
439
+ $$renderer.push(`<!---->`);
440
+ } else $$renderer.push("<!--[-1-->");
441
+ $$renderer.push(`<!--]--></div>`);
442
+ }
443
+ //#endregion
444
+ //#region src/lib/components/addons/AddonsTab.svelte
445
+ function AddonsTab($$renderer, $$props) {
446
+ $$renderer.component(($$renderer) => {
447
+ const ADDON_ACRONYMS = {
448
+ api: "API",
449
+ ssh: "SSH",
450
+ ui: "UI"
451
+ };
452
+ function formatAddonName(name) {
453
+ return name.split(/[-_]/).filter(Boolean).map((w) => ADDON_ACRONYMS[w.toLowerCase()] ?? w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
454
+ }
455
+ let addons = [];
456
+ let loading = false;
457
+ let actionLoading = null;
458
+ let $$settled = true;
459
+ let $$inner_renderer;
460
+ function $$render_inner($$renderer) {
461
+ $$renderer.push(`<div class="panel" role="tabpanel"><div class="panel-header"><div><h2>Addons</h2> <p class="panel-subtitle">Optional features you can enable or disable. Credentials are written to the stack config and applied when the addon container restarts.</p></div> <button class="btn btn-secondary btn-sm"${attr("disabled", loading, true)}>`);
462
+ $$renderer.push("<!--[-1-->");
463
+ $$renderer.push(`<!--]--> Refresh</button></div> <div class="panel-body panel-body--flush">`);
464
+ if (addons.length === 0) {
465
+ $$renderer.push("<!--[2-->");
466
+ {
467
+ function icon($$renderer) {
468
+ $$renderer.push(`<svg aria-hidden="true" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2L2 7l10 5 10-5-10-5z"></path><path d="M2 17l10 5 10-5"></path><path d="M2 12l10 5 10-5"></path></svg>`);
469
+ }
470
+ EmptyState($$renderer, {
471
+ icon,
472
+ children: ($$renderer) => {
473
+ $$renderer.push(`<p>No addons found in registry/addons/.</p>`);
474
+ }});
475
+ }
476
+ } else {
477
+ $$renderer.push("<!--[-1-->");
478
+ $$renderer.push(`<div class="addon-table svelte-87zh26"><div class="addon-table-header svelte-87zh26"><span class="addon-col addon-col--name svelte-87zh26">Addon</span> <span class="addon-col addon-col--status svelte-87zh26">Status</span> <span class="addon-col addon-col--actions svelte-87zh26"></span></div> <!--[-->`);
479
+ const each_array = ensure_array_like(addons);
480
+ for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
481
+ let addon = each_array[$$index];
482
+ $$renderer.push(`<div class="addon-row svelte-87zh26"><span class="addon-col addon-col--name addon-name svelte-87zh26"${attr("title", addon.name)}>${escape_html(formatAddonName(addon.name))}</span> <span class="addon-col addon-col--status svelte-87zh26"><span${attr_class("badge", void 0, {
483
+ "badge-enabled": addon.enabled,
484
+ "badge-disabled": !addon.enabled
485
+ })}>${escape_html(addon.enabled ? "Enabled" : "Disabled")}</span></span> <span class="addon-col addon-col--actions svelte-87zh26">`);
486
+ if (addon.name === "voice" && addon.enabled) {
487
+ $$renderer.push("<!--[0-->");
488
+ $$renderer.push(`<button class="btn btn-sm btn-secondary" aria-label="Configure Voice addon settings">Configure</button>`);
489
+ } else {
490
+ $$renderer.push("<!--[-1-->");
491
+ $$renderer.push(`<button class="btn btn-sm btn-secondary"${attr("disabled", !addon.available, true)}>Credentials</button>`);
492
+ }
493
+ $$renderer.push(`<!--]--> <button${attr_class("btn btn-sm", void 0, {
494
+ "btn-danger": addon.enabled,
495
+ "btn-outline": !addon.enabled
496
+ })}${attr("disabled", actionLoading === addon.name || !addon.available, true)}>`);
497
+ if (actionLoading === addon.name) {
498
+ $$renderer.push("<!--[0-->");
499
+ Spinner($$renderer, {});
500
+ } else {
501
+ $$renderer.push("<!--[-1-->");
502
+ $$renderer.push(`${escape_html(addon.enabled ? "Disable" : "Enable")}`);
503
+ }
504
+ $$renderer.push(`<!--]--></button></span></div>`);
505
+ }
506
+ $$renderer.push(`<!--]--></div>`);
507
+ }
508
+ $$renderer.push(`<!--]--></div> `);
509
+ $$renderer.push("<!--[-1-->");
510
+ $$renderer.push(`<!--]--></div>`);
511
+ }
512
+ do {
513
+ $$settled = true;
514
+ $$inner_renderer = $$renderer.copy();
515
+ $$render_inner($$inner_renderer);
516
+ } while (!$$settled);
517
+ $$renderer.subsume($$inner_renderer);
518
+ });
519
+ }
520
+ //#endregion
521
+ //#region src/lib/components/common/Panel.svelte
522
+ function Panel($$renderer, $$props) {
523
+ /** Heading text rendered in the panel header. */
524
+ /** Action button(s) shown at the right of the header. */
525
+ /** Panel content below the header (typically a `.panel-body`). */
526
+ /** ARIA role for the panel container (e.g. "tabpanel"). */
527
+ let { title, actions, children, role } = $$props;
528
+ $$renderer.push(`<div class="panel"${attr("role", role)}><div class="panel-header"><h2>${escape_html(title)}</h2> `);
529
+ if (actions) {
530
+ $$renderer.push("<!--[0-->");
531
+ $$renderer.push(`<div class="panel-header-actions">`);
532
+ actions($$renderer);
533
+ $$renderer.push(`<!----></div>`);
534
+ } else $$renderer.push("<!--[-1-->");
535
+ $$renderer.push(`<!--]--></div> `);
536
+ children($$renderer);
537
+ $$renderer.push(`<!----></div>`);
538
+ }
539
+ //#endregion
540
+ //#region src/lib/components/admin/containers/container-format.ts
541
+ function parseImageTag(image) {
542
+ const atIdx = image.indexOf("@");
543
+ const base = atIdx > -1 ? image.slice(0, atIdx) : image;
544
+ const colonIdx = base.lastIndexOf(":");
545
+ if (colonIdx > -1) return {
546
+ name: base.slice(0, colonIdx),
547
+ tag: base.slice(colonIdx + 1)
548
+ };
549
+ return {
550
+ name: base,
551
+ tag: "latest"
552
+ };
553
+ }
554
+ function containerStatusColor(state) {
555
+ if (state === "running") return "success";
556
+ if (state === "exited" || state === "dead" || state === "stopped") return "danger";
557
+ if (state === "restarting" || state === "paused") return "warning";
558
+ return "idle";
559
+ }
560
+ function fmtState(s) {
561
+ if (!s) return s ?? "";
562
+ return s.charAt(0).toUpperCase() + s.slice(1);
563
+ }
564
+ //#endregion
565
+ //#region src/lib/components/admin/containers/ContainerRow.svelte
566
+ function ContainerRow($$renderer, $$props) {
567
+ $$renderer.component(($$renderer) => {
568
+ let { entry, selected} = $$props;
569
+ let img = derived(() => entry.docker ? parseImageTag(entry.docker.Image) : null);
570
+ $$renderer.push(`<button class="container-table-row container-table-row--clickable svelte-1clpuus"${attr("aria-expanded", selected)}><span class="ct-col ct-col--name"><span${attr_class(`ct-indicator ct-indicator--${stringify(containerStatusColor(entry.state))}`, "svelte-1clpuus")}></span> <span class="ct-service-name svelte-1clpuus">${escape_html(entry.service)}</span></span> <span class="ct-col ct-col--image ct-mono svelte-1clpuus">`);
571
+ if (img()) {
572
+ $$renderer.push("<!--[0-->");
573
+ $$renderer.push(`${escape_html(img().name)}`);
574
+ } else {
575
+ $$renderer.push("<!--[-1-->");
576
+ $$renderer.push(`<span class="ct-not-created svelte-1clpuus">--</span>`);
577
+ }
578
+ $$renderer.push(`<!--]--></span> <span class="ct-col ct-col--tag">`);
579
+ if (img()) {
580
+ $$renderer.push("<!--[0-->");
581
+ $$renderer.push(`<span class="tag-badge">${escape_html(img().tag)}</span>`);
582
+ } else {
583
+ $$renderer.push("<!--[-1-->");
584
+ $$renderer.push(`<span class="ct-not-created svelte-1clpuus">--</span>`);
585
+ }
586
+ $$renderer.push(`<!--]--></span> <span class="ct-col ct-col--status"><span${attr_class(`badge badge-${stringify(containerStatusColor(entry.state))}`, "svelte-1clpuus")}>${escape_html(fmtState(entry.state))}</span></span> <span class="ct-col ct-col--actions"><svg aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"${attr_class("svelte-1clpuus", void 0, { "ct-chevron-open": selected })}><polyline points="6 9 12 15 18 9"></polyline></svg></span></button>`);
587
+ });
588
+ }
589
+ //#endregion
590
+ //#region src/lib/components/admin/containers/ContainerDetail.svelte
591
+ function ContainerDetail($$renderer, $$props) {
592
+ $$renderer.component(($$renderer) => {
593
+ let { entry, actionInFlight, confirmAction, feedback} = $$props;
594
+ let img = derived(() => entry.docker ? parseImageTag(entry.docker.Image) : null);
595
+ let isAnyActionInFlight = derived(() => actionInFlight !== null);
596
+ let isNotCreated = derived(() => !entry.docker);
597
+ $$renderer.push(`<div class="container-detail svelte-17lh9yz">`);
598
+ if (entry.docker) {
599
+ $$renderer.push("<!--[0-->");
600
+ const container = entry.docker;
601
+ $$renderer.push(`<div class="detail-grid svelte-17lh9yz"><div class="detail-item svelte-17lh9yz"><span class="detail-label svelte-17lh9yz">Container ID</span> <span class="detail-value detail-mono svelte-17lh9yz">${escape_html(container.ID)}</span></div> <div class="detail-item svelte-17lh9yz"><span class="detail-label svelte-17lh9yz">Name</span> <span class="detail-value detail-mono svelte-17lh9yz">${escape_html(container.Name || container.Names)}</span></div> <div class="detail-item svelte-17lh9yz"><span class="detail-label svelte-17lh9yz">Image</span> <span class="detail-value detail-mono svelte-17lh9yz">${escape_html(container.Image)}</span></div> `);
602
+ if (img()) {
603
+ $$renderer.push("<!--[0-->");
604
+ $$renderer.push(`<div class="detail-item svelte-17lh9yz"><span class="detail-label svelte-17lh9yz">Image Name</span> <span class="detail-value detail-mono svelte-17lh9yz">${escape_html(img().name)}</span></div> <div class="detail-item svelte-17lh9yz"><span class="detail-label svelte-17lh9yz">Tag / Digest</span> <span class="detail-value svelte-17lh9yz"><span class="tag-badge tag-badge--lg">${escape_html(img().tag)}</span> `);
605
+ if (container.Image.includes("@")) {
606
+ $$renderer.push("<!--[0-->");
607
+ $$renderer.push(`<span class="detail-mono detail-digest svelte-17lh9yz">${escape_html(container.Image.split("@")[1]?.slice(0, 19))}...</span>`);
608
+ } else $$renderer.push("<!--[-1-->");
609
+ $$renderer.push(`<!--]--></span></div>`);
610
+ } else $$renderer.push("<!--[-1-->");
611
+ $$renderer.push(`<!--]--> <div class="detail-item svelte-17lh9yz"><span class="detail-label svelte-17lh9yz">State</span> <span class="detail-value svelte-17lh9yz"><span${attr_class(`badge badge-${stringify(containerStatusColor(container.State))}`, "svelte-17lh9yz")}>${escape_html(fmtState(container.State))}</span></span></div> <div class="detail-item svelte-17lh9yz"><span class="detail-label svelte-17lh9yz">Status</span> <span class="detail-value svelte-17lh9yz">${escape_html(container.Status)}</span></div> `);
612
+ if (container.Health) {
613
+ $$renderer.push("<!--[0-->");
614
+ $$renderer.push(`<div class="detail-item svelte-17lh9yz"><span class="detail-label svelte-17lh9yz">Health</span> <span class="detail-value svelte-17lh9yz"><span${attr_class("badge", void 0, {
615
+ "badge-success": container.Health === "healthy",
616
+ "badge-warning": container.Health === "starting",
617
+ "badge-danger": container.Health === "unhealthy",
618
+ "badge-idle": ![
619
+ "healthy",
620
+ "starting",
621
+ "unhealthy"
622
+ ].includes(container.Health)
623
+ })}>${escape_html(container.Health)}</span></span></div>`);
624
+ } else $$renderer.push("<!--[-1-->");
625
+ $$renderer.push(`<!--]--> `);
626
+ if (container.Ports) {
627
+ $$renderer.push("<!--[0-->");
628
+ $$renderer.push(`<div class="detail-item svelte-17lh9yz"><span class="detail-label svelte-17lh9yz">Ports</span> <span class="detail-value detail-mono svelte-17lh9yz">${escape_html(container.Ports)}</span></div>`);
629
+ } else $$renderer.push("<!--[-1-->");
630
+ $$renderer.push(`<!--]--> `);
631
+ if (container.RunningFor) {
632
+ $$renderer.push("<!--[0-->");
633
+ $$renderer.push(`<div class="detail-item svelte-17lh9yz"><span class="detail-label svelte-17lh9yz">Uptime</span> <span class="detail-value svelte-17lh9yz">${escape_html(container.RunningFor)}</span></div>`);
634
+ } else $$renderer.push("<!--[-1-->");
635
+ $$renderer.push(`<!--]--> `);
636
+ if (container.CreatedAt) {
637
+ $$renderer.push("<!--[0-->");
638
+ $$renderer.push(`<div class="detail-item svelte-17lh9yz"><span class="detail-label svelte-17lh9yz">Created</span> <span class="detail-value svelte-17lh9yz">${escape_html(container.CreatedAt)}</span></div>`);
639
+ } else $$renderer.push("<!--[-1-->");
640
+ $$renderer.push(`<!--]--> `);
641
+ if (container.Project) {
642
+ $$renderer.push("<!--[0-->");
643
+ $$renderer.push(`<div class="detail-item svelte-17lh9yz"><span class="detail-label svelte-17lh9yz">Project</span> <span class="detail-value detail-mono svelte-17lh9yz">${escape_html(container.Project)}</span></div>`);
644
+ } else $$renderer.push("<!--[-1-->");
645
+ $$renderer.push(`<!--]--></div>`);
646
+ } else {
647
+ $$renderer.push("<!--[-1-->");
648
+ $$renderer.push(`<div class="detail-not-created svelte-17lh9yz"><p class="svelte-17lh9yz">Container has not been created yet. Use <strong>Start</strong> to create and start it.</p></div>`);
649
+ }
650
+ $$renderer.push(`<!--]--> `);
651
+ if (feedback) {
652
+ $$renderer.push("<!--[0-->");
653
+ $$renderer.push(`<div${attr_class(`action-feedback action-feedback--${stringify(feedback.type)}`, "svelte-17lh9yz")} role="status">${escape_html(feedback.message)}</div>`);
654
+ } else $$renderer.push("<!--[-1-->");
655
+ $$renderer.push(`<!--]--> `);
656
+ if (confirmAction) {
657
+ $$renderer.push("<!--[0-->");
658
+ $$renderer.push(`<div class="confirm-bar svelte-17lh9yz" role="alert"><span class="confirm-text svelte-17lh9yz">${escape_html(confirmAction.charAt(0).toUpperCase() + confirmAction.slice(1))} <strong>${escape_html(entry.service)}</strong>?</span> <div class="confirm-actions svelte-17lh9yz"><button class="btn btn-danger btn-sm">Confirm</button> <button class="btn btn-secondary btn-sm">Cancel</button></div></div>`);
659
+ } else {
660
+ $$renderer.push("<!--[-1-->");
661
+ $$renderer.push(`<div class="detail-actions svelte-17lh9yz">`);
662
+ if (isNotCreated()) {
663
+ $$renderer.push("<!--[0-->");
664
+ $$renderer.push(`<button class="btn btn-primary btn-sm"${attr("disabled", isAnyActionInFlight(), true)}>`);
665
+ if (actionInFlight === "start") {
666
+ $$renderer.push("<!--[0-->");
667
+ Spinner($$renderer, { size: 12 });
668
+ } else $$renderer.push("<!--[-1-->");
669
+ $$renderer.push(`<!--]--> Start</button>`);
670
+ } else {
671
+ $$renderer.push("<!--[-1-->");
672
+ $$renderer.push(`<button class="btn btn-secondary btn-sm"${attr("disabled", isAnyActionInFlight(), true)}>`);
673
+ if (actionInFlight === "start") {
674
+ $$renderer.push("<!--[0-->");
675
+ Spinner($$renderer, { size: 12 });
676
+ } else $$renderer.push("<!--[-1-->");
677
+ $$renderer.push(`<!--]--> Start</button> <button class="btn btn-danger btn-sm"${attr("disabled", isAnyActionInFlight(), true)}>`);
678
+ if (actionInFlight === "stop") {
679
+ $$renderer.push("<!--[0-->");
680
+ Spinner($$renderer, { size: 12 });
681
+ } else $$renderer.push("<!--[-1-->");
682
+ $$renderer.push(`<!--]--> Stop</button> <button class="btn btn-secondary btn-sm"${attr("disabled", isAnyActionInFlight(), true)}>`);
683
+ if (actionInFlight === "restart") {
684
+ $$renderer.push("<!--[0-->");
685
+ Spinner($$renderer, { size: 12 });
686
+ } else $$renderer.push("<!--[-1-->");
687
+ $$renderer.push(`<!--]--> Restart</button>`);
688
+ }
689
+ $$renderer.push(`<!--]--></div>`);
690
+ }
691
+ $$renderer.push(`<!--]--></div>`);
692
+ });
693
+ }
694
+ //#endregion
695
+ //#region src/lib/components/admin/containers/ContainersEmptyState.svelte
696
+ function ContainersEmptyState($$renderer, $$props) {
697
+ $$renderer.component(($$renderer) => {
698
+ let { loading, error, containerData} = $$props;
699
+ $$renderer.push(`<div class="empty-state svelte-llpoy7"><svg aria-hidden="true" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"></rect><rect x="2" y="14" width="20" height="8" rx="2" ry="2"></rect><line x1="6" y1="6" x2="6.01" y2="6"></line><line x1="6" y1="18" x2="6.01" y2="18"></line></svg> `);
700
+ if (loading) {
701
+ $$renderer.push("<!--[0-->");
702
+ $$renderer.push(`<p>Loading container status...</p>`);
703
+ } else if (error) {
704
+ $$renderer.push("<!--[1-->");
705
+ $$renderer.push(`<p class="text-danger svelte-llpoy7">${escape_html(error)}</p> <button class="btn btn-secondary btn-sm svelte-llpoy7"${attr("disabled", false, true)}>Try Again</button>`);
706
+ } else if (containerData && !containerData.dockerAvailable) {
707
+ $$renderer.push("<!--[2-->");
708
+ $$renderer.push(`<p>Docker is not available on this host.</p> <p class="hint svelte-llpoy7">Ensure Docker is running and the admin service has access to the Docker socket.</p>`);
709
+ } else {
710
+ $$renderer.push("<!--[-1-->");
711
+ $$renderer.push(`<p>No containers found. Services may not be installed yet.</p>`);
712
+ }
713
+ $$renderer.push(`<!--]--></div>`);
714
+ });
715
+ }
716
+ //#endregion
717
+ //#region src/lib/components/admin/containers/ContainersTab.svelte
718
+ function ContainersTab($$renderer, $$props) {
719
+ $$renderer.component(($$renderer) => {
720
+ let { containerData, serviceEntries, loading, error, selectedContainerId, lastUpdated} = $$props;
721
+ let hasEntries = derived(() => serviceEntries.length > 0);
722
+ let rowState = {};
723
+ {
724
+ function actions($$renderer) {
725
+ if (lastUpdated) {
726
+ $$renderer.push("<!--[0-->");
727
+ $$renderer.push(`<span class="last-updated svelte-fnc5b8">Updated ${escape_html(lastUpdated)}</span>`);
728
+ } else $$renderer.push("<!--[-1-->");
729
+ $$renderer.push(`<!--]--> <button class="btn btn-secondary btn-sm"${attr("disabled", false, true)}>`);
730
+ $$renderer.push("<!--[-1-->");
731
+ $$renderer.push(`<!--]--> Pull Images</button> <button class="btn btn-secondary btn-sm"${attr("disabled", loading || false, true)}>`);
732
+ if (loading) {
733
+ $$renderer.push("<!--[0-->");
734
+ Spinner($$renderer, {});
735
+ } else $$renderer.push("<!--[-1-->");
736
+ $$renderer.push(`<!--]--> Refresh</button>`);
737
+ }
738
+ Panel($$renderer, {
739
+ title: "Container Status",
740
+ role: "tabpanel",
741
+ actions,
742
+ children: ($$renderer) => {
743
+ $$renderer.push(`<div class="panel-body panel-body--flush">`);
744
+ if (hasEntries()) {
745
+ $$renderer.push("<!--[0-->");
746
+ $$renderer.push(`<div class="container-table svelte-fnc5b8"><div class="container-table-header svelte-fnc5b8"><span class="ct-col ct-col--name">Container</span> <span class="ct-col ct-col--image">Image</span> <span class="ct-col ct-col--tag">Tag</span> <span class="ct-col ct-col--status">Status</span> <span class="ct-col ct-col--actions"></span></div> <!--[-->`);
747
+ const each_array = ensure_array_like(serviceEntries);
748
+ for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
749
+ let entry = each_array[$$index];
750
+ const selected = selectedContainerId === entry.id;
751
+ ContainerRow($$renderer, {
752
+ entry,
753
+ selected});
754
+ $$renderer.push(`<!----> `);
755
+ if (selected) {
756
+ $$renderer.push("<!--[0-->");
757
+ ContainerDetail($$renderer, {
758
+ entry,
759
+ actionInFlight: rowState[entry.id]?.inFlight ?? null,
760
+ confirmAction: rowState[entry.id]?.confirm ?? null,
761
+ feedback: rowState[entry.id]?.feedback ?? null});
762
+ } else $$renderer.push("<!--[-1-->");
763
+ $$renderer.push(`<!--]-->`);
764
+ }
765
+ $$renderer.push(`<!--]--></div>`);
766
+ } else {
767
+ $$renderer.push("<!--[-1-->");
768
+ ContainersEmptyState($$renderer, {
769
+ loading,
770
+ error,
771
+ containerData});
772
+ }
773
+ $$renderer.push(`<!--]--></div>`);
774
+ }});
775
+ }
776
+ });
777
+ }
778
+ //#endregion
779
+ //#region src/lib/components/admin/automations/AutomationsTab.svelte
780
+ function AutomationsTab($$renderer, $$props) {
781
+ $$renderer.component(($$renderer) => {
782
+ let { data, loading, error} = $$props;
783
+ let hasAutomations = derived(() => data !== null && Array.isArray(data.automations) && data.automations.length > 0);
784
+ /** Reverse map: cron expression -> friendly label */
785
+ const CRON_TO_LABEL = {
786
+ "* * * * *": "Every minute",
787
+ "*/5 * * * *": "Every 5 minutes",
788
+ "*/15 * * * *": "Every 15 minutes",
789
+ "0 * * * *": "Every hour",
790
+ "0 0 * * *": "Daily at midnight",
791
+ "0 8 * * *": "Daily at 8 AM",
792
+ "0 0 * * 0": "Weekly (Sunday midnight)",
793
+ "0 3 * * 0": "Weekly (Sunday 3 AM)",
794
+ "0 4 * * 0": "Weekly (Sunday 4 AM)"
795
+ };
796
+ function formatSchedule(cron) {
797
+ const friendly = CRON_TO_LABEL[cron];
798
+ if (friendly) return {
799
+ label: friendly,
800
+ cron
801
+ };
802
+ return null;
803
+ }
804
+ $$renderer.push(`<div class="panel" role="tabpanel"><div class="panel-header"><div><h2>Automations</h2> <p class="panel-subtitle">Scheduled tasks read from <code>~/.openpalm/knowledge/tasks/</code>. Add or edit task files there to manage automations — changes take effect on refresh.</p></div> <div class="panel-header-actions"><button class="btn btn-secondary btn-sm"${attr("disabled", false, true)}>New task</button> <button class="btn btn-secondary btn-sm"${attr("disabled", loading || false, true)}>`);
805
+ if (loading) {
806
+ $$renderer.push("<!--[0-->");
807
+ Spinner($$renderer, {});
808
+ } else $$renderer.push("<!--[-1-->");
809
+ $$renderer.push(`<!--]--> Refresh</button></div></div> `);
810
+ $$renderer.push("<!--[-1-->");
811
+ $$renderer.push(`<!--]--> <div class="panel-body">`);
812
+ if (hasAutomations() && data) {
813
+ $$renderer.push("<!--[0-->");
814
+ $$renderer.push(`<div class="automation-list svelte-1xltcby"><!--[-->`);
815
+ const each_array = ensure_array_like(data.automations);
816
+ for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
817
+ let automation = each_array[$$index];
818
+ const preset = formatSchedule(automation.schedule);
819
+ $$renderer.push(`<div class="automation-card svelte-1xltcby"><div class="automation-row svelte-1xltcby"><div class="automation-main svelte-1xltcby"><div class="automation-name svelte-1xltcby">${escape_html(automation.name)} <span${attr_class("badge", void 0, {
820
+ "badge-enabled": automation.enabled,
821
+ "badge-disabled": !automation.enabled
822
+ })}>${escape_html(automation.enabled ? "Enabled" : "Disabled")}</span> <span class="badge badge-type svelte-1xltcby">${escape_html(automation.action.type)}</span></div> `);
823
+ if (automation.description) {
824
+ $$renderer.push("<!--[0-->");
825
+ $$renderer.push(`<div class="automation-desc svelte-1xltcby">${escape_html(automation.description)}</div>`);
826
+ } else $$renderer.push("<!--[-1-->");
827
+ $$renderer.push(`<!--]--></div> <div class="automation-meta svelte-1xltcby">`);
828
+ if (preset?.cron) {
829
+ $$renderer.push("<!--[0-->");
830
+ $$renderer.push(`<span class="meta-item schedule-friendly svelte-1xltcby">${escape_html(preset.label)}</span>`);
831
+ } else {
832
+ $$renderer.push("<!--[-1-->");
833
+ $$renderer.push(`<span class="meta-item svelte-1xltcby"><code class="svelte-1xltcby">${escape_html(automation.schedule)}</code></span> <span class="meta-item meta-tz svelte-1xltcby">${escape_html(automation.timezone)}</span>`);
834
+ }
835
+ $$renderer.push(`<!--]--></div></div> <div class="automation-footer svelte-1xltcby"><span class="automation-file svelte-1xltcby">${escape_html(automation.fileName)}</span> <div class="automation-actions svelte-1xltcby"><button class="btn btn-ghost btn-sm"${attr("disabled", false, true)}>Edit</button> <button class="btn btn-ghost btn-sm"${attr("disabled", false, true)}${attr("aria-label", `Delete ${stringify(automation.fileName)}`)}>Delete</button></div></div></div>`);
836
+ }
837
+ $$renderer.push(`<!--]--></div>`);
838
+ } else {
839
+ $$renderer.push("<!--[-1-->");
840
+ {
841
+ function icon($$renderer) {
842
+ $$renderer.push(`<svg aria-hidden="true" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>`);
843
+ }
844
+ EmptyState($$renderer, {
845
+ icon,
846
+ children: ($$renderer) => {
847
+ if (loading) {
848
+ $$renderer.push("<!--[0-->");
849
+ $$renderer.push(`<p>Loading automations...</p>`);
850
+ } else if (error) {
851
+ $$renderer.push("<!--[1-->");
852
+ $$renderer.push(`<p class="text-danger svelte-1xltcby">${escape_html(error)}</p> <button class="btn btn-secondary btn-sm empty-state-btn svelte-1xltcby">Try Again</button>`);
853
+ } else {
854
+ $$renderer.push("<!--[-1-->");
855
+ $$renderer.push(`<p>No automations configured.</p> <p class="empty-state-hint svelte-1xltcby">Drop <code class="svelte-1xltcby">.md</code> task files into <code class="svelte-1xltcby">~/.openpalm/knowledge/tasks/</code>, or install via <code class="svelte-1xltcby">akm</code>.</p>`);
856
+ }
857
+ $$renderer.push(`<!--]-->`);
858
+ }});
859
+ }
860
+ }
861
+ $$renderer.push(`<!--]--></div></div>`);
862
+ });
863
+ }
864
+ //#endregion
865
+ //#region src/lib/components/providers/ProvidersPanel.svelte
866
+ function ProvidersPanel($$renderer, $$props) {
867
+ $$renderer.component(($$renderer) => {
868
+ let pageState = {
869
+ providers: []};
870
+ let loading = true;
871
+ const connected = derived(() => pageState.providers.filter((p) => p.connected));
872
+ let mainModelChoice = "";
873
+ let smallModelChoice = "";
874
+ let modelSaveError = null;
875
+ async function saveModel(target, value) {
876
+ modelSaveError = null;
877
+ try {
878
+ const res = await fetch("/admin/opencode/model", {
879
+ method: "POST",
880
+ headers: {
881
+ ...buildHeaders(),
882
+ "content-type": "application/json"
883
+ },
884
+ body: JSON.stringify({ [target]: value || null })
885
+ });
886
+ if (!res.ok) modelSaveError = (await res.json().catch(() => ({}))).message ?? `Save failed (${res.status})`;
887
+ } catch (err) {
888
+ modelSaveError = err instanceof Error ? err.message : "Request failed.";
889
+ }
890
+ }
891
+ let disconnectingId = null;
892
+ const BADGE_LABEL = {
893
+ env: "env",
894
+ api: "api key",
895
+ oauth: "oauth",
896
+ config: "config",
897
+ custom: "custom"
898
+ };
899
+ function authBadge(p) {
900
+ return p.credentialType ? BADGE_LABEL[p.credentialType] : "";
901
+ }
902
+ $$renderer.push(`<div class="panel" role="tabpanel"><div class="panel-header"><div><h2>Connections</h2> <p class="panel-subtitle">Sign in to AI providers. Credentials are stored in OpenCode's auth.json.</p></div> <div class="panel-header-actions"><button type="button" class="btn btn-secondary btn-sm"${attr("disabled", true, true)}${attr("title", "No host OpenCode installation detected")}>Import from host</button> <button type="button" class="btn btn-primary btn-sm">Add provider</button> <button class="btn btn-secondary btn-sm"${attr("disabled", loading, true)}>`);
903
+ {
904
+ $$renderer.push("<!--[0-->");
905
+ Spinner($$renderer, {});
906
+ }
907
+ $$renderer.push(`<!--]--> Refresh</button></div></div> `);
908
+ $$renderer.push("<!--[-1-->");
909
+ $$renderer.push(`<!--]--> <div class="panel-body panel-body--flush">`);
910
+ if (pageState.providers.length === 0) {
911
+ $$renderer.push("<!--[1-->");
912
+ $$renderer.push(`<div class="loading-state">`);
913
+ Spinner($$renderer, {});
914
+ $$renderer.push(`<!----> <span>Loading providers…</span></div>`);
915
+ } else if (connected().length === 0) {
916
+ $$renderer.push("<!--[2-->");
917
+ {
918
+ function icon($$renderer) {
919
+ $$renderer.push(`<svg aria-hidden="true" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path></svg>`);
920
+ }
921
+ EmptyState($$renderer, {
922
+ icon,
923
+ children: ($$renderer) => {
924
+ $$renderer.push(`<p>No providers connected yet.</p> <p class="empty-hint svelte-19zt4ct">Click <strong>Add provider</strong> above to sign in to one.</p>`);
925
+ }});
926
+ }
927
+ } else {
928
+ $$renderer.push("<!--[-1-->");
929
+ $$renderer.push(`<div class="model-defaults svelte-19zt4ct"><div class="model-field svelte-19zt4ct"><label class="form-label" for="default-model">Default model</label> `);
930
+ $$renderer.select({
931
+ id: "default-model",
932
+ class: "form-input",
933
+ value: mainModelChoice,
934
+ onchange: (e) => void saveModel("model", e.currentTarget.value)
935
+ }, ($$renderer) => {
936
+ $$renderer.option({ value: "" }, ($$renderer) => {
937
+ $$renderer.push(`— OpenCode default —`);
938
+ });
939
+ $$renderer.push(`<!--[-->`);
940
+ const each_array = ensure_array_like(connected());
941
+ for (let $$index_1 = 0, $$length = each_array.length; $$index_1 < $$length; $$index_1++) {
942
+ let p = each_array[$$index_1];
943
+ if (p.models.length > 0) {
944
+ $$renderer.push("<!--[0-->");
945
+ $$renderer.push(`<optgroup${attr("label", p.name)}><!--[-->`);
946
+ const each_array_1 = ensure_array_like(p.models);
947
+ for (let $$index = 0, $$length = each_array_1.length; $$index < $$length; $$index++) {
948
+ let m = each_array_1[$$index];
949
+ $$renderer.option({ value: `${stringify(p.id)}/${stringify(m.id)}` }, ($$renderer) => {
950
+ $$renderer.push(`${escape_html(m.name || m.id)}`);
951
+ });
952
+ }
953
+ $$renderer.push(`<!--]--></optgroup>`);
954
+ } else $$renderer.push("<!--[-1-->");
955
+ $$renderer.push(`<!--]-->`);
956
+ }
957
+ $$renderer.push(`<!--]-->`);
958
+ });
959
+ $$renderer.push(`</div> <div class="model-field svelte-19zt4ct"><label class="form-label" for="small-model">Small model</label> `);
960
+ $$renderer.select({
961
+ id: "small-model",
962
+ class: "form-input",
963
+ value: smallModelChoice,
964
+ onchange: (e) => void saveModel("small_model", e.currentTarget.value)
965
+ }, ($$renderer) => {
966
+ $$renderer.option({ value: "" }, ($$renderer) => {
967
+ $$renderer.push(`— OpenCode default —`);
968
+ });
969
+ $$renderer.push(`<!--[-->`);
970
+ const each_array_2 = ensure_array_like(connected());
971
+ for (let $$index_3 = 0, $$length = each_array_2.length; $$index_3 < $$length; $$index_3++) {
972
+ let p = each_array_2[$$index_3];
973
+ if (p.models.length > 0) {
974
+ $$renderer.push("<!--[0-->");
975
+ $$renderer.push(`<optgroup${attr("label", p.name)}><!--[-->`);
976
+ const each_array_3 = ensure_array_like(p.models);
977
+ for (let $$index_2 = 0, $$length = each_array_3.length; $$index_2 < $$length; $$index_2++) {
978
+ let m = each_array_3[$$index_2];
979
+ $$renderer.option({ value: `${stringify(p.id)}/${stringify(m.id)}` }, ($$renderer) => {
980
+ $$renderer.push(`${escape_html(m.name || m.id)}`);
981
+ });
982
+ }
983
+ $$renderer.push(`<!--]--></optgroup>`);
984
+ } else $$renderer.push("<!--[-1-->");
985
+ $$renderer.push(`<!--]-->`);
986
+ }
987
+ $$renderer.push(`<!--]-->`);
988
+ });
989
+ $$renderer.push(`</div> `);
990
+ if (modelSaveError) {
991
+ $$renderer.push("<!--[0-->");
992
+ $$renderer.push(`<p class="model-error svelte-19zt4ct">${escape_html(modelSaveError)}</p>`);
993
+ } else $$renderer.push("<!--[-1-->");
994
+ $$renderer.push(`<!--]--></div> <!--[-->`);
995
+ const each_array_4 = ensure_array_like(connected());
996
+ for (let $$index_4 = 0, $$length = each_array_4.length; $$index_4 < $$length; $$index_4++) {
997
+ let p = each_array_4[$$index_4];
998
+ $$renderer.push(`<div class="provider-row svelte-19zt4ct"><div class="provider-id svelte-19zt4ct"><span class="provider-name svelte-19zt4ct">${escape_html(p.name)}</span> <span class="badge badge-connected">${escape_html(authBadge(p))}</span></div> <button class="btn btn-outline btn-sm"${attr("disabled", disconnectingId === p.id, true)}>`);
999
+ if (disconnectingId === p.id) {
1000
+ $$renderer.push("<!--[0-->");
1001
+ Spinner($$renderer, {});
1002
+ } else $$renderer.push("<!--[-1-->");
1003
+ $$renderer.push(`<!--]--> Disconnect</button></div>`);
1004
+ }
1005
+ $$renderer.push(`<!--]-->`);
1006
+ }
1007
+ $$renderer.push(`<!--]--></div></div> `);
1008
+ $$renderer.push("<!--[-1-->");
1009
+ $$renderer.push(`<!--]--> `);
1010
+ $$renderer.push("<!--[-1-->");
1011
+ $$renderer.push(`<!--]--> `);
1012
+ $$renderer.push("<!--[-1-->");
1013
+ $$renderer.push(`<!--]--> `);
1014
+ $$renderer.push("<!--[-1-->");
1015
+ $$renderer.push(`<!--]-->`);
1016
+ });
1017
+ }
1018
+ //#endregion
1019
+ //#region src/lib/components/admin/logs/LogsTab.svelte
1020
+ function LogsTab($$renderer, $$props) {
1021
+ $$renderer.component(($$renderer) => {
1022
+ let { services } = $$props;
1023
+ let logs = "";
1024
+ let logsLoaded = false;
1025
+ let loading = false;
1026
+ let error = "";
1027
+ let selectedService = "";
1028
+ let tailLines = 100;
1029
+ let autoScroll = true;
1030
+ async function loadLogs() {
1031
+ loading = true;
1032
+ error = "";
1033
+ try {
1034
+ const result = await fetchServiceLogs({
1035
+ service: void 0,
1036
+ tail: tailLines
1037
+ });
1038
+ if (result.ok) {
1039
+ logs = result.logs;
1040
+ logsLoaded = true;
1041
+ } else error = result.error ?? "Failed to fetch logs.";
1042
+ } catch (e) {
1043
+ error = e instanceof Error ? e.message : "Failed to fetch logs.";
1044
+ } finally {
1045
+ loading = false;
1046
+ }
1047
+ }
1048
+ {
1049
+ function actions($$renderer) {
1050
+ $$renderer.push(`<button class="btn btn-secondary btn-sm"${attr("disabled", !logs, true)}>${escape_html("Copy")}</button> <button class="btn btn-secondary btn-sm"${attr("disabled", loading || false, true)}>`);
1051
+ if (loading) {
1052
+ $$renderer.push("<!--[0-->");
1053
+ Spinner($$renderer, {});
1054
+ } else $$renderer.push("<!--[-1-->");
1055
+ $$renderer.push(`<!--]--> Refresh</button>`);
1056
+ }
1057
+ Panel($$renderer, {
1058
+ title: "Service Logs",
1059
+ role: "tabpanel",
1060
+ actions,
1061
+ children: ($$renderer) => {
1062
+ $$renderer.push(`<div class="controls svelte-coqj2u"><div class="control-group svelte-coqj2u"><label for="log-service" class="control-label svelte-coqj2u">Service</label> `);
1063
+ $$renderer.select({
1064
+ id: "log-service",
1065
+ class: "control-input",
1066
+ value: selectedService,
1067
+ onchange: () => void loadLogs()
1068
+ }, ($$renderer) => {
1069
+ $$renderer.option({ value: "" }, ($$renderer) => {
1070
+ $$renderer.push(`All services`);
1071
+ });
1072
+ $$renderer.push(`<!--[-->`);
1073
+ const each_array = ensure_array_like(services);
1074
+ for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
1075
+ let svc = each_array[$$index];
1076
+ $$renderer.option({ value: svc }, ($$renderer) => {
1077
+ $$renderer.push(`${escape_html(svc)}`);
1078
+ });
1079
+ }
1080
+ $$renderer.push(`<!--]-->`);
1081
+ }, "svelte-coqj2u");
1082
+ $$renderer.push(`</div> <div class="control-group svelte-coqj2u"><label for="log-tail" class="control-label svelte-coqj2u">Lines</label> `);
1083
+ $$renderer.select({
1084
+ id: "log-tail",
1085
+ class: "control-input",
1086
+ value: tailLines,
1087
+ onchange: () => void loadLogs()
1088
+ }, ($$renderer) => {
1089
+ $$renderer.option({ value: 50 }, ($$renderer) => {
1090
+ $$renderer.push(`50`);
1091
+ });
1092
+ $$renderer.option({ value: 100 }, ($$renderer) => {
1093
+ $$renderer.push(`100`);
1094
+ });
1095
+ $$renderer.option({ value: 250 }, ($$renderer) => {
1096
+ $$renderer.push(`250`);
1097
+ });
1098
+ $$renderer.option({ value: 500 }, ($$renderer) => {
1099
+ $$renderer.push(`500`);
1100
+ });
1101
+ $$renderer.option({ value: 1e3 }, ($$renderer) => {
1102
+ $$renderer.push(`1000`);
1103
+ });
1104
+ }, "svelte-coqj2u");
1105
+ $$renderer.push(`</div> <div class="control-group control-group--toggle svelte-coqj2u"><label class="toggle-label svelte-coqj2u"><input type="checkbox"${attr("checked", autoScroll, true)} class="svelte-coqj2u"/> <span>Auto-scroll</span></label></div> <button class="btn btn-primary btn-sm"${attr("disabled", loading || false, true)}>`);
1106
+ if (loading) {
1107
+ $$renderer.push("<!--[0-->");
1108
+ Spinner($$renderer, {});
1109
+ } else $$renderer.push("<!--[-1-->");
1110
+ $$renderer.push(`<!--]--> Load Logs</button></div> <div class="panel-body panel-body--flush">`);
1111
+ if (error) {
1112
+ $$renderer.push("<!--[0-->");
1113
+ $$renderer.push(`<div class="error-banner svelte-coqj2u"><span>${escape_html(error)}</span></div>`);
1114
+ } else $$renderer.push("<!--[-1-->");
1115
+ $$renderer.push(`<!--]--> `);
1116
+ if (logs) {
1117
+ $$renderer.push("<!--[0-->");
1118
+ $$renderer.push(`<pre class="log-output svelte-coqj2u">${escape_html(logs)}</pre>`);
1119
+ } else if (!loading) {
1120
+ $$renderer.push("<!--[1-->");
1121
+ {
1122
+ function icon($$renderer) {
1123
+ $$renderer.push(`<svg aria-hidden="true" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line></svg>`);
1124
+ }
1125
+ EmptyState($$renderer, {
1126
+ icon,
1127
+ children: ($$renderer) => {
1128
+ if (logsLoaded) {
1129
+ $$renderer.push("<!--[0-->");
1130
+ $$renderer.push(`<p>No log output — the container may not be running or has no recent output.</p>`);
1131
+ } else {
1132
+ $$renderer.push("<!--[-1-->");
1133
+ $$renderer.push(`<p>Select a service and click "Load Logs" to view container output.</p>`);
1134
+ }
1135
+ $$renderer.push(`<!--]-->`);
1136
+ }});
1137
+ }
1138
+ } else $$renderer.push("<!--[-1-->");
1139
+ $$renderer.push(`<!--]--></div>`);
1140
+ }});
1141
+ }
1142
+ });
1143
+ }
1144
+ //#endregion
1145
+ //#region src/lib/components/admin/secrets/SecretsTab.svelte
1146
+ function SecretsTab($$renderer, $$props) {
1147
+ $$renderer.component(($$renderer) => {
1148
+ let busy = false;
1149
+ let files = [];
1150
+ let selected = null;
1151
+ let newName = "";
1152
+ function fmtSize(n) {
1153
+ if (n < 1024) return `${n} B`;
1154
+ return `${(n / 1024).toFixed(1)} KB`;
1155
+ }
1156
+ $$renderer.push(`<div class="panel" role="tabpanel"><div class="panel-header svelte-epscb2"><h2>Secrets</h2> <div class="panel-header-actions"><button class="btn btn-secondary btn-sm"${attr("disabled", false, true)}>`);
1157
+ $$renderer.push("<!--[-1-->");
1158
+ $$renderer.push(`<!--]--> Refresh</button></div></div> <p class="section-note svelte-epscb2">Files in the assistant's secrets directory (<code>/stash/secrets</code> → <code>knowledge/secrets</code>). These are mounted into the assistant and granted to
1159
+ services via Docker secrets. Files are stored 0600. Editing here changes the live
1160
+ file — restart affected services to pick up changes.</p> `);
1161
+ $$renderer.push("<!--[-1-->");
1162
+ $$renderer.push(`<!--]--> <div class="secrets-layout svelte-epscb2"><div class="secrets-list svelte-epscb2">`);
1163
+ if (files.length === 0 && true) {
1164
+ $$renderer.push("<!--[0-->");
1165
+ $$renderer.push(`<p class="empty-note svelte-epscb2">No secret files found.</p>`);
1166
+ } else $$renderer.push("<!--[-1-->");
1167
+ $$renderer.push(`<!--]--> <!--[-->`);
1168
+ const each_array = ensure_array_like(files);
1169
+ for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
1170
+ let f = each_array[$$index];
1171
+ $$renderer.push(`<div${attr_class(`secret-row ${selected === f.name ? "active" : ""}`, "svelte-epscb2")}><button class="secret-name svelte-epscb2"${attr("disabled", busy, true)}${attr("aria-label", `Edit ${stringify(f.name)}`)}><span class="mono svelte-epscb2">${escape_html(f.name)}</span> <span class="secret-size svelte-epscb2">${escape_html(fmtSize(f.size))}</span></button> <button class="btn btn-ghost btn-sm"${attr("disabled", busy, true)}${attr("aria-label", `Delete ${stringify(f.name)}`)}>✕</button></div>`);
1172
+ }
1173
+ $$renderer.push(`<!--]--> <div class="new-secret svelte-epscb2"><label class="new-secret-label svelte-epscb2" for="new-secret-name">New secret file</label> <div class="new-secret-row svelte-epscb2"><input id="new-secret-name" class="control-input" type="text" spellcheck="false" placeholder="new-file-name"${attr("value", newName)}${attr("disabled", busy, true)}/> <button class="btn btn-secondary btn-sm"${attr("disabled", !newName.trim(), true)}>Add</button></div></div></div> <div class="secrets-editor svelte-epscb2">`);
1174
+ $$renderer.push("<!--[-1-->");
1175
+ $$renderer.push(`<div class="editor-empty svelte-epscb2"><svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="svelte-epscb2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg> <p class="svelte-epscb2">Select a file to view or edit its contents.</p> <button class="btn btn-secondary btn-sm">New secret</button></div>`);
1176
+ $$renderer.push(`<!--]--></div></div></div>`);
1177
+ });
1178
+ }
1179
+ //#endregion
1180
+ //#region src/lib/components/common/PasswordInput.svelte
1181
+ function PasswordInput($$renderer, $$props) {
1182
+ $$renderer.component(($$renderer) => {
1183
+ let { value = "", id, placeholder, disabled = false } = $$props;
1184
+ $$renderer.push(`<div class="input-with-toggle svelte-176sy43"><input${attr("id", id)} class="control-input svelte-176sy43"${attr("type", "password")} spellcheck="false" autocomplete="new-password"${attr("placeholder", placeholder)}${attr("value", value)}${attr("disabled", disabled, true)}/> <button type="button" class="btn-icon svelte-176sy43"${attr("aria-label", "Show value")}${attr("disabled", disabled, true)}>${escape_html("Show")}</button></div>`);
1185
+ bind_props($$props, { value });
1186
+ });
1187
+ }
1188
+ //#endregion
1189
+ //#region src/lib/components/akm/EmbeddingSection.svelte
1190
+ function EmbeddingSection($$renderer, $$props) {
1191
+ $$renderer.component(($$renderer) => {
1192
+ let { endpoint = "", model = "", provider = "", apiKey = "", dimension = 1536, localModel = "", batchSize = "", chunkSize = "", contextLength = "", ollamaNumCtx = "", disabled = false } = $$props;
1193
+ let $$settled = true;
1194
+ let $$inner_renderer;
1195
+ function $$render_inner($$renderer) {
1196
+ $$renderer.push(`<section class="config-section svelte-y5k1u8"><h3 class="section-title svelte-y5k1u8">Semantic search (embeddings)</h3> <p class="section-note svelte-y5k1u8">Vector embedding provider for semantic search. Leave Endpoint and Model blank to use built-in local embeddings.</p> <div class="controls--grid svelte-y5k1u8"><div class="control-group control-group--wide svelte-y5k1u8"><label class="control-label svelte-y5k1u8" for="embEndpoint">Endpoint</label> <input id="embEndpoint" class="control-input svelte-y5k1u8" type="url" spellcheck="false" placeholder="https://api.openai.com/v1/embeddings"${attr("value", endpoint)}${attr("disabled", disabled, true)}/></div> <div class="control-group svelte-y5k1u8"><label class="control-label svelte-y5k1u8" for="embModel">Model</label> <input id="embModel" class="control-input svelte-y5k1u8" type="text" spellcheck="false" placeholder="text-embedding-3-small"${attr("value", model)}${attr("disabled", disabled, true)}/></div> <div class="control-group svelte-y5k1u8"><label class="control-label svelte-y5k1u8" for="embProvider">Provider (label)</label> <input id="embProvider" class="control-input svelte-y5k1u8" type="text" spellcheck="false" placeholder="openai"${attr("value", provider)}${attr("disabled", disabled, true)}/></div> <div class="control-group svelte-y5k1u8"><label class="control-label svelte-y5k1u8" for="embApiKey">API Key</label> `);
1197
+ PasswordInput($$renderer, {
1198
+ id: "embApiKey",
1199
+ placeholder: "${AKM_EMBED_API_KEY}",
1200
+ disabled,
1201
+ get value() {
1202
+ return apiKey;
1203
+ },
1204
+ set value($$value) {
1205
+ apiKey = $$value;
1206
+ $$settled = false;
1207
+ }
1208
+ });
1209
+ $$renderer.push(`<!----></div> <div class="control-group svelte-y5k1u8"><label class="control-label svelte-y5k1u8" for="embDimension">Dimensions</label> <input id="embDimension" class="control-input control-input--narrow svelte-y5k1u8" type="number" min="1"${attr("value", dimension)}${attr("disabled", disabled, true)}/></div> <div class="control-group svelte-y5k1u8"><label class="control-label svelte-y5k1u8" for="embLocalModel">Local model</label> <input id="embLocalModel" class="control-input svelte-y5k1u8" type="text" spellcheck="false" placeholder="Xenova/bge-small-en-v1.5"${attr("value", localModel)}${attr("disabled", disabled, true)}/></div> <div class="control-group svelte-y5k1u8"><label class="control-label svelte-y5k1u8" for="embBatchSize">Batch size</label> <input id="embBatchSize" class="control-input control-input--narrow svelte-y5k1u8" type="number" min="1"${attr("value", batchSize)}${attr("disabled", disabled, true)}/></div> <div class="control-group svelte-y5k1u8"><label class="control-label svelte-y5k1u8" for="embChunkSize">Chunk size (chars)</label> <input id="embChunkSize" class="control-input control-input--narrow svelte-y5k1u8" type="number" min="1"${attr("value", chunkSize)}${attr("disabled", disabled, true)}/></div> <div class="control-group svelte-y5k1u8"><label class="control-label svelte-y5k1u8" for="embContextLength">Context length</label> <input id="embContextLength" class="control-input control-input--narrow svelte-y5k1u8" type="number" min="1"${attr("value", contextLength)}${attr("disabled", disabled, true)}/></div> <div class="control-group svelte-y5k1u8"><label class="control-label svelte-y5k1u8" for="embOllamaNumCtx">Ollama num_ctx</label> <input id="embOllamaNumCtx" class="control-input control-input--narrow svelte-y5k1u8" type="number" min="1"${attr("value", ollamaNumCtx)}${attr("disabled", disabled, true)}/></div></div></section>`);
1210
+ }
1211
+ do {
1212
+ $$settled = true;
1213
+ $$inner_renderer = $$renderer.copy();
1214
+ $$render_inner($$inner_renderer);
1215
+ } while (!$$settled);
1216
+ $$renderer.subsume($$inner_renderer);
1217
+ bind_props($$props, {
1218
+ endpoint,
1219
+ model,
1220
+ provider,
1221
+ apiKey,
1222
+ dimension,
1223
+ localModel,
1224
+ batchSize,
1225
+ chunkSize,
1226
+ contextLength,
1227
+ ollamaNumCtx
1228
+ });
1229
+ });
1230
+ }
1231
+ //#endregion
1232
+ //#region src/lib/components/akm/ProfileRow.svelte
1233
+ function ProfileRow($$renderer, $$props) {
1234
+ /** Optional badges/extras rendered after the name (e.g. platform, description). */
1235
+ let { name, isDefault, disabled = false, extra, onsetdefault, onedit, onremove } = $$props;
1236
+ $$renderer.push(`<div class="profile-row svelte-zzh9mp"><span class="profile-row-name svelte-zzh9mp">${escape_html(name || "(unnamed)")}</span> `);
1237
+ if (extra) {
1238
+ $$renderer.push("<!--[0-->");
1239
+ extra($$renderer);
1240
+ $$renderer.push(`<!---->`);
1241
+ } else $$renderer.push("<!--[-1-->");
1242
+ $$renderer.push(`<!--]--> `);
1243
+ if (isDefault && name) {
1244
+ $$renderer.push("<!--[0-->");
1245
+ $$renderer.push(`<span class="badge badge--default svelte-zzh9mp">Default</span>`);
1246
+ } else $$renderer.push("<!--[-1-->");
1247
+ $$renderer.push(`<!--]--> <div class="profile-row-actions svelte-zzh9mp">`);
1248
+ if (name && !isDefault) {
1249
+ $$renderer.push("<!--[0-->");
1250
+ $$renderer.push(`<button class="btn btn-sm"${attr("disabled", disabled, true)}>Set Default</button>`);
1251
+ } else $$renderer.push("<!--[-1-->");
1252
+ $$renderer.push(`<!--]--> <button class="btn btn-sm"${attr("disabled", disabled, true)}>Edit</button> <button class="btn btn-sm btn-danger"${attr("disabled", disabled, true)}>Remove</button></div></div>`);
1253
+ }
1254
+ //#endregion
1255
+ //#region src/lib/components/akm/LlmProfilesSection.svelte
1256
+ function LlmProfilesSection($$renderer, $$props) {
1257
+ $$renderer.component(($$renderer) => {
1258
+ let { profiles = [], defaultName = "", disabled = false, onedit, onadd, onremove } = $$props;
1259
+ $$renderer.push(`<section class="config-section svelte-zwwvog"><h3 class="section-title svelte-zwwvog">Language models <span class="section-title-aka svelte-zwwvog">akm LLM profiles</span></h3> <p class="section-note svelte-zwwvog">The language models your assistant uses to organize and improve its memory. Add one per LLM service.</p> `);
1260
+ if (profiles.length === 0) {
1261
+ $$renderer.push("<!--[0-->");
1262
+ $$renderer.push(`<div class="profile-empty svelte-zwwvog"><svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="svelte-zwwvog"><ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M3 5v14c0 1.66 4.03 3 9 3s9-1.34 9-3V5"></path><path d="M3 12c0 1.66 4.03 3 9 3s9-1.34 9-3"></path></svg> <p class="empty-note svelte-zwwvog">No LLM profiles configured — add one below.</p></div>`);
1263
+ } else {
1264
+ $$renderer.push("<!--[-1-->");
1265
+ $$renderer.push(`<div class="profile-list svelte-zwwvog"><!--[-->`);
1266
+ const each_array = ensure_array_like(profiles);
1267
+ for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
1268
+ let p = each_array[$$index];
1269
+ ProfileRow($$renderer, {
1270
+ name: p.name,
1271
+ isDefault: defaultName === p.name,
1272
+ disabled,
1273
+ onsetdefault: () => {
1274
+ defaultName = p.name;
1275
+ },
1276
+ onedit: () => onedit(p),
1277
+ onremove: () => onremove(p.id)
1278
+ });
1279
+ }
1280
+ $$renderer.push(`<!--]--></div>`);
1281
+ }
1282
+ $$renderer.push(`<!--]--> <button class="btn btn-secondary btn-sm"${attr("disabled", disabled, true)}>+ Add LLM Profile</button></section>`);
1283
+ bind_props($$props, {
1284
+ profiles,
1285
+ defaultName
1286
+ });
1287
+ });
1288
+ }
1289
+ //#endregion
1290
+ //#region src/lib/components/akm/AgentProfilesSection.svelte
1291
+ function AgentProfilesSection($$renderer, $$props) {
1292
+ $$renderer.component(($$renderer) => {
1293
+ let { profiles = [], defaultName = "", disabled = false, onedit, onadd, onremove } = $$props;
1294
+ $$renderer.push(`<section class="config-section svelte-anyxpa"><h3 class="section-title svelte-anyxpa">Agent runners <span class="section-title-aka svelte-anyxpa">akm agent profiles</span></h3> <p class="section-note svelte-anyxpa">Runner configs for maintenance steps that spawn a subprocess (opencode or claude CLI).</p> `);
1295
+ if (profiles.length === 0) {
1296
+ $$renderer.push("<!--[0-->");
1297
+ $$renderer.push(`<div class="profile-empty svelte-anyxpa"><svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="svelte-anyxpa"><rect x="2" y="3" width="20" height="14" rx="2"></rect><path d="M8 21h8m-4-4v4"></path><circle cx="12" cy="10" r="2"></circle><path d="M9 10H7m10 0h-2"></path></svg> <p class="empty-note svelte-anyxpa">No agent profiles defined.</p></div>`);
1298
+ } else {
1299
+ $$renderer.push("<!--[-1-->");
1300
+ $$renderer.push(`<div class="profile-list svelte-anyxpa"><!--[-->`);
1301
+ const each_array = ensure_array_like(profiles);
1302
+ for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
1303
+ let p = each_array[$$index];
1304
+ {
1305
+ function extra($$renderer) {
1306
+ $$renderer.push(`<span class="badge svelte-anyxpa">${escape_html(p.platform)}</span>`);
1307
+ }
1308
+ ProfileRow($$renderer, {
1309
+ name: p.name,
1310
+ isDefault: defaultName === p.name,
1311
+ disabled,
1312
+ onsetdefault: () => {
1313
+ defaultName = p.name;
1314
+ },
1315
+ onedit: () => onedit(p),
1316
+ onremove: () => onremove(p.id),
1317
+ extra});
1318
+ }
1319
+ }
1320
+ $$renderer.push(`<!--]--></div>`);
1321
+ }
1322
+ $$renderer.push(`<!--]--> <button class="btn btn-secondary btn-sm"${attr("disabled", disabled, true)}>+ Add Agent Profile</button></section>`);
1323
+ bind_props($$props, {
1324
+ profiles,
1325
+ defaultName
1326
+ });
1327
+ });
1328
+ }
1329
+ //#endregion
1330
+ //#region src/lib/components/akm/ImproveProfilesSection.svelte
1331
+ function ImproveProfilesSection($$renderer, $$props) {
1332
+ $$renderer.component(($$renderer) => {
1333
+ let { profiles = [], defaultName = "", disabled = false, onedit, onadd, onremove } = $$props;
1334
+ $$renderer.push(`<section class="config-section svelte-1ngozvb"><h3 class="section-title svelte-1ngozvb">Memory maintenance <span class="section-title-aka svelte-1ngozvb">akm improve</span></h3> <p class="section-note svelte-1ngozvb">Scheduled runs that distill, deduplicate, and improve stored memories. Each configuration picks which steps run and which language model they use — add a language model above first.</p> `);
1335
+ if (profiles.length === 0) {
1336
+ $$renderer.push("<!--[0-->");
1337
+ $$renderer.push(`<div class="profile-empty svelte-1ngozvb"><svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="svelte-1ngozvb"><path d="M12 3c-1 2-2 3-3 4 1 3 3 5 3 8a6 6 0 0 1-6-6c0-3 2-5 3-6"></path><path d="M17.5 3.5c.5 1.5.5 3-.5 4.5 1 1 2 2.5 2 4a4 4 0 0 1-4-4c0-2 1-3.5 2.5-4.5z"></path></svg> <p class="empty-note svelte-1ngozvb">No improve profiles defined — add one below.</p></div>`);
1338
+ } else {
1339
+ $$renderer.push("<!--[-1-->");
1340
+ $$renderer.push(`<div class="profile-list svelte-1ngozvb"><!--[-->`);
1341
+ const each_array = ensure_array_like(profiles);
1342
+ for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
1343
+ let ip = each_array[$$index];
1344
+ {
1345
+ function extra($$renderer) {
1346
+ if (ip.description) {
1347
+ $$renderer.push("<!--[0-->");
1348
+ $$renderer.push(`<span class="profile-row-desc svelte-1ngozvb">${escape_html(ip.description)}</span>`);
1349
+ } else $$renderer.push("<!--[-1-->");
1350
+ $$renderer.push(`<!--]-->`);
1351
+ }
1352
+ ProfileRow($$renderer, {
1353
+ name: ip.name,
1354
+ isDefault: defaultName === ip.name,
1355
+ disabled,
1356
+ onsetdefault: () => {
1357
+ defaultName = ip.name;
1358
+ },
1359
+ onedit: () => onedit(ip),
1360
+ onremove: () => onremove(ip.id),
1361
+ extra});
1362
+ }
1363
+ }
1364
+ $$renderer.push(`<!--]--></div>`);
1365
+ }
1366
+ $$renderer.push(`<!--]--> <button class="btn btn-secondary btn-sm"${attr("disabled", disabled, true)}>+ Add Improve Profile</button></section>`);
1367
+ bind_props($$props, {
1368
+ profiles,
1369
+ defaultName
1370
+ });
1371
+ });
1372
+ }
1373
+ //#endregion
1374
+ //#region src/lib/components/akm/LlmProfileDrawer.svelte
1375
+ function LlmProfileDrawer($$renderer, $$props) {
1376
+ $$renderer.component(($$renderer) => {
1377
+ let { draft = void 0, oncancel, onapply } = $$props;
1378
+ let $$settled = true;
1379
+ let $$inner_renderer;
1380
+ function $$render_inner($$renderer) {
1381
+ $$renderer.push(`<div class="drawer-scrim svelte-1gmn25z" role="presentation"></div> <div class="drawer svelte-1gmn25z" role="dialog" aria-modal="true" aria-label="Edit profile"><div class="drawer-header svelte-1gmn25z"><h3 class="drawer-title svelte-1gmn25z">LLM Profile</h3> <button class="drawer-close svelte-1gmn25z" aria-label="Close">✕</button></div> <div class="drawer-body svelte-1gmn25z"><div class="controls controls--grid svelte-1gmn25z"><div class="control-group svelte-1gmn25z"><label class="control-label svelte-1gmn25z" for="d-llm-name">Profile Name</label> <input id="d-llm-name" class="control-input svelte-1gmn25z" type="text" spellcheck="false" placeholder="e.g. default"${attr("value", draft.name)}/></div> <div class="control-group control-group--wide svelte-1gmn25z"><label class="control-label svelte-1gmn25z" for="d-llm-endpoint">Endpoint</label> <input id="d-llm-endpoint" class="control-input svelte-1gmn25z" type="url" spellcheck="false" placeholder="https://api.openai.com/v1/chat/completions"${attr("value", draft.endpoint)}/></div> <div class="control-group svelte-1gmn25z"><label class="control-label svelte-1gmn25z" for="d-llm-model">Model</label> <input id="d-llm-model" class="control-input svelte-1gmn25z" type="text" spellcheck="false" placeholder="gpt-4o-mini"${attr("value", draft.model)}/></div> <div class="control-group svelte-1gmn25z"><label class="control-label svelte-1gmn25z" for="d-llm-provider">Provider (label)</label> <input id="d-llm-provider" class="control-input svelte-1gmn25z" type="text" spellcheck="false" placeholder="openai"${attr("value", draft.provider)}/></div> <div class="control-group svelte-1gmn25z"><label class="control-label svelte-1gmn25z" for="d-llm-apikey">API Key</label> `);
1382
+ PasswordInput($$renderer, {
1383
+ id: "d-llm-apikey",
1384
+ placeholder: "${AKM_LLM_API_KEY}",
1385
+ get value() {
1386
+ return draft.apiKey;
1387
+ },
1388
+ set value($$value) {
1389
+ draft.apiKey = $$value;
1390
+ $$settled = false;
1391
+ }
1392
+ });
1393
+ $$renderer.push(`<!----></div> <div class="control-group svelte-1gmn25z"><label class="control-label svelte-1gmn25z" for="d-llm-temperature">Temperature (0–2)</label> <input id="d-llm-temperature" class="control-input control-input--narrow svelte-1gmn25z" type="number" min="0" max="2" step="0.1"${attr("value", draft.temperature)}/></div> <div class="control-group svelte-1gmn25z"><label class="control-label svelte-1gmn25z" for="d-llm-maxtokens">Max tokens</label> <input id="d-llm-maxtokens" class="control-input control-input--narrow svelte-1gmn25z" type="number" min="1"${attr("value", draft.maxTokens)}/></div> <div class="control-group svelte-1gmn25z"><label class="control-label svelte-1gmn25z" for="d-llm-timeout">Timeout (ms)</label> <input id="d-llm-timeout" class="control-input control-input--narrow svelte-1gmn25z" type="number" min="1"${attr("value", draft.timeoutMs)}/></div> <div class="control-group svelte-1gmn25z"><label class="control-label svelte-1gmn25z" for="d-llm-concurrency">Concurrency</label> <input id="d-llm-concurrency" class="control-input control-input--narrow svelte-1gmn25z" type="number" min="1"${attr("value", draft.concurrency)}/></div> <div class="control-group svelte-1gmn25z"><label class="control-label svelte-1gmn25z" for="d-llm-contextlength">Context length</label> <input id="d-llm-contextlength" class="control-input control-input--narrow svelte-1gmn25z" type="number" min="1"${attr("value", draft.contextLength)}/></div> <div class="control-group svelte-1gmn25z"><label class="control-label svelte-1gmn25z" for="d-llm-judgemodel">Judge model</label> <input id="d-llm-judgemodel" class="control-input svelte-1gmn25z" type="text" spellcheck="false" placeholder="gpt-4o"${attr("value", draft.judgeModel)}/></div></div> <label class="toggle-row svelte-1gmn25z" style="margin-top: var(--space-4)"><input type="checkbox"${attr("checked", draft.supportsJsonSchema, true)} class="svelte-1gmn25z"/> <span class="toggle-label svelte-1gmn25z">Supports JSON schema</span> <span class="toggle-hint svelte-1gmn25z">Use response_format: json_schema for structured output</span></label> <label class="toggle-row svelte-1gmn25z"><input type="checkbox"${attr("checked", draft.structuredOutput, true)} class="svelte-1gmn25z"/> <span class="toggle-label svelte-1gmn25z">Structured output capability</span> <span class="toggle-hint svelte-1gmn25z">capabilities.structuredOutput — model reliably returns valid structured JSON</span></label> <label class="toggle-row svelte-1gmn25z"><input type="checkbox"${attr("checked", draft.enableThinking, true)} class="svelte-1gmn25z"/> <span class="toggle-label svelte-1gmn25z">Enable thinking</span> <span class="toggle-hint svelte-1gmn25z">Allow extended/thinking tokens for reasoning models</span></label> <div class="control-group control-group--wide svelte-1gmn25z" style="margin-top: var(--space-4)"><label class="control-label svelte-1gmn25z" for="d-llm-extra">Extra params (JSON)</label> <textarea id="d-llm-extra" class="control-input svelte-1gmn25z" rows="3" spellcheck="false" placeholder="{ &quot;top_p&quot;: 0.9 }">`);
1394
+ const $$body = escape_html(draft.extraParams);
1395
+ if ($$body) $$renderer.push(`${$$body}`);
1396
+ $$renderer.push(`</textarea> <span class="feat-hint svelte-1gmn25z">Merged into the provider request body. Must be a JSON object.</span></div></div> <div class="drawer-footer svelte-1gmn25z"><button class="btn btn-secondary">Cancel</button> <button class="btn btn-primary">Apply</button></div></div>`);
1397
+ }
1398
+ do {
1399
+ $$settled = true;
1400
+ $$inner_renderer = $$renderer.copy();
1401
+ $$render_inner($$inner_renderer);
1402
+ } while (!$$settled);
1403
+ $$renderer.subsume($$inner_renderer);
1404
+ bind_props($$props, { draft });
1405
+ });
1406
+ }
1407
+ //#endregion
1408
+ //#region src/lib/components/akm/AgentProfileDrawer.svelte
1409
+ function AgentProfileDrawer($$renderer, $$props) {
1410
+ $$renderer.component(($$renderer) => {
1411
+ let { draft = void 0, oncancel, onapply } = $$props;
1412
+ $$renderer.push(`<div class="drawer-scrim svelte-1evj0pt" role="presentation"></div> <div class="drawer svelte-1evj0pt" role="dialog" aria-modal="true" aria-label="Edit profile"><div class="drawer-header svelte-1evj0pt"><h3 class="drawer-title svelte-1evj0pt">Agent Profile</h3> <button class="drawer-close svelte-1evj0pt" aria-label="Close">✕</button></div> <div class="drawer-body svelte-1evj0pt"><div class="controls controls--grid svelte-1evj0pt"><div class="control-group svelte-1evj0pt"><label class="control-label svelte-1evj0pt" for="d-agent-name">Profile Name</label> <input id="d-agent-name" class="control-input svelte-1evj0pt" type="text" spellcheck="false" placeholder="e.g. opencode"${attr("value", draft.name)}/></div> <div class="control-group svelte-1evj0pt"><label class="control-label svelte-1evj0pt" for="d-agent-platform">Platform</label> `);
1413
+ $$renderer.select({
1414
+ id: "d-agent-platform",
1415
+ class: "control-input",
1416
+ value: draft.platform
1417
+ }, ($$renderer) => {
1418
+ $$renderer.option({ value: "opencode" }, ($$renderer) => {
1419
+ $$renderer.push(`opencode`);
1420
+ });
1421
+ $$renderer.option({ value: "claude" }, ($$renderer) => {
1422
+ $$renderer.push(`claude`);
1423
+ });
1424
+ $$renderer.option({ value: "opencode-sdk" }, ($$renderer) => {
1425
+ $$renderer.push(`opencode-sdk`);
1426
+ });
1427
+ }, "svelte-1evj0pt");
1428
+ $$renderer.push(`</div> `);
1429
+ if (draft.platform !== "opencode-sdk") {
1430
+ $$renderer.push("<!--[0-->");
1431
+ $$renderer.push(`<div class="control-group svelte-1evj0pt"><label class="control-label svelte-1evj0pt" for="d-agent-bin">Binary</label> <input id="d-agent-bin" class="control-input svelte-1evj0pt" type="text" spellcheck="false" placeholder="opencode"${attr("value", draft.bin)}/></div> <div class="control-group control-group--wide svelte-1evj0pt"><label class="control-label svelte-1evj0pt" for="d-agent-args">Extra args (space-separated)</label> <input id="d-agent-args" class="control-input svelte-1evj0pt" type="text" spellcheck="false" placeholder="run --model gpt-4o"${attr("value", draft.args)}/></div>`);
1432
+ } else {
1433
+ $$renderer.push("<!--[-1-->");
1434
+ $$renderer.push(`<div class="control-group svelte-1evj0pt"><label class="control-label svelte-1evj0pt" for="d-agent-model">Model</label> <input id="d-agent-model" class="control-input svelte-1evj0pt" type="text" spellcheck="false" placeholder="anthropic/claude-sonnet-4-5"${attr("value", draft.model)}/></div> <div class="control-group svelte-1evj0pt"><label class="control-label svelte-1evj0pt" for="d-agent-workspace">Workspace</label> <input id="d-agent-workspace" class="control-input svelte-1evj0pt" type="text" spellcheck="false" placeholder="\${PWD}"${attr("value", draft.workspace)}/></div>`);
1435
+ }
1436
+ $$renderer.push(`<!--]--></div></div> <div class="drawer-footer svelte-1evj0pt"><button class="btn btn-secondary">Cancel</button> <button class="btn btn-primary">Apply</button></div></div>`);
1437
+ bind_props($$props, { draft });
1438
+ });
1439
+ }
1440
+ //#endregion
1441
+ //#region src/lib/components/akm/improve-process-helpers.ts
1442
+ var PROCESS_KEYS = [
1443
+ "reflect",
1444
+ "distill",
1445
+ "consolidate",
1446
+ "validation",
1447
+ "memoryInference",
1448
+ "graphExtraction",
1449
+ "extract",
1450
+ "triage"
1451
+ ];
1452
+ var PROCESS_HINTS = {
1453
+ reflect: "Propose stash updates via self-reflection",
1454
+ distill: "Quality-judge and distill feedback",
1455
+ consolidate: "Deduplicate and merge overlapping memories",
1456
+ validation: "Third-model confidence and staleness scoring",
1457
+ memoryInference: "Derive structured memories from pending files",
1458
+ graphExtraction: "Extract entities and relations for graph search",
1459
+ extract: "Read session logs and queue insight proposals",
1460
+ triage: "Auto-review and accept/promote queued proposals"
1461
+ };
1462
+ var DEFAULT_ENABLED = {
1463
+ reflect: true,
1464
+ distill: true,
1465
+ consolidate: false,
1466
+ validation: false,
1467
+ memoryInference: true,
1468
+ graphExtraction: true,
1469
+ extract: true,
1470
+ triage: false
1471
+ };
1472
+ function emptyFEntry(enabled) {
1473
+ return {
1474
+ enabled,
1475
+ mode: "",
1476
+ profile: "",
1477
+ timeoutMs: "",
1478
+ allowedTypes: "",
1479
+ qualityGate: "",
1480
+ contradictionDetection: "",
1481
+ defaultSince: "",
1482
+ maxTotalChars: "",
1483
+ maxChunkSize: "",
1484
+ applyMode: "",
1485
+ policy: "",
1486
+ maxAcceptsPerRun: "",
1487
+ maxDiffLines: "",
1488
+ rejectEmpty: false,
1489
+ judgment: {
1490
+ mode: "",
1491
+ profile: "",
1492
+ timeoutMs: ""
1493
+ },
1494
+ rest: {}
1495
+ };
1496
+ }
1497
+ //#endregion
1498
+ //#region src/lib/components/akm/ImproveProfileDrawer.svelte
1499
+ function ImproveProfileDrawer($$renderer, $$props) {
1500
+ $$renderer.component(($$renderer) => {
1501
+ let { draft = void 0, llmProfileNames, oncancel, onapply } = $$props;
1502
+ $$renderer.push(`<datalist id="llm-profiles-list"><!--[-->`);
1503
+ const each_array = ensure_array_like(llmProfileNames);
1504
+ for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
1505
+ let name = each_array[$$index];
1506
+ $$renderer.option({ value: name }, ($$renderer) => {});
1507
+ }
1508
+ $$renderer.push(`<!--]--></datalist> <div class="drawer-scrim svelte-1ndbe78" role="presentation"></div> <div class="drawer svelte-1ndbe78" role="dialog" aria-modal="true" aria-label="Edit profile"><div class="drawer-header svelte-1ndbe78"><h3 class="drawer-title svelte-1ndbe78">Improve Profile</h3> <button class="drawer-close svelte-1ndbe78" aria-label="Close">✕</button></div> <div class="drawer-body svelte-1ndbe78"><div class="controls controls--grid svelte-1ndbe78"><div class="control-group svelte-1ndbe78"><label class="control-label svelte-1ndbe78" for="d-imp-name">Profile Name</label> <input id="d-imp-name" class="control-input svelte-1ndbe78" type="text" spellcheck="false" placeholder="e.g. default"${attr("value", draft.name)}/></div> <div class="control-group control-group--wide svelte-1ndbe78"><label class="control-label svelte-1ndbe78" for="d-imp-desc">Description</label> <input id="d-imp-desc" class="control-input svelte-1ndbe78" type="text" spellcheck="false" placeholder="Optional description"${attr("value", draft.description)}/></div> <div class="control-group svelte-1ndbe78"><label class="control-label svelte-1ndbe78" for="d-imp-limit">Max proposals per run</label> <input id="d-imp-limit" class="control-input control-input--narrow svelte-1ndbe78" type="number" min="1" max="100"${attr("value", draft.limit)}/></div> <div class="control-group svelte-1ndbe78"><label class="control-label svelte-1ndbe78" for="d-imp-autoacc">Auto-accept threshold (0 = manual)</label> <input id="d-imp-autoacc" class="control-input control-input--narrow svelte-1ndbe78" type="number" min="0" max="1" step="0.05"${attr("value", draft.autoAccept)}/></div></div> <div class="proc-list svelte-1ndbe78"><!--[-->`);
1509
+ const each_array_1 = ensure_array_like(PROCESS_KEYS);
1510
+ for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
1511
+ let key = each_array_1[$$index_1];
1512
+ const proc = draft.processes[key];
1513
+ $$renderer.push(`<div class="proc-card svelte-1ndbe78"><div class="proc-head svelte-1ndbe78"><input type="checkbox"${attr("checked", proc.enabled, true)}${attr("aria-label", `${stringify(key)} enabled`)} class="svelte-1ndbe78"/> <div class="proc-name svelte-1ndbe78"><span class="feat-name svelte-1ndbe78">${escape_html(key)}</span><span class="feat-hint svelte-1ndbe78">${escape_html(PROCESS_HINTS[key])}</span></div> `);
1514
+ $$renderer.select({
1515
+ class: "control-input",
1516
+ value: proc.mode,
1517
+ "aria-label": `${stringify(key)} mode`
1518
+ }, ($$renderer) => {
1519
+ $$renderer.option({ value: "" }, ($$renderer) => {
1520
+ $$renderer.push(`Default mode`);
1521
+ });
1522
+ $$renderer.option({ value: "llm" }, ($$renderer) => {
1523
+ $$renderer.push(`LLM (direct call)`);
1524
+ });
1525
+ $$renderer.option({ value: "agent" }, ($$renderer) => {
1526
+ $$renderer.push(`Agent (subprocess)`);
1527
+ });
1528
+ $$renderer.option({ value: "sdk" }, ($$renderer) => {
1529
+ $$renderer.push(`SDK (programmatic)`);
1530
+ });
1531
+ }, "svelte-1ndbe78");
1532
+ $$renderer.push(` <input class="control-input svelte-1ndbe78" type="text" spellcheck="false" list="llm-profiles-list" placeholder="— default profile —"${attr("value", proc.profile)}${attr("aria-label", `${stringify(key)} profile`)}/> <input class="control-input control-input--narrow svelte-1ndbe78" type="number" min="1" placeholder="timeout ms"${attr("value", proc.timeoutMs)}${attr("aria-label", `${stringify(key)} timeout`)}/></div> <details class="proc-adv svelte-1ndbe78"><summary class="svelte-1ndbe78">Advanced</summary> <div class="proc-adv-grid svelte-1ndbe78"><label class="adv-field svelte-1ndbe78"><span class="svelte-1ndbe78">Allowed types (comma-separated)</span> <input class="control-input svelte-1ndbe78" type="text" spellcheck="false" placeholder="skill, knowledge, …"${attr("value", proc.allowedTypes)}/></label> `);
1533
+ if (key === "reflect" || key === "distill") {
1534
+ $$renderer.push("<!--[0-->");
1535
+ $$renderer.push(`<label class="adv-field svelte-1ndbe78"><span class="svelte-1ndbe78">Quality gate</span> `);
1536
+ $$renderer.select({
1537
+ class: "control-input",
1538
+ value: proc.qualityGate
1539
+ }, ($$renderer) => {
1540
+ $$renderer.option({ value: "" }, ($$renderer) => {
1541
+ $$renderer.push(`Default`);
1542
+ });
1543
+ $$renderer.option({ value: "on" }, ($$renderer) => {
1544
+ $$renderer.push(`Enabled`);
1545
+ });
1546
+ $$renderer.option({ value: "off" }, ($$renderer) => {
1547
+ $$renderer.push(`Disabled`);
1548
+ });
1549
+ }, "svelte-1ndbe78");
1550
+ $$renderer.push(`</label>`);
1551
+ } else $$renderer.push("<!--[-1-->");
1552
+ $$renderer.push(`<!--]--> `);
1553
+ if (key === "consolidate") {
1554
+ $$renderer.push("<!--[0-->");
1555
+ $$renderer.push(`<label class="adv-field svelte-1ndbe78"><span class="svelte-1ndbe78">Contradiction detection</span> `);
1556
+ $$renderer.select({
1557
+ class: "control-input",
1558
+ value: proc.contradictionDetection
1559
+ }, ($$renderer) => {
1560
+ $$renderer.option({ value: "" }, ($$renderer) => {
1561
+ $$renderer.push(`Default`);
1562
+ });
1563
+ $$renderer.option({ value: "on" }, ($$renderer) => {
1564
+ $$renderer.push(`Enabled`);
1565
+ });
1566
+ $$renderer.option({ value: "off" }, ($$renderer) => {
1567
+ $$renderer.push(`Disabled`);
1568
+ });
1569
+ }, "svelte-1ndbe78");
1570
+ $$renderer.push(`</label>`);
1571
+ } else $$renderer.push("<!--[-1-->");
1572
+ $$renderer.push(`<!--]--> `);
1573
+ if (key === "extract") {
1574
+ $$renderer.push("<!--[0-->");
1575
+ $$renderer.push(`<label class="adv-field svelte-1ndbe78"><span class="svelte-1ndbe78">Default since</span> <input class="control-input svelte-1ndbe78" type="text" spellcheck="false" placeholder="e.g. 7d, 2026-01-01"${attr("value", proc.defaultSince)}/></label> <label class="adv-field svelte-1ndbe78"><span class="svelte-1ndbe78">Max total chars</span> <input class="control-input control-input--narrow svelte-1ndbe78" type="number" min="1"${attr("value", proc.maxTotalChars)}/></label> <label class="adv-field svelte-1ndbe78"><span class="svelte-1ndbe78">Max chunk size (1–50)</span> <input class="control-input control-input--narrow svelte-1ndbe78" type="number" min="1" max="50"${attr("value", proc.maxChunkSize)}/></label>`);
1576
+ } else $$renderer.push("<!--[-1-->");
1577
+ $$renderer.push(`<!--]--> `);
1578
+ if (key === "triage") {
1579
+ $$renderer.push("<!--[0-->");
1580
+ $$renderer.push(`<label class="adv-field svelte-1ndbe78"><span class="svelte-1ndbe78">Apply mode</span> `);
1581
+ $$renderer.select({
1582
+ class: "control-input",
1583
+ value: proc.applyMode
1584
+ }, ($$renderer) => {
1585
+ $$renderer.option({ value: "" }, ($$renderer) => {
1586
+ $$renderer.push(`Default`);
1587
+ });
1588
+ $$renderer.option({ value: "queue" }, ($$renderer) => {
1589
+ $$renderer.push(`Queue`);
1590
+ });
1591
+ $$renderer.option({ value: "promote" }, ($$renderer) => {
1592
+ $$renderer.push(`Promote`);
1593
+ });
1594
+ }, "svelte-1ndbe78");
1595
+ $$renderer.push(`</label> <label class="adv-field svelte-1ndbe78"><span class="svelte-1ndbe78">Policy</span> <input class="control-input svelte-1ndbe78" type="text" spellcheck="false" placeholder="policy name/ref"${attr("value", proc.policy)}/></label> <label class="adv-field svelte-1ndbe78"><span class="svelte-1ndbe78">Max accepts per run</span> <input class="control-input control-input--narrow svelte-1ndbe78" type="number" min="1"${attr("value", proc.maxAcceptsPerRun)}/></label> <label class="adv-field svelte-1ndbe78"><span class="svelte-1ndbe78">Max diff lines</span> <input class="control-input control-input--narrow svelte-1ndbe78" type="number" min="1"${attr("value", proc.maxDiffLines)}/></label> <label class="adv-field adv-field--check svelte-1ndbe78"><input type="checkbox"${attr("checked", proc.rejectEmpty, true)}/> <span class="svelte-1ndbe78">Reject empty diffs</span></label> <div class="adv-field adv-field--wide svelte-1ndbe78"><span class="adv-sublabel svelte-1ndbe78">Judgment (overrides for the accept/reject decision)</span> <div class="proc-adv-grid svelte-1ndbe78"><label class="adv-field svelte-1ndbe78"><span class="svelte-1ndbe78">Mode</span> `);
1596
+ $$renderer.select({
1597
+ class: "control-input",
1598
+ value: proc.judgment.mode
1599
+ }, ($$renderer) => {
1600
+ $$renderer.option({ value: "" }, ($$renderer) => {
1601
+ $$renderer.push(`Default`);
1602
+ });
1603
+ $$renderer.option({ value: "llm" }, ($$renderer) => {
1604
+ $$renderer.push(`LLM`);
1605
+ });
1606
+ $$renderer.option({ value: "agent" }, ($$renderer) => {
1607
+ $$renderer.push(`Agent`);
1608
+ });
1609
+ $$renderer.option({ value: "sdk" }, ($$renderer) => {
1610
+ $$renderer.push(`SDK`);
1611
+ });
1612
+ }, "svelte-1ndbe78");
1613
+ $$renderer.push(`</label> <label class="adv-field svelte-1ndbe78"><span class="svelte-1ndbe78">Profile</span> <input class="control-input svelte-1ndbe78" type="text" spellcheck="false" list="llm-profiles-list"${attr("value", proc.judgment.profile)}/></label> <label class="adv-field svelte-1ndbe78"><span class="svelte-1ndbe78">Timeout (ms)</span> <input class="control-input control-input--narrow svelte-1ndbe78" type="number" min="1"${attr("value", proc.judgment.timeoutMs)}/></label></div></div>`);
1614
+ } else $$renderer.push("<!--[-1-->");
1615
+ $$renderer.push(`<!--]--></div></details></div>`);
1616
+ }
1617
+ $$renderer.push(`<!--]--></div> <div class="controls controls--grid svelte-1ndbe78"><div class="control-group svelte-1ndbe78"><label class="control-label svelte-1ndbe78" for="d-imp-sync">Git sync after run</label> `);
1618
+ $$renderer.select({
1619
+ id: "d-imp-sync",
1620
+ class: "control-input",
1621
+ value: draft.syncEnabled
1622
+ }, ($$renderer) => {
1623
+ $$renderer.option({ value: "" }, ($$renderer) => {
1624
+ $$renderer.push(`Default`);
1625
+ });
1626
+ $$renderer.option({ value: "on" }, ($$renderer) => {
1627
+ $$renderer.push(`Enabled`);
1628
+ });
1629
+ $$renderer.option({ value: "off" }, ($$renderer) => {
1630
+ $$renderer.push(`Disabled`);
1631
+ });
1632
+ }, "svelte-1ndbe78");
1633
+ $$renderer.push(`</div> <div class="control-group svelte-1ndbe78"><label class="control-label svelte-1ndbe78" for="d-imp-syncpush">Push to remote</label> `);
1634
+ $$renderer.select({
1635
+ id: "d-imp-syncpush",
1636
+ class: "control-input",
1637
+ value: draft.syncPush
1638
+ }, ($$renderer) => {
1639
+ $$renderer.option({ value: "" }, ($$renderer) => {
1640
+ $$renderer.push(`Default`);
1641
+ });
1642
+ $$renderer.option({ value: "on" }, ($$renderer) => {
1643
+ $$renderer.push(`Enabled`);
1644
+ });
1645
+ $$renderer.option({ value: "off" }, ($$renderer) => {
1646
+ $$renderer.push(`Disabled`);
1647
+ });
1648
+ }, "svelte-1ndbe78");
1649
+ $$renderer.push(`</div> <div class="control-group control-group--wide svelte-1ndbe78"><label class="control-label svelte-1ndbe78" for="d-imp-syncmsg">Commit message</label> <input id="d-imp-syncmsg" class="control-input svelte-1ndbe78" type="text" spellcheck="false" placeholder="Optional commit message"${attr("value", draft.syncMessage)}/></div></div></div> <div class="drawer-footer svelte-1ndbe78"><button class="btn btn-secondary">Cancel</button> <button class="btn btn-primary">Apply</button></div></div>`);
1650
+ bind_props($$props, { draft });
1651
+ });
1652
+ }
1653
+ //#endregion
1654
+ //#region src/lib/components/akm/AkmTab.svelte
1655
+ function AkmTab($$renderer, $$props) {
1656
+ $$renderer.component(($$renderer) => {
1657
+ let saving = false;
1658
+ let llmProfiles = [];
1659
+ let defaultLlmProfile = "";
1660
+ let agentProfiles = [];
1661
+ let defaultAgentProfile = "";
1662
+ let improveProfiles = [];
1663
+ let defaultImproveProfile = "";
1664
+ let embEndpoint = "";
1665
+ let embModel = "";
1666
+ let embProvider = "";
1667
+ let embApiKey = "";
1668
+ let embDimension = 1536;
1669
+ let embLocalModel = "";
1670
+ let embBatchSize = "";
1671
+ let embChunkSize = "";
1672
+ let embContextLength = "";
1673
+ let embOllamaNumCtx = "";
1674
+ let drawerType = null;
1675
+ let drawerLlm = null;
1676
+ let drawerAgent = null;
1677
+ let drawerImprove = null;
1678
+ let llmProfileNames = derived(() => llmProfiles.map((p) => p.name).filter((n) => n));
1679
+ function newLlmProfile() {
1680
+ return {
1681
+ id: crypto.randomUUID(),
1682
+ name: "",
1683
+ endpoint: "",
1684
+ model: "",
1685
+ provider: "",
1686
+ apiKey: "",
1687
+ showApiKey: false,
1688
+ temperature: "",
1689
+ maxTokens: "",
1690
+ timeoutMs: "",
1691
+ concurrency: "",
1692
+ contextLength: "",
1693
+ judgeModel: "",
1694
+ supportsJsonSchema: false,
1695
+ enableThinking: false,
1696
+ structuredOutput: false,
1697
+ extraParams: ""
1698
+ };
1699
+ }
1700
+ function newAgentProfile() {
1701
+ return {
1702
+ id: crypto.randomUUID(),
1703
+ name: "",
1704
+ platform: "opencode",
1705
+ bin: "",
1706
+ args: "",
1707
+ workspace: "",
1708
+ model: ""
1709
+ };
1710
+ }
1711
+ function newImproveProfile() {
1712
+ const processes = {};
1713
+ for (const k of PROCESS_KEYS) processes[k] = emptyFEntry(DEFAULT_ENABLED[k]);
1714
+ return {
1715
+ id: crypto.randomUUID(),
1716
+ name: "",
1717
+ description: "",
1718
+ limit: 25,
1719
+ autoAccept: 0,
1720
+ processes,
1721
+ syncEnabled: "",
1722
+ syncPush: "",
1723
+ syncMessage: ""
1724
+ };
1725
+ }
1726
+ function openLlmDrawer(p) {
1727
+ drawerLlm = { ...p };
1728
+ drawerType = "llm";
1729
+ }
1730
+ function openAgentDrawer(p) {
1731
+ drawerAgent = { ...p };
1732
+ drawerType = "agent";
1733
+ }
1734
+ function openImproveDrawer(ip) {
1735
+ const processes = {};
1736
+ for (const k of PROCESS_KEYS) {
1737
+ const src = ip.processes[k];
1738
+ processes[k] = {
1739
+ ...src,
1740
+ judgment: { ...src.judgment },
1741
+ rest: { ...src.rest }
1742
+ };
1743
+ }
1744
+ drawerImprove = {
1745
+ ...ip,
1746
+ processes
1747
+ };
1748
+ drawerType = "improve";
1749
+ }
1750
+ function applyDrawer() {
1751
+ if (drawerType === "llm" && drawerLlm) {
1752
+ const copy = { ...drawerLlm };
1753
+ const idx = llmProfiles.findIndex((p) => p.id === copy.id);
1754
+ const oldName = idx >= 0 ? llmProfiles[idx].name : "";
1755
+ llmProfiles = idx >= 0 ? llmProfiles.map((p, i) => i === idx ? copy : p) : [...llmProfiles, copy];
1756
+ if (defaultLlmProfile === oldName) defaultLlmProfile = copy.name;
1757
+ } else if (drawerType === "agent" && drawerAgent) {
1758
+ const copy = { ...drawerAgent };
1759
+ const idx = agentProfiles.findIndex((p) => p.id === copy.id);
1760
+ const oldName = idx >= 0 ? agentProfiles[idx].name : "";
1761
+ agentProfiles = idx >= 0 ? agentProfiles.map((p, i) => i === idx ? copy : p) : [...agentProfiles, copy];
1762
+ if (defaultAgentProfile === oldName) defaultAgentProfile = copy.name;
1763
+ } else if (drawerType === "improve" && drawerImprove) {
1764
+ const copy = {
1765
+ ...drawerImprove,
1766
+ processes: { ...drawerImprove.processes }
1767
+ };
1768
+ const idx = improveProfiles.findIndex((ip) => ip.id === copy.id);
1769
+ const oldName = idx >= 0 ? improveProfiles[idx].name : "";
1770
+ improveProfiles = idx >= 0 ? improveProfiles.map((ip, i) => i === idx ? copy : ip) : [...improveProfiles, copy];
1771
+ if (defaultImproveProfile === oldName) defaultImproveProfile = copy.name;
1772
+ }
1773
+ closeDrawer();
1774
+ }
1775
+ function closeDrawer() {
1776
+ drawerType = null;
1777
+ drawerLlm = null;
1778
+ drawerAgent = null;
1779
+ drawerImprove = null;
1780
+ }
1781
+ function removeProfile(type, id) {
1782
+ if (type === "llm") {
1783
+ const name = llmProfiles.find((p) => p.id === id)?.name ?? "";
1784
+ if (defaultLlmProfile === name) defaultLlmProfile = "";
1785
+ llmProfiles = llmProfiles.filter((p) => p.id !== id);
1786
+ } else if (type === "agent") {
1787
+ const name = agentProfiles.find((p) => p.id === id)?.name ?? "";
1788
+ if (defaultAgentProfile === name) defaultAgentProfile = "";
1789
+ agentProfiles = agentProfiles.filter((p) => p.id !== id);
1790
+ } else {
1791
+ const name = improveProfiles.find((ip) => ip.id === id)?.name ?? "";
1792
+ if (defaultImproveProfile === name) defaultImproveProfile = "";
1793
+ improveProfiles = improveProfiles.filter((ip) => ip.id !== id);
1794
+ }
1795
+ if (drawerType === type) closeDrawer();
1796
+ }
1797
+ let $$settled = true;
1798
+ let $$inner_renderer;
1799
+ function $$render_inner($$renderer) {
1800
+ $$renderer.push(`<div class="panel" role="tabpanel"><div class="panel-header svelte-19wb2va"><h2 class="svelte-19wb2va">Knowledge</h2> <div class="panel-header-actions svelte-19wb2va"><button class="btn btn-secondary btn-sm"${attr("disabled", false, true)}>`);
1801
+ $$renderer.push("<!--[-1-->");
1802
+ $$renderer.push(`<!--]--> Refresh</button> <button class="btn btn-primary btn-sm"${attr("disabled", false, true)}>`);
1803
+ $$renderer.push("<!--[-1-->");
1804
+ $$renderer.push(`<!--]--> Save</button></div></div> `);
1805
+ $$renderer.push("<!--[-1-->");
1806
+ $$renderer.push(`<!--]--> <div class="panel-body svelte-19wb2va"><div class="k-tabs svelte-19wb2va" role="tablist" aria-label="Knowledge sections"><button role="tab"${attr_class("k-tab svelte-19wb2va", void 0, { "k-tab--active": true })}${attr("aria-selected", true)}>AI Services</button> <button role="tab"${attr_class("k-tab svelte-19wb2va", void 0, { "k-tab--active": false })}${attr("aria-selected", false)}>Behavior</button></div> `);
1807
+ $$renderer.push("<!--[0-->");
1808
+ $$renderer.push(`<p class="section-note section-note--lead svelte-19wb2va">The AI services your assistant uses to build and search its memory — the language models that organize memories, the embedding provider for semantic search, and the maintenance pipeline.</p> `);
1809
+ LlmProfilesSection($$renderer, {
1810
+ disabled: saving,
1811
+ onedit: (p) => openLlmDrawer(p),
1812
+ onadd: () => {
1813
+ drawerLlm = newLlmProfile();
1814
+ drawerType = "llm";
1815
+ },
1816
+ onremove: (id) => removeProfile("llm", id),
1817
+ get profiles() {
1818
+ return llmProfiles;
1819
+ },
1820
+ set profiles($$value) {
1821
+ llmProfiles = $$value;
1822
+ $$settled = false;
1823
+ },
1824
+ get defaultName() {
1825
+ return defaultLlmProfile;
1826
+ },
1827
+ set defaultName($$value) {
1828
+ defaultLlmProfile = $$value;
1829
+ $$settled = false;
1830
+ }
1831
+ });
1832
+ $$renderer.push(`<!----> `);
1833
+ AgentProfilesSection($$renderer, {
1834
+ disabled: saving,
1835
+ onedit: (p) => openAgentDrawer(p),
1836
+ onadd: () => {
1837
+ drawerAgent = newAgentProfile();
1838
+ drawerType = "agent";
1839
+ },
1840
+ onremove: (id) => removeProfile("agent", id),
1841
+ get profiles() {
1842
+ return agentProfiles;
1843
+ },
1844
+ set profiles($$value) {
1845
+ agentProfiles = $$value;
1846
+ $$settled = false;
1847
+ },
1848
+ get defaultName() {
1849
+ return defaultAgentProfile;
1850
+ },
1851
+ set defaultName($$value) {
1852
+ defaultAgentProfile = $$value;
1853
+ $$settled = false;
1854
+ }
1855
+ });
1856
+ $$renderer.push(`<!----> `);
1857
+ ImproveProfilesSection($$renderer, {
1858
+ disabled: saving,
1859
+ onedit: (ip) => openImproveDrawer(ip),
1860
+ onadd: () => {
1861
+ drawerImprove = newImproveProfile();
1862
+ drawerType = "improve";
1863
+ },
1864
+ onremove: (id) => removeProfile("improve", id),
1865
+ get profiles() {
1866
+ return improveProfiles;
1867
+ },
1868
+ set profiles($$value) {
1869
+ improveProfiles = $$value;
1870
+ $$settled = false;
1871
+ },
1872
+ get defaultName() {
1873
+ return defaultImproveProfile;
1874
+ },
1875
+ set defaultName($$value) {
1876
+ defaultImproveProfile = $$value;
1877
+ $$settled = false;
1878
+ }
1879
+ });
1880
+ $$renderer.push(`<!----> `);
1881
+ EmbeddingSection($$renderer, {
1882
+ disabled: saving,
1883
+ get endpoint() {
1884
+ return embEndpoint;
1885
+ },
1886
+ set endpoint($$value) {
1887
+ embEndpoint = $$value;
1888
+ $$settled = false;
1889
+ },
1890
+ get model() {
1891
+ return embModel;
1892
+ },
1893
+ set model($$value) {
1894
+ embModel = $$value;
1895
+ $$settled = false;
1896
+ },
1897
+ get provider() {
1898
+ return embProvider;
1899
+ },
1900
+ set provider($$value) {
1901
+ embProvider = $$value;
1902
+ $$settled = false;
1903
+ },
1904
+ get apiKey() {
1905
+ return embApiKey;
1906
+ },
1907
+ set apiKey($$value) {
1908
+ embApiKey = $$value;
1909
+ $$settled = false;
1910
+ },
1911
+ get dimension() {
1912
+ return embDimension;
1913
+ },
1914
+ set dimension($$value) {
1915
+ embDimension = $$value;
1916
+ $$settled = false;
1917
+ },
1918
+ get localModel() {
1919
+ return embLocalModel;
1920
+ },
1921
+ set localModel($$value) {
1922
+ embLocalModel = $$value;
1923
+ $$settled = false;
1924
+ },
1925
+ get batchSize() {
1926
+ return embBatchSize;
1927
+ },
1928
+ set batchSize($$value) {
1929
+ embBatchSize = $$value;
1930
+ $$settled = false;
1931
+ },
1932
+ get chunkSize() {
1933
+ return embChunkSize;
1934
+ },
1935
+ set chunkSize($$value) {
1936
+ embChunkSize = $$value;
1937
+ $$settled = false;
1938
+ },
1939
+ get contextLength() {
1940
+ return embContextLength;
1941
+ },
1942
+ set contextLength($$value) {
1943
+ embContextLength = $$value;
1944
+ $$settled = false;
1945
+ },
1946
+ get ollamaNumCtx() {
1947
+ return embOllamaNumCtx;
1948
+ },
1949
+ set ollamaNumCtx($$value) {
1950
+ embOllamaNumCtx = $$value;
1951
+ $$settled = false;
1952
+ }
1953
+ });
1954
+ $$renderer.push(`<!---->`);
1955
+ $$renderer.push(`<!--]--> `);
1956
+ $$renderer.push("<!--[-1-->");
1957
+ $$renderer.push(`<!--]--></div> `);
1958
+ if (drawerType === "llm" && drawerLlm) {
1959
+ $$renderer.push("<!--[0-->");
1960
+ LlmProfileDrawer($$renderer, {
1961
+ oncancel: closeDrawer,
1962
+ onapply: applyDrawer,
1963
+ get draft() {
1964
+ return drawerLlm;
1965
+ },
1966
+ set draft($$value) {
1967
+ drawerLlm = $$value;
1968
+ $$settled = false;
1969
+ }
1970
+ });
1971
+ } else if (drawerType === "agent" && drawerAgent) {
1972
+ $$renderer.push("<!--[1-->");
1973
+ AgentProfileDrawer($$renderer, {
1974
+ oncancel: closeDrawer,
1975
+ onapply: applyDrawer,
1976
+ get draft() {
1977
+ return drawerAgent;
1978
+ },
1979
+ set draft($$value) {
1980
+ drawerAgent = $$value;
1981
+ $$settled = false;
1982
+ }
1983
+ });
1984
+ } else if (drawerType === "improve" && drawerImprove) {
1985
+ $$renderer.push("<!--[2-->");
1986
+ ImproveProfileDrawer($$renderer, {
1987
+ llmProfileNames: llmProfileNames(),
1988
+ oncancel: closeDrawer,
1989
+ onapply: applyDrawer,
1990
+ get draft() {
1991
+ return drawerImprove;
1992
+ },
1993
+ set draft($$value) {
1994
+ drawerImprove = $$value;
1995
+ $$settled = false;
1996
+ }
1997
+ });
1998
+ } else $$renderer.push("<!--[-1-->");
1999
+ $$renderer.push(`<!--]--></div>`);
2000
+ }
2001
+ do {
2002
+ $$settled = true;
2003
+ $$inner_renderer = $$renderer.copy();
2004
+ $$render_inner($$inner_renderer);
2005
+ } while (!$$settled);
2006
+ $$renderer.subsume($$inner_renderer);
2007
+ });
2008
+ }
2009
+ //#endregion
2010
+ //#region src/lib/components/akm/HostSharingSection.svelte
2011
+ function HostSharingSection($$renderer, $$props) {
2012
+ $$renderer.component(($$renderer) => {
2013
+ $$renderer.push(`<div class="panel" role="tabpanel"><div class="panel-header svelte-fv9i73"><h2 class="svelte-fv9i73">Host knowledge sharing</h2></div> <div class="panel-body">`);
2014
+ $$renderer.push("<!--[0-->");
2015
+ $$renderer.push(`<div class="hs-loading svelte-fv9i73">`);
2016
+ Spinner($$renderer, {});
2017
+ $$renderer.push(`<!----> Checking host stash…</div>`);
2018
+ $$renderer.push(`<!--]--></div></div>`);
2019
+ });
2020
+ }
2021
+ //#endregion
2022
+ //#region src/lib/components/voice/VoiceTtsSection.svelte
2023
+ function VoiceTtsSection($$renderer, $$props) {
2024
+ $$renderer.component(($$renderer) => {
2025
+ let { value, onchange, engineOptions, engineConfigs, reachable, hiddenEngines, engineSelected, ttsAutoEnabled, busy } = $$props;
2026
+ $$renderer.push(`<section class="engine-section svelte-1b9l1t7"><h3 class="engine-heading svelte-1b9l1t7">Text-to-Speech</h3> <p class="engine-subheading svelte-1b9l1t7">How your assistant speaks</p> `);
2027
+ VoiceEngineSelector($$renderer, {
2028
+ kind: "tts",
2029
+ value,
2030
+ onchange,
2031
+ engineOptions,
2032
+ engineConfigs,
2033
+ reachable,
2034
+ reachabilityEngineId: "remote",
2035
+ hiddenEngines
2036
+ });
2037
+ $$renderer.push(`<!----> `);
2038
+ if (engineSelected) {
2039
+ $$renderer.push("<!--[0-->");
2040
+ $$renderer.push(`<div class="tts-extras svelte-1b9l1t7"><div class="test-voice-row svelte-1b9l1t7"><button type="button" class="btn btn-secondary btn-sm"${attr("disabled", busy, true)}>`);
2041
+ $$renderer.push("<!--[-1-->");
2042
+ $$renderer.push(`<!--]--> Test voice</button> `);
2043
+ $$renderer.push("<!--[-1-->");
2044
+ $$renderer.push(`<!--]--></div> <label class="auto-speak-toggle svelte-1b9l1t7"><input type="checkbox"${attr("checked", ttsAutoEnabled, true)} class="svelte-1b9l1t7"/> <span>Speak assistant replies aloud automatically</span></label></div>`);
2045
+ } else $$renderer.push("<!--[-1-->");
2046
+ $$renderer.push(`<!--]--></section>`);
2047
+ });
2048
+ }
2049
+ //#endregion
2050
+ //#region src/lib/components/voice/VoiceSttSection.svelte
2051
+ function VoiceSttSection($$renderer, $$props) {
2052
+ let { value, onchange, engineOptions, engineConfigs, reachable, disabledEngines, hiddenEngines } = $$props;
2053
+ $$renderer.push(`<section class="engine-section svelte-1qwlk8j"><h3 class="engine-heading svelte-1qwlk8j">Speech-to-Text</h3> <p class="engine-subheading svelte-1qwlk8j">How your assistant listens</p> `);
2054
+ VoiceEngineSelector($$renderer, {
2055
+ kind: "stt",
2056
+ value,
2057
+ onchange,
2058
+ engineOptions,
2059
+ engineConfigs,
2060
+ reachable,
2061
+ reachabilityEngineId: "remote",
2062
+ disabledEngines,
2063
+ hiddenEngines
2064
+ });
2065
+ $$renderer.push(`<!----></section>`);
2066
+ }
2067
+ //#endregion
2068
+ //#region src/lib/components/voice/VoiceAddonProfileSection.svelte
2069
+ function VoiceAddonProfileSection($$renderer, $$props) {
2070
+ let { profiles, selectedProfile, onchange } = $$props;
2071
+ $$renderer.push(`<section class="engine-section svelte-1r7l91t"><h3 class="engine-heading svelte-1r7l91t">Hardware profile</h3> `);
2072
+ VoiceProfileSelector($$renderer, {
2073
+ profiles,
2074
+ selectedProfile,
2075
+ onchange
2076
+ });
2077
+ $$renderer.push(`<!----></section>`);
2078
+ }
2079
+ //#endregion
2080
+ //#region src/lib/components/voice/VoiceTab.svelte
2081
+ function VoiceTab($$renderer, $$props) {
2082
+ $$renderer.component(($$renderer) => {
2083
+ const ADMIN_TTS_OPTIONS = [
2084
+ {
2085
+ id: "openpalm-voice",
2086
+ name: "OpenPalm Voice",
2087
+ type: "local",
2088
+ recommended: true,
2089
+ desc: "Local Kokoro TTS + Whisper STT bundled together."
2090
+ },
2091
+ {
2092
+ id: "remote",
2093
+ name: "Remote (OpenAI-compatible)",
2094
+ type: "cloud",
2095
+ desc: "Point at any /v1/audio/speech endpoint (OpenAI, Kokoro, Piper, …)."
2096
+ },
2097
+ {
2098
+ id: "browser",
2099
+ name: "Browser",
2100
+ type: "builtin",
2101
+ desc: "Web Speech API on this device. No setup, voice quality varies."
2102
+ }
2103
+ ];
2104
+ const ADMIN_STT_OPTIONS = [
2105
+ {
2106
+ id: "openpalm-voice",
2107
+ name: "OpenPalm Voice",
2108
+ type: "local",
2109
+ recommended: true,
2110
+ desc: "Local Kokoro TTS + Whisper STT bundled together."
2111
+ },
2112
+ {
2113
+ id: "remote",
2114
+ name: "Remote (OpenAI-compatible)",
2115
+ type: "cloud",
2116
+ desc: "Point at any /v1/audio/transcriptions endpoint (Whisper, …)."
2117
+ },
2118
+ {
2119
+ id: "browser",
2120
+ name: "Browser",
2121
+ type: "builtin",
2122
+ desc: "Web Speech API on this device. Chrome/Edge only on desktop."
2123
+ }
2124
+ ];
2125
+ const ADMIN_TTS_ENGINES = {
2126
+ "openpalm-voice": {
2127
+ id: "openpalm-voice",
2128
+ fields: []
2129
+ },
2130
+ remote: {
2131
+ id: "remote",
2132
+ fields: [
2133
+ {
2134
+ key: "baseURL",
2135
+ label: "Endpoint URL",
2136
+ placeholder: "http://host.docker.internal:8880/v1",
2137
+ hint: "OpenAI-compatible /v1/audio/speech endpoint."
2138
+ },
2139
+ {
2140
+ key: "model",
2141
+ label: "Model",
2142
+ placeholder: "tts-1"
2143
+ },
2144
+ {
2145
+ key: "voice",
2146
+ label: "Voice",
2147
+ placeholder: "alloy"
2148
+ }
2149
+ ]
2150
+ },
2151
+ browser: {
2152
+ id: "browser",
2153
+ fields: []
2154
+ }
2155
+ };
2156
+ const ADMIN_STT_ENGINES = {
2157
+ "openpalm-voice": {
2158
+ id: "openpalm-voice",
2159
+ fields: []
2160
+ },
2161
+ remote: {
2162
+ id: "remote",
2163
+ fields: [
2164
+ {
2165
+ key: "baseURL",
2166
+ label: "Endpoint URL",
2167
+ placeholder: "http://host.docker.internal:9000/v1",
2168
+ hint: "OpenAI-compatible /v1/audio/transcriptions endpoint."
2169
+ },
2170
+ {
2171
+ key: "model",
2172
+ label: "Model",
2173
+ placeholder: "whisper-1"
2174
+ },
2175
+ {
2176
+ key: "language",
2177
+ label: "Language",
2178
+ placeholder: "en",
2179
+ hint: "A code like `en` or `fr`, or leave blank to detect."
2180
+ }
2181
+ ]
2182
+ },
2183
+ browser: {
2184
+ id: "browser",
2185
+ fields: [{
2186
+ key: "language",
2187
+ label: "Language",
2188
+ placeholder: "en-US"
2189
+ }]
2190
+ }
2191
+ };
2192
+ const EMPTY_SECTION = () => ({
2193
+ engine: "",
2194
+ baseURL: "",
2195
+ model: "",
2196
+ voice: "",
2197
+ language: ""
2198
+ });
2199
+ let loading = false;
2200
+ let tts = EMPTY_SECTION();
2201
+ let stt = EMPTY_SECTION();
2202
+ let availability = {
2203
+ stt: {
2204
+ remoteConfigured: false,
2205
+ remoteReachable: false
2206
+ },
2207
+ tts: {
2208
+ remoteConfigured: false,
2209
+ remoteReachable: false
2210
+ }
2211
+ };
2212
+ let addonProfiles = [];
2213
+ let selectedProfile = "";
2214
+ const wantsOpenpalmVoice = derived(() => tts.engine === "openpalm-voice" || stt.engine === "openpalm-voice");
2215
+ function sectionToValue(s) {
2216
+ return {
2217
+ engine: s.engine,
2218
+ ...s.baseURL ? { baseURL: s.baseURL } : {},
2219
+ ...s.model ? { model: s.model } : {},
2220
+ ...s.voice ? { voice: s.voice } : {},
2221
+ ...s.language ? { language: s.language } : {}
2222
+ };
2223
+ }
2224
+ function applyTtsChange(v) {
2225
+ tts.engine = v.engine || "";
2226
+ tts.baseURL = v.baseURL ?? "";
2227
+ tts.model = v.model ?? "";
2228
+ tts.voice = v.voice ?? "";
2229
+ }
2230
+ function applySttChange(v) {
2231
+ stt.engine = v.engine || "";
2232
+ stt.baseURL = v.baseURL ?? "";
2233
+ stt.model = v.model ?? "";
2234
+ stt.language = v.language ?? "";
2235
+ }
2236
+ const sttDisabledEngines = derived(() => {
2237
+ return {};
2238
+ });
2239
+ const ttsHiddenEngines = derived(() => new Set(["browser"]));
2240
+ const sttHiddenEngines = derived(() => new Set(["browser"]));
2241
+ $$renderer.push(`<div class="panel" role="tabpanel"><div class="panel-header svelte-nokcxu"><h2 class="svelte-nokcxu">Voice</h2> <div class="panel-header-actions svelte-nokcxu"><button class="btn btn-secondary btn-sm"${attr("disabled", false, true)}>`);
2242
+ $$renderer.push("<!--[-1-->");
2243
+ $$renderer.push(`<!--]--> Refresh</button> <button class="btn btn-primary btn-sm"${attr("disabled", false, true)}>`);
2244
+ $$renderer.push("<!--[-1-->");
2245
+ $$renderer.push(`<!--]--> Save</button></div></div> `);
2246
+ $$renderer.push("<!--[-1-->");
2247
+ $$renderer.push(`<!--]--> <div class="panel-body svelte-nokcxu"><p class="section-desc svelte-nokcxu">Configure how the assistant listens and speaks. Choose an engine for each;
2248
+ the in-app mic uses STT and the optional auto-speak toggle uses TTS.</p> `);
2249
+ VoiceTtsSection($$renderer, {
2250
+ value: sectionToValue(tts),
2251
+ onchange: applyTtsChange,
2252
+ engineOptions: ADMIN_TTS_OPTIONS,
2253
+ engineConfigs: ADMIN_TTS_ENGINES,
2254
+ reachable: availability.tts,
2255
+ hiddenEngines: ttsHiddenEngines(),
2256
+ engineSelected: !!tts.engine,
2257
+ ttsAutoEnabled: voiceState.ttsAutoEnabled,
2258
+ busy: loading
2259
+ });
2260
+ $$renderer.push(`<!----> `);
2261
+ VoiceSttSection($$renderer, {
2262
+ value: sectionToValue(stt),
2263
+ onchange: applySttChange,
2264
+ engineOptions: ADMIN_STT_OPTIONS,
2265
+ engineConfigs: ADMIN_STT_ENGINES,
2266
+ reachable: availability.stt,
2267
+ disabledEngines: sttDisabledEngines(),
2268
+ hiddenEngines: sttHiddenEngines()
2269
+ });
2270
+ $$renderer.push(`<!----> `);
2271
+ if (wantsOpenpalmVoice() && addonProfiles.length > 0) {
2272
+ $$renderer.push("<!--[0-->");
2273
+ VoiceAddonProfileSection($$renderer, {
2274
+ profiles: addonProfiles,
2275
+ selectedProfile,
2276
+ onchange: (id) => selectedProfile = id
2277
+ });
2278
+ } else $$renderer.push("<!--[-1-->");
2279
+ $$renderer.push(`<!--]--></div></div>`);
2280
+ });
2281
+ }
2282
+ //#endregion
2283
+ //#region src/routes/admin/+page.svelte
2284
+ function _page($$renderer, $$props) {
2285
+ $$renderer.component(($$renderer) => {
2286
+ let authLocked = true;
2287
+ let authLoading = false;
2288
+ let authError = "";
2289
+ let adminHealth = null;
2290
+ let healthLoading = false;
2291
+ let upgradeLoading = false;
2292
+ let containersLoading = false;
2293
+ let automationsLoading = false;
2294
+ let containerData = null;
2295
+ let containerError = "";
2296
+ let containersLastUpdated = null;
2297
+ let automationsData = null;
2298
+ let automationsError = "";
2299
+ let selectedContainerId = null;
2300
+ let activeTab = "overview";
2301
+ let currentImageTag = "";
2302
+ let inElectron = false;
2303
+ let tagChangeLoading = false;
2304
+ let uiDownloadLoading = false;
2305
+ let selectedImageTag = "latest";
2306
+ let selectedUiTag = "";
2307
+ let releases = [];
2308
+ let releasesLoading = false;
2309
+ let uiVersions = [];
2310
+ let uiVersionsLoading = false;
2311
+ const POLL_INTERVAL_MS = 1e4;
2312
+ let pollTimer = null;
2313
+ function startContainerPolling() {
2314
+ stopContainerPolling();
2315
+ pollTimer = setInterval(() => {
2316
+ if (!authLocked && containerData) loadContainers();
2317
+ }, POLL_INTERVAL_MS);
2318
+ }
2319
+ function stopContainerPolling() {
2320
+ if (pollTimer !== null) {
2321
+ clearInterval(pollTimer);
2322
+ pollTimer = null;
2323
+ }
2324
+ }
2325
+ onDestroy(() => {
2326
+ stopContainerPolling();
2327
+ });
2328
+ let anyDangerousLoading = derived(() => upgradeLoading);
2329
+ /** Merged service → state map (used by OverviewTab for health indicators) */
2330
+ let mergedServices = derived(() => {
2331
+ if (!containerData) return /* @__PURE__ */ new Map();
2332
+ const merged = /* @__PURE__ */ new Map();
2333
+ if (containerData.containers) for (const [name, state] of Object.entries(containerData.containers)) merged.set(name, state);
2334
+ if (containerData.dockerContainers) for (const c of containerData.dockerContainers) merged.set(c.Service, c.State);
2335
+ return merged;
2336
+ });
2337
+ /** Full merged ServiceEntry list (used by ContainersTab for detail rows) */
2338
+ let serviceEntries = derived(() => {
2339
+ if (!containerData) return [];
2340
+ const byService = /* @__PURE__ */ new Map();
2341
+ if (containerData.containers) for (const [name, state] of Object.entries(containerData.containers)) byService.set(name, {
2342
+ id: name,
2343
+ service: name,
2344
+ state,
2345
+ docker: null
2346
+ });
2347
+ if (containerData.dockerContainers) for (const c of containerData.dockerContainers) {
2348
+ const existing = byService.get(c.Service);
2349
+ if (existing) {
2350
+ existing.state = c.State;
2351
+ existing.docker = c;
2352
+ existing.id = c.ID;
2353
+ } else byService.set(c.Service, {
2354
+ id: c.ID,
2355
+ service: c.Service || c.Name,
2356
+ state: c.State,
2357
+ docker: c
2358
+ });
2359
+ }
2360
+ return [...byService.values()].sort((a, b) => {
2361
+ if (a.state === "running" && b.state !== "running") return -1;
2362
+ if (a.state !== "running" && b.state === "running") return 1;
2363
+ return a.service.localeCompare(b.service);
2364
+ });
2365
+ });
2366
+ function applyInvalidTokenState() {
2367
+ authLocked = true;
2368
+ authError = "Invalid password.";
2369
+ }
2370
+ async function handleAuthSuccess(token) {
2371
+ if (authLoading) return false;
2372
+ authLoading = true;
2373
+ authError = "";
2374
+ try {
2375
+ if (!(await fetch("/admin/auth/login", {
2376
+ method: "POST",
2377
+ headers: { "content-type": "application/json" },
2378
+ body: JSON.stringify({ password: token }),
2379
+ credentials: "include"
2380
+ })).ok) {
2381
+ applyInvalidTokenState();
2382
+ return false;
2383
+ }
2384
+ authLocked = false;
2385
+ authError = "";
2386
+ startContainerPolling();
2387
+ await loadHealth();
2388
+ loadContainers();
2389
+ loadAutomations();
2390
+ loadVersions();
2391
+ loadReleases();
2392
+ return true;
2393
+ } catch (e) {
2394
+ console.warn("[page] Auth failed:", e);
2395
+ authError = "Unable to reach admin API.";
2396
+ return false;
2397
+ } finally {
2398
+ authLoading = false;
2399
+ }
2400
+ }
2401
+ async function loadHealth() {
2402
+ healthLoading = true;
2403
+ try {
2404
+ const health = await fetchHealth();
2405
+ adminHealth = health.admin;
2406
+ health.guardian;
2407
+ } catch (e) {
2408
+ console.warn("[page] Health check failed:", e);
2409
+ adminHealth = {
2410
+ status: "error",
2411
+ service: "admin"
2412
+ };
2413
+ }
2414
+ healthLoading = false;
2415
+ }
2416
+ async function loadContainers() {
2417
+ containersLoading = true;
2418
+ containerError = "";
2419
+ try {
2420
+ containerData = await fetchContainers();
2421
+ } catch (e) {
2422
+ containerData = null;
2423
+ const err = e;
2424
+ if (err.status === 401) {
2425
+ containerError = "Invalid password.";
2426
+ applyInvalidTokenState();
2427
+ } else containerError = `Failed to load containers: ${err.message ?? e}`;
2428
+ }
2429
+ containersLoading = false;
2430
+ if (containerData) containersLastUpdated = (/* @__PURE__ */ new Date()).toLocaleTimeString();
2431
+ }
2432
+ async function loadAutomations() {
2433
+ automationsLoading = true;
2434
+ automationsError = "";
2435
+ try {
2436
+ automationsData = await fetchAutomations();
2437
+ } catch (e) {
2438
+ automationsData = null;
2439
+ const err = e;
2440
+ if (err.status === 401) {
2441
+ automationsError = "Invalid password.";
2442
+ applyInvalidTokenState();
2443
+ } else automationsError = `Failed to load automations: ${err.message ?? e}`;
2444
+ }
2445
+ automationsLoading = false;
2446
+ }
2447
+ async function loadVersions() {
2448
+ try {
2449
+ const data = await fetchVersions();
2450
+ currentImageTag = data.imageTag;
2451
+ inElectron = data.inElectron;
2452
+ } catch {}
2453
+ }
2454
+ async function loadReleases() {
2455
+ releasesLoading = true;
2456
+ uiVersionsLoading = true;
2457
+ try {
2458
+ const [releaseData, uiData] = await Promise.all([fetchReleases(), fetchUiVersions()]);
2459
+ releases = releaseData.releases;
2460
+ uiVersions = uiData.versions;
2461
+ if (!selectedUiTag) {
2462
+ const channelPick = uiData.versions.find((v) => v.distTag === "next" || v.distTag === "latest") ?? uiData.versions[0];
2463
+ if (channelPick) selectedUiTag = channelPick.version;
2464
+ }
2465
+ } catch {}
2466
+ releasesLoading = false;
2467
+ uiVersionsLoading = false;
2468
+ }
2469
+ /** Derive service names from container data for the logs tab */
2470
+ let serviceNames = derived(() => {
2471
+ if (!containerData) return [];
2472
+ const names = /* @__PURE__ */ new Set();
2473
+ if (containerData.containers) for (const name of Object.keys(containerData.containers)) names.add(name);
2474
+ if (containerData.dockerContainers) {
2475
+ for (const c of containerData.dockerContainers) if (c.Service) names.add(c.Service);
2476
+ }
2477
+ return [...names].sort();
2478
+ });
2479
+ function handleTabSelect(tab) {
2480
+ activeTab = tab;
2481
+ if (tab === "containers" && !containerData) loadContainers();
2482
+ if (tab === "automations" && !automationsData) loadAutomations();
2483
+ }
2484
+ head("1jef3w8", $$renderer, ($$renderer) => {
2485
+ $$renderer.title(($$renderer) => {
2486
+ $$renderer.push(`<title>OpenPalm Console</title>`);
2487
+ });
2488
+ });
2489
+ if (authLocked) {
2490
+ $$renderer.push("<!--[0-->");
2491
+ AuthGate($$renderer, {
2492
+ onSuccess: handleAuthSuccess,
2493
+ loading: authLoading,
2494
+ error: authError
2495
+ });
2496
+ } else {
2497
+ $$renderer.push("<!--[-1-->");
2498
+ Navbar($$renderer);
2499
+ $$renderer.push(`<!----> <main class="svelte-1jef3w8">`);
2500
+ TabBar($$renderer, {
2501
+ active: activeTab});
2502
+ $$renderer.push(`<!----> `);
2503
+ if (activeTab === "overview") {
2504
+ $$renderer.push("<!--[0-->");
2505
+ OverviewTab($$renderer, {
2506
+ healthLoading,
2507
+ anyDangerousLoading: anyDangerousLoading(),
2508
+ mergedServices: mergedServices(),
2509
+ onNavigate: handleTabSelect
2510
+ });
2511
+ } else if (activeTab === "updates") {
2512
+ $$renderer.push("<!--[1-->");
2513
+ UpdatesTab($$renderer, {
2514
+ currentImageTag,
2515
+ selectedImageTag,
2516
+ tagChangeLoading,
2517
+ anyDangerousLoading: anyDangerousLoading(),
2518
+ inElectron,
2519
+ uiVersions,
2520
+ uiVersionsLoading,
2521
+ selectedUiTag,
2522
+ uiDownloadLoading,
2523
+ releases,
2524
+ releasesLoading,
2525
+ onSelectedImageTagChange: (t) => {
2526
+ selectedImageTag = t;
2527
+ },
2528
+ onSelectedUiTagChange: (t) => {
2529
+ selectedUiTag = t;
2530
+ }});
2531
+ } else if (activeTab === "addons") {
2532
+ $$renderer.push("<!--[2-->");
2533
+ AddonsTab($$renderer);
2534
+ } else if (activeTab === "containers") {
2535
+ $$renderer.push("<!--[3-->");
2536
+ ContainersTab($$renderer, {
2537
+ containerData,
2538
+ serviceEntries: serviceEntries(),
2539
+ loading: containersLoading,
2540
+ error: containerError,
2541
+ selectedContainerId,
2542
+ lastUpdated: containersLastUpdated});
2543
+ } else if (activeTab === "automations") {
2544
+ $$renderer.push("<!--[4-->");
2545
+ AutomationsTab($$renderer, {
2546
+ data: automationsData,
2547
+ loading: automationsLoading,
2548
+ error: automationsError});
2549
+ } else if (activeTab === "connections") {
2550
+ $$renderer.push("<!--[5-->");
2551
+ ProvidersPanel($$renderer);
2552
+ } else if (activeTab === "secrets") {
2553
+ $$renderer.push("<!--[6-->");
2554
+ SecretsTab($$renderer);
2555
+ } else $$renderer.push("<!--[-1-->");
2556
+ $$renderer.push(`<!--]--> `);
2557
+ if (activeTab === "voice") {
2558
+ $$renderer.push("<!--[0-->");
2559
+ VoiceTab($$renderer);
2560
+ } else if (activeTab === "akm") {
2561
+ $$renderer.push("<!--[1-->");
2562
+ AkmTab($$renderer);
2563
+ } else if (activeTab === "host-sharing") {
2564
+ $$renderer.push("<!--[2-->");
2565
+ HostSharingSection($$renderer);
2566
+ } else if (activeTab === "logs") {
2567
+ $$renderer.push("<!--[3-->");
2568
+ LogsTab($$renderer, {
2569
+ services: serviceNames()
2570
+ });
2571
+ } else $$renderer.push("<!--[-1-->");
2572
+ $$renderer.push(`<!--]--></main>`);
2573
+ }
2574
+ $$renderer.push(`<!--]-->`);
2575
+ });
2576
+ }
2577
+
2578
+ export { _page as default };
2579
+ //# sourceMappingURL=_page.svelte-CEjRvc8B.js.map