@xopcai/xopcbot 0.1.5 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/README.md +6 -6
  2. package/README.zh-CN.md +6 -6
  3. package/dist/agent/__tests__/media-processing.test.d.ts +6 -0
  4. package/dist/agent/__tests__/media-processing.test.js +385 -0
  5. package/dist/agent/__tests__/media-processing.test.js.map +1 -0
  6. package/dist/agent/fallback/__tests__/index.test.js +16 -5
  7. package/dist/agent/fallback/__tests__/index.test.js.map +1 -1
  8. package/dist/agent/fallback/candidates.d.ts +2 -4
  9. package/dist/agent/fallback/candidates.js +19 -26
  10. package/dist/agent/fallback/candidates.js.map +1 -1
  11. package/dist/agent/helpers.d.ts +1 -0
  12. package/dist/agent/helpers.js.map +1 -1
  13. package/dist/agent/index.d.ts +6 -1
  14. package/dist/agent/index.js +10 -1
  15. package/dist/agent/index.js.map +1 -1
  16. package/dist/agent/models/compat.d.ts +35 -0
  17. package/dist/agent/models/compat.js +110 -0
  18. package/dist/agent/models/compat.js.map +1 -0
  19. package/dist/agent/models/fallback.d.ts +38 -0
  20. package/dist/agent/models/fallback.js +133 -0
  21. package/dist/agent/models/fallback.js.map +1 -0
  22. package/dist/agent/models/index.d.ts +10 -0
  23. package/dist/agent/models/index.js +11 -0
  24. package/dist/agent/models/index.js.map +1 -0
  25. package/dist/agent/{model-manager.d.ts → models/manager.d.ts} +2 -8
  26. package/dist/agent/{model-manager.js → models/manager.js} +38 -24
  27. package/dist/agent/models/manager.js.map +1 -0
  28. package/dist/agent/models/scan.d.ts +46 -0
  29. package/dist/agent/models/scan.js +177 -0
  30. package/dist/agent/models/scan.js.map +1 -0
  31. package/dist/agent/models/selection.d.ts +44 -0
  32. package/dist/agent/models/selection.js +141 -0
  33. package/dist/agent/models/selection.js.map +1 -0
  34. package/dist/agent/prompt/index.js +1 -1
  35. package/dist/agent/prompt/index.js.map +1 -1
  36. package/dist/agent/service.js +34 -16
  37. package/dist/agent/service.js.map +1 -1
  38. package/dist/agent/skills/__tests__/test-framework.test.js +15 -7
  39. package/dist/agent/skills/__tests__/test-framework.test.js.map +1 -1
  40. package/dist/agent/skills/config.d.ts +1 -1
  41. package/dist/agent/skills/config.js +2 -2
  42. package/dist/agent/skills/config.js.map +1 -1
  43. package/dist/agent/skills/index.js +15 -28
  44. package/dist/agent/skills/index.js.map +1 -1
  45. package/dist/agent/skills/installer.d.ts +1 -1
  46. package/dist/agent/skills/installer.js +1 -1
  47. package/dist/agent/skills/scanner.d.ts +1 -1
  48. package/dist/agent/skills/scanner.js +1 -1
  49. package/dist/agent/skills/test-framework.js +21 -20
  50. package/dist/agent/skills/test-framework.js.map +1 -1
  51. package/dist/agent/skills/types.d.ts +3 -3
  52. package/dist/agent/skills/types.js +1 -1
  53. package/dist/agent/skills/watcher.d.ts +1 -1
  54. package/dist/agent/skills/watcher.js +1 -1
  55. package/dist/agent/system-prompt.d.ts +67 -0
  56. package/dist/agent/system-prompt.js +351 -0
  57. package/dist/agent/system-prompt.js.map +1 -0
  58. package/dist/agent/tools/__tests__/send-media.test.d.ts +6 -0
  59. package/dist/agent/tools/__tests__/send-media.test.js +251 -0
  60. package/dist/agent/tools/__tests__/send-media.test.js.map +1 -0
  61. package/dist/agent/types.agent-defaults.d.ts +48 -0
  62. package/dist/agent/types.agent-defaults.js +5 -0
  63. package/dist/agent/types.agent-defaults.js.map +1 -0
  64. package/dist/agent/types.d.ts +14 -6
  65. package/dist/agent/types.js +5 -0
  66. package/dist/agent/types.js.map +1 -1
  67. package/dist/agent/workspace.d.ts +94 -0
  68. package/dist/agent/workspace.js +625 -0
  69. package/dist/agent/workspace.js.map +1 -0
  70. package/dist/auth/index.js +1 -1
  71. package/dist/auth/index.js.map +1 -1
  72. package/dist/auth/oauth/index.d.ts +1 -0
  73. package/dist/auth/oauth/index.js +1 -0
  74. package/dist/auth/oauth/index.js.map +1 -1
  75. package/dist/auth/oauth/kimi.d.ts +2 -1
  76. package/dist/auth/oauth/kimi.js +51 -48
  77. package/dist/auth/oauth/kimi.js.map +1 -1
  78. package/dist/auth/oauth/minimax-cn.d.ts +12 -0
  79. package/dist/auth/oauth/minimax-cn.js +111 -0
  80. package/dist/auth/oauth/minimax-cn.js.map +1 -0
  81. package/dist/auth/oauth/qwen.d.ts +5 -0
  82. package/dist/auth/oauth/qwen.js +54 -84
  83. package/dist/auth/oauth/qwen.js.map +1 -1
  84. package/dist/auth/profiles/index.d.ts +0 -2
  85. package/dist/auth/profiles/index.js +0 -2
  86. package/dist/auth/profiles/index.js.map +1 -1
  87. package/dist/auth/storage.js +7 -1
  88. package/dist/auth/storage.js.map +1 -1
  89. package/dist/channels/__tests__/media-integration.test.d.ts +6 -0
  90. package/dist/channels/__tests__/media-integration.test.js +398 -0
  91. package/dist/channels/__tests__/media-integration.test.js.map +1 -0
  92. package/dist/channels/__tests__/media.test.d.ts +6 -0
  93. package/dist/channels/__tests__/media.test.js +251 -0
  94. package/dist/channels/__tests__/media.test.js.map +1 -0
  95. package/dist/channels/access-control.d.ts +1 -1
  96. package/dist/channels/access-control.js +1 -1
  97. package/dist/channels/draft-stream.d.ts +1 -1
  98. package/dist/channels/draft-stream.js +1 -1
  99. package/dist/channels/format.d.ts +1 -1
  100. package/dist/channels/format.js +1 -1
  101. package/dist/channels/telegram/command-handler.js +15 -48
  102. package/dist/channels/telegram/command-handler.js.map +1 -1
  103. package/dist/channels/telegram/plugin.js +3 -2
  104. package/dist/channels/telegram/plugin.js.map +1 -1
  105. package/dist/channels/telegram/webhook.d.ts +1 -1
  106. package/dist/channels/telegram/webhook.js +1 -1
  107. package/dist/channels/types.d.ts +1 -1
  108. package/dist/channels/types.js +1 -1
  109. package/dist/channels/update-offset-store.d.ts +1 -1
  110. package/dist/channels/update-offset-store.js +1 -1
  111. package/dist/cli/commands/auth.js +8 -23
  112. package/dist/cli/commands/auth.js.map +1 -1
  113. package/dist/cli/commands/gateway.js +9 -1
  114. package/dist/cli/commands/gateway.js.map +1 -1
  115. package/dist/cli/commands/models.js +35 -29
  116. package/dist/cli/commands/models.js.map +1 -1
  117. package/dist/cli/commands/onboard.js +73 -58
  118. package/dist/cli/commands/onboard.js.map +1 -1
  119. package/dist/cli/commands/skills.js +6 -6
  120. package/dist/cli/commands/skills.js.map +1 -1
  121. package/dist/cli/index.js +0 -0
  122. package/dist/cli/templates.d.ts +2 -0
  123. package/dist/cli/templates.js +1 -1
  124. package/dist/cli/templates.js.map +1 -1
  125. package/dist/config/defaults.d.ts +19 -0
  126. package/dist/config/defaults.js +168 -0
  127. package/dist/config/defaults.js.map +1 -0
  128. package/dist/config/index.d.ts +5 -0
  129. package/dist/config/index.js +4 -0
  130. package/dist/config/index.js.map +1 -1
  131. package/dist/config/integration.d.ts +12 -0
  132. package/dist/config/integration.js +14 -0
  133. package/dist/config/integration.js.map +1 -0
  134. package/dist/config/models-json.d.ts +454 -0
  135. package/dist/config/models-json.js +323 -0
  136. package/dist/config/models-json.js.map +1 -0
  137. package/dist/config/paths.d.ts +2 -0
  138. package/dist/config/paths.js +4 -0
  139. package/dist/config/paths.js.map +1 -1
  140. package/dist/config/reload.d.ts +1 -1
  141. package/dist/config/reload.js +3 -3
  142. package/dist/config/reload.js.map +1 -1
  143. package/dist/config/resolve-config-value.d.ts +36 -0
  144. package/dist/config/resolve-config-value.js +218 -0
  145. package/dist/config/resolve-config-value.js.map +1 -0
  146. package/dist/config/rules.js +3 -2
  147. package/dist/config/rules.js.map +1 -1
  148. package/dist/config/schema.d.ts +17 -884
  149. package/dist/config/schema.js +36 -312
  150. package/dist/config/schema.js.map +1 -1
  151. package/dist/config/types.models.d.ts +54 -0
  152. package/dist/config/types.models.js +2 -0
  153. package/dist/config/types.models.js.map +1 -0
  154. package/dist/cron/validation.d.ts +4 -4
  155. package/dist/gateway/hono/app.js +230 -78
  156. package/dist/gateway/hono/app.js.map +1 -1
  157. package/dist/gateway/hono/oauth-async.d.ts +14 -0
  158. package/dist/gateway/hono/oauth-async.js +285 -0
  159. package/dist/gateway/hono/oauth-async.js.map +1 -0
  160. package/dist/gateway/hono/oauth.d.ts +9 -0
  161. package/dist/gateway/hono/oauth.js +157 -0
  162. package/dist/gateway/hono/oauth.js.map +1 -0
  163. package/dist/gateway/hono/sse.js +5 -2
  164. package/dist/gateway/hono/sse.js.map +1 -1
  165. package/dist/gateway/service.d.ts +6 -2
  166. package/dist/gateway/service.js +20 -6
  167. package/dist/gateway/service.js.map +1 -1
  168. package/dist/gateway/static/root/assets/flow-BqIEBwW6.js +2 -0
  169. package/dist/gateway/static/root/assets/flow-BqIEBwW6.js.map +1 -0
  170. package/dist/gateway/static/root/assets/main-Br2tw-87.js +5168 -0
  171. package/dist/gateway/static/root/assets/main-Br2tw-87.js.map +1 -0
  172. package/dist/gateway/static/root/assets/main-DwlbPf8Z.css +1 -0
  173. package/dist/gateway/static/root/index.html +2 -2
  174. package/dist/plugins/index.d.ts +0 -2
  175. package/dist/plugins/index.js +0 -2
  176. package/dist/plugins/index.js.map +1 -1
  177. package/dist/plugins/types.d.ts +0 -2
  178. package/dist/plugins/types.js +0 -2
  179. package/dist/plugins/types.js.map +1 -1
  180. package/dist/providers/index.d.ts +50 -22
  181. package/dist/providers/index.js +276 -50
  182. package/dist/providers/index.js.map +1 -1
  183. package/dist/providers/model-registry.d.ts +84 -0
  184. package/dist/providers/model-registry.js +385 -0
  185. package/dist/providers/model-registry.js.map +1 -0
  186. package/dist/types/providers.d.ts +2 -63
  187. package/dist/types/providers.js +1 -1
  188. package/dist/utils/__tests__/frontmatter.test.js +4 -3
  189. package/dist/utils/__tests__/frontmatter.test.js.map +1 -1
  190. package/dist/utils/diagnostic-events.d.ts +230 -0
  191. package/dist/utils/diagnostic-events.js +189 -0
  192. package/dist/utils/diagnostic-events.js.map +1 -0
  193. package/dist/utils/frontmatter.d.ts +0 -1
  194. package/dist/utils/frontmatter.js +13 -77
  195. package/dist/utils/frontmatter.js.map +1 -1
  196. package/dist/utils/log-stream.d.ts +95 -0
  197. package/dist/utils/log-stream.js +229 -0
  198. package/dist/utils/log-stream.js.map +1 -0
  199. package/dist/utils/logger.d.ts +5 -0
  200. package/dist/utils/logger.js +25 -0
  201. package/dist/utils/logger.js.map +1 -1
  202. package/dist/utils/redact.d.ts +73 -0
  203. package/dist/utils/redact.js +245 -0
  204. package/dist/utils/redact.js.map +1 -0
  205. package/package.json +6 -4
  206. package/skills/find-skills/SKILL.md +0 -9
  207. package/dist/__tests__/core.test.d.ts +0 -1
  208. package/dist/__tests__/core.test.js +0 -72
  209. package/dist/__tests__/core.test.js.map +0 -1
  210. package/dist/agent/model-manager.js.map +0 -1
  211. package/dist/cli/commands/configure.d.ts +0 -1
  212. package/dist/cli/commands/configure.js +0 -171
  213. package/dist/cli/commands/configure.js.map +0 -1
  214. package/dist/cli/commands/gateway-daemon.d.ts +0 -1
  215. package/dist/cli/commands/gateway-daemon.js +0 -141
  216. package/dist/cli/commands/gateway-daemon.js.map +0 -1
  217. package/dist/config/__tests__/diff.test.d.ts +0 -1
  218. package/dist/config/__tests__/diff.test.js +0 -192
  219. package/dist/config/__tests__/diff.test.js.map +0 -1
  220. package/dist/config/__tests__/loader.test.d.ts +0 -1
  221. package/dist/config/__tests__/loader.test.js +0 -356
  222. package/dist/config/__tests__/loader.test.js.map +0 -1
  223. package/dist/config/__tests__/paths.test.d.ts +0 -1
  224. package/dist/config/__tests__/paths.test.js +0 -192
  225. package/dist/config/__tests__/paths.test.js.map +0 -1
  226. package/dist/config/__tests__/reload.test.d.ts +0 -1
  227. package/dist/config/__tests__/reload.test.js +0 -374
  228. package/dist/config/__tests__/reload.test.js.map +0 -1
  229. package/dist/config/__tests__/rules.test.d.ts +0 -1
  230. package/dist/config/__tests__/rules.test.js +0 -204
  231. package/dist/config/__tests__/rules.test.js.map +0 -1
  232. package/dist/config/__tests__/schema.test.d.ts +0 -1
  233. package/dist/config/__tests__/schema.test.js +0 -672
  234. package/dist/config/__tests__/schema.test.js.map +0 -1
  235. package/dist/daemon/background-start.d.ts +0 -33
  236. package/dist/daemon/background-start.js +0 -89
  237. package/dist/daemon/background-start.js.map +0 -1
  238. package/dist/daemon/gateway-manager.d.ts +0 -87
  239. package/dist/daemon/gateway-manager.js +0 -324
  240. package/dist/daemon/gateway-manager.js.map +0 -1
  241. package/dist/daemon/index.d.ts +0 -5
  242. package/dist/daemon/index.js +0 -6
  243. package/dist/daemon/index.js.map +0 -1
  244. package/dist/gateway/static/root/assets/main-DevbZW9K.js +0 -2227
  245. package/dist/gateway/static/root/assets/main-DevbZW9K.js.map +0 -1
  246. package/dist/gateway/static/root/assets/main-DxZg1Nmz.css +0 -1
  247. package/dist/providers/__tests__/registry.test.d.ts +0 -1
  248. package/dist/providers/__tests__/registry.test.js +0 -110
  249. package/dist/providers/__tests__/registry.test.js.map +0 -1
  250. package/dist/providers/api-strategies.d.ts +0 -15
  251. package/dist/providers/api-strategies.js +0 -96
  252. package/dist/providers/api-strategies.js.map +0 -1
  253. package/dist/providers/auto-discovery.d.ts +0 -39
  254. package/dist/providers/auto-discovery.js +0 -189
  255. package/dist/providers/auto-discovery.js.map +0 -1
  256. package/dist/providers/config.d.ts +0 -25
  257. package/dist/providers/config.js +0 -42
  258. package/dist/providers/config.js.map +0 -1
  259. package/dist/providers/model-catalog.d.ts +0 -92
  260. package/dist/providers/model-catalog.js +0 -998
  261. package/dist/providers/model-catalog.js.map +0 -1
  262. package/dist/providers/models-dev-data.d.ts +0 -11
  263. package/dist/providers/models-dev-data.js +0 -1035
  264. package/dist/providers/models-dev-data.js.map +0 -1
  265. package/dist/providers/models-dev.d.ts +0 -34
  266. package/dist/providers/models-dev.js +0 -33
  267. package/dist/providers/models-dev.js.map +0 -1
  268. package/dist/providers/pi-ai.d.ts +0 -62
  269. package/dist/providers/pi-ai.js +0 -221
  270. package/dist/providers/pi-ai.js.map +0 -1
  271. package/dist/providers/provider-catalog.d.ts +0 -91
  272. package/dist/providers/provider-catalog.js +0 -791
  273. package/dist/providers/provider-catalog.js.map +0 -1
  274. package/dist/providers/registry.d.ts +0 -135
  275. package/dist/providers/registry.js +0 -475
  276. package/dist/providers/registry.js.map +0 -1
  277. package/dist/providers/types.d.ts +0 -95
  278. package/dist/providers/types.js +0 -7
  279. package/dist/providers/types.js.map +0 -1
  280. package/dist/session/chat-manager.d.ts +0 -49
  281. package/dist/session/chat-manager.js +0 -167
  282. package/dist/session/chat-manager.js.map +0 -1
  283. package/dist/session/chat-types.d.ts +0 -53
  284. package/dist/session/chat-types.js +0 -63
  285. package/dist/session/chat-types.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"mappings":"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;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA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A;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;;AAAAA;AAAAA;AAAAA;;AAAAA;AAAAA;AAAAA;AAAAA;;AAAAA;AAAAA;AAAAA;;AAAAA;AAAAA;AAAAA;;AAAAA;AAAAA;AAAAA;;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;;AAAAA;AAAAA;AAAAA;AAAAA;;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;;AAAAA;AAA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","names":["t","e","s","o","n$5","r","n","i","S","c","h","a","l","p","d","u","f","b","y$1","y","v","_","m","g","$","x","E","A","C","P","V","N","I","L","z","H","M","R","k","Z","j","B","D","defaultAttributes","Paperclip","Send","Square","X","builtInTranslations","enTranslations","zhTranslations","translationCache","currentLanguage","path","params","translations","keys","value","key","enValue","paramValue","loadLanguage","lang","response","error","setLanguage","initI18n","defaultLang","legacyKeys","i18n","newKey","iconToSvg","iconData","className","_tag","attrs","children","attrStr","childrenStr","child","cTag","cAttrs","cAttrStr","MessageEditor","LitElement","createRef","files","target","items","imageFiles","item","file","input","html","ref","att","index","unsafeHTML","canSend","type","textarea","attachments","attachment","base64","isImage","resolve","reject","reader","bytes","units","unitIndex","size","__decorateClass","query","property","state","customElement","w","RangeChangedEvent","range","VisibilityChangedEvent","UnpinnedEvent","ScrollerShim","element","node","ScrollerController","client","p1","p2","options","retarget","end","top","left","coordinates","scrollTop","scrollLeft","topDiff","leftDiff","_ResizeObserver","virtualizerRef","SIZER_ATTRIBUTE","DefaultLayoutConstructor","Virtualizer","config","layoutConfig","hostElement","includeSelf","getClippingAncestors","ancestor","style","sizer","Ctor","copy","__vitePreload","message","now","timeElapsed","virtualizationTime","mm","fn","idx","width","height","getMargins","method","_rangeChanged","_itemsChanged","event","arr","next","scrollingElement","layout","bottom","right","hostElementBounds","ancestorBounds","bounds","scrollingElementBounds","offsetWithinScroller","totalScrollSize","pos","xOffset","yOffset","_first","_last","_firstVisible","_lastVisible","behavior","reason","changes","change","el","getMarginValue","float","getParentElement","parentNode","getElementAncestors","ancestors","parent","foundFixed","defaultKeyFunction","defaultRenderItem","VirtualizeDirective","AsyncDirective","part","PartType","itemsToRender","repeat","itemsChanged","noChange","renderItem","keyFunction","scroller","virtualize","directive","getIcon","name","fallbackIcons","getDocumentIcon","mimeType","AttachmentRenderer","images","documents","count","galleryClass","img","doc","UsageBadge","parts","MessageBubble","isUser","isAssistant","roleLabel","avatarLetter","content","block","isError","timestamp","MessageList","container","threshold","scrollHeight","clientHeight","StreamingMessageContainer","isComplete","inputStr","text","div","getBaseUrl","apiUrl","authHeaders","token","XopcbotGatewayChat","atBottom","attachmentData","changedProperties","route","targetSessionKey","sessionKey","offset","url","headers","res","session","messages","newMessages","msg","err","smooth","eventsUrl","data","gatewaySessions","sessionsWithMessages","recentKey","emptySession","newHash","chatId","body","json","buffer","currentEventType","currentEventData","done","newlineIndex","line","lines","parsed","textBlock","color","SessionCard","action","dateStr","date","diffDays","channel","displayName","isArchived","isPinned","tag","tokens","SessionList","SessionDetailDrawer","results","direction","resultIndex","isSearchResult","isCurrentResult","ConfirmDialog","confirmed","SessionAPIClient","baseUrl","queryString","format","SessionManager","httpUrl","reset","result","blob","status","ms","timeout","CronAPIClient","id","schedule","updates","enabled","limit","ModelSelector","endpoint","models","modelId","model","css","CronManager","chatIds","job","knownChannels","delivery","payload","jobData","fullJob","jobId","nothing","ch","diff","mins","hours","days","LOG_LEVELS","LOG_LEVEL_COLORS","LogAPIClient","LogManager","level","log","startAsyncOAuthLogin","provider","fetchOAuthSessionStatus","sessionId","submitOAuthCode","code","cancelOAuth","cleanupOAuthSession","revokeOAuth","ProviderConfig","categoryClass","isMasked","inputValue","isOAuthConfigured","ProviderList","category","apiKey","providers","groups","cat","list","isExpanded","configuredCount","fetchConfiguredModels","fetchProviderMeta","fetchModelsJson","validateModelsJson","saveModelsJson","reloadModelsJson","testApiKey","createCustomModel","overrides","isShellCommand","isEnvVar","getApiKeyType","maskApiKey","INPUT_TYPES","ModelEditDialog","isNew","field","title","subtitle","cost","compat","order","only","API_TYPES","PROVIDER_PRESETS","ProviderEditDialog","providerId","presetKey","preset","api","ModelJsonEditor","expanded","newConfig","handleClose","presetConfig","show","editingModel","providerCount","modelCount","sum","isPasswordVisible","testResult","apiKeyType","updatedModels","SettingsPage","loadError","modelValue","providerMeta","configuredProviders","meta","newSettings","current","success","modelsErr","sections","section","dmPolicyOptions","groupPolicyOptions","replyToModeOptions","streamModeOptions","opt","TokenDialog","getTabGroups","getTabLabel","tab","TAB_ICONS","parseChatHash","hash","cleanHash","getChatHash","renderNavItem","isActive","onClick","icon","label","TOKEN_KEY","THEME_KEY","LANGUAGE_KEY","getToken","setToken","getTheme","theme","setTheme","getLanguage","XopcbotApp","urlToken","newUrl","chatRoute","isDark","setStoredLanguage","group","styles","parseMarkdown","match","inParagraph","trimmed","MarkdownRenderer","htmlContent","unsafeCSS","XopcbotSettings","iconName","descKey","sectionId","fullKey","isDirty","showPassword","inputType","hasDirty","XopcbotChat","currentScrollTop","distanceFromBottom","ev"],"ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,22,23,24,25],"sources":["../../../../../ui/node_modules/.pnpm/@lit+reactive-element@2.1.2/node_modules/@lit/reactive-element/css-tag.js","../../../../../ui/node_modules/.pnpm/@lit+reactive-element@2.1.2/node_modules/@lit/reactive-element/reactive-element.js","../../../../../ui/node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/lit-html.js","../../../../../ui/node_modules/.pnpm/lit-element@4.2.2/node_modules/lit-element/lit-element.js","../../../../../ui/node_modules/.pnpm/@lit+reactive-element@2.1.2/node_modules/@lit/reactive-element/decorators/custom-element.js","../../../../../ui/node_modules/.pnpm/@lit+reactive-element@2.1.2/node_modules/@lit/reactive-element/decorators/property.js","../../../../../ui/node_modules/.pnpm/@lit+reactive-element@2.1.2/node_modules/@lit/reactive-element/decorators/state.js","../../../../../ui/node_modules/.pnpm/@lit+reactive-element@2.1.2/node_modules/@lit/reactive-element/decorators/base.js","../../../../../ui/node_modules/.pnpm/@lit+reactive-element@2.1.2/node_modules/@lit/reactive-element/decorators/query.js","../../../../../ui/node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/directive-helpers.js","../../../../../ui/node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/directive.js","../../../../../ui/node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/async-directive.js","../../../../../ui/node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/directives/ref.js","../../../../../ui/node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/directives/unsafe-html.js","../../../../../ui/node_modules/.pnpm/lucide@0.456.0/node_modules/lucide/dist/esm/defaultAttributes.js","../../../../../ui/node_modules/.pnpm/lucide@0.456.0/node_modules/lucide/dist/esm/icons/paperclip.js","../../../../../ui/node_modules/.pnpm/lucide@0.456.0/node_modules/lucide/dist/esm/icons/send.js","../../../../../ui/node_modules/.pnpm/lucide@0.456.0/node_modules/lucide/dist/esm/icons/square.js","../../../../../ui/node_modules/.pnpm/lucide@0.456.0/node_modules/lucide/dist/esm/icons/x.js","../../../../../ui/src/utils/i18n.ts","../../../../../ui/src/components/MessageEditor.ts","../../../../../ui/node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/directives/repeat.js","../../../../../ui/node_modules/.pnpm/@lit-labs+virtualizer@2.1.1/node_modules/@lit-labs/virtualizer/events.js","../../../../../ui/node_modules/.pnpm/@lit-labs+virtualizer@2.1.1/node_modules/@lit-labs/virtualizer/ScrollerController.js","../../../../../ui/node_modules/.pnpm/@lit-labs+virtualizer@2.1.1/node_modules/@lit-labs/virtualizer/Virtualizer.js","../../../../../ui/node_modules/.pnpm/@lit-labs+virtualizer@2.1.1/node_modules/@lit-labs/virtualizer/virtualize.js","../../../../../ui/src/utils/icons.ts","../../../../../ui/src/components/MessageList/AttachmentRenderer.ts","../../../../../ui/src/components/MessageList/UsageBadge.ts","../../../../../ui/src/components/MessageList/MessageBubble.ts","../../../../../ui/src/components/MessageList/index.ts","../../../../../ui/src/components/StreamingMessageContainer.ts","../../../../../ui/src/gateway-chat.ts","../../../../../ui/src/components/SessionCard.ts","../../../../../ui/src/components/SessionList.ts","../../../../../ui/src/components/SessionDetailDrawer.ts","../../../../../ui/src/components/ConfirmDialog.ts","../../../../../ui/src/utils/session-api.ts","../../../../../ui/src/pages/SessionManager.ts","../../../../../ui/src/utils/cron-api.ts","../../../../../ui/src/components/ModelSelector.ts","../../../../../ui/src/pages/CronManager.ts","../../../../../ui/src/utils/log-api.ts","../../../../../ui/src/pages/LogManager.ts","../../../../../ui/src/utils/oauth-api.ts","../../../../../ui/src/components/ProviderConfig.ts","../../../../../ui/src/components/ProviderList.ts","../../../../../ui/src/config/registry-client.ts","../../../../../ui/src/config/models-json-client.ts","../../../../../ui/src/components/ModelEditDialog.ts","../../../../../ui/src/components/ProviderEditDialog.ts","../../../../../ui/src/components/ModelJsonEditor.ts","../../../../../ui/src/pages/SettingsPage.ts","../../../../../ui/src/components/TokenDialog.ts","../../../../../ui/src/navigation.ts","../../../../../ui/src/utils/storage.ts","../../../../../ui/src/app.ts","../../../../../ui/src/components/MarkdownRenderer.ts","../../../../../ui/src/dialogs/SettingsDialog.ts","../../../../../ui/src/index.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow)&&\"adoptedStyleSheets\"in Document.prototype&&\"replace\"in CSSStyleSheet.prototype,s=Symbol(),o=new WeakMap;class n{constructor(t,e,o){if(this._$cssResult$=!0,o!==s)throw Error(\"CSSResult is not constructable. Use `unsafeCSS` or `css` instead.\");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const s=this.t;if(e&&void 0===t){const e=void 0!==s&&1===s.length;e&&(t=o.get(s)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&o.set(s,t))}return t}toString(){return this.cssText}}const r=t=>new n(\"string\"==typeof t?t:t+\"\",void 0,s),i=(t,...e)=>{const o=1===t.length?t[0]:e.reduce((e,s,o)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if(\"number\"==typeof t)return t;throw Error(\"Value passed to 'css' function must be a 'css' function result: \"+t+\". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.\")})(s)+t[o+1],t[0]);return new n(o,t,s)},S=(s,o)=>{if(e)s.adoptedStyleSheets=o.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(const e of o){const o=document.createElement(\"style\"),n=t.litNonce;void 0!==n&&o.setAttribute(\"nonce\",n),o.textContent=e.cssText,s.appendChild(o)}},c=e?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e=\"\";for(const s of t.cssRules)e+=s.cssText;return r(e)})(t):t;export{n as CSSResult,S as adoptStyles,i as css,c as getCompatibleStyle,e as supportsAdoptingStyleSheets,r as unsafeCSS};\n//# sourceMappingURL=css-tag.js.map\n","import{getCompatibleStyle as t,adoptStyles as s}from\"./css-tag.js\";export{CSSResult,css,supportsAdoptingStyleSheets,unsafeCSS}from\"./css-tag.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const{is:i,defineProperty:e,getOwnPropertyDescriptor:h,getOwnPropertyNames:r,getOwnPropertySymbols:o,getPrototypeOf:n}=Object,a=globalThis,c=a.trustedTypes,l=c?c.emptyScript:\"\",p=a.reactiveElementPolyfillSupport,d=(t,s)=>t,u={toAttribute(t,s){switch(s){case Boolean:t=t?l:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,s){let i=t;switch(s){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},f=(t,s)=>!i(t,s),b={attribute:!0,type:String,converter:u,reflect:!1,useDefault:!1,hasChanged:f};Symbol.metadata??=Symbol(\"metadata\"),a.litPropertyMetadata??=new WeakMap;class y extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,s=b){if(s.state&&(s.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((s=Object.create(s)).wrapped=!0),this.elementProperties.set(t,s),!s.noAccessor){const i=Symbol(),h=this.getPropertyDescriptor(t,i,s);void 0!==h&&e(this.prototype,t,h)}}static getPropertyDescriptor(t,s,i){const{get:e,set:r}=h(this.prototype,t)??{get(){return this[s]},set(t){this[s]=t}};return{get:e,set(s){const h=e?.call(this);r?.call(this,s),this.requestUpdate(t,h,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??b}static _$Ei(){if(this.hasOwnProperty(d(\"elementProperties\")))return;const t=n(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(d(\"finalized\")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(d(\"properties\"))){const t=this.properties,s=[...r(t),...o(t)];for(const i of s)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const s=litPropertyMetadata.get(t);if(void 0!==s)for(const[t,i]of s)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,s]of this.elementProperties){const i=this._$Eu(t,s);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(s){const i=[];if(Array.isArray(s)){const e=new Set(s.flat(1/0).reverse());for(const s of e)i.unshift(t(s))}else void 0!==s&&i.push(t(s));return i}static _$Eu(t,s){const i=s.attribute;return!1===i?void 0:\"string\"==typeof i?i:\"string\"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,s=this.constructor.elementProperties;for(const i of s.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return s(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,s,i){this._$AK(t,i)}_$ET(t,s){const i=this.constructor.elementProperties.get(t),e=this.constructor._$Eu(t,i);if(void 0!==e&&!0===i.reflect){const h=(void 0!==i.converter?.toAttribute?i.converter:u).toAttribute(s,i.type);this._$Em=t,null==h?this.removeAttribute(e):this.setAttribute(e,h),this._$Em=null}}_$AK(t,s){const i=this.constructor,e=i._$Eh.get(t);if(void 0!==e&&this._$Em!==e){const t=i.getPropertyOptions(e),h=\"function\"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:u;this._$Em=e;const r=h.fromAttribute(s,t.type);this[e]=r??this._$Ej?.get(e)??r,this._$Em=null}}requestUpdate(t,s,i,e=!1,h){if(void 0!==t){const r=this.constructor;if(!1===e&&(h=this[t]),i??=r.getPropertyOptions(t),!((i.hasChanged??f)(h,s)||i.useDefault&&i.reflect&&h===this._$Ej?.get(t)&&!this.hasAttribute(r._$Eu(t,i))))return;this.C(t,s,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,s,{useDefault:i,reflect:e,wrapped:h},r){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,r??s??this[t]),!0!==h||void 0!==r)||(this._$AL.has(t)||(this.hasUpdated||i||(s=void 0),this._$AL.set(t,s)),!0===e&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,s]of this._$Ep)this[t]=s;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[s,i]of t){const{wrapped:t}=i,e=this[s];!0!==t||this._$AL.has(s)||void 0===e||this.C(s,void 0,i,e)}}let t=!1;const s=this._$AL;try{t=this.shouldUpdate(s),t?(this.willUpdate(s),this._$EO?.forEach(t=>t.hostUpdate?.()),this.update(s)):this._$EM()}catch(s){throw t=!1,this._$EM(),s}t&&this._$AE(s)}willUpdate(t){}_$AE(t){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(t){}firstUpdated(t){}}y.elementStyles=[],y.shadowRootOptions={mode:\"open\"},y[d(\"elementProperties\")]=new Map,y[d(\"finalized\")]=new Map,p?.({ReactiveElement:y}),(a.reactiveElementVersions??=[]).push(\"2.1.2\");export{y as ReactiveElement,s as adoptStyles,u as defaultConverter,t as getCompatibleStyle,f as notEqual};\n//# sourceMappingURL=reactive-element.js.map\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t=globalThis,i=t=>t,s=t.trustedTypes,e=s?s.createPolicy(\"lit-html\",{createHTML:t=>t}):void 0,h=\"$lit$\",o=`lit$${Math.random().toFixed(9).slice(2)}$`,n=\"?\"+o,r=`<${n}>`,l=document,c=()=>l.createComment(\"\"),a=t=>null===t||\"object\"!=typeof t&&\"function\"!=typeof t,u=Array.isArray,d=t=>u(t)||\"function\"==typeof t?.[Symbol.iterator],f=\"[ \\t\\n\\f\\r]\",v=/<(?:(!--|\\/[^a-zA-Z])|(\\/?[a-zA-Z][^>\\s]*)|(\\/?$))/g,_=/-->/g,m=/>/g,p=RegExp(`>|${f}(?:([^\\\\s\"'>=/]+)(${f}*=${f}*(?:[^ \\t\\n\\f\\r\"'\\`<>=]|(\"|')|))|$)`,\"g\"),g=/'/g,$=/\"/g,y=/^(?:script|style|textarea|title)$/i,x=t=>(i,...s)=>({_$litType$:t,strings:i,values:s}),b=x(1),w=x(2),T=x(3),E=Symbol.for(\"lit-noChange\"),A=Symbol.for(\"lit-nothing\"),C=new WeakMap,P=l.createTreeWalker(l,129);function V(t,i){if(!u(t)||!t.hasOwnProperty(\"raw\"))throw Error(\"invalid template strings array\");return void 0!==e?e.createHTML(i):i}const N=(t,i)=>{const s=t.length-1,e=[];let n,l=2===i?\"<svg>\":3===i?\"<math>\":\"\",c=v;for(let i=0;i<s;i++){const s=t[i];let a,u,d=-1,f=0;for(;f<s.length&&(c.lastIndex=f,u=c.exec(s),null!==u);)f=c.lastIndex,c===v?\"!--\"===u[1]?c=_:void 0!==u[1]?c=m:void 0!==u[2]?(y.test(u[2])&&(n=RegExp(\"</\"+u[2],\"g\")),c=p):void 0!==u[3]&&(c=p):c===p?\">\"===u[0]?(c=n??v,d=-1):void 0===u[1]?d=-2:(d=c.lastIndex-u[2].length,a=u[1],c=void 0===u[3]?p:'\"'===u[3]?$:g):c===$||c===g?c=p:c===_||c===m?c=v:(c=p,n=void 0);const x=c===p&&t[i+1].startsWith(\"/>\")?\" \":\"\";l+=c===v?s+r:d>=0?(e.push(a),s.slice(0,d)+h+s.slice(d)+o+x):s+o+(-2===d?i:x)}return[V(t,l+(t[s]||\"<?>\")+(2===i?\"</svg>\":3===i?\"</math>\":\"\")),e]};class S{constructor({strings:t,_$litType$:i},e){let r;this.parts=[];let l=0,a=0;const u=t.length-1,d=this.parts,[f,v]=N(t,i);if(this.el=S.createElement(f,e),P.currentNode=this.el.content,2===i||3===i){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(r=P.nextNode())&&d.length<u;){if(1===r.nodeType){if(r.hasAttributes())for(const t of r.getAttributeNames())if(t.endsWith(h)){const i=v[a++],s=r.getAttribute(t).split(o),e=/([.?@])?(.*)/.exec(i);d.push({type:1,index:l,name:e[2],strings:s,ctor:\".\"===e[1]?I:\"?\"===e[1]?L:\"@\"===e[1]?z:H}),r.removeAttribute(t)}else t.startsWith(o)&&(d.push({type:6,index:l}),r.removeAttribute(t));if(y.test(r.tagName)){const t=r.textContent.split(o),i=t.length-1;if(i>0){r.textContent=s?s.emptyScript:\"\";for(let s=0;s<i;s++)r.append(t[s],c()),P.nextNode(),d.push({type:2,index:++l});r.append(t[i],c())}}}else if(8===r.nodeType)if(r.data===n)d.push({type:2,index:l});else{let t=-1;for(;-1!==(t=r.data.indexOf(o,t+1));)d.push({type:7,index:l}),t+=o.length-1}l++}}static createElement(t,i){const s=l.createElement(\"template\");return s.innerHTML=t,s}}function M(t,i,s=t,e){if(i===E)return i;let h=void 0!==e?s._$Co?.[e]:s._$Cl;const o=a(i)?void 0:i._$litDirective$;return h?.constructor!==o&&(h?._$AO?.(!1),void 0===o?h=void 0:(h=new o(t),h._$AT(t,s,e)),void 0!==e?(s._$Co??=[])[e]=h:s._$Cl=h),void 0!==h&&(i=M(t,h._$AS(t,i.values),h,e)),i}class R{constructor(t,i){this._$AV=[],this._$AN=void 0,this._$AD=t,this._$AM=i}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(t){const{el:{content:i},parts:s}=this._$AD,e=(t?.creationScope??l).importNode(i,!0);P.currentNode=e;let h=P.nextNode(),o=0,n=0,r=s[0];for(;void 0!==r;){if(o===r.index){let i;2===r.type?i=new k(h,h.nextSibling,this,t):1===r.type?i=new r.ctor(h,r.name,r.strings,this,t):6===r.type&&(i=new Z(h,this,t)),this._$AV.push(i),r=s[++n]}o!==r?.index&&(h=P.nextNode(),o++)}return P.currentNode=l,e}p(t){let i=0;for(const s of this._$AV)void 0!==s&&(void 0!==s.strings?(s._$AI(t,s,i),i+=s.strings.length-2):s._$AI(t[i])),i++}}class k{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(t,i,s,e){this.type=2,this._$AH=A,this._$AN=void 0,this._$AA=t,this._$AB=i,this._$AM=s,this.options=e,this._$Cv=e?.isConnected??!0}get parentNode(){let t=this._$AA.parentNode;const i=this._$AM;return void 0!==i&&11===t?.nodeType&&(t=i.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,i=this){t=M(this,t,i),a(t)?t===A||null==t||\"\"===t?(this._$AH!==A&&this._$AR(),this._$AH=A):t!==this._$AH&&t!==E&&this._(t):void 0!==t._$litType$?this.$(t):void 0!==t.nodeType?this.T(t):d(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==A&&a(this._$AH)?this._$AA.nextSibling.data=t:this.T(l.createTextNode(t)),this._$AH=t}$(t){const{values:i,_$litType$:s}=t,e=\"number\"==typeof s?this._$AC(t):(void 0===s.el&&(s.el=S.createElement(V(s.h,s.h[0]),this.options)),s);if(this._$AH?._$AD===e)this._$AH.p(i);else{const t=new R(e,this),s=t.u(this.options);t.p(i),this.T(s),this._$AH=t}}_$AC(t){let i=C.get(t.strings);return void 0===i&&C.set(t.strings,i=new S(t)),i}k(t){u(this._$AH)||(this._$AH=[],this._$AR());const i=this._$AH;let s,e=0;for(const h of t)e===i.length?i.push(s=new k(this.O(c()),this.O(c()),this,this.options)):s=i[e],s._$AI(h),e++;e<i.length&&(this._$AR(s&&s._$AB.nextSibling,e),i.length=e)}_$AR(t=this._$AA.nextSibling,s){for(this._$AP?.(!1,!0,s);t!==this._$AB;){const s=i(t).nextSibling;i(t).remove(),t=s}}setConnected(t){void 0===this._$AM&&(this._$Cv=t,this._$AP?.(t))}}class H{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(t,i,s,e,h){this.type=1,this._$AH=A,this._$AN=void 0,this.element=t,this.name=i,this._$AM=e,this.options=h,s.length>2||\"\"!==s[0]||\"\"!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=A}_$AI(t,i=this,s,e){const h=this.strings;let o=!1;if(void 0===h)t=M(this,t,i,0),o=!a(t)||t!==this._$AH&&t!==E,o&&(this._$AH=t);else{const e=t;let n,r;for(t=h[0],n=0;n<h.length-1;n++)r=M(this,e[s+n],i,n),r===E&&(r=this._$AH[n]),o||=!a(r)||r!==this._$AH[n],r===A?t=A:t!==A&&(t+=(r??\"\")+h[n+1]),this._$AH[n]=r}o&&!e&&this.j(t)}j(t){t===A?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,t??\"\")}}class I extends H{constructor(){super(...arguments),this.type=3}j(t){this.element[this.name]=t===A?void 0:t}}class L extends H{constructor(){super(...arguments),this.type=4}j(t){this.element.toggleAttribute(this.name,!!t&&t!==A)}}class z extends H{constructor(t,i,s,e,h){super(t,i,s,e,h),this.type=5}_$AI(t,i=this){if((t=M(this,t,i,0)??A)===E)return;const s=this._$AH,e=t===A&&s!==A||t.capture!==s.capture||t.once!==s.once||t.passive!==s.passive,h=t!==A&&(s===A||e);e&&this.element.removeEventListener(this.name,this,s),h&&this.element.addEventListener(this.name,this,t),this._$AH=t}handleEvent(t){\"function\"==typeof this._$AH?this._$AH.call(this.options?.host??this.element,t):this._$AH.handleEvent(t)}}class Z{constructor(t,i,s){this.element=t,this.type=6,this._$AN=void 0,this._$AM=i,this.options=s}get _$AU(){return this._$AM._$AU}_$AI(t){M(this,t)}}const j={M:h,P:o,A:n,C:1,L:N,R,D:d,V:M,I:k,H,N:L,U:z,B:I,F:Z},B=t.litHtmlPolyfillSupport;B?.(S,k),(t.litHtmlVersions??=[]).push(\"3.3.2\");const D=(t,i,s)=>{const e=s?.renderBefore??i;let h=e._$litPart$;if(void 0===h){const t=s?.renderBefore??null;e._$litPart$=h=new k(i.insertBefore(c(),t),t,void 0,s??{})}return h._$AI(t),h};export{j as _$LH,b as html,T as mathml,E as noChange,A as nothing,D as render,w as svg};\n//# sourceMappingURL=lit-html.js.map\n","import{ReactiveElement as t}from\"@lit/reactive-element\";export*from\"@lit/reactive-element\";import{render as e,noChange as r}from\"lit-html\";export*from\"lit-html\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const s=globalThis;class i extends t{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const r=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=e(r,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return r}}i._$litElement$=!0,i[\"finalized\"]=!0,s.litElementHydrateSupport?.({LitElement:i});const o=s.litElementPolyfillSupport;o?.({LitElement:i});const n={_$AK:(t,e,r)=>{t._$AK(e,r)},_$AL:t=>t._$AL};(s.litElementVersions??=[]).push(\"4.2.2\");export{i as LitElement,n as _$LE};\n//# sourceMappingURL=lit-element.js.map\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t=t=>(e,o)=>{void 0!==o?o.addInitializer(()=>{customElements.define(t,e)}):customElements.define(t,e)};export{t as customElement};\n//# sourceMappingURL=custom-element.js.map\n","import{notEqual as t,defaultConverter as e}from\"../reactive-element.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const o={attribute:!0,type:String,converter:e,reflect:!1,hasChanged:t},r=(t=o,e,r)=>{const{kind:n,metadata:i}=r;let s=globalThis.litPropertyMetadata.get(i);if(void 0===s&&globalThis.litPropertyMetadata.set(i,s=new Map),\"setter\"===n&&((t=Object.create(t)).wrapped=!0),s.set(r.name,t),\"accessor\"===n){const{name:o}=r;return{set(r){const n=e.get.call(this);e.set.call(this,r),this.requestUpdate(o,n,t,!0,r)},init(e){return void 0!==e&&this.C(o,void 0,t,e),e}}}if(\"setter\"===n){const{name:o}=r;return function(r){const n=this[o];e.call(this,r),this.requestUpdate(o,n,t,!0,r)}}throw Error(\"Unsupported decorator location: \"+n)};function n(t){return(e,o)=>\"object\"==typeof o?r(t,e,o):((t,e,o)=>{const r=e.hasOwnProperty(o);return e.constructor.createProperty(o,t),r?Object.getOwnPropertyDescriptor(e,o):void 0})(t,e,o)}export{n as property,r as standardProperty};\n//# sourceMappingURL=property.js.map\n","import{property as t}from\"./property.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */function r(r){return t({...r,state:!0,attribute:!1})}export{r as state};\n//# sourceMappingURL=state.js.map\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst e=(e,t,c)=>(c.configurable=!0,c.enumerable=!0,Reflect.decorate&&\"object\"!=typeof t&&Object.defineProperty(e,t,c),c);export{e as desc};\n//# sourceMappingURL=base.js.map\n","import{desc as t}from\"./base.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */function e(e,r){return(n,s,i)=>{const o=t=>t.renderRoot?.querySelector(e)??null;if(r){const{get:e,set:r}=\"object\"==typeof s?n:i??(()=>{const t=Symbol();return{get(){return this[t]},set(e){this[t]=e}}})();return t(n,s,{get(){let t=e.call(this);return void 0===t&&(t=o(this),(null!==t||this.hasUpdated)&&r.call(this,t)),t}})}return t(n,s,{get(){return o(this)}})}}export{e as query};\n//# sourceMappingURL=query.js.map\n","import{_$LH as o}from\"./lit-html.js\";\n/**\n * @license\n * Copyright 2020 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const{I:t}=o,i=o=>o,n=o=>null===o||\"object\"!=typeof o&&\"function\"!=typeof o,e={HTML:1,SVG:2,MATHML:3},l=(o,t)=>void 0===t?void 0!==o?._$litType$:o?._$litType$===t,d=o=>null!=o?._$litType$?.h,c=o=>void 0!==o?._$litDirective$,f=o=>o?._$litDirective$,r=o=>void 0===o.strings,s=()=>document.createComment(\"\"),v=(o,n,e)=>{const l=o._$AA.parentNode,d=void 0===n?o._$AB:n._$AA;if(void 0===e){const i=l.insertBefore(s(),d),n=l.insertBefore(s(),d);e=new t(i,n,o,o.options)}else{const t=e._$AB.nextSibling,n=e._$AM,c=n!==o;if(c){let t;e._$AQ?.(o),e._$AM=o,void 0!==e._$AP&&(t=o._$AU)!==n._$AU&&e._$AP(t)}if(t!==d||c){let o=e._$AA;for(;o!==t;){const t=i(o).nextSibling;i(l).insertBefore(o,d),o=t}}}return e},u=(o,t,i=o)=>(o._$AI(t,i),o),m={},p=(o,t=m)=>o._$AH=t,M=o=>o._$AH,h=o=>{o._$AR(),o._$AA.remove()},j=o=>{o._$AR()};export{e as TemplateResultType,j as clearPart,M as getCommittedValue,f as getDirectiveClass,v as insertPart,d as isCompiledTemplateResult,c as isDirectiveResult,n as isPrimitive,r as isSingleExpression,l as isTemplateResult,h as removePart,u as setChildPartValue,p as setCommittedValue};\n//# sourceMappingURL=directive-helpers.js.map\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},e=t=>(...e)=>({_$litDirective$:t,values:e});class i{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}}export{i as Directive,t as PartType,e as directive};\n//# sourceMappingURL=directive.js.map\n","import{isSingleExpression as i}from\"./directive-helpers.js\";import{Directive as t,PartType as e}from\"./directive.js\";export{directive}from\"./directive.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const s=(i,t)=>{const e=i._$AN;if(void 0===e)return!1;for(const i of e)i._$AO?.(t,!1),s(i,t);return!0},o=i=>{let t,e;do{if(void 0===(t=i._$AM))break;e=t._$AN,e.delete(i),i=t}while(0===e?.size)},r=i=>{for(let t;t=i._$AM;i=t){let e=t._$AN;if(void 0===e)t._$AN=e=new Set;else if(e.has(i))break;e.add(i),c(t)}};function h(i){void 0!==this._$AN?(o(this),this._$AM=i,r(this)):this._$AM=i}function n(i,t=!1,e=0){const r=this._$AH,h=this._$AN;if(void 0!==h&&0!==h.size)if(t)if(Array.isArray(r))for(let i=e;i<r.length;i++)s(r[i],!1),o(r[i]);else null!=r&&(s(r,!1),o(r));else s(this,i)}const c=i=>{i.type==e.CHILD&&(i._$AP??=n,i._$AQ??=h)};class f extends t{constructor(){super(...arguments),this._$AN=void 0}_$AT(i,t,e){super._$AT(i,t,e),r(this),this.isConnected=i._$AU}_$AO(i,t=!0){i!==this.isConnected&&(this.isConnected=i,i?this.reconnected?.():this.disconnected?.()),t&&(s(this,i),o(this))}setValue(t){if(i(this._$Ct))this._$Ct._$AI(t,this);else{const i=[...this._$Ct._$AH];i[this._$Ci]=t,this._$Ct._$AI(i,this,0)}}disconnected(){}reconnected(){}}export{f as AsyncDirective,t as Directive,e as PartType};\n//# sourceMappingURL=async-directive.js.map\n","import{nothing as t}from\"../lit-html.js\";import{AsyncDirective as i}from\"../async-directive.js\";import{directive as s}from\"../directive.js\";\n/**\n * @license\n * Copyright 2020 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const e=()=>new h;class h{}const o=new WeakMap,n=s(class extends i{render(i){return t}update(i,[s]){const e=s!==this.G;return e&&void 0!==this.G&&this.rt(void 0),(e||this.lt!==this.ct)&&(this.G=s,this.ht=i.options?.host,this.rt(this.ct=i.element)),t}rt(t){if(this.isConnected||(t=void 0),\"function\"==typeof this.G){const i=this.ht??globalThis;let s=o.get(i);void 0===s&&(s=new WeakMap,o.set(i,s)),void 0!==s.get(this.G)&&this.G.call(this.ht,void 0),s.set(this.G,t),void 0!==t&&this.G.call(this.ht,t)}else this.G.value=t}get lt(){return\"function\"==typeof this.G?o.get(this.ht??globalThis)?.get(this.G):this.G?.value}disconnected(){this.lt===this.ct&&this.rt(void 0)}reconnected(){this.rt(this.ct)}});export{e as createRef,n as ref};\n//# sourceMappingURL=ref.js.map\n","import{nothing as t,noChange as i}from\"../lit-html.js\";import{directive as r,Directive as s,PartType as n}from\"../directive.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */class e extends s{constructor(i){if(super(i),this.it=t,i.type!==n.CHILD)throw Error(this.constructor.directiveName+\"() can only be used in child bindings\")}render(r){if(r===t||null==r)return this._t=void 0,this.it=r;if(r===i)return r;if(\"string\"!=typeof r)throw Error(this.constructor.directiveName+\"() called with a non-string value\");if(r===this.it)return this._t;this.it=r;const s=[r];return s.raw=s,this._t={_$litType$:this.constructor.resultType,strings:s,values:[]}}}e.directiveName=\"unsafeHTML\",e.resultType=1;const o=r(e);export{e as UnsafeHTMLDirective,o as unsafeHTML};\n//# sourceMappingURL=unsafe-html.js.map\n","/**\n * @license lucide v0.456.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n \"stroke-width\": 2,\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.js.map\n","/**\n * @license lucide v0.456.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport defaultAttributes from '../defaultAttributes.js';\n\nconst Paperclip = [\n \"svg\",\n defaultAttributes,\n [\n [\n \"path\",\n {\n d: \"m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48\"\n }\n ]\n ]\n];\n\nexport { Paperclip as default };\n//# sourceMappingURL=paperclip.js.map\n","/**\n * @license lucide v0.456.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport defaultAttributes from '../defaultAttributes.js';\n\nconst Send = [\n \"svg\",\n defaultAttributes,\n [\n [\n \"path\",\n {\n d: \"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z\"\n }\n ],\n [\"path\", { d: \"m21.854 2.147-10.94 10.939\" }]\n ]\n];\n\nexport { Send as default };\n//# sourceMappingURL=send.js.map\n","/**\n * @license lucide v0.456.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport defaultAttributes from '../defaultAttributes.js';\n\nconst Square = [\n \"svg\",\n defaultAttributes,\n [[\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\" }]]\n];\n\nexport { Square as default };\n//# sourceMappingURL=square.js.map\n","/**\n * @license lucide v0.456.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport defaultAttributes from '../defaultAttributes.js';\n\nconst X = [\n \"svg\",\n defaultAttributes,\n [\n [\"path\", { d: \"M18 6 6 18\" }],\n [\"path\", { d: \"m6 6 12 12\" }]\n ]\n];\n\nexport { X as default };\n//# sourceMappingURL=x.js.map\n","import enTranslations from '../i18n/en.json';\nimport zhTranslations from '../i18n/zh.json';\n\nexport type Language = 'en' | 'zh';\n\n// Built-in translations (bundled for production compatibility)\nconst builtInTranslations: Record<Language, Record<string, unknown>> = {\n en: enTranslations as Record<string, unknown>,\n zh: zhTranslations as Record<string, unknown>,\n};\n\n// Translation cache (for runtime-loaded translations)\nconst translationCache: Map<Language, Record<string, unknown>> = new Map();\n\n// Initialize cache with built-in translations\ntranslationCache.set('en', builtInTranslations.en);\ntranslationCache.set('zh', builtInTranslations.zh);\n\nlet currentLanguage: Language = 'en';\n\n// Simple path-based translation getter\nexport function t(path: string, params?: Record<string, string | number>): string {\n const translations = translationCache.get(currentLanguage);\n if (!translations) return path;\n \n const keys = path.split('.');\n let value: unknown = translations;\n \n for (const key of keys) {\n if (value && typeof value === 'object' && key in value) {\n value = (value as Record<string, unknown>)[key];\n } else {\n // Fallback to English\n const enTranslations = translationCache.get('en');\n if (enTranslations && currentLanguage !== 'en') {\n let enValue: unknown = enTranslations;\n for (const k of keys) {\n if (enValue && typeof enValue === 'object' && k in enValue) {\n enValue = (enValue as Record<string, unknown>)[k];\n } else {\n return path;\n }\n }\n value = enValue;\n } else {\n return path;\n }\n }\n }\n \n if (typeof value !== 'string') return path;\n \n // Replace params\n if (params) {\n return value.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key) => {\n const paramValue = params[key];\n return paramValue !== undefined ? String(paramValue) : `{{${key}}}`;\n });\n }\n \n return value;\n}\n\n// Load translations for a language (runtime loading, optional)\nexport async function loadLanguage(lang: Language): Promise<void> {\n if (translationCache.has(lang)) {\n currentLanguage = lang;\n return;\n }\n \n try {\n const response = await fetch(`/src/i18n/${lang}.json`);\n if (!response.ok) {\n throw new Error(`Failed to load ${lang} translations`);\n }\n const translations = await response.json();\n translationCache.set(lang, translations);\n currentLanguage = lang;\n \n // Dispatch language change event\n window.dispatchEvent(new CustomEvent('languagechange', { detail: { language: lang } }));\n } catch (error) {\n console.error(`Failed to load ${lang} translations:`, error);\n // Fallback to English if available\n if (lang !== 'en' && translationCache.has('en')) {\n currentLanguage = 'en';\n }\n }\n}\n\n// Set language\nexport function setLanguage(lang: Language): void {\n if (translationCache.has(lang)) {\n currentLanguage = lang;\n window.dispatchEvent(new CustomEvent('languagechange', { detail: { language: lang } }));\n } else {\n // Try to load\n loadLanguage(lang);\n }\n}\n\n// Get current language\nexport function getCurrentLanguage(): Language {\n return currentLanguage;\n}\n\n// Initialize i18n (sync - uses built-in translations)\nexport function initI18n(defaultLang: Language = 'en'): void {\n currentLanguage = defaultLang;\n}\n\n// Legacy compatibility - old translation keys\nexport const legacyKeys: Record<string, string> = {\n 'Type a message...': 'chat.typeMessage',\n 'Attach file': 'chat.attachFile',\n 'Send message': 'chat.sendMessage',\n 'Abort': 'chat.abort',\n 'No session available': 'errors.noSession',\n 'No agent set': 'errors.noAgent',\n 'Configuration': 'config.title',\n 'Cancel': 'settings.cancel',\n 'Save': 'settings.save',\n 'No result': 'config.noResult',\n 'Artifacts': 'config.artifacts',\n 'Show artifacts': 'config.showArtifacts',\n};\n\n// Legacy i18n function for backward compatibility\nexport function i18n(key: string): string {\n // First check if it's a legacy key\n const newKey = legacyKeys[key];\n if (newKey) {\n return t(newKey);\n }\n // If not a legacy key, try to use as path\n return t(key);\n}\n\n// Export for direct access\nexport { translationCache as translations };\n","import { html, LitElement, type TemplateResult } from 'lit';\nimport { customElement, property, state, query } from 'lit/decorators.js';\nimport { createRef, ref } from 'lit/directives/ref.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport { Paperclip, Send, Square, X } from 'lucide';\n\n// Convert lucide icon array format to SVG string\nfunction iconToSvg(iconData: unknown, className = ''): string {\n if (!iconData || !Array.isArray(iconData)) return '';\n\n const [_tag, attrs, children] = iconData as [string, Record<string, string>, unknown[]];\n\n const attrStr = Object.entries(attrs || {})\n .map(([k, v]) => `${k}=\"${v}\"`)\n .join(' ');\n\n const childrenStr = Array.isArray(children)\n ? children.map(child => {\n if (Array.isArray(child)) {\n const [cTag, cAttrs] = child;\n const cAttrStr = Object.entries(cAttrs || {})\n .map(([k, v]) => `${k}=\"${v}\"`)\n .join(' ');\n return `<${cTag} ${cAttrStr} />`;\n }\n return '';\n }).join('')\n : '';\n\n const finalAttrs = className ? `${attrStr} class=\"${className}\"` : attrStr;\n\n return `<svg ${finalAttrs}>${childrenStr}</svg>`;\n}\nimport { i18n, t } from '../utils/i18n';\n\nexport interface Attachment {\n id: string;\n name: string;\n type: string;\n mimeType: string;\n size: number;\n content: string; // base64\n}\n\n@customElement('message-editor')\nexport class MessageEditor extends LitElement {\n @query('textarea') private textarea!: HTMLTextAreaElement;\n\n @property({ type: String }) value = '';\n @property({ type: Array }) attachments: Attachment[] = [];\n @property({ type: Boolean }) isStreaming = false;\n @property({ type: Boolean }) showAttachmentButton = true;\n @property({ type: Boolean }) showModelSelector = true;\n @property({ attribute: false }) currentModel?: { id: string; provider: string };\n\n @property({ attribute: false }) onSend?: (input: string, attachments: Attachment[]) => void;\n @property({ attribute: false }) onAbort?: () => void;\n @property({ attribute: false }) onModelSelect?: () => void;\n\n @state() private _isComposing = false;\n @state() private _isDragging = false;\n @state() private _processingFiles = false;\n @state() private _isSending = false;\n\n private textareaRef = createRef<HTMLTextAreaElement>();\n private fileInputRef = createRef<HTMLInputElement>();\n private readonly maxFileSize = 20 * 1024 * 1024; // 20MB\n private readonly acceptedTypes = 'image/*,application/pdf,.docx,.pptx,.xlsx,.xls,.txt,.md,.json,.xml,.html,.css,.js,.ts,.jsx,.tsx,.yml,.yaml,.zip';\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('dragover', this._handleDocumentDragOver);\n document.addEventListener('drop', this._handleDocumentDrop);\n document.addEventListener('dragleave', this._handleDocumentDragLeave);\n document.addEventListener('click', this._handleOutsideClick);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('dragover', this._handleDocumentDragOver);\n document.removeEventListener('drop', this._handleDocumentDrop);\n document.removeEventListener('dragleave', this._handleDocumentDragLeave);\n document.removeEventListener('click', this._handleOutsideClick);\n }\n\n private _handleDocumentDragOver = (e: DragEvent) => {\n if (e.dataTransfer?.types.includes('Files')) {\n e.preventDefault();\n this._isDragging = true;\n }\n };\n\n private _handleDocumentDragLeave = (e: DragEvent) => {\n if (e.relatedTarget === null) {\n this._isDragging = false;\n }\n };\n\n private _handleDocumentDrop = async (e: DragEvent) => {\n e.preventDefault();\n this._isDragging = false;\n \n const files = e.dataTransfer?.files;\n if (files && files.length > 0) {\n await this._processFiles(Array.from(files));\n }\n };\n\n override render(): unknown {\n return html`\n <div class=\"editor-container\">\n ${this.attachments.length > 0 ? this._renderAttachments() : ''}\n \n <div class=\"input-row ${this._isDragging ? 'dragging' : ''}\">\n ${this.showAttachmentButton ? this._renderAttachmentButton() : ''}\n \n <textarea\n ${ref(this.textareaRef)}\n class=\"text-input\"\n placeholder=${i18n('Type a message...')}\n .value=${this.value}\n @input=${this._handleInput}\n @keydown=${this._handleKeydown}\n @compositionstart=${() => this._isComposing = true}\n @compositionend=${() => this._isComposing = false}\n @paste=${this._handlePaste}\n rows=\"1\"\n ></textarea>\n\n <div class=\"input-actions\">\n ${this._renderSendButton()}\n </div>\n </div>\n\n ${this._isDragging ? this._renderDropOverlay() : ''}\n </div>\n `;\n }\n\n private _renderAttachments(): unknown {\n return html`\n <div class=\"attachments-row\">\n ${this.attachments.map((att, index) => html`\n <div class=\"attachment-chip\">\n <div class=\"attachment-preview\">\n ${att.mimeType.startsWith('image/') ? html`\n <img src=\"${att.content}\" alt=\"${att.name}\" />\n ` : html`\n ${unsafeHTML(iconToSvg(FileText, 'w-4 h-4'))}\n `}\n </div>\n <span class=\"attachment-name\">${att.name}</span>\n <button type=\"button\" class=\"attachment-remove\" @click=${() => this._removeAttachment(index)}>\n ${unsafeHTML(iconToSvg(X, 'w-3 h-3'))}\n </button>\n </div>\n `)}\n </div>\n `;\n }\n\n private _renderAttachmentButton(): unknown {\n return html`\n <button type=\"button\" class=\"attach-btn\" @click=${() => this._triggerFileSelect('all')} title=${i18n('Attach file')}>\n ${unsafeHTML(iconToSvg(Paperclip, 'w-4 h-4'))}\n </button>\n \n <input\n ${ref(this.fileInputRef)}\n type=\"file\"\n multiple\n accept=${this.acceptedTypes}\n class=\"hidden\"\n @change=${this._handleFileInputChange}\n />\n `;\n }\n\n private _renderSendButton(): unknown {\n const canSend = this.value.trim() || this.attachments.length > 0;\n\n if (this.isStreaming) {\n return html`\n <button type=\"button\" class=\"stop-btn\" @click=${() => this.onAbort?.()} title=${i18n('Abort')}>\n ${unsafeHTML(iconToSvg(Square, 'w-4 h-4'))}\n </button>\n `;\n }\n\n return html`\n <button\n type=\"button\"\n class=\"send-btn ${canSend ? 'active' : ''}\"\n ?disabled=${!canSend}\n @click=${this._send}\n title=${i18n('Send message')}\n >\n ${unsafeHTML(iconToSvg(Send, 'w-4 h-4'))}\n </button>\n `;\n }\n\n private _renderDropOverlay(): unknown {\n return html`\n <div class=\"drop-overlay\">\n <span>Drop files here to attach</span>\n </div>\n `;\n }\n\n private _triggerFileSelect(type: 'image' | 'document' | 'all'): void {\n // Try ref first\n let input: HTMLInputElement | null | undefined = this.fileInputRef.value;\n\n // Fallback: query selector since we're using light DOM\n if (!input) {\n input = this.querySelector('input[type=\"file\"]') as HTMLInputElement | null;\n }\n\n if (!input) {\n console.warn('File input not found');\n return;\n }\n\n if (type === 'image') {\n input.accept = 'image/*';\n } else if (type === 'document') {\n input.accept = '.pdf,.docx,.pptx,.xlsx,.xls,.txt,.md,.json,.xml,.html,.css,.js,.ts,.jsx,.tsx,.yml,.yaml,.zip';\n } else {\n input.accept = this.acceptedTypes;\n }\n\n input.click();\n }\n\n private _handleInput = (e: Event): void => {\n const target = e.target as HTMLTextAreaElement;\n this.value = target.value;\n this._adjustTextareaHeight();\n };\n\n private _handleKeydown = (e: KeyboardEvent): void => {\n if (e.key === 'Enter' && !e.shiftKey && !this._isComposing) {\n e.preventDefault();\n this._send();\n }\n };\n\n private _handlePaste = async (e: ClipboardEvent): Promise<void> => {\n const items = e.clipboardData?.items;\n if (!items) return;\n\n const imageFiles: File[] = [];\n \n for (const item of Array.from(items)) {\n if (item.type.startsWith('image/')) {\n const file = item.getAsFile();\n if (file) {\n imageFiles.push(file);\n }\n }\n }\n\n if (imageFiles.length > 0) {\n e.preventDefault();\n await this._processFiles(imageFiles);\n }\n };\n\n private _adjustTextareaHeight(): void {\n const textarea = this.textareaRef.value;\n if (!textarea) return;\n \n textarea.style.height = 'auto';\n textarea.style.height = Math.min(textarea.scrollHeight, 200) + 'px';\n }\n\n private _send(): void {\n if (this._isSending || this.isStreaming) return;\n if (!this.value.trim() && this.attachments.length === 0) return;\n \n this._isSending = true;\n const attachments = [...this.attachments];\n this.onSend?.(this.value, attachments);\n this.value = '';\n this.attachments = [];\n \n requestAnimationFrame(() => {\n this._adjustTextareaHeight();\n setTimeout(() => {\n this._isSending = false;\n }, 500);\n });\n }\n\n private _handleFileInputChange = async (e: Event): Promise<void> => {\n const input = e.target as HTMLInputElement;\n const files = input.files;\n if (!files) return;\n\n await this._processFiles(Array.from(files));\n input.value = '';\n };\n\n private async _processFiles(files: File[]): Promise<void> {\n this._processingFiles = true;\n\n try {\n for (const file of files) {\n if (file.size > this.maxFileSize) {\n console.warn(`File ${file.name} exceeds max size of ${this.maxFileSize} bytes`);\n continue;\n }\n\n const attachment = await this._loadAttachment(file);\n this.attachments = [...this.attachments, attachment];\n }\n } finally {\n this._processingFiles = false;\n }\n }\n\n private async _loadAttachment(file: File): Promise<Attachment> {\n const base64 = await this._readFileAsBase64(file);\n const isImage = file.type.startsWith('image/');\n\n return {\n id: crypto.randomUUID(),\n name: file.name,\n type: isImage ? 'image' : 'document',\n mimeType: file.type,\n size: file.size,\n content: base64,\n };\n }\n\n private _readFileAsBase64(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = () => reject(reader.error);\n reader.readAsDataURL(file);\n });\n }\n\n private _removeAttachment(index: number): void {\n this.attachments = this.attachments.filter((_, i) => i !== index);\n }\n\n private _formatFileSize(bytes: number): string {\n const units = ['B', 'KB', 'MB', 'GB'];\n let unitIndex = 0;\n let size = bytes;\n while (size >= 1024 && unitIndex < units.length - 1) {\n size /= 1024;\n unitIndex++;\n }\n return `${size.toFixed(1)} ${units[unitIndex]}`;\n }\n}\n","import{noChange as e}from\"../lit-html.js\";import{directive as s,Directive as t,PartType as r}from\"../directive.js\";import{getCommittedValue as l,setChildPartValue as o,insertPart as i,removePart as n,setCommittedValue as f}from\"../directive-helpers.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst u=(e,s,t)=>{const r=new Map;for(let l=s;l<=t;l++)r.set(e[l],l);return r},c=s(class extends t{constructor(e){if(super(e),e.type!==r.CHILD)throw Error(\"repeat() can only be used in text expressions\")}dt(e,s,t){let r;void 0===t?t=s:void 0!==s&&(r=s);const l=[],o=[];let i=0;for(const s of e)l[i]=r?r(s,i):i,o[i]=t(s,i),i++;return{values:o,keys:l}}render(e,s,t){return this.dt(e,s,t).values}update(s,[t,r,c]){const d=l(s),{values:p,keys:a}=this.dt(t,r,c);if(!Array.isArray(d))return this.ut=a,p;const h=this.ut??=[],v=[];let m,y,x=0,j=d.length-1,k=0,w=p.length-1;for(;x<=j&&k<=w;)if(null===d[x])x++;else if(null===d[j])j--;else if(h[x]===a[k])v[k]=o(d[x],p[k]),x++,k++;else if(h[j]===a[w])v[w]=o(d[j],p[w]),j--,w--;else if(h[x]===a[w])v[w]=o(d[x],p[w]),i(s,v[w+1],d[x]),x++,w--;else if(h[j]===a[k])v[k]=o(d[j],p[k]),i(s,d[x],d[j]),j--,k++;else if(void 0===m&&(m=u(a,k,w),y=u(h,x,j)),m.has(h[x]))if(m.has(h[j])){const e=y.get(a[k]),t=void 0!==e?d[e]:null;if(null===t){const e=i(s,d[x]);o(e,p[k]),v[k]=e}else v[k]=o(t,p[k]),i(s,d[x],t),d[e]=null;k++}else n(d[j]),j--;else n(d[x]),x++;for(;k<=w;){const e=i(s,v[w+1]);o(e,p[k]),v[k++]=e}for(;x<=j;){const e=d[x++];null!==e&&n(e)}return this.ut=a,f(s,v),e}});export{c as repeat};\n//# sourceMappingURL=repeat.js.map\n","/**\n * @license\n * Copyright 2021 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nexport class RangeChangedEvent extends Event {\n constructor(range) {\n super(RangeChangedEvent.eventName, { bubbles: false });\n this.first = range.first;\n this.last = range.last;\n }\n}\nRangeChangedEvent.eventName = 'rangeChanged';\nexport class VisibilityChangedEvent extends Event {\n constructor(range) {\n super(VisibilityChangedEvent.eventName, { bubbles: false });\n this.first = range.first;\n this.last = range.last;\n }\n}\nVisibilityChangedEvent.eventName = 'visibilityChanged';\nexport class UnpinnedEvent extends Event {\n constructor() {\n super(UnpinnedEvent.eventName, { bubbles: false });\n }\n}\nUnpinnedEvent.eventName = 'unpinned';\n//# sourceMappingURL=events.js.map","/**\n * @license\n * Copyright 2021 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nexport class ScrollerShim {\n constructor(element) {\n this._element = null;\n const node = element ?? window;\n this._node = node;\n if (element) {\n this._element = element;\n }\n }\n get element() {\n return (this._element || document.scrollingElement || document.documentElement);\n }\n get scrollTop() {\n return this.element.scrollTop || window.scrollY;\n }\n get scrollLeft() {\n return this.element.scrollLeft || window.scrollX;\n }\n get scrollHeight() {\n return this.element.scrollHeight;\n }\n get scrollWidth() {\n return this.element.scrollWidth;\n }\n get viewportHeight() {\n return this._element\n ? this._element.getBoundingClientRect().height\n : window.innerHeight;\n }\n get viewportWidth() {\n return this._element\n ? this._element.getBoundingClientRect().width\n : window.innerWidth;\n }\n get maxScrollTop() {\n return this.scrollHeight - this.viewportHeight;\n }\n get maxScrollLeft() {\n return this.scrollWidth - this.viewportWidth;\n }\n}\nexport class ScrollerController extends ScrollerShim {\n constructor(client, element) {\n super(element);\n this._clients = new Set();\n this._retarget = null;\n this._end = null;\n this.__destination = null;\n this.correctingScrollError = false;\n this._checkForArrival = this._checkForArrival.bind(this);\n this._updateManagedScrollTo = this._updateManagedScrollTo.bind(this);\n this.scrollTo = this.scrollTo.bind(this);\n this.scrollBy = this.scrollBy.bind(this);\n const node = this._node;\n this._originalScrollTo = node.scrollTo;\n this._originalScrollBy = node.scrollBy;\n this._originalScroll = node.scroll;\n this._attach(client);\n }\n get _destination() {\n return this.__destination;\n }\n get scrolling() {\n return this._destination !== null;\n }\n scrollTo(p1, p2) {\n const options = typeof p1 === 'number' && typeof p2 === 'number'\n ? { left: p1, top: p2 }\n : p1;\n this._scrollTo(options);\n }\n scrollBy(p1, p2) {\n const options = typeof p1 === 'number' && typeof p2 === 'number'\n ? { left: p1, top: p2 }\n : p1;\n if (options.top !== undefined) {\n options.top += this.scrollTop;\n }\n if (options.left !== undefined) {\n options.left += this.scrollLeft;\n }\n this._scrollTo(options);\n }\n _nativeScrollTo(options) {\n this._originalScrollTo.bind(this._element || window)(options);\n }\n _scrollTo(options, retarget = null, end = null) {\n if (this._end !== null) {\n this._end();\n }\n if (options.behavior === 'smooth') {\n this._setDestination(options);\n this._retarget = retarget;\n this._end = end;\n }\n else {\n this._resetScrollState();\n }\n this._nativeScrollTo(options);\n }\n _setDestination(options) {\n let { top, left } = options;\n top =\n top === undefined\n ? undefined\n : Math.max(0, Math.min(top, this.maxScrollTop));\n left =\n left === undefined\n ? undefined\n : Math.max(0, Math.min(left, this.maxScrollLeft));\n if (this._destination !== null &&\n left === this._destination.left &&\n top === this._destination.top) {\n return false;\n }\n this.__destination = { top, left, behavior: 'smooth' };\n return true;\n }\n _resetScrollState() {\n this.__destination = null;\n this._retarget = null;\n this._end = null;\n }\n _updateManagedScrollTo(coordinates) {\n if (this._destination) {\n if (this._setDestination(coordinates)) {\n this._nativeScrollTo(this._destination);\n }\n }\n }\n managedScrollTo(options, retarget, end) {\n this._scrollTo(options, retarget, end);\n return this._updateManagedScrollTo;\n }\n correctScrollError(coordinates) {\n this.correctingScrollError = true;\n requestAnimationFrame(() => requestAnimationFrame(() => (this.correctingScrollError = false)));\n // Correct the error\n this._nativeScrollTo(coordinates);\n // Then, if we were headed for a specific destination, we continue scrolling:\n // First, we update our target destination, if applicable...\n if (this._retarget) {\n this._setDestination(this._retarget());\n }\n // Then we go ahead and resume scrolling\n if (this._destination) {\n this._nativeScrollTo(this._destination);\n }\n }\n _checkForArrival() {\n if (this._destination !== null) {\n const { scrollTop, scrollLeft } = this;\n let { top, left } = this._destination;\n top = Math.min(top || 0, this.maxScrollTop);\n left = Math.min(left || 0, this.maxScrollLeft);\n const topDiff = Math.abs(top - scrollTop);\n const leftDiff = Math.abs(left - scrollLeft);\n // We check to see if we've arrived at our destination.\n if (topDiff < 1 && leftDiff < 1) {\n if (this._end) {\n this._end();\n }\n this._resetScrollState();\n }\n }\n }\n detach(client) {\n this._clients.delete(client);\n /**\n * If there aren't any more clients, then return the node's default\n * scrolling methods\n */\n if (this._clients.size === 0) {\n this._node.scrollTo = this._originalScrollTo;\n this._node.scrollBy = this._originalScrollBy;\n this._node.scroll = this._originalScroll;\n this._node.removeEventListener('scroll', this._checkForArrival);\n }\n return null;\n }\n _attach(client) {\n this._clients.add(client);\n /**\n * The node should only have the methods shimmed when adding the first\n * client – otherwise it's redundant\n */\n if (this._clients.size === 1) {\n this._node.scrollTo = this.scrollTo;\n this._node.scrollBy = this.scrollBy;\n this._node.scroll = this.scrollTo;\n this._node.addEventListener('scroll', this._checkForArrival);\n }\n }\n}\n//# sourceMappingURL=ScrollerController.js.map","/**\n * @license\n * Copyright 2021 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nimport { RangeChangedEvent, VisibilityChangedEvent, UnpinnedEvent, } from './events.js';\nimport { ScrollerController } from './ScrollerController.js';\n// Virtualizer depends on `ResizeObserver`, which is supported in\n// all modern browsers. For developers whose browser support\n// matrix includes older browsers, we include a compatible\n// polyfill in the package; this bit of module state facilitates\n// a simple mechanism (see ./polyfillLoaders/ResizeObserver.js.)\n// for loading the polyfill.\nlet _ResizeObserver = typeof window !== 'undefined' ? window.ResizeObserver : undefined;\n/**\n * Call this function to provide a `ResizeObserver` polyfill for Virtualizer to use.\n * @param Ctor Constructor for a `ResizeObserver` polyfill (recommend using the one provided with the Virtualizer package)\n */\nexport function provideResizeObserver(Ctor) {\n _ResizeObserver = Ctor;\n}\nexport const virtualizerRef = Symbol('virtualizerRef');\nconst SIZER_ATTRIBUTE = 'virtualizer-sizer';\nlet DefaultLayoutConstructor;\n/**\n * Provides virtual scrolling boilerplate.\n *\n * Extensions of this class must set hostElement and layout.\n *\n * Extensions of this class must also override VirtualRepeater's DOM\n * manipulation methods.\n */\nexport class Virtualizer {\n constructor(config) {\n this._benchmarkStart = null;\n this._layout = null;\n this._clippingAncestors = [];\n /**\n * Layout provides these values, we set them on _render().\n * TODO @straversi: Can we find an XOR type, usable for the key here?\n */\n this._scrollSize = null;\n /**\n * Difference between scroll target's current and required scroll offsets.\n * Provided by layout.\n */\n this._scrollError = null;\n /**\n * A list of the positions (top, left) of the children in the current range.\n */\n this._childrenPos = null;\n // TODO: (graynorton): type\n this._childMeasurements = null;\n this._toBeMeasured = new Map();\n this._rangeChanged = true;\n this._itemsChanged = true;\n this._visibilityChanged = true;\n this._scrollerController = null;\n this._isScroller = false;\n this._sizer = null;\n /**\n * Resize observer attached to hostElement.\n */\n this._hostElementRO = null;\n /**\n * Resize observer attached to children.\n */\n this._childrenRO = null;\n this._mutationObserver = null;\n this._scrollEventListeners = [];\n this._scrollEventListenerOptions = {\n passive: true,\n };\n // TODO (graynorton): Rethink, per longer comment below\n this._loadListener = this._childLoaded.bind(this);\n /**\n * Index of element to scroll into view, plus scroll\n * behavior options, as imperatively specified via\n * `element(index).scrollIntoView()`\n */\n this._scrollIntoViewTarget = null;\n this._updateScrollIntoViewCoordinates = null;\n /**\n * Items to render. Set by items.\n */\n this._items = [];\n /**\n * Index of the first child in the range, not necessarily the first visible child.\n * TODO @straversi: Consider renaming these.\n */\n this._first = -1;\n /**\n * Index of the last child in the range.\n */\n this._last = -1;\n /**\n * Index of the first item intersecting the viewport.\n */\n this._firstVisible = -1;\n /**\n * Index of the last item intersecting the viewport.\n */\n this._lastVisible = -1;\n this._scheduled = new WeakSet();\n /**\n * Invoked at the end of each render cycle: children in the range are\n * measured, and their dimensions passed to this callback. Use it to layout\n * children as needed.\n */\n this._measureCallback = null;\n this._measureChildOverride = null;\n /**\n * State for `layoutComplete` promise\n */\n this._layoutCompletePromise = null;\n this._layoutCompleteResolver = null;\n this._layoutCompleteRejecter = null;\n this._pendingLayoutComplete = null;\n /**\n * Layout initialization is async because we dynamically load\n * the default layout if none is specified. This state is to track\n * whether init is complete.\n */\n this._layoutInitialized = null;\n /**\n * Track connection state to guard against errors / unnecessary work\n */\n this._connected = false;\n if (!config) {\n throw new Error('Virtualizer constructor requires a configuration object');\n }\n if (config.hostElement) {\n this._init(config);\n }\n else {\n throw new Error('Virtualizer configuration requires the \"hostElement\" property');\n }\n }\n set items(items) {\n if (Array.isArray(items) && items !== this._items) {\n this._itemsChanged = true;\n this._items = items;\n this._schedule(this._updateLayout);\n }\n }\n _init(config) {\n this._isScroller = !!config.scroller;\n this._initHostElement(config);\n // If no layout is specified, we make an empty\n // layout config, which will result in the default\n // layout with default parameters\n const layoutConfig = config.layout || {};\n // Save the promise returned by `_initLayout` as a state\n // variable we can check before updating layout config\n this._layoutInitialized = this._initLayout(layoutConfig);\n }\n _initObservers() {\n this._mutationObserver = new MutationObserver(this._finishDOMUpdate.bind(this));\n this._hostElementRO = new _ResizeObserver(() => this._hostElementSizeChanged());\n this._childrenRO = new _ResizeObserver(this._childrenSizeChanged.bind(this));\n }\n _initHostElement(config) {\n const hostElement = (this._hostElement = config.hostElement);\n this._applyVirtualizerStyles();\n hostElement[virtualizerRef] = this;\n }\n connected() {\n this._initObservers();\n const includeSelf = this._isScroller;\n this._clippingAncestors = getClippingAncestors(this._hostElement, includeSelf);\n this._scrollerController = new ScrollerController(this, this._clippingAncestors[0]);\n this._schedule(this._updateLayout);\n this._observeAndListen();\n this._connected = true;\n }\n _observeAndListen() {\n this._mutationObserver.observe(this._hostElement, { childList: true });\n this._hostElementRO.observe(this._hostElement);\n this._scrollEventListeners.push(window);\n window.addEventListener('scroll', this, this._scrollEventListenerOptions);\n this._clippingAncestors.forEach((ancestor) => {\n ancestor.addEventListener('scroll', this, this._scrollEventListenerOptions);\n this._scrollEventListeners.push(ancestor);\n this._hostElementRO.observe(ancestor);\n });\n this._hostElementRO.observe(this._scrollerController.element);\n this._children.forEach((child) => this._childrenRO.observe(child));\n this._scrollEventListeners.forEach((target) => target.addEventListener('scroll', this, this._scrollEventListenerOptions));\n }\n disconnected() {\n this._scrollEventListeners.forEach((target) => target.removeEventListener('scroll', this, this._scrollEventListenerOptions));\n this._scrollEventListeners = [];\n this._clippingAncestors = [];\n this._scrollerController?.detach(this);\n this._scrollerController = null;\n this._mutationObserver?.disconnect();\n this._mutationObserver = null;\n this._hostElementRO?.disconnect();\n this._hostElementRO = null;\n this._childrenRO?.disconnect();\n this._childrenRO = null;\n this._rejectLayoutCompletePromise('disconnected');\n this._connected = false;\n }\n _applyVirtualizerStyles() {\n const hostElement = this._hostElement;\n // Would rather set these CSS properties on the host using Shadow Root\n // style scoping (and falling back to a global stylesheet where native\n // Shadow DOM is not available), but this Mobile Safari bug is preventing\n // that from working: https://bugs.webkit.org/show_bug.cgi?id=226195\n const style = hostElement.style;\n style.display = style.display || 'block';\n style.position = style.position || 'relative';\n style.contain = style.contain || 'size layout';\n if (this._isScroller) {\n style.overflow = style.overflow || 'auto';\n style.minHeight = style.minHeight || '150px';\n }\n }\n _getSizer() {\n const hostElement = this._hostElement;\n if (!this._sizer) {\n // Use a preexisting sizer element if provided (for better integration\n // with vDOM renderers)\n let sizer = hostElement.querySelector(`[${SIZER_ATTRIBUTE}]`);\n if (!sizer) {\n sizer = document.createElement('div');\n sizer.setAttribute(SIZER_ATTRIBUTE, '');\n hostElement.appendChild(sizer);\n }\n // When the scrollHeight is large, the height of this element might be\n // ignored. Setting content and font-size ensures the element has a size.\n Object.assign(sizer.style, {\n position: 'absolute',\n margin: '-2px 0 0 0',\n padding: 0,\n visibility: 'hidden',\n fontSize: '2px',\n });\n sizer.textContent = '&nbsp;';\n sizer.setAttribute(SIZER_ATTRIBUTE, '');\n this._sizer = sizer;\n }\n return this._sizer;\n }\n async updateLayoutConfig(layoutConfig) {\n // If layout initialization hasn't finished yet, we wait\n // for it to finish so we can check whether the new config\n // is compatible with the existing layout before proceeding.\n await this._layoutInitialized;\n const Ctor = layoutConfig.type ||\n // The new config is compatible with the current layout,\n // so we update the config and return true to indicate\n // a successful update\n DefaultLayoutConstructor;\n if (typeof Ctor === 'function' && this._layout instanceof Ctor) {\n const config = { ...layoutConfig };\n delete config.type;\n this._layout.config = config;\n // The new config requires a different layout altogether, but\n // to limit implementation complexity we don't support dynamically\n // changing the layout of an existing virtualizer instance.\n // Returning false here lets the caller know that they should\n // instead make a new virtualizer instance with the desired layout.\n return true;\n }\n return false;\n }\n async _initLayout(layoutConfig) {\n let config;\n let Ctor;\n if (typeof layoutConfig.type === 'function') {\n // If we have a full LayoutSpecifier, the `type` property\n // gives us our constructor...\n Ctor = layoutConfig.type;\n // ...while the rest of the specifier is our layout config\n const copy = { ...layoutConfig };\n delete copy.type;\n config = copy;\n }\n else {\n // If we don't have a full LayoutSpecifier, we just\n // have a config for the default layout\n config = layoutConfig;\n }\n if (Ctor === undefined) {\n // If we don't have a constructor yet, load the default\n DefaultLayoutConstructor = Ctor = (await import('./layouts/flow.js'))\n .FlowLayout;\n }\n this._layout = new Ctor((message) => this._handleLayoutMessage(message), config);\n if (this._layout.measureChildren &&\n typeof this._layout.updateItemSizes === 'function') {\n if (typeof this._layout.measureChildren === 'function') {\n this._measureChildOverride = this._layout.measureChildren;\n }\n this._measureCallback = this._layout.updateItemSizes.bind(this._layout);\n }\n if (this._layout.listenForChildLoadEvents) {\n this._hostElement.addEventListener('load', this._loadListener, true);\n }\n this._schedule(this._updateLayout);\n }\n // TODO (graynorton): Rework benchmarking so that it has no API and\n // instead is always on except in production builds\n startBenchmarking() {\n if (this._benchmarkStart === null) {\n this._benchmarkStart = window.performance.now();\n }\n }\n stopBenchmarking() {\n if (this._benchmarkStart !== null) {\n const now = window.performance.now();\n const timeElapsed = now - this._benchmarkStart;\n const entries = performance.getEntriesByName('uv-virtualizing', 'measure');\n const virtualizationTime = entries\n .filter((e) => e.startTime >= this._benchmarkStart && e.startTime < now)\n .reduce((t, m) => t + m.duration, 0);\n this._benchmarkStart = null;\n return { timeElapsed, virtualizationTime };\n }\n return null;\n }\n _measureChildren() {\n const mm = {};\n const children = this._children;\n const fn = this._measureChildOverride || this._measureChild;\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n const idx = this._first + i;\n if (this._itemsChanged || this._toBeMeasured.has(child)) {\n mm[idx] = fn.call(this, child, this._items[idx]);\n }\n }\n this._childMeasurements = mm;\n this._schedule(this._updateLayout);\n this._toBeMeasured.clear();\n }\n /**\n * Returns the width, height, and margins of the given child.\n */\n _measureChild(element) {\n // offsetWidth doesn't take transforms in consideration, so we use\n // getBoundingClientRect which does.\n const { width, height } = element.getBoundingClientRect();\n return Object.assign({ width, height }, getMargins(element));\n }\n async _schedule(method) {\n if (!this._scheduled.has(method)) {\n this._scheduled.add(method);\n await Promise.resolve();\n this._scheduled.delete(method);\n method.call(this);\n }\n }\n async _updateDOM(state) {\n this._scrollSize = state.scrollSize;\n this._adjustRange(state.range);\n this._childrenPos = state.childPositions;\n this._scrollError = state.scrollError || null;\n const { _rangeChanged, _itemsChanged } = this;\n if (this._visibilityChanged) {\n this._notifyVisibility();\n this._visibilityChanged = false;\n }\n if (_rangeChanged || _itemsChanged) {\n this._notifyRange();\n this._rangeChanged = false;\n }\n this._finishDOMUpdate();\n }\n _finishDOMUpdate() {\n if (this._connected) {\n // _childrenRO should be non-null if we're connected\n this._children.forEach((child) => this._childrenRO.observe(child));\n this._checkScrollIntoViewTarget(this._childrenPos);\n this._positionChildren(this._childrenPos);\n this._sizeHostElement(this._scrollSize);\n this._correctScrollError();\n if (this._benchmarkStart && 'mark' in window.performance) {\n window.performance.mark('uv-end');\n }\n }\n }\n _updateLayout() {\n if (this._layout && this._connected) {\n this._layout.items = this._items;\n this._updateView();\n if (this._childMeasurements !== null) {\n // If the layout has been changed, we may have measurements but no callback\n if (this._measureCallback) {\n this._measureCallback(this._childMeasurements);\n }\n this._childMeasurements = null;\n }\n this._layout.reflowIfNeeded();\n if (this._benchmarkStart && 'mark' in window.performance) {\n window.performance.mark('uv-end');\n }\n }\n }\n _handleScrollEvent() {\n if (this._benchmarkStart && 'mark' in window.performance) {\n try {\n window.performance.measure('uv-virtualizing', 'uv-start', 'uv-end');\n }\n catch (e) {\n console.warn('Error measuring performance data: ', e);\n }\n window.performance.mark('uv-start');\n }\n if (this._scrollerController.correctingScrollError === false) {\n // This is a user-initiated scroll, so we unpin the layout\n this._layout?.unpin();\n }\n this._schedule(this._updateLayout);\n }\n handleEvent(event) {\n switch (event.type) {\n case 'scroll':\n if (event.currentTarget === window ||\n this._clippingAncestors.includes(event.currentTarget)) {\n this._handleScrollEvent();\n }\n break;\n default:\n console.warn('event not handled', event);\n }\n }\n _handleLayoutMessage(message) {\n if (message.type === 'stateChanged') {\n this._updateDOM(message);\n }\n else if (message.type === 'visibilityChanged') {\n this._firstVisible = message.firstVisible;\n this._lastVisible = message.lastVisible;\n this._notifyVisibility();\n }\n else if (message.type === 'unpinned') {\n this._hostElement.dispatchEvent(new UnpinnedEvent());\n }\n }\n get _children() {\n const arr = [];\n let next = this._hostElement.firstElementChild;\n while (next) {\n if (!next.hasAttribute(SIZER_ATTRIBUTE)) {\n arr.push(next);\n }\n next = next.nextElementSibling;\n }\n return arr;\n }\n _updateView() {\n const hostElement = this._hostElement;\n const scrollingElement = this._scrollerController?.element;\n const layout = this._layout;\n if (hostElement && scrollingElement && layout) {\n let top, left, bottom, right;\n const hostElementBounds = hostElement.getBoundingClientRect();\n top = 0;\n left = 0;\n bottom = window.innerHeight;\n right = window.innerWidth;\n const ancestorBounds = this._clippingAncestors.map((ancestor) => ancestor.getBoundingClientRect());\n ancestorBounds.unshift(hostElementBounds);\n for (const bounds of ancestorBounds) {\n top = Math.max(top, bounds.top);\n left = Math.max(left, bounds.left);\n bottom = Math.min(bottom, bounds.bottom);\n right = Math.min(right, bounds.right);\n }\n const scrollingElementBounds = scrollingElement.getBoundingClientRect();\n const offsetWithinScroller = {\n left: hostElementBounds.left - scrollingElementBounds.left,\n top: hostElementBounds.top - scrollingElementBounds.top,\n };\n const totalScrollSize = {\n width: scrollingElement.scrollWidth,\n height: scrollingElement.scrollHeight,\n };\n const scrollTop = top - hostElementBounds.top + hostElement.scrollTop;\n const scrollLeft = left - hostElementBounds.left + hostElement.scrollLeft;\n const height = Math.max(0, bottom - top);\n const width = Math.max(0, right - left);\n layout.viewportSize = { width, height };\n layout.viewportScroll = { top: scrollTop, left: scrollLeft };\n layout.totalScrollSize = totalScrollSize;\n layout.offsetWithinScroller = offsetWithinScroller;\n }\n }\n /**\n * Styles the host element so that its size reflects the\n * total size of all items.\n */\n _sizeHostElement(size) {\n // Some browsers seem to crap out if the host element gets larger than\n // a certain size, so we clamp it here (this value based on ad hoc\n // testing in Chrome / Safari / Firefox Mac)\n const max = 8200000;\n const h = size && size.width !== null ? Math.min(max, size.width) : 0;\n const v = size && size.height !== null ? Math.min(max, size.height) : 0;\n if (this._isScroller) {\n this._getSizer().style.transform = `translate(${h}px, ${v}px)`;\n }\n else {\n const style = this._hostElement.style;\n style.minWidth = h ? `${h}px` : '100%';\n style.minHeight = v ? `${v}px` : '100%';\n }\n }\n /**\n * Sets the top and left transform style of the children from the values in\n * pos.\n */\n _positionChildren(pos) {\n if (pos) {\n pos.forEach(({ top, left, width, height, xOffset, yOffset }, index) => {\n const child = this._children[index - this._first];\n if (child) {\n child.style.position = 'absolute';\n child.style.boxSizing = 'border-box';\n child.style.transform = `translate(${left}px, ${top}px)`;\n if (width !== undefined) {\n child.style.width = width + 'px';\n }\n if (height !== undefined) {\n child.style.height = height + 'px';\n }\n child.style.left =\n xOffset === undefined ? null : xOffset + 'px';\n child.style.top =\n yOffset === undefined ? null : yOffset + 'px';\n }\n });\n }\n }\n async _adjustRange(range) {\n const { _first, _last, _firstVisible, _lastVisible } = this;\n this._first = range.first;\n this._last = range.last;\n this._firstVisible = range.firstVisible;\n this._lastVisible = range.lastVisible;\n this._rangeChanged =\n this._rangeChanged || this._first !== _first || this._last !== _last;\n this._visibilityChanged =\n this._visibilityChanged ||\n this._firstVisible !== _firstVisible ||\n this._lastVisible !== _lastVisible;\n }\n _correctScrollError() {\n if (this._scrollError) {\n const { scrollTop, scrollLeft } = this._scrollerController;\n const { top, left } = this._scrollError;\n this._scrollError = null;\n this._scrollerController.correctScrollError({\n top: scrollTop - top,\n left: scrollLeft - left,\n });\n }\n }\n element(index) {\n if (index === Infinity) {\n index = this._items.length - 1;\n }\n return this._items?.[index] === undefined\n ? undefined\n : {\n scrollIntoView: (options = {}) => this._scrollElementIntoView({ ...options, index }),\n };\n }\n _scrollElementIntoView(options) {\n if (options.index >= this._first && options.index <= this._last) {\n this._children[options.index - this._first].scrollIntoView(options);\n }\n else {\n options.index = Math.min(options.index, this._items.length - 1);\n if (options.behavior === 'smooth') {\n const coordinates = this._layout.getScrollIntoViewCoordinates(options);\n const { behavior } = options;\n this._updateScrollIntoViewCoordinates =\n this._scrollerController.managedScrollTo(Object.assign(coordinates, { behavior }), () => this._layout.getScrollIntoViewCoordinates(options), () => (this._scrollIntoViewTarget = null));\n this._scrollIntoViewTarget = options;\n }\n else {\n this._layout.pin = options;\n }\n }\n }\n /**\n * If we are smoothly scrolling to an element and the target element\n * is in the DOM, we update our target coordinates as needed\n */\n _checkScrollIntoViewTarget(pos) {\n const { index } = this._scrollIntoViewTarget || {};\n if (index && pos?.has(index)) {\n this._updateScrollIntoViewCoordinates(this._layout.getScrollIntoViewCoordinates(this._scrollIntoViewTarget));\n }\n }\n /**\n * Emits a rangechange event with the current first, last, firstVisible, and\n * lastVisible.\n */\n _notifyRange() {\n this._hostElement.dispatchEvent(new RangeChangedEvent({ first: this._first, last: this._last }));\n }\n _notifyVisibility() {\n this._hostElement.dispatchEvent(new VisibilityChangedEvent({\n first: this._firstVisible,\n last: this._lastVisible,\n }));\n }\n get layoutComplete() {\n // Lazily create promise\n if (!this._layoutCompletePromise) {\n this._layoutCompletePromise = new Promise((resolve, reject) => {\n this._layoutCompleteResolver = resolve;\n this._layoutCompleteRejecter = reject;\n });\n }\n return this._layoutCompletePromise;\n }\n _rejectLayoutCompletePromise(reason) {\n if (this._layoutCompleteRejecter !== null) {\n this._layoutCompleteRejecter(reason);\n }\n this._resetLayoutCompleteState();\n }\n _scheduleLayoutComplete() {\n // Don't do anything unless we have a pending promise\n // And only request a frame if we haven't already done so\n if (this._layoutCompletePromise && this._pendingLayoutComplete === null) {\n // Wait one additional frame to be sure the layout is stable\n this._pendingLayoutComplete = requestAnimationFrame(() => requestAnimationFrame(() => this._resolveLayoutCompletePromise()));\n }\n }\n _resolveLayoutCompletePromise() {\n if (this._layoutCompleteResolver !== null) {\n this._layoutCompleteResolver();\n }\n this._resetLayoutCompleteState();\n }\n _resetLayoutCompleteState() {\n this._layoutCompletePromise = null;\n this._layoutCompleteResolver = null;\n this._layoutCompleteRejecter = null;\n this._pendingLayoutComplete = null;\n }\n /**\n * Render and update the view at the next opportunity with the given\n * hostElement size.\n */\n _hostElementSizeChanged() {\n this._schedule(this._updateLayout);\n }\n // TODO (graynorton): Rethink how this works. Probably child loading is too specific\n // to have dedicated support for; might want some more generic lifecycle hooks for\n // layouts to use. Possibly handle measurement this way, too, or maybe that remains\n // a first-class feature?\n _childLoaded() { }\n // This is the callback for the ResizeObserver that watches the\n // virtualizer's children. We land here at the end of every virtualizer\n // update cycle that results in changes to physical items, and we also\n // end up here if one or more children change size independently of\n // the virtualizer update cycle.\n _childrenSizeChanged(changes) {\n // Only measure if the layout requires it\n if (this._layout?.measureChildren) {\n for (const change of changes) {\n this._toBeMeasured.set(change.target, change.contentRect);\n }\n this._measureChildren();\n }\n // If this is the end of an update cycle, we need to reset some\n // internal state. This should be a harmless no-op if we're handling\n // an out-of-cycle ResizeObserver callback, so we don't need to\n // distinguish between the two cases.\n this._scheduleLayoutComplete();\n this._itemsChanged = false;\n this._rangeChanged = false;\n }\n}\nfunction getMargins(el) {\n const style = window.getComputedStyle(el);\n return {\n marginTop: getMarginValue(style.marginTop),\n marginRight: getMarginValue(style.marginRight),\n marginBottom: getMarginValue(style.marginBottom),\n marginLeft: getMarginValue(style.marginLeft),\n };\n}\nfunction getMarginValue(value) {\n const float = value ? parseFloat(value) : NaN;\n return Number.isNaN(float) ? 0 : float;\n}\n// TODO (graynorton): Deal with iframes?\nfunction getParentElement(el) {\n if (el.assignedSlot !== null) {\n return el.assignedSlot;\n }\n if (el.parentElement !== null) {\n return el.parentElement;\n }\n const parentNode = el.parentNode;\n if (parentNode && parentNode.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n return parentNode.host || null;\n }\n return null;\n}\n///\nfunction getElementAncestors(el, includeSelf = false) {\n const ancestors = [];\n let parent = includeSelf ? el : getParentElement(el);\n while (parent !== null) {\n ancestors.push(parent);\n parent = getParentElement(parent);\n }\n return ancestors;\n}\nfunction getClippingAncestors(el, includeSelf = false) {\n let foundFixed = false;\n return getElementAncestors(el, includeSelf).filter((a) => {\n if (foundFixed) {\n return false;\n }\n const style = getComputedStyle(a);\n foundFixed = style.position === 'fixed';\n return style.overflow !== 'visible';\n });\n}\n//# sourceMappingURL=Virtualizer.js.map","/**\n * @license\n * Copyright 2021 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nimport { html, noChange } from 'lit';\nimport { directive, PartType } from 'lit/directive.js';\nimport { AsyncDirective } from 'lit/async-directive.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { Virtualizer } from './Virtualizer.js';\nexport { virtualizerRef } from './Virtualizer.js';\nexport const defaultKeyFunction = (item) => item;\nexport const defaultRenderItem = (item, idx) => html `${idx}: ${JSON.stringify(item, null, 2)}`;\nclass VirtualizeDirective extends AsyncDirective {\n constructor(part) {\n super(part);\n this._virtualizer = null;\n this._first = 0;\n this._last = -1;\n this._renderItem = (item, idx) => defaultRenderItem(item, idx + this._first);\n this._keyFunction = (item, idx) => defaultKeyFunction(item, idx + this._first);\n this._items = [];\n if (part.type !== PartType.CHILD) {\n throw new Error('The virtualize directive can only be used in child expressions');\n }\n }\n render(config) {\n if (config) {\n this._setFunctions(config);\n }\n const itemsToRender = [];\n if (this._first >= 0 && this._last >= this._first) {\n for (let i = this._first; i <= this._last; i++) {\n itemsToRender.push(this._items[i]);\n }\n }\n return repeat(itemsToRender, this._keyFunction, this._renderItem);\n }\n update(part, [config]) {\n this._setFunctions(config);\n const itemsChanged = this._items !== config.items;\n this._items = config.items || [];\n if (this._virtualizer) {\n this._updateVirtualizerConfig(part, config);\n }\n else {\n this._initialize(part, config);\n }\n return itemsChanged ? noChange : this.render();\n }\n async _updateVirtualizerConfig(part, config) {\n const compatible = await this._virtualizer.updateLayoutConfig(config.layout || {});\n if (!compatible) {\n const hostElement = part.parentNode;\n this._makeVirtualizer(hostElement, config);\n }\n this._virtualizer.items = this._items;\n }\n _setFunctions(config) {\n const { renderItem, keyFunction } = config;\n if (renderItem) {\n this._renderItem = (item, idx) => renderItem(item, idx + this._first);\n }\n if (keyFunction) {\n this._keyFunction = (item, idx) => keyFunction(item, idx + this._first);\n }\n }\n _makeVirtualizer(hostElement, config) {\n if (this._virtualizer) {\n this._virtualizer.disconnected();\n }\n const { layout, scroller, items } = config;\n this._virtualizer = new Virtualizer({ hostElement, layout, scroller });\n this._virtualizer.items = items;\n this._virtualizer.connected();\n }\n _initialize(part, config) {\n const hostElement = part.parentNode;\n if (hostElement && hostElement.nodeType === 1) {\n hostElement.addEventListener('rangeChanged', (e) => {\n this._first = e.first;\n this._last = e.last;\n this.setValue(this.render());\n });\n this._makeVirtualizer(hostElement, config);\n }\n }\n disconnected() {\n this._virtualizer?.disconnected();\n }\n reconnected() {\n this._virtualizer?.connected();\n }\n}\nexport const virtualize = directive(VirtualizeDirective);\n//# sourceMappingURL=virtualize.js.map","import { html, type TemplateResult } from 'lit';\n\n// Dynamic icon loader using lucide\nexport async function loadIcon(name: string): Promise<TemplateResult> {\n try {\n // Dynamic import from lucide\n const lucide = await import('lucide');\n const iconFn = (lucide as Record<string, (props: { size?: number }) => string>)[name];\n \n if (iconFn) {\n const svgString = iconFn({ size: 18 });\n return html`${svgString}`;\n }\n } catch {\n // Fallback to inline icons\n }\n \n // Fallback inline icons\n return fallbackIcons[name] || fallbackIcons.helpCircle;\n}\n\n// Synchronous icon getter (returns fallback if not cached)\nexport function getIcon(name: string): TemplateResult {\n return fallbackIcons[name] || fallbackIcons.helpCircle;\n}\n\n// Inline SVG fallback icons\nconst fallbackIcons: Record<string, TemplateResult> = {\n messageSquare: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\n </svg>\n `,\n settings: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\n <path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z\"></path>\n </svg>\n `,\n menu: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"></line>\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"></line>\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"></line>\n </svg>\n `,\n chevronDown: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"6 9 12 15 18 9\"></polyline>\n </svg>\n `,\n sun: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"5\"></circle>\n <line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\"></line>\n <line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\"></line>\n <line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\"></line>\n <line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\"></line>\n <line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\"></line>\n <line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\"></line>\n <line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\"></line>\n <line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\"></line>\n </svg>\n `,\n moon: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\"></path>\n </svg>\n `,\n monitor: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\"></rect>\n <line x1=\"8\" y1=\"21\" x2=\"16\" y2=\"21\"></line>\n <line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\"></line>\n </svg>\n `,\n send: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n `,\n paperclip: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\"></path>\n </svg>\n `,\n x: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n `,\n fileText: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"></path>\n <polyline points=\"14 2 14 8 20 8\"></polyline>\n <line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"></line>\n <line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"></line>\n <polyline points=\"10 9 9 9 8 9\"></polyline>\n </svg>\n `,\n image: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect>\n <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"></circle>\n <polyline points=\"21 15 16 10 5 21\"></polyline>\n </svg>\n `,\n file: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"></path>\n <polyline points=\"14 2 14 8 20 8\"></polyline>\n </svg>\n `,\n plug: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M12 22v-5\"></path>\n <path d=\"M15 8V2\"></path>\n <path d=\"M9 8V2\"></path>\n <path d=\"M15 8a3 3 0 0 1 3 3v5a3 3 0 0 1-3 3H9a3 3 0 0 1-3-3v-5a3 3 0 0 1 3-3h6z\"></path>\n </svg>\n `,\n palette: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"13.5\" cy=\"6.5\" r=\".5\"></circle>\n <circle cx=\"17.5\" cy=\"10.5\" r=\".5\"></circle>\n <circle cx=\"8.5\" cy=\"7.5\" r=\".5\"></circle>\n <circle cx=\"6.5\" cy=\"12.5\" r=\".5\"></circle>\n <path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688 0-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 0 1 1.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.01 17.461 2 12 2z\"></path>\n </svg>\n `,\n alertCircle: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line>\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line>\n </svg>\n `,\n check: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\"></polyline>\n </svg>\n `,\n chevronRight: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n `,\n arrowLeft: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\"></line>\n <polyline points=\"12 19 5 12 12 5\"></polyline>\n </svg>\n `,\n bot: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"10\" rx=\"2\"></rect>\n <circle cx=\"12\" cy=\"5\" r=\"2\"></circle>\n <path d=\"M12 7v4\"></path>\n <line x1=\"8\" y1=\"16\" x2=\"8\" y2=\"16.01\"></line>\n <line x1=\"16\" y1=\"16\" x2=\"16\" y2=\"16.01\"></line>\n </svg>\n `,\n helpCircle: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\"></path>\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"></line>\n </svg>\n `,\n rotateCcw: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"1 4 1 10 7 10\"></polyline>\n <path d=\"M3.51 15a9 9 0 1 0 2.13-9.36L1 10\"></path>\n </svg>\n `,\n square: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect>\n </svg>\n `,\n moreHorizontal: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"1\"></circle>\n <circle cx=\"19\" cy=\"12\" r=\"1\"></circle>\n <circle cx=\"5\" cy=\"12\" r=\"1\"></circle>\n </svg>\n `,\n copy: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect>\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path>\n </svg>\n `,\n download: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"></path>\n <polyline points=\"7 10 12 15 17 10\"></polyline>\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\"></line>\n </svg>\n `,\n // Session management icons\n folderOpen: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M6 17h12a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3.5\"></path>\n <path d=\"M2 17V5a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v1\"></path>\n </svg>\n `,\n phone: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"></path>\n </svg>\n `,\n globe: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"></line>\n <path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"></path>\n </svg>\n `,\n terminal: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"4 17 10 11 4 5\"></polyline>\n <line x1=\"12\" y1=\"19\" x2=\"20\" y2=\"19\"></line>\n </svg>\n `,\n zap: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polygon points=\"13 2 3 14 12 14 11 22 21 10 12 10 13 2\"></polygon>\n </svg>\n `,\n pin: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"22\"></line>\n <path d=\"M5 17h14v-3a2 2 0 0 0-2-2h-3.5\"></path>\n <path d=\"M5 12V7a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v5\"></path>\n <circle cx=\"12\" cy=\"7\" r=\"1\"></circle>\n </svg>\n `,\n pinOff: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"2\" y1=\"2\" x2=\"22\" y2=\"22\"></line>\n <line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"22\"></line>\n <path d=\"M5 17h14v-3a2 2 0 0 0-2-2h-3.5\"></path>\n <path d=\"M5 12V7a2 2 0 0 1 2-2h1\"></path>\n </svg>\n `,\n archive: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"21 8 21 21 3 21 3 8\"></polyline>\n <rect x=\"1\" y=\"3\" width=\"22\" height=\"5\"></rect>\n <line x1=\"10\" y1=\"12\" x2=\"14\" y2=\"12\"></line>\n </svg>\n `,\n archiveRestore: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"21 8 21 21 3 21 3 8\"></polyline>\n <rect x=\"1\" y=\"3\" width=\"22\" height=\"5\"></rect>\n <polyline points=\"10 12 14 12 14 8\"></polyline>\n </svg>\n `,\n trash: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"3 6 5 6 21 6\"></polyline>\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"></path>\n </svg>\n `,\n grid: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"></rect>\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"></rect>\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"></rect>\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"></rect>\n </svg>\n `,\n list: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\"></line>\n <line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\"></line>\n <line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\"></line>\n <line x1=\"3\" y1=\"6\" x2=\"3.01\" y2=\"6\"></line>\n <line x1=\"3\" y1=\"12\" x2=\"3.01\" y2=\"12\"></line>\n <line x1=\"3\" y1=\"18\" x2=\"3.01\" y2=\"18\"></line>\n </svg>\n `,\n layers: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polygon points=\"12 2 2 7 12 12 22 7 12 2\"></polygon>\n <polyline points=\"2 17 12 22 22 17\"></polyline>\n <polyline points=\"2 12 12 17 22 12\"></polyline>\n </svg>\n `,\n circle: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n </svg>\n `,\n search: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\n </svg>\n `,\n key: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"7.5\" cy=\"15.5\" r=\"5.5\"></circle>\n <path d=\"m21 2-9.6 9.6\"></path>\n <path d=\"m15.5 7.5 3 3L22 7l-3-3\"></path>\n </svg>\n `,\n lock: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect width=\"18\" height=\"11\" x=\"3\" y=\"11\" rx=\"2\" ry=\"2\"></rect>\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path>\n </svg>\n `,\n chevronUp: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"18 15 12 9 6 15\"></polyline>\n </svg>\n `,\n alertTriangle: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"></path>\n <line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"></line>\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"></line>\n </svg>\n `,\n info: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line>\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line>\n </svg>\n `,\n folder: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z\"></path>\n </svg>\n `,\n clock: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <polyline points=\"12 6 12 12 16 14\"></polyline>\n </svg>\n `,\n plus: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"></line>\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line>\n </svg>\n `,\n refresh: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"23 4 23 10 17 10\"></polyline>\n <polyline points=\"1 20 1 14 7 14\"></polyline>\n <path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\"></path>\n </svg>\n `,\n play: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polygon points=\"5 3 19 12 5 21 5 3\"></polygon>\n </svg>\n `,\n edit: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"></path>\n <path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\"></path>\n </svg>\n `,\n pause: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\"></rect>\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\"></rect>\n </svg>\n `,\n refreshCw: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"23 4 23 10 17 10\"></polyline>\n <polyline points=\"1 20 1 14 7 14\"></polyline>\n <path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\"></path>\n </svg>\n `,\n cloud: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z\"></path>\n </svg>\n `,\n checkCircle: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"></path>\n <polyline points=\"22 4 12 14.01 9 11.01\"></polyline>\n </svg>\n `,\n xCircle: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"></line>\n <line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"></line>\n </svg>\n `,\n loader: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"6\"></line>\n <line x1=\"12\" y1=\"18\" x2=\"12\" y2=\"22\"></line>\n <line x1=\"4.93\" y1=\"4.93\" x2=\"7.76\" y2=\"7.76\"></line>\n <line x1=\"16.24\" y1=\"16.24\" x2=\"19.07\" y2=\"19.07\"></line>\n <line x1=\"2\" y1=\"12\" x2=\"6\" y2=\"12\"></line>\n <line x1=\"18\" y1=\"12\" x2=\"22\" y2=\"12\"></line>\n <line x1=\"4.93\" y1=\"19.07\" x2=\"7.76\" y2=\"16.24\"></line>\n <line x1=\"16.24\" y1=\"7.76\" x2=\"19.07\" y2=\"4.93\"></line>\n </svg>\n `,\n slash: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <line x1=\"4.93\" y1=\"4.93\" x2=\"19.07\" y2=\"19.07\"></line>\n </svg>\n `,\n cpu: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\"></rect>\n <rect x=\"9\" y=\"9\" width=\"6\" height=\"6\"></rect>\n <line x1=\"9\" y1=\"1\" x2=\"9\" y2=\"4\"></line>\n <line x1=\"15\" y1=\"1\" x2=\"15\" y2=\"4\"></line>\n <line x1=\"9\" y1=\"20\" x2=\"9\" y2=\"23\"></line>\n <line x1=\"15\" y1=\"20\" x2=\"15\" y2=\"23\"></line>\n <line x1=\"20\" y1=\"9\" x2=\"23\" y2=\"9\"></line>\n <line x1=\"20\" y1=\"14\" x2=\"23\" y2=\"14\"></line>\n <line x1=\"1\" y1=\"9\" x2=\"4\" y2=\"9\"></line>\n <line x1=\"1\" y1=\"14\" x2=\"4\" y2=\"14\"></line>\n </svg>\n `,\n eye: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"></path>\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\n </svg>\n `,\n eyeOff: html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 0.5 18 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24\"></path>\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>\n </svg>\n `,\n};\n\n// Document type icons\nexport function getDocumentIcon(mimeType: string): TemplateResult {\n if (mimeType.includes('pdf')) {\n return html`\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#ef4444\" stroke-width=\"2\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/>\n <polyline points=\"14,2 14,8 20,8\"/>\n </svg>\n `;\n }\n if (mimeType.includes('word') || mimeType.includes('document')) {\n return html`\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#2563eb\" stroke-width=\"2\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/>\n <polyline points=\"14,2 14,8 20,8\"/>\n </svg>\n `;\n }\n if (mimeType.includes('sheet') || mimeType.includes('excel')) {\n return html`\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#16a34a\" stroke-width=\"2\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/>\n <polyline points=\"14,2 14,8 20,8\"/>\n </svg>\n `;\n }\n if (mimeType.includes('presentation') || mimeType.includes('powerpoint')) {\n return html`\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#f59e0b\" stroke-width=\"2\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/>\n <polyline points=\"14,2 14,8 20,8\"/>\n </svg>\n `;\n }\n return fallbackIcons.file;\n}\n","import { html, LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { getDocumentIcon } from '../../utils/icons';\nimport { t } from '../../utils/i18n';\nimport type { Attachment } from './types';\n\n@customElement('attachment-renderer')\nexport class AttachmentRenderer extends LitElement {\n @property({ attribute: false }) attachments: Attachment[] = [];\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n override render(): unknown {\n if (!this.attachments?.length) return null;\n\n const images = this.attachments.filter(att => \n att.type === 'image' || att.mimeType?.startsWith('image/')\n );\n const documents = this.attachments.filter(att => \n att.type !== 'image' && !att.mimeType?.startsWith('image/')\n );\n\n return html`\n <div class=\"flex flex-col gap-2 mt-2\">\n ${images.length > 0 ? this._renderImageGallery(images) : ''}\n ${documents.length > 0 ? this._renderDocumentList(documents) : ''}\n </div>\n `;\n }\n\n private _renderImageGallery(images: Attachment[]): unknown {\n const count = images.length;\n let galleryClass = 'single';\n if (count === 2) galleryClass = 'double';\n else if (count === 3) galleryClass = 'triple';\n else if (count >= 4) galleryClass = 'quad';\n\n return html`\n <div class=\"image-gallery ${galleryClass}\">\n ${images.map((img) => html`\n <img \n src=\"${img.data || img.content}\" \n alt=\"${img.name || t('fileUpload.image')}\" \n @click=${() => this._handleImageClick(img)}\n />\n `)}\n </div>\n `;\n }\n\n private _renderDocumentList(documents: Attachment[]): unknown {\n return html`\n <div class=\"flex flex-col gap-2\">\n ${documents.map((doc) => this._renderDocumentPreview(doc))}\n </div>\n `;\n }\n\n private _renderDocumentPreview(doc: Attachment): unknown {\n const name = doc.name || t('fileUpload.document');\n const size = doc.size ? this._formatFileSize(doc.size) : '';\n\n return html`\n <div class=\"document-preview\" @click=${() => this._handleDocumentClick(doc)}>\n <div class=\"icon\">${getDocumentIcon(doc.mimeType || '')}</div>\n <div class=\"info\">\n <div class=\"name\">${name}</div>\n <div class=\"meta\">${size || doc.mimeType || t('fileUpload.unknown')}</div>\n </div>\n </div>\n `;\n }\n\n private _formatFileSize(bytes: number): string {\n const units = ['B', 'KB', 'MB', 'GB'];\n let unitIndex = 0;\n let size = bytes;\n while (size >= 1024 && unitIndex < units.length - 1) {\n size /= 1024;\n unitIndex++;\n }\n return `${size.toFixed(1)} ${units[unitIndex]}`;\n }\n\n private _handleImageClick(img: Attachment): void {\n // Dispatch event for parent to handle (e.g., open lightbox)\n this.dispatchEvent(new CustomEvent('image-click', { \n detail: img,\n bubbles: true,\n composed: true \n }));\n }\n\n private _handleDocumentClick(doc: Attachment): void {\n this.dispatchEvent(new CustomEvent('document-click', { \n detail: doc,\n bubbles: true,\n composed: true \n }));\n }\n}\n","import { html, LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport type { MessageContent } from './types';\n\n@customElement('usage-badge')\nexport class UsageBadge extends LitElement {\n @property({ attribute: false }) usage?: {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n cost?: number;\n };\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n override render(): unknown {\n if (!this.usage) return null;\n\n const parts: string[] = [];\n \n if (this.usage.totalTokens !== undefined) {\n parts.push(`${this.usage.totalTokens} tokens`);\n } else if (this.usage.inputTokens !== undefined && this.usage.outputTokens !== undefined) {\n parts.push(`${this.usage.inputTokens + this.usage.outputTokens} tokens`);\n }\n \n if (this.usage.cost !== undefined && this.usage.cost > 0) {\n parts.push(`$${this.usage.cost.toFixed(4)}`);\n }\n\n if (parts.length === 0) return null;\n\n return html`\n <span class=\"usage-badge\">\n ${parts.join(' · ')}\n </span>\n `;\n }\n}\n","import { html, LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { t } from '../../utils/i18n';\nimport type { Message, MessageContent } from './types';\nimport './AttachmentRenderer';\nimport './UsageBadge';\n\n@customElement('message-bubble')\nexport class MessageBubble extends LitElement {\n @property({ attribute: false }) message!: Message;\n @property({ type: Boolean }) isStreaming = false;\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n override render(): unknown {\n const isUser = this.message.role === 'user' || this.message.role === 'user-with-attachments';\n const isAssistant = this.message.role === 'assistant';\n const isTool = this.message.role === 'tool' || this.message.role === 'tool_result';\n\n const roleLabel = isUser ? t('chat.you') : isAssistant ? t('chat.assistant') : t('chat.tool');\n const avatarLetter = roleLabel.charAt(0);\n\n return html`\n <div class=\"message-item ${isUser ? 'flex-row-reverse' : ''}\">\n <div class=\"avatar ${isUser ? 'user' : isAssistant ? 'assistant' : 'tool'}\">\n ${avatarLetter}\n </div>\n\n <div class=\"flex flex-col gap-1 max-w-[85%]\">\n <div class=\"flex items-center gap-2 text-xs text-muted\">\n <span class=\"font-medium\">${roleLabel}</span>\n <span>·</span>\n <span>${this._formatTime(this.message.timestamp)}</span>\n ${this.isStreaming ? html`<span class=\"text-primary animate-pulse\">${t('chat.thinking')}</span>` : ''}\n </div>\n\n <div class=\"message-bubble ${isUser ? 'bg-primary-light' : 'bg-secondary'}\">\n ${this._renderContent(this.message.content)}\n ${this.message.attachments?.length ? html`\n <attachment-renderer .attachments=${this.message.attachments}></attachment-renderer>\n ` : ''}\n </div>\n\n ${isAssistant && this.message.usage ? html`\n <usage-badge .usage=${this.message.usage}></usage-badge>\n ` : ''}\n </div>\n </div>\n `;\n }\n\n private _renderContent(content: MessageContent[]): unknown {\n if (!content || content.length === 0) {\n return this.isStreaming ? html`<span class=\"streaming-cursor\"></span>` : null;\n }\n\n return html`\n <div class=\"markdown-content\">\n ${content.map((block) => this._renderContentBlock(block))}\n ${this.isStreaming ? html`<span class=\"streaming-cursor\"></span>` : ''}\n </div>\n `;\n }\n\n private _renderContentBlock(block: MessageContent): unknown {\n switch (block.type) {\n case 'text':\n if (block.text) {\n return html`<p class=\"whitespace-pre-wrap\">${block.text}</p>`;\n }\n break;\n \n case 'image':\n if (block.source?.data) {\n return html`<img src=\"${block.source.data}\" class=\"rounded-lg max-w-full\" />`;\n }\n break;\n \n case 'tool_use':\n case 'tool_result':\n return this._renderToolCall(block);\n \n default:\n // Handle unknown content types gracefully\n if (block.text) {\n return html`<p class=\"whitespace-pre-wrap\">${block.text}</p>`;\n }\n }\n return null;\n }\n\n private _renderToolCall(block: MessageContent): unknown {\n const isError = block.is_error || block.error;\n const name = block.name || block.function?.name || 'Tool';\n const input = block.input || block.function?.arguments;\n\n return html`\n <div class=\"tool-call ${isError ? 'tool-call--error' : ''}\">\n <div class=\"tool-call-header\">\n <span>🔧 ${name}</span>\n ${isError ? html`<span class=\"text-red-500 text-xs\">Error</span>` : ''}\n </div>\n ${input ? html`\n <pre class=\"tool-call-content\">${JSON.stringify(input, null, 2)}</pre>\n ` : ''}\n ${block.content ? html`\n <div class=\"tool-call-result\">${JSON.stringify(block.content)}</div>\n ` : ''}\n </div>\n `;\n }\n\n private _formatTime(timestamp?: number): string {\n if (!timestamp) return '';\n return new Date(timestamp).toLocaleTimeString([], { \n hour: '2-digit', \n minute: '2-digit' \n });\n }\n}\n","import { html, LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { virtualize, virtualizerRef } from '@lit-labs/virtualizer/virtualize.js';\nimport { t } from '../../utils/i18n';\nimport type { Message } from './types';\nimport './MessageBubble';\n\n@customElement('message-list')\nexport class MessageList extends LitElement {\n @property({ attribute: false }) messages: Message[] = [];\n @property({ type: Boolean }) isStreaming = false;\n @property({ type: Boolean }) useVirtualScroll = true;\n @property({ type: Number }) virtualScrollThreshold = 50;\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n override render(): unknown {\n if (!this.messages || this.messages.length === 0) {\n return this._renderEmptyState();\n }\n\n const shouldVirtualize = this.useVirtualScroll && \n this.messages.length > this.virtualScrollThreshold;\n\n if (shouldVirtualize) {\n return this._renderVirtualList();\n }\n\n return this._renderSimpleList();\n }\n\n private _renderSimpleList(): unknown {\n return html`\n <div class=\"flex flex-col gap-4 pb-4\">\n ${this.messages.map((message, index) => html`\n <message-bubble \n .message=${message}\n .isStreaming=${this.isStreaming && index === this.messages.length - 1}\n ></message-bubble>\n `)}\n </div>\n `;\n }\n\n private _renderVirtualList(): unknown {\n return html`\n <div class=\"flex flex-col pb-4\">\n ${virtualize({\n items: this.messages,\n renderItem: (message, index) => html`\n <div class=\"py-2\">\n <message-bubble \n .message=${message}\n .isStreaming=${this.isStreaming && index === this.messages.length - 1}\n ></message-bubble>\n </div>\n `,\n scroller: true,\n })}\n </div>\n `;\n }\n\n private _renderEmptyState(): unknown {\n return html`\n <div class=\"empty-state\">\n <div class=\"icon\">💬</div>\n <div class=\"title\">${t('chat.emptyState')}</div>\n <div class=\"description\">${t('chat.emptyStateDescription')}</div>\n </div>\n `;\n }\n\n // Scroll to bottom\n scrollToBottom(): void {\n const container = this.closest('.overflow-y-auto');\n if (container) {\n container.scrollTop = container.scrollHeight;\n }\n }\n\n // Check if scrolled near bottom\n isNearBottom(threshold = 100): boolean {\n const container = this.closest('.overflow-y-auto');\n if (!container) return true;\n \n const { scrollTop, scrollHeight, clientHeight } = container;\n return scrollHeight - scrollTop - clientHeight < threshold;\n }\n}\n","import { html, LitElement } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\ninterface MessageContent {\n type: string;\n text?: string;\n name?: string;\n input?: any;\n function?: { name?: string; arguments?: any };\n}\n\n@customElement('streaming-message-container')\nexport class StreamingMessageContainer extends LitElement {\n @property({ attribute: false }) tools: Map<string, any> = new Map();\n @property({ attribute: false }) pendingToolCalls: Set<string> = new Set();\n @property({ type: Boolean }) isStreaming = false;\n\n @state() private _currentMessage: any = null;\n @state() private _isComplete = false;\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n public setMessage(message: any, isComplete: boolean): void {\n this._currentMessage = message;\n this._isComplete = isComplete;\n }\n\n override render(): unknown {\n if (!this._currentMessage) return null;\n\n return html`\n <div class=\"flex gap-3 message-item\">\n <div class=\"avatar assistant\">\n AI\n </div>\n \n <div class=\"flex flex-col gap-1 max-w-[85%]\">\n <div class=\"flex items-center gap-2 text-xs text-muted\">\n <span class=\"font-medium\">Assistant</span>\n <span>·</span>\n <span class=\"text-accent animate-pulse\">thinking...</span>\n </div>\n \n <div class=\"rounded-xl p-3 bg-secondary\">\n ${this.renderStreamingContent()}\n </div>\n </div>\n </div>\n `;\n }\n\n private renderStreamingContent(): unknown {\n const content = this._currentMessage?.content || [];\n \n return html`\n <div class=\"markdown-content\">\n ${content.map((block: MessageContent) => {\n if (block.type === 'text') {\n return html`<p class=\"whitespace-pre-wrap\">${this._escapeHtml(block.text || '')}<span class=\"streaming-cursor\"></span></p>`;\n }\n if (block.type === 'tool_use') {\n return this.renderToolUse(block);\n }\n return '';\n })}\n ${this.isStreaming && (!content.length || content[content.length - 1]?.type !== 'text') ? html`<span class=\"streaming-cursor\"></span>` : ''}\n </div>\n `;\n }\n\n private renderToolUse(block: MessageContent): unknown {\n const name = block.name || block.function?.name;\n const input = block.input || block.function?.arguments || {};\n \n const inputStr = typeof input === 'string' ? input : JSON.stringify(input, null, 2);\n \n return html`\n <div class=\"tool-call\">\n <div class=\"name\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z\"/>\n </svg>\n <span>${name}</span>\n </div>\n <pre class=\"input\">${inputStr}</pre>\n </div>\n `;\n }\n\n private _escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n}\n","import { html, LitElement } from 'lit';\nimport { customElement, property, state, query } from 'lit/decorators.js';\nimport './components/MessageEditor';\nimport './components/MessageList';\nimport './components/StreamingMessageContainer';\nimport { t, initI18n } from './utils/i18n';\nimport type { Attachment } from './utils/attachment-utils';\nimport type { MessageEditor } from './components/MessageEditor';\nimport type { ChatRoute } from './navigation';\n\n// ---------- Types ----------\n\nexport type ChatPayload = {\n type?: 'status' | 'token' | 'error';\n content?: string;\n status?: 'ok' | 'complete' | 'error';\n runId?: string;\n sessionKey?: string;\n message?: unknown;\n errorMessage?: string;\n};\n\nexport type ErrorPayload = {\n code: string;\n message: string;\n};\n\nexport type GatewayClientConfig = {\n /** @deprecated No longer needed - always uses current origin */\n url?: string;\n token?: string;\n autoReconnect?: boolean;\n maxReconnectAttempts?: number;\n reconnectDelay?: number;\n};\n\ninterface Message {\n role: 'user' | 'assistant';\n content: Array<{ type: string; text?: string }>;\n attachments?: Array<{ type: string; mimeType?: string; data?: string; name?: string; size?: number }>;\n timestamp: number;\n}\n\ntype ConnectionState = 'connecting' | 'connected' | 'disconnected' | 'reconnecting' | 'error';\n\n// ---------- Helpers ----------\n\n/** Get the base URL - always uses current origin. */\nfunction getBaseUrl(): string {\n return window.location.origin;\n}\n\n/** Build an HTTP URL from the path. */\nfunction apiUrl(path: string): string {\n return `${getBaseUrl()}${path}`;\n}\n\nfunction authHeaders(token?: string): Record<string, string> {\n const h: Record<string, string> = { 'Content-Type': 'application/json' };\n if (token) h['Authorization'] = `Bearer ${token}`;\n return h;\n}\n\n// ---------- Component ----------\n\n@customElement('xopcbot-gateway-chat')\nexport class XopcbotGatewayChat extends LitElement {\n @property({ attribute: false }) config?: GatewayClientConfig;\n @property({ attribute: false }) route?: ChatRoute;\n @property({ type: Boolean }) enableAttachments = true;\n @property({ type: Boolean }) enableModelSelector = true;\n\n @query('message-editor') private _messageEditor!: MessageEditor;\n @query('.chat-messages') private _chatMessages!: HTMLElement;\n\n @state() private _connectionState: ConnectionState = 'disconnected';\n @state() private _error: string | null = null;\n @state() private _messages: Message[] = [];\n @state() private _isStreaming = false;\n @state() private _streamingContent = '';\n @state() private _streamingMessage: Message | null = null;\n @state() private _reconnectCount = 0;\n @state() private _isAtBottom = true;\n @state() private _currentSessionKey: string | null = null;\n @state() private _sessions: Array<{ key: string; name?: string; updatedAt: string }> = [];\n @state() private _hasMoreMessages = true; // For pagination\n @state() private _isLoadingMore = false;\n\n /** SSE event source for server-pushed events */\n private _eventSource?: EventSource;\n /** AbortController for the current agent POST request */\n private _agentAbort?: AbortController;\n private _shouldReconnect = true;\n private _isSending = false;\n private _lastLoadedSessionKey: string | null = null;\n\n // Configurable reconnection settings\n private get _maxReconnectAttempts(): number {\n return this.config?.maxReconnectAttempts ?? 10;\n }\n\n private get _autoReconnect(): boolean {\n return this.config?.autoReconnect ?? true;\n }\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n override async connectedCallback(): Promise<void> {\n super.connectedCallback();\n this.classList.add('chat-container');\n await initI18n('en');\n }\n\n override firstUpdated(): void {\n // Add scroll listener directly to chat messages element after render\n if (this._chatMessages) {\n this._chatMessages.addEventListener('scroll', this._handleScroll as EventListener);\n }\n\n // Load session based on current route\n this._handleRouteChange();\n }\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n \n // Connect when config changes and disconnected\n if (changedProperties.has('config') && this.config && this._connectionState === 'disconnected') {\n this.connect();\n }\n \n // Reload session when route changes\n if (changedProperties.has('route') && this.route) {\n this._handleRouteChange();\n }\n }\n\n /**\n * Handle route changes - load appropriate session\n */\n private async _handleRouteChange(): Promise<void> {\n const route = this.route;\n if (!route) return;\n\n // Get target session key from route\n let targetSessionKey: string | null = null;\n\n switch (route.type) {\n case 'recent':\n // Reset last loaded key to force reload of most recent session\n this._lastLoadedSessionKey = null;\n // Load recent sessions - this will load the most recent one\n await this._loadSessions();\n return;\n case 'session':\n targetSessionKey = route.sessionKey;\n break;\n case 'new':\n await this._createNewSession();\n return;\n }\n\n // If we have a target session, load it directly\n if (targetSessionKey) {\n if (targetSessionKey !== this._lastLoadedSessionKey) {\n await this._loadSession(targetSessionKey, 0); // Load with offset 0\n this._lastLoadedSessionKey = targetSessionKey;\n }\n }\n }\n\n /**\n * Load session with pagination support\n */\n private async _loadSession(sessionKey: string, offset = 0): Promise<void> {\n if (!this.config) return;\n\n try {\n const url = apiUrl(`/api/sessions/${encodeURIComponent(sessionKey)}?offset=${offset}&limit=50`);\n const headers = authHeaders(this.config.token);\n const res = await fetch(url, { headers });\n \n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n \n const data = await res.json();\n const session = data.session;\n \n this._currentSessionKey = sessionKey;\n \n // Convert session messages to UI format\n const messages = session.messages || [];\n const newMessages = messages\n .filter((msg: any) => msg.role === 'user' || msg.role === 'assistant')\n .map((msg: any) => ({\n role: msg.role,\n content: typeof msg.content === 'string' \n ? [{ type: 'text', text: msg.content }] \n : (msg.content || []),\n attachments: msg.attachments,\n timestamp: msg.timestamp ? new Date(msg.timestamp).getTime() : Date.now(),\n }));\n \n // Handle pagination - prepend if loading older messages\n if (offset > 0) {\n this._messages = [...newMessages, ...this._messages];\n } else {\n this._messages = newMessages;\n }\n \n // Check if there are more messages to load\n this._hasMoreMessages = messages.length >= 50;\n\n // Scroll to bottom only on initial load (instant scroll, no animation)\n if (offset === 0) {\n this._scrollToBottom(false);\n }\n this.requestUpdate();\n } catch (err) {\n console.error('[GatewayChat] Failed to load session:', err);\n }\n }\n\n /**\n * Load more messages when user scrolls to top\n */\n private async _loadMoreMessages(): Promise<void> {\n if (!this._currentSessionKey || this._isLoadingMore || !this._hasMoreMessages) return;\n \n this._isLoadingMore = true;\n const offset = this._messages.length;\n \n try {\n await this._loadSession(this._currentSessionKey, offset);\n } finally {\n this._isLoadingMore = false;\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._shouldReconnect = false;\n this.disconnect();\n // Remove scroll listener from chat messages element\n if (this._chatMessages) {\n this._chatMessages.removeEventListener('scroll', this._handleScroll as EventListener);\n }\n }\n\n // ========== Scroll handling ==========\n\n private _handleScroll = (): void => {\n if (!this._chatMessages) return;\n const { scrollTop, scrollHeight, clientHeight } = this._chatMessages;\n const atBottom = scrollHeight - scrollTop - clientHeight < 50;\n\n // Update bottom state\n if (atBottom !== this._isAtBottom) {\n this._isAtBottom = atBottom;\n }\n\n // Load more when scrolling to top\n if (scrollTop < 100 && !this._isAtBottom && this._hasMoreMessages && !this._isLoadingMore) {\n this._loadMoreMessages();\n }\n };\n\n private _scrollToBottom(smooth = true): void {\n // Wait for DOM update before scrolling to ensure messages are rendered\n this.updateComplete.then(() => {\n if (this._chatMessages) {\n this._chatMessages.scrollTo({\n top: this._chatMessages.scrollHeight,\n behavior: smooth ? 'smooth' : 'auto'\n });\n }\n });\n }\n\n // ========== Connection (SSE for server-push) ==========\n\n connect(): void {\n if (!this.config || this._connectionState === 'connecting') return;\n\n this._connectionState = 'connecting';\n this._error = null;\n this.requestUpdate();\n\n try {\n const eventsUrl = apiUrl('/api/events');\n const url = new URL(eventsUrl);\n if (this.config.token) url.searchParams.set('token', this.config.token);\n\n this._eventSource = new EventSource(url.toString());\n\n // EventSource fires onopen when the connection is established\n this._eventSource.onopen = () => {\n this._connectionState = 'connected';\n this._error = null;\n this._reconnectCount = 0;\n this.requestUpdate();\n // Load sessions after connection is established (only if not already loaded)\n if (!this._lastLoadedSessionKey) {\n this._loadSessions();\n }\n };\n\n // Also listen for our custom 'connected' event from the server\n this._eventSource.addEventListener('connected', () => {\n this._connectionState = 'connected';\n this._error = null;\n this.requestUpdate();\n });\n\n this._eventSource.addEventListener('config.reload', (e: MessageEvent) => {\n try {\n const data = JSON.parse(e.data);\n this.dispatchEvent(new CustomEvent('config-reload', { detail: data }));\n } catch { /* ignore */ }\n });\n\n this._eventSource.addEventListener('channels.status', (e: MessageEvent) => {\n try {\n const data = JSON.parse(e.data);\n this.dispatchEvent(new CustomEvent('channels-status', { detail: data }));\n } catch { /* ignore */ }\n });\n\n this._eventSource.addEventListener('message.sent', (e: MessageEvent) => {\n try {\n const data = JSON.parse(e.data);\n this.dispatchEvent(new CustomEvent('message-sent', { detail: data }));\n } catch { /* ignore */ }\n });\n\n // EventSource auto-reconnects on error. Handle permanent disconnection.\n // readyState: 0=CONNECTING, 1=OPEN, 2=CLOSED\n this._eventSource.onerror = () => {\n if (this._eventSource?.readyState === EventSource.CLOSED) {\n // Permanently closed - EventSource has given up auto-reconnect\n this._connectionState = 'disconnected';\n this._handlePermanentDisconnect();\n } else {\n // CONNECTING - EventSource is auto-reconnecting\n this._connectionState = 'reconnecting';\n }\n this.requestUpdate();\n };\n } catch (err) {\n console.error('[GatewayChat] Failed to create EventSource:', err);\n this._connectionState = 'error';\n this._error = t('errors.connectionError');\n this.requestUpdate();\n }\n }\n\n private _handlePermanentDisconnect(): void {\n // Reset streaming state if interrupted\n if (this._isStreaming) {\n this._isStreaming = false;\n this._isSending = false;\n this._streamingContent = '';\n this._streamingMessage = null;\n }\n\n // Auto-reconnect with exponential backoff (EventSource handles it)\n if (this._shouldReconnect && this._autoReconnect) {\n this._reconnectCount++;\n if (this._reconnectCount > this._maxReconnectAttempts) {\n this._error = t('errors.connectionError');\n this._connectionState = 'error';\n }\n // EventSource will auto-reconnect, no manual timer needed\n }\n }\n\n disconnect(): void {\n this._shouldReconnect = false;\n this._eventSource?.close();\n this._eventSource = undefined;\n this._agentAbort?.abort();\n this._agentAbort = undefined;\n this._connectionState = 'disconnected';\n }\n\n reconnect(): void {\n this._shouldReconnect = true;\n this._reconnectCount = 0;\n this.disconnect();\n setTimeout(() => this.connect(), 100);\n }\n\n // ========== Session management ==========\n\n private async _loadSessions(): Promise<void> {\n if (!this.config) {\n return;\n }\n\n try {\n const url = apiUrl('/api/sessions?limit=20');\n const headers = authHeaders(this.config.token);\n const res = await fetch(url, { headers });\n\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n\n const data = await res.json();\n const sessions = data.items || [];\n\n // Filter gateway sessions and sort by updatedAt (newest first)\n const gatewaySessions = sessions\n .filter((s: any) => s.key.startsWith('gateway:'))\n .sort((a: any, b: any) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());\n\n this._sessions = gatewaySessions;\n\n // Filter out empty sessions and get sessions with messages\n const sessionsWithMessages = gatewaySessions.filter((s: any) => s.messageCount > 0);\n\n if (sessionsWithMessages.length > 0) {\n // Load the most recent session with messages\n const recentKey = sessionsWithMessages[0].key;\n await this._loadSession(recentKey, 0);\n this._lastLoadedSessionKey = recentKey;\n\n // Update URL to reflect current session\n this._updateUrlWithSession(recentKey);\n } else if (gatewaySessions.length > 0) {\n // No sessions with messages, use the most recent empty session\n const emptySession = gatewaySessions[0];\n this._currentSessionKey = emptySession.key;\n this._messages = [];\n this._lastLoadedSessionKey = emptySession.key;\n this._updateUrlWithSession(emptySession.key);\n } else {\n // No sessions at all, create a new one\n await this._createNewSession();\n }\n } catch (err) {\n console.error('[GatewayChat] Failed to load sessions:', err);\n }\n }\n\n /**\n * Update URL hash with session key\n */\n private _updateUrlWithSession(sessionKey: string): void {\n const newHash = `#/chat/${encodeURIComponent(sessionKey)}`;\n if (location.hash !== newHash) {\n history.replaceState(null, '', newHash);\n }\n }\n\n async _createNewSession(): Promise<void> {\n if (!this.config) return;\n\n // Check if there's already an empty session\n const emptySession = this._sessions.find((s: any) => s.messageCount === 0);\n if (emptySession) {\n // Navigate to existing empty session instead of creating a new one\n this._currentSessionKey = emptySession.key;\n this._messages = [];\n this._lastLoadedSessionKey = emptySession.key;\n this._updateUrlWithSession(emptySession.key);\n return;\n }\n\n try {\n const url = apiUrl('/api/sessions');\n const headers = {\n ...authHeaders(this.config.token),\n 'Content-Type': 'application/json',\n };\n \n const res = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({ channel: 'gateway' }),\n });\n \n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n \n const data = await res.json();\n const session = data.session;\n \n this._currentSessionKey = session.key;\n this._messages = [];\n \n // Add to sessions list\n this._sessions = [{\n key: session.key,\n name: session.name,\n updatedAt: session.updatedAt,\n }, ...this._sessions];\n \n this._currentSessionKey = session.key;\n this._lastLoadedSessionKey = session.key;\n \n // Update URL to reflect new session\n this._updateUrlWithSession(session.key);\n \n this._scrollToBottom();\n this.requestUpdate();\n } catch (err) {\n console.error('[GatewayChat] Failed to create new session:', err);\n }\n }\n\n // ========== Agent messaging (POST + SSE response) ==========\n\n async sendMessage(\n content: string,\n attachments?: Array<{ type: string; mimeType?: string; data?: string; name?: string; size?: number }>,\n ): Promise<void> {\n if (this._isSending || this._isStreaming) return;\n if (!content.trim() && !attachments?.length) return;\n if (!this.config) return;\n\n this._isSending = true;\n\n // Add user message to UI\n this._messages = [\n ...this._messages,\n {\n role: 'user',\n content: content ? [{ type: 'text', text: content }] : [],\n attachments,\n timestamp: Date.now(),\n },\n ];\n this._scrollToBottom();\n this.requestUpdate();\n\n try {\n this._agentAbort = new AbortController();\n const url = apiUrl('/api/agent');\n const headers = {\n ...authHeaders(this.config.token),\n Accept: 'text/event-stream',\n };\n\n // Extract chatId from current session key (format: \"gateway:chat_xxx\")\n const chatId = this._currentSessionKey\n ? this._currentSessionKey.replace('gateway:', '')\n : 'default';\n\n const res = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n message: content,\n channel: 'gateway',\n chatId,\n attachments,\n }),\n signal: this._agentAbort.signal,\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({}));\n throw new Error(body.error?.message || `HTTP ${res.status}`);\n }\n\n const contentType = res.headers.get('Content-Type') || '';\n\n if (contentType.includes('text/event-stream') && res.body) {\n // --- SSE stream ---\n await this._consumeSSEStream(res.body);\n } else {\n // --- JSON fallback ---\n const json = await res.json();\n if (json.ok && json.payload?.content) {\n this._updateStreamingMessage(json.payload.content);\n this._finalizeMessage();\n }\n }\n } catch (error) {\n if ((error as Error).name === 'AbortError') return; // user aborted\n this._error = error instanceof Error ? error.message : t('errors.sendFailed');\n this._isStreaming = false;\n this._isSending = false;\n this._streamingMessage = null;\n this.requestUpdate();\n } finally {\n this._agentAbort = undefined;\n this._isSending = false;\n }\n }\n\n /** Consume a fetch ReadableStream as SSE events. */\n private async _consumeSSEStream(body: ReadableStream<Uint8Array>): Promise<void> {\n const reader = body.pipeThrough(new TextDecoderStream()).getReader();\n let buffer = '';\n // State for multi-line data handling\n let currentEventType = '';\n let currentEventData = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += value;\n\n // Process complete lines\n while (buffer.includes('\\n')) {\n const newlineIndex = buffer.indexOf('\\n');\n const line = buffer.slice(0, newlineIndex);\n buffer = buffer.slice(newlineIndex + 1);\n\n if (line.startsWith('event:')) {\n currentEventType = line.slice(6).trim();\n } else if (line.startsWith('data:')) {\n // Append data (support multi-line data)\n currentEventData += (currentEventData ? '\\n' : '') + line.slice(5).trim();\n } else if (line === '') {\n // Empty line = event boundary\n if (currentEventData) {\n this._handleSSEEvent(currentEventType || 'message', currentEventData);\n currentEventType = '';\n currentEventData = '';\n }\n }\n // Ignore other lines (id:, retry:, etc.)\n }\n }\n\n // Process remaining buffer (last event may not have trailing newline)\n if (buffer.trim() || currentEventData) {\n if (buffer.trim()) {\n const lines = buffer.split('\\n');\n for (const line of lines) {\n if (line.startsWith('event:')) {\n currentEventType = line.slice(6).trim();\n } else if (line.startsWith('data:')) {\n currentEventData += (currentEventData ? '\\n' : '') + line.slice(5).trim();\n } else if (line === '' && currentEventData) {\n this._handleSSEEvent(currentEventType || 'message', currentEventData);\n currentEventType = '';\n currentEventData = '';\n }\n }\n }\n // If we still have unprocessed data, emit it\n if (currentEventData) {\n this._handleSSEEvent(currentEventType || 'message', currentEventData);\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n private _handleSSEEvent(event: string, data: string): void {\n try {\n const parsed = JSON.parse(data);\n\n switch (event) {\n case 'status':\n this._isStreaming = true;\n this.requestUpdate();\n break;\n\n case 'token':\n if (parsed.content) {\n this._updateStreamingMessage(parsed.content);\n }\n break;\n\n case 'error':\n this._error = parsed.content || parsed.error?.message || t('errors.sendFailed');\n this._isStreaming = false;\n this._isSending = false;\n this._streamingMessage = null;\n this.requestUpdate();\n break;\n\n case 'result':\n this._finalizeMessage();\n break;\n\n default:\n // Unknown event type — treat as token if it has content\n if (parsed.content) {\n this._updateStreamingMessage(parsed.content);\n }\n break;\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n // ========== Streaming message helpers ==========\n\n private _updateStreamingMessage(content: string): void {\n if (this._streamingMessage) {\n const textBlock = this._streamingMessage.content.find(b => b.type === 'text');\n if (textBlock) {\n textBlock.text = (textBlock.text || '') + content;\n } else {\n this._streamingMessage.content.push({ type: 'text', text: content });\n }\n } else {\n this._streamingMessage = {\n role: 'assistant',\n content: [{ type: 'text', text: content }],\n timestamp: Date.now(),\n };\n }\n this._isStreaming = true;\n this._streamingContent = content;\n this.requestUpdate();\n\n // Auto-scroll to bottom while streaming if user is at bottom\n if (this._isAtBottom) {\n this._scrollToBottom();\n }\n }\n\n private _finalizeMessage(): void {\n if (this._streamingMessage) {\n this._messages = [...this._messages, this._streamingMessage];\n this._streamingMessage = null;\n }\n this._isStreaming = false;\n this._streamingContent = '';\n this._isSending = false;\n \n // Auto-scroll to bottom if user is at bottom\n if (this._isAtBottom) {\n this._scrollToBottom();\n }\n this.requestUpdate();\n }\n\n // ========== Public HTTP API ==========\n\n /** Generic REST request helper for external components. */\n public async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n if (!this.config) throw new Error('Not configured');\n\n const url = apiUrl(path);\n const res = await fetch(url, {\n method,\n headers: authHeaders(this.config.token),\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({ error: { message: `HTTP ${res.status}` } }));\n throw new Error(err.error?.message || `HTTP ${res.status}`);\n }\n\n return res.json() as Promise<T>;\n }\n\n abort(): void {\n this._agentAbort?.abort();\n this._agentAbort = undefined;\n this._isStreaming = false;\n this._isSending = false;\n this._streamingContent = '';\n this._streamingMessage = null;\n this.requestUpdate();\n }\n\n // Public getters\n public get connectionState(): ConnectionState {\n return this._connectionState;\n }\n\n public get messages(): Message[] {\n return this._messages;\n }\n\n public clearMessages(): void {\n this._messages = [];\n this.requestUpdate();\n }\n\n // ========== Render ==========\n\n override render(): unknown {\n return html`\n ${this._renderStatus()}\n ${this._renderHeader()}\n\n <div class=\"chat-messages\">\n <div class=\"chat-messages-inner\">\n ${this._renderMessages()}\n </div>\n </div>\n\n <!-- Scroll to bottom button - placed outside overflow container -->\n ${!this._isAtBottom ? html`\n <button\n class=\"scroll-to-bottom-btn\"\n style=\"position: fixed; bottom: 100px; right: 24px; width: 48px; height: 48px; border-radius: 50%; background: #3b82f6; color: white; border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 100;\"\n @click=${this._scrollToBottom}\n title=\"Scroll to bottom\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m6 9 6 6 6-6\"/></svg>\n </button>\n ` : ''}\n\n <div class=\"chat-input-container\">\n <div class=\"chat-input-inner\">\n ${this._renderInput()}\n </div>\n </div>\n `;\n }\n\n private _renderHeader(): unknown {\n return html`\n <div class=\"chat-header\">\n <div class=\"chat-header-title\">\n <span class=\"font-semibold\">${t('chat.title') || 'XopcBot'}</span>\n ${this._currentSessionKey ? html`\n <span class=\"text-xs text-muted ml-2\">${this._sessions.find(s => s.key === this._currentSessionKey)?.name || this._currentSessionKey}</span>\n ` : ''}\n </div>\n <button class=\"new-session-btn\" @click=${() => this._createNewSession()}>\n ${this._renderIcon('plus')}\n <span>${t('chat.newSession') || 'New Chat'}</span>\n </button>\n </div>\n `;\n }\n\n private _renderStatus(): unknown {\n if (this._connectionState === 'error' && this._error) {\n return html`\n <div class=\"status-bar error\">\n ${this._renderIcon('alertCircle')}\n <span>${this._error}</span>\n <button class=\"underline ml-auto\" @click=${() => this.reconnect()}>${t('chat.retry')}</button>\n </div>\n `;\n }\n \n if (this._connectionState === 'reconnecting') {\n return html`\n <div class=\"status-bar warning\">\n <div class=\"w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin\"></div>\n <span>${t('chat.reconnecting')}</span>\n </div>\n `;\n }\n \n if (this._connectionState === 'connecting') {\n return html`\n <div class=\"status-bar warning\">\n <div class=\"w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin\"></div>\n <span>${t('chat.connecting')}</span>\n </div>\n `;\n }\n \n return null;\n }\n\n private _renderIcon(name: string): unknown {\n const icons: Record<string, unknown> = {\n alertCircle: html`\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>\n </svg>\n `,\n chevronDown: html`\n <svg class=\"w-5 h-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <polyline points=\"6 9 12 15 18 9\"/>\n </svg>\n `,\n plus: html`\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/>\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/>\n </svg>\n `,\n };\n return icons[name] || '';\n }\n\n private _renderScrollToBottomButton(): unknown {\n return html`\n <button\n class=\"scroll-to-bottom-btn\"\n style=\"background: red !important; width: 60px; height: 60px; font-size: 24px;\"\n @click=${this._scrollToBottom}\n title=\"Scroll to bottom\"\n >\n 👇\n </button>\n `;\n }\n\n private _renderMessages(): unknown {\n if (!this._messages.length && !this._isStreaming) {\n return html`\n <div class=\"empty-state\" style=\"padding-top: 30vh;\">\n <div class=\"icon\">🤖</div>\n <div class=\"title\">${t('chat.welcomeTitle')}</div>\n <div class=\"description\">${t('chat.welcomeDescription')}</div>\n </div>\n `;\n }\n\n return html`\n <div class=\"flex flex-col gap-4\">\n ${this._messages.map(msg => this._renderMessage(msg))}\n ${this._isStreaming && this._streamingMessage ? this._renderStreamingMessage() : ''}\n </div>\n `;\n }\n\n private _renderMessage(message: Message): unknown {\n const isUser = message.role === 'user';\n const hasContent = message.content?.some((block) => block.text);\n if (!hasContent && !message.attachments?.length) return null;\n\n return html`\n <div class=\"message-item ${isUser ? 'flex-row-reverse' : ''}\">\n <div class=\"avatar ${isUser ? 'user' : 'assistant'}\">\n ${isUser ? t('chat.you').charAt(0) : 'X'}\n </div>\n \n <div class=\"flex flex-col gap-1 max-w-[calc(100%-3rem)]\">\n <div class=\"flex items-center gap-2 text-xs text-muted ${isUser ? 'flex-row-reverse' : ''}\">\n <span class=\"font-medium\">${isUser ? t('chat.you') : t('chat.assistant')}</span>\n <span>·</span>\n <span>${this._formatTime(message.timestamp)}</span>\n </div>\n \n <div class=\"message-bubble ${isUser ? 'user' : 'assistant'}\">\n ${this._renderMessageContent(message.content)}\n ${message.attachments?.length ? this._renderAttachments(message.attachments) : ''}\n </div>\n </div>\n </div>\n `;\n }\n\n private _renderStreamingMessage(): unknown {\n const content = this._streamingMessage?.content || [];\n \n return html`\n <div class=\"message-item\">\n <div class=\"avatar assistant\">X</div>\n <div class=\"flex flex-col gap-1 max-w-[calc(100%-3rem)]\">\n <div class=\"flex items-center gap-2 text-xs text-muted\">\n <span class=\"font-medium\">${t('chat.assistant')}</span>\n <span>·</span>\n <span class=\"text-primary animate-pulse\">${t('chat.thinking')}</span>\n </div>\n <div class=\"message-bubble assistant\">\n <div class=\"markdown-content\">\n ${content.map((block) => {\n if (block.type === 'text' && block.text) {\n return html`<p class=\"whitespace-pre-wrap\">${block.text}<span class=\"streaming-cursor\"></span></p>`;\n }\n return '';\n })}\n ${!content.length ? html`<span class=\"streaming-cursor\"></span>` : ''}\n </div>\n </div>\n </div>\n </div>\n `;\n }\n\n private _renderMessageContent(content: Array<{ type: string; text?: string }>): unknown {\n if (!content || content.length === 0) return null;\n return html`\n <div class=\"markdown-content\">\n ${content.map((block) => {\n if (block.type === 'text' && block.text) {\n return html`<p class=\"whitespace-pre-wrap\">${block.text}</p>`;\n }\n return '';\n })}\n </div>\n `;\n }\n\n private _renderAttachments(attachments: Array<{ type: string; mimeType?: string; data?: string; name?: string; size?: number }>): unknown {\n const images = attachments.filter(att => att.type === 'image' || att.mimeType?.startsWith('image/'));\n const documents = attachments.filter(att => att.type !== 'image' && !att.mimeType?.startsWith('image/'));\n \n return html`\n <div class=\"flex flex-col gap-2 mt-2\">\n ${images.length > 0 ? this._renderImageGallery(images) : ''}\n ${documents.length > 0 ? this._renderDocumentList(documents) : ''}\n </div>\n `;\n }\n\n private _renderImageGallery(images: Array<{ data?: string; name?: string }>): unknown {\n const count = images.length;\n let galleryClass = 'single';\n if (count === 2) galleryClass = 'double';\n else if (count === 3) galleryClass = 'triple';\n else if (count >= 4) galleryClass = 'quad';\n \n return html`\n <div class=\"image-gallery ${galleryClass}\">\n ${images.map((img) => html`<img src=\"${img.data}\" alt=\"${img.name || 'Image'}\" />`)}\n </div>\n `;\n }\n\n private _renderDocumentList(documents: Array<{ mimeType?: string; name?: string; size?: number }>): unknown {\n return html`\n <div class=\"flex flex-col gap-2\">\n ${documents.map((doc) => this._renderDocumentPreview(doc))}\n </div>\n `;\n }\n\n private _renderDocumentPreview(doc: { mimeType?: string; name?: string; size?: number }): unknown {\n const name = doc.name || 'Document';\n const size = doc.size ? this._formatFileSize(doc.size) : '';\n \n return html`\n <div class=\"document-preview\">\n <div class=\"icon\">${this._getDocumentIcon(doc.mimeType || '')}</div>\n <div class=\"info\">\n <div class=\"name\">${name}</div>\n <div class=\"meta\">${size || doc.mimeType || 'File'}</div>\n </div>\n </div>\n `;\n }\n\n private _getDocumentIcon(mimeType: string): unknown {\n const color = mimeType.includes('pdf') ? '#ef4444'\n : (mimeType.includes('word') || mimeType.includes('document')) ? '#2563eb'\n : (mimeType.includes('sheet') || mimeType.includes('excel')) ? '#16a34a'\n : 'currentColor';\n\n return html`\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${color}\" stroke-width=\"2\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/>\n <polyline points=\"14,2 14,8 20,8\"/>\n </svg>\n `;\n }\n\n private _renderInput(): unknown {\n return html`\n <message-editor\n .isStreaming=${this._isStreaming}\n .showAttachmentButton=${this.enableAttachments}\n .showModelSelector=${this.enableModelSelector}\n .onSend=${(input: string, attachments: Attachment[]) => this._handleSend(input, attachments)}\n .onAbort=${() => this.abort()}\n ></message-editor>\n `;\n }\n\n private _handleSend = (input: string, attachments: Attachment[]): void => {\n const attachmentData = attachments?.map(att => ({\n type: att.type || 'file',\n mimeType: att.mimeType,\n data: att.content,\n name: att.name,\n size: att.size,\n }));\n this.sendMessage(input, attachmentData);\n };\n\n private _formatTime(timestamp: number): string {\n return new Date(timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n }\n\n private _formatFileSize(bytes: number): string {\n const units = ['B', 'KB', 'MB', 'GB'];\n let unitIndex = 0;\n let size = bytes;\n while (size >= 1024 && unitIndex < units.length - 1) {\n size /= 1024;\n unitIndex++;\n }\n return `${size.toFixed(1)} ${units[unitIndex]}`;\n }\n}\n","// Session Card Component\n\nimport { html, LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { t } from '../utils/i18n';\nimport { getIcon } from '../utils/icons';\nimport type { SessionMetadata } from '../utils/session-api';\n\nexport interface SessionCardEventDetail {\n action: 'click' | 'rename' | 'delete' | 'archive' | 'unarchive' | 'pin' | 'unpin' | 'export';\n key: string;\n}\n\n@customElement('session-card')\nexport class SessionCard extends LitElement {\n @property({ attribute: false }) session!: SessionMetadata;\n @property({ type: Boolean }) selected = false;\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n private _emit(action: SessionCardEventDetail['action']): void {\n this.dispatchEvent(new CustomEvent<SessionCardEventDetail>('session-action', {\n detail: { action, key: this.session.key },\n bubbles: true,\n composed: true,\n }));\n }\n\n private _formatDate(dateStr: string): string {\n const date = new Date(dateStr);\n const now = new Date();\n const diffDays = Math.floor((now.getTime() - date.getTime()) / (1000 * 60 * 60 * 24));\n\n if (diffDays === 0) {\n return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n } else if (diffDays === 1) {\n return 'Yesterday';\n } else if (diffDays < 7) {\n return date.toLocaleDateString([], { weekday: 'short' });\n } else {\n return date.toLocaleDateString([], { month: 'short', day: 'numeric' });\n }\n }\n\n private _getChannelIcon(channel: string): string {\n const icons: Record<string, string> = {\n telegram: 'send',\n whatsapp: 'phone',\n gateway: 'globe',\n cli: 'terminal',\n };\n return icons[channel] || 'messageSquare';\n }\n\n private _getStatusBadge(): string {\n switch (this.session.status) {\n case 'archived':\n return 'bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400';\n case 'pinned':\n return 'bg-blue-100 text-blue-600 dark:bg-blue-900/30 dark:text-blue-400';\n default:\n return 'bg-green-100 text-green-600 dark:bg-green-900/30 dark:text-green-400';\n }\n }\n\n override render(): unknown {\n const displayName = this.session.name || this.session.key;\n const isArchived = this.session.status === 'archived';\n const isPinned = this.session.status === 'pinned';\n\n return html`\n <div \n class=\"session-card ${this.selected ? 'session-card--selected' : ''} ${isArchived ? 'session-card--archived' : ''}\"\n @click=${() => this._emit('click')}\n >\n <div class=\"session-card__header\">\n <div class=\"session-card__channel\">\n <span class=\"channel-icon\">${getIcon(this._getChannelIcon(this.session.sourceChannel))}</span>\n <span class=\"channel-name\">${this.session.sourceChannel}</span>\n </div>\n <div class=\"session-card__meta\">\n ${isPinned ? html`<span class=\"pin-badge\" title=\"Pinned\">${getIcon('pin')}</span>` : ''}\n <span class=\"date\">${this._formatDate(this.session.updatedAt)}</span>\n </div>\n </div>\n\n <div class=\"session-card__title\">\n ${displayName}\n </div>\n\n <div class=\"session-card__stats\">\n <span class=\"stat\">\n ${getIcon('messageSquare')}\n ${this.session.messageCount}\n </span>\n <span class=\"stat\">\n ${getIcon('zap')}\n ${this._formatTokens(this.session.estimatedTokens)}\n </span>\n </div>\n\n ${this.session.tags.length > 0 ? html`\n <div class=\"session-card__tags\">\n ${this.session.tags.slice(0, 3).map(tag => html`\n <span class=\"tag\">${tag}</span>\n `)}\n ${this.session.tags.length > 3 ? html`\n <span class=\"tag tag--more\">+${this.session.tags.length - 3}</span>\n ` : ''}\n </div>\n ` : ''}\n\n <div class=\"session-card__actions\" @click=${(e: Event) => e.stopPropagation()}>\n ${isArchived ? html`\n <button \n class=\"btn-icon btn-icon--success\" \n title=\"Unarchive\"\n @click=${() => this._emit('unarchive')}\n >${getIcon('archiveRestore')}</button>\n ` : html`\n <button \n class=\"btn-icon\" \n title=\"Archive\"\n @click=${() => this._emit('archive')}\n >${getIcon('archive')}</button>\n `}\n \n ${isPinned ? html`\n <button \n class=\"btn-icon btn-icon--primary\" \n title=\"Unpin\"\n @click=${() => this._emit('unpin')}\n >${getIcon('pinOff')}</button>\n ` : html`\n <button \n class=\"btn-icon\" \n title=\"Pin\"\n @click=${() => this._emit('pin')}\n >${getIcon('pin')}</button>\n `}\n \n <button \n class=\"btn-icon\" \n title=\"Export\"\n @click=${() => this._emit('export')}\n >${getIcon('download')}</button>\n \n <button \n class=\"btn-icon btn-icon--danger\" \n title=\"Delete\"\n @click=${() => this._emit('delete')}\n >${getIcon('trash')}</button>\n </div>\n </div>\n `;\n }\n\n private _formatTokens(tokens: number): string {\n if (tokens >= 1000) {\n return (tokens / 1000).toFixed(1) + 'k';\n }\n return tokens.toString();\n }\n}\n\nexport default SessionCard;\n","// Session List Component\n\nimport { html, LitElement } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { t } from '../utils/i18n';\nimport { getIcon } from '../utils/icons';\nimport './SessionCard';\nimport type { SessionMetadata } from '../utils/session-api';\nimport type { SessionCardEventDetail } from './SessionCard';\n\nexport interface SessionListEventDetail {\n action: 'select' | 'rename' | 'delete' | 'archive' | 'unarchive' | 'pin' | 'unpin' | 'export';\n key: string;\n}\n\n@customElement('session-list')\nexport class SessionList extends LitElement {\n @property({ attribute: false }) sessions: SessionMetadata[] = [];\n @property({ type: Boolean }) loading = false;\n @property({ type: Boolean }) hasMore = false;\n @property({ type: String }) selectedKey: string | null = null;\n\n @state() private _viewMode: 'grid' | 'list' = 'grid';\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n private _emit(action: SessionListEventDetail['action'], key: string): void {\n this.dispatchEvent(new CustomEvent<SessionListEventDetail>('list-action', {\n detail: { action, key },\n bubbles: true,\n composed: true,\n }));\n }\n\n private _handleCardAction(e: CustomEvent<SessionCardEventDetail>): void {\n const { action, key } = e.detail;\n if (action === 'click') {\n this._emit('select', key);\n } else {\n this._emit(action as SessionListEventDetail['action'], key);\n }\n }\n\n private _loadMore(): void {\n this.dispatchEvent(new CustomEvent('load-more', {\n bubbles: true,\n composed: true,\n }));\n }\n\n override render(): unknown {\n if (this.loading && this.sessions.length === 0) {\n return this._renderLoading();\n }\n\n if (this.sessions.length === 0) {\n return this._renderEmpty();\n }\n\n return html`\n <div class=\"session-list\">\n ${this._renderToolbar()}\n \n <div class=\"session-list__content session-list__content--${this._viewMode}\">\n ${this.sessions.map(session => html`\n <session-card\n .session=${session}\n .selected=${session.key === this.selectedKey}\n @session-action=${this._handleCardAction}\n ></session-card>\n `)}\n </div>\n\n ${this.hasMore ? html`\n <div class=\"session-list__load-more\">\n <button class=\"btn btn--secondary\" @click=${this._loadMore}>\n ${getIcon('chevronDown')}\n Load More\n </button>\n </div>\n ` : ''}\n\n ${this.loading ? html`\n <div class=\"session-list__loading-overlay\">\n <div class=\"spinner\"></div>\n </div>\n ` : ''}\n </div>\n `;\n }\n\n private _renderToolbar(): unknown {\n return html`\n <div class=\"session-list__toolbar\">\n <div class=\"session-list__count\">\n ${this.sessions.length} sessions\n </div>\n \n <div class=\"session-list__view-toggle\">\n <button \n class=\"btn-icon ${this._viewMode === 'grid' ? 'btn-icon--active' : ''}\"\n title=\"Grid view\"\n @click=${() => this._viewMode = 'grid'}\n >${getIcon('grid')}</button>\n <button \n class=\"btn-icon ${this._viewMode === 'list' ? 'btn-icon--active' : ''}\"\n title=\"List view\"\n @click=${() => this._viewMode = 'list'}\n >${getIcon('list')}</button>\n </div>\n </div>\n `;\n }\n\n private _renderLoading(): unknown {\n return html`\n <div class=\"session-list session-list--loading\">\n <div class=\"session-list__skeleton\">\n ${Array.from({ length: 6 }).map(() => html`\n <div class=\"skeleton-card\">\n <div class=\"skeleton skeleton--header\"></div>\n <div class=\"skeleton skeleton--title\"></div>\n <div class=\"skeleton skeleton--stats\"></div>\n </div>\n `)}\n </div>\n </div>\n `;\n }\n\n private _renderEmpty(): unknown {\n return html`\n <div class=\"session-list session-list--empty\">\n <div class=\"empty-state\">\n <div class=\"empty-state__icon\">${getIcon('folderOpen')}</div>\n <div class=\"empty-state__title\">No sessions found</div>\n <div class=\"empty-state__description\">\n Start a conversation to create your first session.\n </div>\n </div>\n </div>\n `;\n }\n}\n\nexport default SessionList;\n","// Session Detail Drawer Component\n\nimport { html, LitElement } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { getIcon } from '../utils/icons';\nimport type { SessionDetail } from '../utils/session-api';\n\nexport interface SessionDetailEventDetail {\n action: 'close' | 'archive' | 'unarchive' | 'pin' | 'unpin' | 'delete' | 'export';\n}\n\n@customElement('session-detail-drawer')\nexport class SessionDetailDrawer extends LitElement {\n @property({ attribute: false }) session: SessionDetail | null = null;\n @property({ type: Boolean }) open = false;\n @property({ type: Boolean }) loading = false;\n\n @state() private _searchQuery = '';\n @state() private _searchResults: number[] = [];\n @state() private _currentResultIndex = -1;\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n private _emit(action: SessionDetailEventDetail['action']): void {\n this.dispatchEvent(new CustomEvent<SessionDetailEventDetail>('detail-action', {\n detail: { action },\n bubbles: true,\n composed: true,\n }));\n }\n\n private _handleClose(): void {\n this._emit('close');\n }\n\n private _handleBackdropClick(e: MouseEvent): void {\n if (e.target === e.currentTarget) {\n this._handleClose();\n }\n }\n\n private _handleSearch(e: InputEvent): void {\n const target = e.target as HTMLInputElement;\n this._searchQuery = target.value;\n this._performSearch();\n }\n\n private _performSearch(): void {\n if (!this.session || !this._searchQuery.trim()) {\n this._searchResults = [];\n this._currentResultIndex = -1;\n return;\n }\n\n const query = this._searchQuery.toLowerCase();\n const results: number[] = [];\n\n this.session.messages.forEach((msg, index) => {\n if (msg.content.toLowerCase().includes(query)) {\n results.push(index);\n }\n });\n\n this._searchResults = results;\n this._currentResultIndex = results.length > 0 ? 0 : -1;\n }\n\n private _navigateSearch(direction: 'prev' | 'next'): void {\n if (this._searchResults.length === 0) return;\n\n if (direction === 'next') {\n this._currentResultIndex = (this._currentResultIndex + 1) % this._searchResults.length;\n } else {\n this._currentResultIndex = (this._currentResultIndex - 1 + this._searchResults.length) % this._searchResults.length;\n }\n\n // Scroll to result\n const resultIndex = this._searchResults[this._currentResultIndex];\n const element = this.querySelector(`[data-message-index=\"${resultIndex}\"]`);\n if (element) {\n element.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }\n }\n\n private _highlightText(text: string): unknown {\n if (!this._searchQuery.trim()) return text;\n\n const query = this._searchQuery;\n const parts = text.split(new RegExp(`(${query})`, 'gi'));\n\n return parts.map((part, i) => {\n if (part.toLowerCase() === query.toLowerCase()) {\n return html`<mark class=\"search-highlight\">${part}</mark>`;\n }\n return part;\n });\n }\n\n private _formatDate(dateStr: string): string {\n const date = new Date(dateStr);\n return date.toLocaleString();\n }\n\n override render(): unknown {\n if (!this.open) return '';\n\n return html`\n <div class=\"drawer-backdrop\" @click=${this._handleBackdropClick}>\n <div class=\"drawer drawer--${this.open ? 'open' : 'closed'}\">\n ${this._renderHeader()}\n ${this._renderSearch()}\n ${this._renderContent()}\n ${this._renderActions()}\n </div>\n </div>\n `;\n }\n\n private _renderHeader(): unknown {\n if (!this.session) return '';\n\n const isArchived = this.session.status === 'archived';\n const isPinned = this.session.status === 'pinned';\n\n return html`\n <div class=\"drawer-header\">\n <div class=\"drawer-header__info\">\n <div class=\"drawer-header__title\">\n ${this.session.name || this.session.key}\n ${isPinned ? html`<span class=\"pin-badge\">${getIcon('pin')}</span>` : ''}\n ${isArchived ? html`<span class=\"archive-badge\">Archived</span>` : ''}\n </div>\n <div class=\"drawer-header__meta\">\n <span>${this.session.sourceChannel}</span>\n <span>•</span>\n <span>${this.session.messageCount} messages</span>\n <span>•</span>\n <span>${this._formatDate(this.session.updatedAt)}</span>\n </div>\n </div>\n <button class=\"btn-icon\" @click=${this._handleClose} title=\"Close\">\n ${getIcon('x')}\n </button>\n </div>\n `;\n }\n\n private _renderSearch(): unknown {\n if (!this.session) return '';\n\n return html`\n <div class=\"drawer-search\">\n <div class=\"search-input-wrapper\">\n ${getIcon('search')}\n <input\n type=\"text\"\n placeholder=\"Search in session...\"\n .value=${this._searchQuery}\n @input=${this._handleSearch}\n />\n ${this._searchQuery ? html`\n <button class=\"btn-icon btn-icon--sm\" @click=${() => { this._searchQuery = ''; this._performSearch(); }}>\n ${getIcon('x')}\n </button>\n ` : ''}\n </div>\n \n ${this._searchResults.length > 0 ? html`\n <div class=\"search-nav\">\n <span class=\"search-count\">${this._currentResultIndex + 1} / ${this._searchResults.length}</span>\n <button class=\"btn-icon btn-icon--sm\" @click=${() => this._navigateSearch('prev')} title=\"Previous\">\n ${getIcon('chevronUp')}\n </button>\n <button class=\"btn-icon btn-icon--sm\" @click=${() => this._navigateSearch('next')} title=\"Next\">\n ${getIcon('chevronDown')}\n </button>\n </div>\n ` : ''}\n </div>\n `;\n }\n\n private _renderContent(): unknown {\n if (this.loading) {\n return html`\n <div class=\"drawer-content drawer-content--loading\">\n <div class=\"spinner\"></div>\n <span>Loading...</span>\n </div>\n `;\n }\n\n if (!this.session) {\n return html`\n <div class=\"drawer-content drawer-content--empty\">\n <span>No session selected</span>\n </div>\n `;\n }\n\n return html`\n <div class=\"drawer-content\">\n ${this.session.messages.map((msg, index) => {\n const isSearchResult = this._searchResults.includes(index);\n const isCurrentResult = this._searchResults[this._currentResultIndex] === index;\n\n return html`\n <div \n class=\"message ${msg.role} ${isSearchResult ? 'message--highlight' : ''} ${isCurrentResult ? 'message--current' : ''}\"\n data-message-index=\"${index}\"\n >\n <div class=\"message__header\">\n <span class=\"message__role\">${msg.role}</span>\n ${msg.timestamp ? html`<span class=\"message__time\">${this._formatDate(msg.timestamp)}</span>` : ''}\n </div>\n <div class=\"message__content\">${this._highlightText(msg.content)}</div>\n </div>\n `;\n })}\n </div>\n `;\n }\n\n private _renderActions(): unknown {\n if (!this.session) return '';\n\n const isArchived = this.session.status === 'archived';\n const isPinned = this.session.status === 'pinned';\n\n return html`\n <div class=\"drawer-actions\">\n ${isArchived ? html`\n <button class=\"btn btn--secondary\" @click=${() => this._emit('unarchive')}>\n ${getIcon('archiveRestore')} Unarchive\n </button>\n ` : html`\n <button class=\"btn btn--secondary\" @click=${() => this._emit('archive')}>\n ${getIcon('archive')} Archive\n </button>\n `}\n\n ${isPinned ? html`\n <button class=\"btn btn--secondary\" @click=${() => this._emit('unpin')}>\n ${getIcon('pinOff')} Unpin\n </button>\n ` : html`\n <button class=\"btn btn--secondary\" @click=${() => this._emit('pin')}>\n ${getIcon('pin')} Pin\n </button>\n `}\n\n <button class=\"btn btn--secondary\" @click=${() => this._emit('export')}>\n ${getIcon('download')} Export\n </button>\n\n <button class=\"btn btn--danger\" @click=${() => this._emit('delete')}>\n ${getIcon('trash')} Delete\n </button>\n </div>\n `;\n }\n}\n\nexport default SessionDetailDrawer;\n","// Confirm Dialog Component\n\nimport { html, LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { getIcon } from '../utils/icons';\n\nexport interface ConfirmDialogEventDetail {\n confirmed: boolean;\n}\n\n@customElement('confirm-dialog')\nexport class ConfirmDialog extends LitElement {\n @property({ type: Boolean }) open = false;\n @property({ type: String }) title = 'Confirm';\n @property({ type: String }) message = 'Are you sure?';\n @property({ type: String }) confirmText = 'Confirm';\n @property({ type: String }) cancelText = 'Cancel';\n @property({ type: String }) type: 'danger' | 'warning' | 'info' = 'warning';\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n private _emit(confirmed: boolean): void {\n this.dispatchEvent(new CustomEvent<ConfirmDialogEventDetail>('confirm', {\n detail: { confirmed },\n bubbles: true,\n composed: true,\n }));\n this.open = false;\n }\n\n private _handleBackdropClick(e: MouseEvent): void {\n if (e.target === e.currentTarget) {\n this._emit(false);\n }\n }\n\n private _getIcon(): string {\n switch (this.type) {\n case 'danger':\n return 'trash';\n case 'warning':\n return 'alertTriangle';\n case 'info':\n return 'info';\n default:\n return 'helpCircle';\n }\n }\n\n private _getIconColor(): string {\n switch (this.type) {\n case 'danger':\n return 'text-red-500';\n case 'warning':\n return 'text-amber-500';\n case 'info':\n return 'text-blue-500';\n default:\n return 'text-gray-500';\n }\n }\n\n override render(): unknown {\n if (!this.open) return '';\n\n return html`\n <div class=\"modal-backdrop\" @click=${this._handleBackdropClick}>\n <div class=\"modal modal--${this.type}\">\n <div class=\"modal__icon ${this._getIconColor()}\">\n ${getIcon(this._getIcon())}\n </div>\n \n <div class=\"modal__content\">\n <h3 class=\"modal__title\">${this.title}</h3>\n <p class=\"modal__message\">${this.message}</p>\n </div>\n \n <div class=\"modal__actions\">\n <button class=\"btn btn--secondary\" @click=${() => this._emit(false)}>\n ${this.cancelText}\n </button>\n <button class=\"btn btn--${this.type === 'danger' ? 'danger' : 'primary'}\" @click=${() => this._emit(true)}>\n ${this.confirmText}\n </button>\n </div>\n </div>\n </div>\n `;\n }\n}\n\nexport default ConfirmDialog;\n","// Session API - HTTP client for session management\n\nexport interface SessionMetadata {\n key: string;\n name?: string;\n status: 'active' | 'idle' | 'archived' | 'pinned';\n tags: string[];\n createdAt: string;\n updatedAt: string;\n lastAccessedAt: string;\n messageCount: number;\n estimatedTokens: number;\n compactedCount: number;\n sourceChannel: string;\n sourceChatId: string;\n}\n\nexport interface SessionDetail extends SessionMetadata {\n messages: Array<{\n role: string;\n content: string;\n timestamp?: string;\n }>;\n}\n\nexport interface SessionListQuery {\n status?: 'active' | 'idle' | 'archived' | 'pinned' | ('active' | 'idle' | 'archived' | 'pinned')[];\n channel?: string;\n tags?: string[];\n search?: string;\n sortBy?: 'updatedAt' | 'createdAt' | 'messageCount' | 'lastAccessedAt';\n sortOrder?: 'asc' | 'desc';\n limit?: number;\n offset?: number;\n}\n\nexport interface PaginatedResult<T> {\n items: T[];\n total: number;\n limit: number;\n offset: number;\n hasMore: boolean;\n}\n\nexport interface SessionStats {\n totalSessions: number;\n activeSessions: number;\n archivedSessions: number;\n pinnedSessions: number;\n totalMessages: number;\n totalTokens: number;\n oldestSession?: string;\n newestSession?: string;\n byChannel: Record<string, number>;\n}\n\nexport type ExportFormat = 'json' | 'markdown';\n\nexport class SessionAPIClient {\n private baseUrl: string;\n private token?: string;\n\n constructor(baseUrl: string, token?: string) {\n // Normalize URL - remove trailing slash\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n this.token = token;\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n \n if (this.token) {\n headers['Authorization'] = `Bearer ${this.token}`;\n }\n\n const response = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: 'Request failed' }));\n throw new Error(error.error || `HTTP ${response.status}`);\n }\n\n return response.json();\n }\n\n // ========== Session API Methods ==========\n\n async listSessions(query?: SessionListQuery): Promise<PaginatedResult<SessionMetadata>> {\n const params = new URLSearchParams();\n if (query?.status) params.set('status', query.status as string);\n if (query?.search) params.set('search', query.search);\n if (query?.limit) params.set('limit', String(query.limit));\n if (query?.offset) params.set('offset', String(query.offset));\n \n const queryString = params.toString();\n const path = `/api/sessions${queryString ? `?${queryString}` : ''}`;\n return await this.request<PaginatedResult<SessionMetadata>>('GET', path);\n }\n\n async getSession(key: string): Promise<SessionDetail | null> {\n try {\n const result = await this.request<{ session: SessionDetail }>('GET', `/api/sessions/${key}`);\n return result.session || null;\n } catch (err) {\n if (err instanceof Error && err.message.includes('404')) {\n return null;\n }\n throw err;\n }\n }\n\n async deleteSession(key: string): Promise<{ deleted: boolean }> {\n return await this.request<{ deleted: boolean }>('DELETE', `/api/sessions/${key}`);\n }\n\n async archiveSession(key: string): Promise<{ archived: boolean }> {\n return await this.request<{ archived: boolean }>('POST', `/api/sessions/${key}/archive`);\n }\n\n async unarchiveSession(key: string): Promise<{ unarchived: boolean }> {\n return await this.request<{ unarchived: boolean }>('POST', `/api/sessions/${key}/unarchive`);\n }\n\n async pinSession(key: string): Promise<{ pinned: boolean }> {\n return await this.request<{ pinned: boolean }>('POST', `/api/sessions/${key}/pin`);\n }\n\n async unpinSession(key: string): Promise<{ unpinned: boolean }> {\n return await this.request<{ unpinned: boolean }>('POST', `/api/sessions/${key}/unpin`);\n }\n\n async renameSession(key: string, name: string): Promise<{ renamed: boolean }> {\n return await this.request<{ renamed: boolean }>('POST', `/api/sessions/${key}/rename`, { name });\n }\n\n async exportSession(key: string, format: ExportFormat = 'json'): Promise<string> {\n const result = await this.request<{ content: string }>('GET', `/api/sessions/${key}/export?format=${format}`);\n return result.content;\n }\n\n async getStats(): Promise<SessionStats> {\n return await this.request<SessionStats>('GET', '/api/sessions/stats');\n }\n}\n","// Session Manager Page Component (精简版)\n\nimport { html, LitElement } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport '../components/SessionList';\nimport '../components/SessionDetailDrawer';\nimport '../components/ConfirmDialog';\nimport { getIcon } from '../utils/icons';\nimport { t } from '../utils/i18n';\nimport { SessionAPIClient, type SessionMetadata, type SessionDetail, type SessionStats } from '../utils/session-api';\nimport type { SessionListEventDetail } from '../components/SessionList';\nimport type { SessionDetailEventDetail } from '../components/SessionDetailDrawer';\n\nexport interface SessionManagerConfig {\n /** @deprecated No longer needed - always uses current origin */\n url?: string;\n token?: string;\n}\n\n@customElement('session-manager')\nexport class SessionManager extends LitElement {\n @property({ attribute: false }) config?: SessionManagerConfig;\n\n @state() private _sessions: SessionMetadata[] = [];\n @state() private _loading = false;\n @state() private _hasMore = false;\n @state() private _stats: SessionStats | null = null;\n @state() private _searchQuery = '';\n @state() private _statusFilter: 'all' | 'active' | 'archived' | 'pinned' = 'all';\n @state() private _offset = 0;\n @state() private _error: string | null = null;\n\n // Detail drawer state\n @state() private _detailOpen = false;\n @state() private _detailSession: SessionDetail | null = null;\n @state() private _detailLoading = false;\n\n // Confirm dialog state\n @state() private _confirmOpen = false;\n @state() private _confirmTitle = '';\n @state() private _confirmMessage = '';\n @state() private _confirmKey: string | null = null;\n @state() private _confirmAction: 'delete' | null = null;\n\n private _api!: SessionAPIClient;\n private _limit = 20;\n private _initialized = false;\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._tryInitialize();\n }\n\n override willUpdate(changedProperties: Map<string, unknown>): void {\n super.willUpdate(changedProperties);\n if (changedProperties.has('config')) {\n this._tryInitialize();\n }\n }\n\n private _tryInitialize(): void {\n if (this._initialized) {\n return;\n }\n const httpUrl = window.location.origin;\n this._api = new SessionAPIClient(httpUrl, this.config?.token);\n this._initialized = true;\n this._loadSessions();\n this._loadStats();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n }\n\n private async _loadSessions(reset = false): Promise<void> {\n if (this._loading) return;\n\n this._loading = true;\n this._error = null;\n\n if (reset) {\n this._offset = 0;\n this._sessions = [];\n }\n\n try {\n const query = {\n limit: this._limit,\n offset: this._offset,\n sortBy: 'updatedAt' as const,\n sortOrder: 'desc' as const,\n ...(this._statusFilter !== 'all' && { status: this._statusFilter }),\n ...(this._searchQuery && { search: this._searchQuery }),\n };\n\n const result = await this._api.listSessions(query);\n \n if (reset) {\n this._sessions = result.items;\n } else {\n this._sessions = [...this._sessions, ...result.items];\n }\n \n this._hasMore = result.hasMore;\n this._offset = result.offset + result.items.length;\n } catch (err) {\n this._error = err instanceof Error ? err.message : 'Failed to load sessions';\n console.error('[SessionManager] Load error:', err);\n } finally {\n this._loading = false;\n }\n }\n\n private async _loadStats(): Promise<void> {\n try {\n this._stats = await this._api.getStats();\n } catch (err) {\n console.error('[SessionManager] Stats error:', err);\n }\n }\n\n // ========== Detail Drawer ==========\n\n private async _openDetail(key: string): Promise<void> {\n this._detailOpen = true;\n this._detailLoading = true;\n\n try {\n const session = await this._api.getSession(key);\n this._detailSession = session;\n } catch (err) {\n console.error('[SessionManager] Load detail error:', err);\n this._detailOpen = false;\n } finally {\n this._detailLoading = false;\n }\n }\n\n private _closeDetail(): void {\n this._detailOpen = false;\n this._detailSession = null;\n }\n\n private _handleDetailAction(e: CustomEvent<SessionDetailEventDetail>): void {\n const { action } = e.detail;\n const key = this._detailSession?.key;\n if (!key) return;\n\n switch (action) {\n case 'close':\n this._closeDetail();\n break;\n case 'delete':\n this._showConfirm(key);\n break;\n case 'archive':\n this._archiveSession(key);\n break;\n case 'unarchive':\n this._unarchiveSession(key);\n break;\n case 'pin':\n this._pinSession(key);\n break;\n case 'unpin':\n this._unpinSession(key);\n break;\n case 'export':\n this._exportSession(key);\n break;\n }\n }\n\n // ========== Confirm Dialog ==========\n\n private _showConfirm(key: string): void {\n this._confirmKey = key;\n this._confirmAction = 'delete';\n this._confirmTitle = 'Delete Session';\n this._confirmMessage = `Are you sure you want to delete session \"${key}\"?\\n\\nThis action cannot be undone.`;\n this._confirmOpen = true;\n }\n\n private _handleConfirm(e: CustomEvent<{ confirmed: boolean }>): void {\n if (!e.detail.confirmed || !this._confirmKey) {\n this._confirmOpen = false;\n this._confirmKey = null;\n return;\n }\n\n this._deleteSession(this._confirmKey);\n this._confirmOpen = false;\n this._confirmKey = null;\n }\n\n // ========== Actions ==========\n\n private async _deleteSession(key: string): Promise<void> {\n try {\n await this._api.deleteSession(key);\n this._sessions = this._sessions.filter(s => s.key !== key);\n \n if (this._detailSession?.key === key) {\n this._closeDetail();\n }\n \n await this._loadStats();\n } catch (err) {\n alert('Failed to delete session: ' + (err instanceof Error ? err.message : String(err)));\n }\n }\n\n private async _archiveSession(key: string): Promise<void> {\n try {\n await this._api.archiveSession(key);\n this._updateSessionStatus(key, 'archived');\n if (this._detailSession?.key === key) {\n this._detailSession = { ...this._detailSession, status: 'archived' };\n }\n await this._loadStats();\n } catch (err) {\n console.error('[SessionManager] Archive error:', err);\n }\n }\n\n private async _unarchiveSession(key: string): Promise<void> {\n try {\n await this._api.unarchiveSession(key);\n this._updateSessionStatus(key, 'active');\n if (this._detailSession?.key === key) {\n this._detailSession = { ...this._detailSession, status: 'active' };\n }\n await this._loadStats();\n } catch (err) {\n console.error('[SessionManager] Unarchive error:', err);\n }\n }\n\n private async _pinSession(key: string): Promise<void> {\n try {\n await this._api.pinSession(key);\n this._updateSessionStatus(key, 'pinned');\n if (this._detailSession?.key === key) {\n this._detailSession = { ...this._detailSession, status: 'pinned' };\n }\n await this._loadStats();\n } catch (err) {\n console.error('[SessionManager] Pin error:', err);\n }\n }\n\n private async _unpinSession(key: string): Promise<void> {\n try {\n await this._api.unpinSession(key);\n this._updateSessionStatus(key, 'active');\n if (this._detailSession?.key === key) {\n this._detailSession = { ...this._detailSession, status: 'active' };\n }\n await this._loadStats();\n } catch (err) {\n console.error('[SessionManager] Unpin error:', err);\n }\n }\n\n private async _exportSession(key: string): Promise<void> {\n try {\n const content = await this._api.exportSession(key, 'json');\n const blob = new Blob([content], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = `session-${key.replace(/[^a-z0-9]/gi, '_')}.json`;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n } catch (err) {\n alert('Failed to export session: ' + (err instanceof Error ? err.message : String(err)));\n }\n }\n\n private _updateSessionStatus(key: string, status: SessionMetadata['status']): void {\n this._sessions = this._sessions.map(s => \n s.key === key ? { ...s, status } : s\n );\n }\n\n // ========== List Handlers ==========\n\n private _handleListAction(e: CustomEvent<SessionListEventDetail>): void {\n const { action, key } = e.detail;\n \n switch (action) {\n case 'select':\n this._openDetail(key);\n break;\n case 'delete':\n this._showConfirm(key);\n break;\n case 'archive':\n this._archiveSession(key);\n break;\n case 'unarchive':\n this._unarchiveSession(key);\n break;\n case 'pin':\n this._pinSession(key);\n break;\n case 'unpin':\n this._unpinSession(key);\n break;\n case 'export':\n this._exportSession(key);\n break;\n }\n }\n\n private _handleSearch(e: InputEvent): void {\n const target = e.target as HTMLInputElement;\n this._searchQuery = target.value;\n this._debouncedSearch();\n }\n\n private _debouncedSearch = this._debounce(() => {\n this._loadSessions(true);\n }, 300);\n\n private _debounce(fn: () => void, ms: number): () => void {\n let timeout: ReturnType<typeof setTimeout>;\n return () => {\n clearTimeout(timeout);\n timeout = setTimeout(fn, ms);\n };\n }\n\n private _handleStatusFilter(status: typeof this._statusFilter): void {\n this._statusFilter = status;\n this._loadSessions(true);\n }\n\n private _handleLoadMore(): void {\n this._loadSessions();\n }\n\n // ========== Render ==========\n\n override render(): unknown {\n return html`\n <div class=\"session-manager\">\n ${this._renderHeader()}\n ${this._renderFilters()}\n ${this._renderStats()}\n ${this._error ? html`<div class=\"error-banner\">${this._error}</div>` : ''}\n \n <session-list\n .sessions=${this._sessions}\n .loading=${this._loading}\n .hasMore=${this._hasMore}\n @list-action=${this._handleListAction}\n @load-more=${this._handleLoadMore}\n ></session-list>\n </div>\n\n <session-detail-drawer\n .session=${this._detailSession}\n .open=${this._detailOpen}\n .loading=${this._detailLoading}\n @detail-action=${this._handleDetailAction}\n ></session-detail-drawer>\n\n <confirm-dialog\n .open=${this._confirmOpen}\n .title=${this._confirmTitle}\n .message=${this._confirmMessage}\n .confirmText=\"Delete\"\n .cancelText=\"Cancel\"\n .type=\"danger\"\n @confirm=${this._handleConfirm}\n ></confirm-dialog>\n `;\n }\n\n private _renderHeader(): unknown {\n return html`\n <div class=\"session-manager__header\">\n <h1 class=\"page-title\">${getIcon('folderOpen')} ${t('sessions.title')}</h1>\n <div class=\"search-box\">\n ${getIcon('search')}\n <input\n type=\"text\"\n placeholder=\"${t('sessions.searchPlaceholder')}\"\n .value=${this._searchQuery}\n @input=${this._handleSearch}\n />\n </div>\n </div>\n `;\n }\n\n private _renderFilters(): unknown {\n const filters = [\n { key: 'all', label: 'All', icon: 'layers' },\n { key: 'active', label: 'Active', icon: 'circle' },\n { key: 'pinned', label: 'Pinned', icon: 'pin' },\n { key: 'archived', label: 'Archived', icon: 'archive' },\n ] as const;\n\n return html`\n <div class=\"session-manager__filters\">\n ${filters.map(f => html`\n <button\n class=\"filter-btn ${this._statusFilter === f.key ? 'filter-btn--active' : ''}\"\n @click=${() => this._handleStatusFilter(f.key as typeof this._statusFilter)}\n >\n ${getIcon(f.icon)}\n ${f.label}\n </button>\n `)}\n </div>\n `;\n }\n\n private _renderStats(): unknown {\n if (!this._stats) return '';\n\n return html`\n <div class=\"session-manager__stats\">\n <div class=\"stat-card\">\n <div class=\"stat-value\">${this._stats.totalSessions}</div>\n <div class=\"stat-label\">${t('sessions.totalSessions')}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${this._stats.activeSessions}</div>\n <div class=\"stat-label\">${t('sessions.activeSessions')}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${this._stats.pinnedSessions}</div>\n <div class=\"stat-label\">${t('sessions.pinnedSessions')}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${this._stats.archivedSessions}</div>\n <div class=\"stat-label\">${t('sessions.archivedSessions')}</div>\n </div>\n </div>\n `;\n }\n}\n\nexport default SessionManager;\n","// Cron API - HTTP client for cron job management\n\nexport interface CronDelivery {\n mode: 'none' | 'announce' | 'direct';\n channel?: string;\n to?: string;\n bestEffort?: boolean;\n}\n\nexport interface CronPayload {\n kind: 'systemEvent' | 'agentTurn';\n text?: string;\n message?: string;\n model?: string;\n timeoutSeconds?: number;\n}\n\nexport interface CronJob {\n id: string;\n name?: string;\n schedule: string;\n message: string;\n enabled: boolean;\n timezone?: string;\n maxRetries: number;\n timeout: number;\n next_run?: string;\n created_at: string;\n updated_at: string;\n // New fields\n sessionTarget?: 'main' | 'isolated';\n payload?: CronPayload;\n delivery?: CronDelivery;\n model?: string;\n}\n\nexport interface AddJobOptions {\n name?: string;\n timezone?: string;\n sessionTarget?: 'main' | 'isolated';\n model?: string;\n delivery?: CronDelivery;\n}\n\nexport interface ModelInfo {\n id: string;\n name: string;\n provider: string;\n}\n\nexport interface ConfigInfo {\n model?: string;\n}\n\nexport interface ChannelStatus {\n name: string;\n enabled: boolean;\n connected: boolean;\n}\n\nexport interface SessionChatId {\n channel: string;\n chatId: string;\n lastActive: string;\n}\n\nexport interface CronJobExecution {\n id: string;\n jobId: string;\n status: 'running' | 'success' | 'failed' | 'cancelled';\n startedAt: string;\n endedAt?: string;\n duration?: number;\n error?: string;\n output?: string;\n retryCount: number;\n}\n\nexport interface CronMetrics {\n totalJobs: number;\n runningJobs: number;\n enabledJobs: number;\n failedLastHour: number;\n avgExecutionTime: number;\n nextScheduledJob?: {\n id: string;\n name?: string;\n runAt: Date;\n };\n}\n\nexport interface CronJobUpdate {\n name?: string;\n schedule?: string;\n message?: string;\n enabled?: boolean;\n timezone?: string;\n maxRetries?: number;\n timeout?: number;\n sessionTarget?: 'main' | 'isolated';\n model?: string;\n delivery?: CronDelivery;\n}\n\nexport class CronAPIClient {\n private baseUrl: string;\n private token?: string;\n\n constructor(baseUrl: string, token?: string) {\n // Normalize URL - remove trailing slash\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n this.token = token;\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n \n if (this.token) {\n headers['Authorization'] = `Bearer ${this.token}`;\n }\n\n const response = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: 'Request failed' }));\n throw new Error(error.error || `HTTP ${response.status}`);\n }\n\n return response.json();\n }\n\n // ========== Cron API Methods ==========\n\n async listJobs(): Promise<CronJob[]> {\n const result = await this.request<{ jobs: CronJob[] }>('GET', '/api/cron');\n return result.jobs || [];\n }\n\n async getJob(id: string): Promise<CronJob | null> {\n try {\n const result = await this.request<{ job: CronJob }>('GET', `/api/cron/${id}`);\n return result.job || null;\n } catch (err) {\n if (err instanceof Error && err.message.includes('404')) {\n return null;\n }\n throw err;\n }\n }\n\n async addJob(schedule: string, message: string, options?: AddJobOptions): Promise<{ id: string; schedule: string }> {\n return await this.request<{ id: string; schedule: string }>('POST', '/api/cron', {\n schedule,\n message,\n ...options,\n });\n }\n\n async updateJob(id: string, updates: CronJobUpdate): Promise<boolean> {\n const result = await this.request<{ updated: boolean }>('PATCH', `/api/cron/${id}`, updates);\n return result.updated;\n }\n\n async removeJob(id: string): Promise<boolean> {\n const result = await this.request<{ removed: boolean }>('DELETE', `/api/cron/${id}`);\n return result.removed;\n }\n\n async toggleJob(id: string, enabled: boolean): Promise<boolean> {\n const result = await this.request<{ toggled: boolean }>('POST', `/api/cron/${id}/toggle`, { enabled });\n return result.toggled;\n }\n\n async runJob(id: string): Promise<void> {\n await this.request<{ triggered: boolean }>('POST', `/api/cron/${id}/run`);\n }\n\n async getHistory(id: string, limit = 10): Promise<CronJobExecution[]> {\n const result = await this.request<{ history: CronJobExecution[] }>('GET', `/api/cron/${id}/history?limit=${limit}`);\n return result.history || [];\n }\n\n async getMetrics(): Promise<CronMetrics> {\n return await this.request<CronMetrics>('GET', '/api/cron/metrics');\n }\n\n async getChannels(): Promise<ChannelStatus[]> {\n const result = await this.request<{ ok: boolean; payload: { channels: ChannelStatus[] } }>('GET', '/api/channels/status');\n return result.payload?.channels || [];\n }\n\n async getModels(): Promise<ModelInfo[]> {\n const result = await this.request<{ ok: boolean; payload: { models: ModelInfo[] } }>('GET', '/api/models');\n return result.payload?.models || [];\n }\n\n async getConfig(): Promise<ConfigInfo> {\n const result = await this.request<{ config: ConfigInfo }>('GET', '/api/config');\n // Extract model from nested config structure\n const config = result.config || {};\n return {\n model: (config as any).agents?.defaults?.model || '',\n };\n }\n\n async getSessionChatIds(channel?: string): Promise<SessionChatId[]> {\n const query = channel ? `?channel=${encodeURIComponent(channel)}` : '';\n const result = await this.request<{ ok: boolean; payload: { chatIds: SessionChatId[] } }>('GET', `/api/sessions/chat-ids${query}`);\n return result.payload?.chatIds || [];\n }\n\n /**\n * Disconnect/cleanup method (no-op for HTTP client, provided for interface compatibility)\n */\n disconnect(): void {\n // HTTP client has no persistent connection to close\n }\n}\n","/**\n * Model selector component - loads models dynamically from backend API.\n */\n\nimport { html, LitElement, css } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nexport interface Model {\n id: string;\n name: string;\n provider: string;\n contextWindow?: number;\n maxTokens?: number;\n reasoning?: boolean;\n vision?: boolean;\n cost?: {\n input: number;\n output: number;\n };\n}\n\nexport interface ModelSelectEvent {\n modelId: string;\n model: Model | null;\n}\n\n@customElement('model-selector')\nexport class ModelSelector extends LitElement {\n @property({ type: String }) value: string = '';\n @property({ type: String }) label: string = 'Model';\n @property({ type: String }) placeholder: string = 'Select a model...';\n @property({ type: Boolean }) required: boolean = false;\n @property({ type: Boolean }) disabled: boolean = false;\n @property({ type: String }) filter: 'all' | 'configured' | 'vision' = 'configured';\n @property({ type: String }) token?: string;\n\n @state() private _models: Model[] = [];\n @state() private _loading: boolean = false;\n @state() private _error: string | null = null;\n\n static styles = css`\n :host { display: block; }\n\n .model-selector {\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n }\n\n .label {\n font-size: 0.8125rem;\n font-weight: 500;\n color: var(--text-primary, #1c1917);\n }\n\n .required { color: var(--accent-error, #dc2626); }\n\n .select-wrapper { position: relative; }\n\n .model-select {\n width: 100%;\n padding: 0.5rem 0.75rem;\n padding-right: 2rem;\n border: 1px solid var(--border-color, #e7e5e4);\n border-radius: var(--radius-md, 0.5rem);\n font-size: 0.8125rem;\n background: var(--bg-primary, #fafaf9);\n color: var(--text-primary, #1c1917);\n cursor: pointer;\n appearance: none;\n transition: all var(--transition-fast, 150ms);\n }\n\n .model-select:focus {\n outline: none;\n border-color: var(--accent-primary, #4f46e5);\n box-shadow: 0 0 0 2px var(--accent-primary-light, #e0e7ff);\n }\n\n .model-select:disabled {\n background: var(--bg-secondary, #f5f5f4);\n cursor: not-allowed;\n opacity: 0.6;\n }\n\n .select-arrow {\n position: absolute;\n right: 0.625rem;\n top: 50%;\n transform: translateY(-50%);\n pointer-events: none;\n color: var(--text-muted, #a8a29e);\n font-size: 0.625rem;\n }\n\n .loading-state {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.75rem;\n color: var(--text-secondary, #57534e);\n font-size: 0.8125rem;\n }\n\n .spinner {\n width: 14px;\n height: 14px;\n border: 2px solid var(--border-color, #e7e5e4);\n border-top-color: var(--accent-primary, #4f46e5);\n border-radius: 50%;\n animation: spin 1s linear infinite;\n }\n\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n\n .error-state {\n padding: 0.5rem 0.75rem;\n color: var(--accent-error, #dc2626);\n font-size: 0.8125rem;\n background: var(--accent-error-light, #fee2e2);\n border-radius: var(--radius-md, 0.5rem);\n }\n\n .empty-state {\n padding: 0.5rem 0.75rem;\n color: var(--text-secondary, #57534e);\n font-size: 0.8125rem;\n }\n `;\n\n connectedCallback() {\n super.connectedCallback();\n this._loadModels();\n }\n\n protected willUpdate(): void {\n // After models are loaded, ensure the select value is properly set\n // This handles the case where value is set before models are loaded\n if (this.value && this._models.length > 0) {\n const hasMatchingModel = this._models.some(m => m.id === this.value);\n if (!hasMatchingModel) {\n console.warn('[ModelSelector] Current value not found in models:', {\n value: this.value,\n availableModels: this._models.map(m => m.id),\n });\n }\n }\n }\n\n private async _loadModels() {\n if (this._loading) return;\n\n this._loading = true;\n this._error = null;\n\n try {\n const endpoint = this.filter === 'all' ? '/api/providers' : '/api/models';\n const headers: Record<string, string> = {};\n if (this.token) {\n headers['Authorization'] = `Bearer ${this.token}`;\n }\n\n const response = await fetch(`${window.location.origin}${endpoint}`, { headers });\n\n if (!response.ok) {\n throw new Error(`Failed to load models: ${response.status}`);\n }\n\n const data = await response.json();\n let models: Model[] = data.payload.models;\n\n if (this.filter === 'vision') {\n models = models.filter(m => m.vision);\n }\n\n models.sort((a, b) => {\n if (a.reasoning !== b.reasoning) {\n return b.reasoning ? 1 : -1;\n }\n if (a.provider !== b.provider) {\n return a.provider.localeCompare(b.provider);\n }\n return a.name.localeCompare(b.name);\n });\n\n this._models = models;\n\n // Debug logging for model selection\n console.log('[ModelSelector] Models loaded:', {\n count: models.length,\n currentValue: this.value,\n hasMatchingModel: models.some(m => m.id === this.value),\n matchingModel: models.find(m => m.id === this.value),\n });\n } catch (err) {\n console.error('[ModelSelector] Failed to load models:', err);\n this._error = err instanceof Error ? err.message : 'Failed to load models';\n } finally {\n this._loading = false;\n }\n }\n\n private _onChange(e: Event) {\n const target = e.target as HTMLSelectElement;\n const modelId = target.value;\n const model = this._models.find(m => m.id === modelId) || null;\n\n this.dispatchEvent(new CustomEvent<ModelSelectEvent>('change', {\n detail: { modelId, model },\n bubbles: true,\n composed: true,\n }));\n }\n\n render() {\n return html`\n <div class=\"model-selector\">\n ${this.label ? html`\n <label class=\"label\">\n ${this.label}\n ${this.required ? html`<span class=\"required\">*</span>` : ''}\n </label>\n ` : ''}\n\n ${this._loading ? html`\n <div class=\"loading-state\">\n <span class=\"spinner\"></span>\n <span>Loading models...</span>\n </div>\n ` : this._error ? html`\n <div class=\"error-state\">\n ${this._error}\n </div>\n ` : this._models.length === 0 ? html`\n <div class=\"empty-state\">\n No models available. Please configure a provider first.\n </div>\n ` : html`\n <div class=\"select-wrapper\">\n <select\n class=\"model-select\"\n .value=${this.value || ''}\n @change=${this._onChange}\n ?disabled=${this.disabled}\n >\n <option value=\"\" disabled ?selected=${!this.value}>\n ${this.placeholder}\n </option>\n ${this._models.map(model => html`\n <option \n value=\"${model.id}\"\n ?selected=${model.id === this.value}\n >\n ${model.provider}/${model.name}\n </option>\n `)}\n </select>\n <span class=\"select-arrow\">▼</span>\n </div>\n `}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'model-selector': ModelSelector;\n }\n}\n","// Cron Manager Page Component\n\nimport { html, LitElement, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { getIcon } from '../utils/icons';\nimport { t } from '../utils/i18n';\nimport { CronAPIClient, type CronJob, type CronJobExecution, type CronMetrics, type ChannelStatus, type ModelInfo, type SessionChatId } from '../utils/cron-api';\nimport '../components/ConfirmDialog';\nimport '../components/ModelSelector';\nimport type { ModelSelectEvent } from '../components/ModelSelector';\n\nexport interface CronManagerConfig {\n /** @deprecated No longer needed - always uses current origin */\n url?: string;\n token?: string;\n}\n\n@customElement('cron-manager')\nexport class CronManager extends LitElement {\n @property({ attribute: false }) config?: CronManagerConfig;\n\n @state() private _jobs: CronJob[] = [];\n @state() private _metrics: CronMetrics | null = null;\n @state() private _channels: ChannelStatus[] = [];\n @state() private _availableModels: ModelInfo[] = [];\n @state() private _defaultModel: string = '';\n @state() private _sessionChatIds: SessionChatId[] = [];\n @state() private _loading = false;\n @state() private _error: string | null = null;\n\n // Form state\n @state() private _formOpen = false;\n @state() private _formMode: 'add' | 'edit' = 'add';\n @state() private _formJobId: string | null = null;\n @state() private _formName = '';\n @state() private _formSchedule = '*/5 * * * *'; \n @state() private _formChannel = 'telegram';\n @state() private _formChatId = '';\n @state() private _formMessage = '';\n @state() private _formSessionTarget: 'main' | 'isolated' = 'main';\n @state() private _formModel = '';\n @state() private _formSubmitting = false;\n\n // Detail drawer state\n @state() private _detailOpen = false;\n @state() private _detailJob: CronJob | null = null;\n @state() private _detailHistory: CronJobExecution[] = [];\n @state() private _detailLoading = false;\n\n // Confirm dialog state\n @state() private _confirmOpen = false;\n @state() private _confirmTitle = '';\n @state() private _confirmMessage = '';\n @state() private _confirmJobId: string | null = null;\n @state() private _confirmAction: 'delete' | 'run' | null = null;\n\n private _api!: CronAPIClient;\n private _initialized = false;\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._tryInitialize();\n }\n\n override willUpdate(changedProperties: Map<string, unknown>): void {\n super.willUpdate(changedProperties);\n if (changedProperties.has('config')) {\n this._tryInitialize();\n }\n }\n\n private _tryInitialize(): void {\n if (this._initialized) {\n return;\n }\n const httpUrl = window.location.origin;\n this._api = new CronAPIClient(httpUrl, this.config?.token);\n this._initialized = true;\n this._loadJobs();\n this._loadMetrics();\n this._loadChannels();\n this._loadModels();\n this._loadSessionChatIds();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._api?.disconnect();\n }\n\n private async _loadJobs(): Promise<void> {\n if (this._loading) return;\n this._loading = true;\n this._error = null;\n\n try {\n this._jobs = await this._api.listJobs();\n } catch (err) {\n this._error = err instanceof Error ? (err.message || t('cron.failedToLoadJobs')) : t('cron.failedToLoadJobs');\n console.error('[CronManager] Load error:', err);\n } finally {\n this._loading = false;\n }\n }\n\n private async _loadMetrics(): Promise<void> {\n try {\n this._metrics = await this._api.getMetrics();\n } catch (err) {\n console.error('[CronManager] Metrics error:', err);\n }\n }\n\n private async _loadChannels(): Promise<void> {\n try {\n this._channels = await this._api.getChannels();\n } catch (err) {\n console.error('[CronManager] Channels error:', err);\n }\n }\n\n private async _loadModels(): Promise<void> {\n try {\n // Load available models from configured providers\n this._availableModels = await this._api.getModels();\n \n // Load config to get default model\n const config = await this._api.getConfig();\n this._defaultModel = config.model || '';\n \n // Set form default model\n this._formModel = this._defaultModel;\n \n console.log('[CronManager] Loaded models:', this._availableModels.length, 'default:', this._defaultModel);\n } catch (err) {\n console.error('[CronManager] Models error:', err);\n }\n }\n\n private async _loadSessionChatIds(): Promise<void> {\n try {\n const chatIds = await this._api.getSessionChatIds(this._formChannel);\n this._sessionChatIds = chatIds;\n console.log('[CronManager] Loaded session chatIds for channel', this._formChannel, ':', chatIds.length, chatIds);\n } catch (err) {\n console.error('[CronManager] Session chatIds error:', err);\n this._sessionChatIds = [];\n }\n }\n\n // ========== Form ==========\n\n private _openForm(job?: CronJob): void {\n this._formOpen = true;\n this._formMode = job ? 'edit' : 'add';\n this._formJobId = job?.id || null;\n \n // Refresh session chat IDs when opening form\n if (!job) {\n this._loadSessionChatIds();\n }\n \n if (job) {\n // Editing existing job - populate form\n this._formName = job.name || '';\n this._formSchedule = job.schedule;\n this._formMessage = job.message;\n this._formSessionTarget = job.sessionTarget || 'main';\n this._formModel = job.model || '';\n \n // Parse delivery info\n if (job.delivery) {\n this._formChannel = job.delivery.channel || 'telegram';\n this._formChatId = job.delivery.to || '';\n } else {\n // Try to parse from message format: \"channel:chat_id:message\"\n const parts = job.message.split(':');\n const knownChannels = ['telegram', 'whatsapp', 'cli', 'gateway'];\n if (parts.length >= 3 && knownChannels.includes(parts[0])) {\n this._formChannel = parts[0];\n this._formChatId = parts[1];\n this._formMessage = parts.slice(2).join(':');\n } else {\n this._formChannel = 'telegram';\n this._formChatId = '';\n }\n }\n } else {\n // Adding new job\n this._formName = '';\n this._formSchedule = '*/5 * * * *';\n this._formChannel = 'telegram';\n this._formChatId = '';\n this._formMessage = '';\n this._formSessionTarget = 'main';\n this._formModel = this._defaultModel || (this._availableModels.length > 0 ? this._availableModels[0].id : '');\n }\n }\n\n private _closeForm(): void {\n this._formOpen = false;\n this._formMode = 'add';\n this._formJobId = null;\n this._formName = '';\n this._formSchedule = '*/5 * * * *';\n this._formChannel = 'telegram';\n this._formChatId = '';\n this._formMessage = '';\n this._formSessionTarget = 'main';\n this._formModel = '';\n }\n\n private async _submitForm(): Promise<void> {\n if (!this._formSchedule || !this._formMessage) {\n this._error = t('cron.scheduleRequired');\n return;\n }\n\n if (!this._formChatId) {\n this._error = t('cron.chatIdRequired');\n return;\n }\n\n this._formSubmitting = true;\n this._error = null;\n\n try {\n // Build message (just the content, not prefixed with channel:chat_id)\n const message = this._formMessage;\n \n // Build delivery config\n const delivery = {\n mode: 'direct' as const,\n channel: this._formChannel,\n to: this._formChatId,\n };\n\n // Build payload based on session target\n const payload = this._formSessionTarget === 'isolated'\n ? { kind: 'agentTurn' as const, message, model: this._formModel }\n : { kind: 'systemEvent' as const, text: message };\n\n const jobData = {\n name: this._formName || undefined,\n schedule: this._formSchedule,\n message,\n sessionTarget: this._formSessionTarget,\n model: this._formSessionTarget === 'isolated' ? this._formModel : undefined,\n delivery,\n };\n\n if (this._formMode === 'edit' && this._formJobId) {\n // Update existing job\n await this._api.updateJob(this._formJobId, jobData);\n } else {\n // Add new job\n await this._api.addJob(this._formSchedule, message, jobData);\n }\n \n this._closeForm();\n await this._loadJobs();\n await this._loadMetrics();\n } catch (err) {\n this._error = err instanceof Error ? (err.message || t('cron.failedToJob', { mode: this._formMode })) : t('cron.failedToJob', { mode: this._formMode });\n } finally {\n this._formSubmitting = false;\n }\n }\n\n // ========== Detail Drawer ==========\n\n private async _openDetail(job: CronJob): Promise<void> {\n this._detailOpen = true;\n this._detailJob = job;\n this._detailLoading = true;\n\n try {\n const fullJob = await this._api.getJob(job.id);\n if (fullJob) {\n this._detailJob = fullJob;\n this._detailHistory = await this._api.getHistory(job.id, 20);\n }\n } catch (err) {\n console.error('[CronManager] Load detail error:', err);\n } finally {\n this._detailLoading = false;\n }\n }\n\n private _closeDetail(): void {\n this._detailOpen = false;\n this._detailJob = null;\n this._detailHistory = [];\n }\n\n // ========== Actions ==========\n\n private async _toggleJob(job: CronJob, enabled: boolean): Promise<void> {\n try {\n await this._api.toggleJob(job.id, enabled);\n await this._loadJobs();\n await this._loadMetrics();\n } catch (err) {\n this._error = err instanceof Error ? (err.message || t('cron.failedToToggleJob')) : t('cron.failedToToggleJob');\n }\n }\n\n private _showRunConfirm(job: CronJob): void {\n this._confirmOpen = true;\n this._confirmTitle = t('cron.runNow');\n this._confirmMessage = t('cron.confirmRun');\n this._confirmJobId = job.id;\n this._confirmAction = 'run';\n }\n\n private _showDeleteConfirm(job: CronJob): void {\n this._confirmOpen = true;\n this._confirmTitle = t('cron.delete');\n this._confirmMessage = t('cron.confirmDelete');\n this._confirmJobId = job.id;\n this._confirmAction = 'delete';\n }\n\n private _closeConfirm(): void {\n this._confirmOpen = false;\n this._confirmTitle = '';\n this._confirmMessage = '';\n this._confirmJobId = null;\n this._confirmAction = null;\n }\n\n private _handleConfirm(e: CustomEvent<{ confirmed: boolean }>): void {\n if (e.detail.confirmed) {\n this._executeConfirmAction();\n } else {\n this._closeConfirm();\n }\n }\n\n private async _executeConfirmAction(): Promise<void> {\n if (!this._confirmJobId || !this._confirmAction) {\n return;\n }\n\n const jobId = this._confirmJobId;\n const action = this._confirmAction; // Save before closing\n this._closeConfirm();\n \n try {\n if (action === 'run') {\n await this._api.runJob(jobId);\n await this._loadJobs();\n await this._loadMetrics();\n } else if (action === 'delete') {\n await this._api.removeJob(jobId);\n await this._loadJobs();\n await this._loadMetrics();\n }\n } catch (err) {\n this._error = err instanceof Error ? (err.message || t('cron.actionFailed')) : t('cron.actionFailed');\n }\n }\n\n // ========== Render ==========\n\n override render(): ReturnType<typeof html> {\n return html`\n <div class=\"cron-manager\">\n ${this._error ? html`<div class=\"error-banner\">${this._error}</div>` : ''}\n\n <!-- Header -->\n <div class=\"cron-manager__header\">\n <h1 class=\"page-title\">${getIcon('clock')} ${t('cron.title')}</h1>\n <div class=\"cron-manager__actions\">\n <button class=\"btn btn-secondary\" @click=${this._loadJobs} ?disabled=${this._loading}>\n ${getIcon('refresh')} ${t('logs.refresh')}\n </button>\n <button class=\"btn btn-primary\" @click=${() => this._openForm()}>\n ${getIcon('plus')} ${t('cron.addJob')}\n </button>\n </div>\n </div>\n\n <!-- Stats -->\n ${this._metrics ? html`\n <div class=\"cron-manager__stats\">\n <div class=\"stat-card\" style=\"text-align: center;\">\n <div class=\"stat-value\">${this._metrics.totalJobs}</div>\n <div class=\"stat-label\">${t('sessions.totalSessions')}</div>\n </div>\n <div class=\"stat-card\" style=\"text-align: center;\">\n <div class=\"stat-value\">${this._metrics.enabledJobs}</div>\n <div class=\"stat-label\">${t('cron.enabled')}</div>\n </div>\n <div class=\"stat-card\" style=\"text-align: center;\">\n <div class=\"stat-value\">${this._metrics.runningJobs}</div>\n <div class=\"stat-label\">${t('cron.running')}</div>\n </div>\n <div class=\"stat-card\" style=\"text-align: center;\">\n <div class=\"stat-value\" style=\"font-size: 0.875rem;\">\n ${this._metrics.nextScheduledJob \n ? this._formatNextRun(this._metrics.nextScheduledJob.runAt)\n : 'N/A'}\n </div>\n <div class=\"stat-label\">${t('cron.nextRun')}</div>\n </div>\n </div>\n ` : nothing}\n\n <!-- Job List -->\n <div class=\"session-list\">\n ${this._loading && this._jobs.length === 0 ? html`\n <div class=\"session-list__loading-overlay\">\n <div class=\"spinner\"></div>\n </div>\n ` : this._jobs.length === 0 ? html`\n <div class=\"session-list session-list--empty\">\n <div class=\"empty-state\">\n <div class=\"empty-state__icon\">${getIcon('clock')}</div>\n <div class=\"empty-state__title\">No cron jobs yet</div>\n <button class=\"btn btn-primary\" @click=${this._openForm}>Create your first job</button>\n </div>\n </div>\n ` : html`\n <div class=\"session-list__toolbar\">\n <div class=\"session-list__count\">${this._jobs.length} job${this._jobs.length !== 1 ? 's' : ''}</div>\n </div>\n <div class=\"session-list__content\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>${t('cron.name')}</th>\n <th>${t('cron.scheduleLabel')}</th>\n <th>${t('cron.nextRun')}</th>\n <th>${t('cron.status')}</th>\n <th>${t('cron.actions')}</th>\n </tr>\n </thead>\n <tbody>\n ${this._jobs.map(job => html`\n <tr>\n <td style=\"vertical-align: middle; text-align: center;\">\n <button class=\"btn btn-link\" @click=${() => this._openDetail(job)}>\n ${job.name || job.id}\n </button>\n </td>\n <td style=\"vertical-align: middle; text-align: center;\"><code>${job.schedule}</code></td>\n <td style=\"vertical-align: middle; text-align: center;\">${job.next_run ? this._formatNextRun(job.next_run) : '-'}</td>\n <td style=\"vertical-align: middle; text-align: center;\">\n <label class=\"toggle\">\n <input \n type=\"checkbox\" \n ?checked=${job.enabled}\n @change=${(e: Event) => this._toggleJob(job, (e.target as HTMLInputElement).checked)}\n />\n <span class=\"toggle__slider\"></span>\n </label>\n </td>\n <td style=\"vertical-align: middle; text-align: center;\">\n <div class=\"action-buttons\">\n <button class=\"btn btn-icon btn-secondary\" title=\"Edit\" @click=${() => this._openForm(job)}>\n ${getIcon('edit')}\n </button>\n <button class=\"btn btn-icon btn-secondary\" title=\"${t('cron.runNow')}\" @click=${() => this._showRunConfirm(job)}>\n ${getIcon('play')}\n </button>\n <button class=\"btn btn-icon btn-danger\" title=\"${t('cron.delete')}\" @click=${() => this._showDeleteConfirm(job)}>\n ${getIcon('trash')}\n </button>\n </div>\n </td>\n </tr>\n `)}\n </tbody>\n </table>\n </div>\n `}\n </div>\n </div>\n\n <!-- Add/Edit Job Form Modal -->\n ${this._formOpen ? html`\n <div class=\"modal-backdrop\" @click=${this._closeForm}>\n <div class=\"modal modal--form\" @click=${(e: Event) => e.stopPropagation()}>\n <div class=\"modal__header\">\n <h2 class=\"modal__title\">${this._formMode === 'edit' ? t('cron.editJob') : t('cron.addJob')}</h2>\n <button class=\"btn-icon\" @click=${this._closeForm}>${getIcon('x')}</button>\n </div>\n <div class=\"modal__content\">\n <div class=\"form-field\">\n <label class=\"form-field__label\">${t('cron.name')}</label>\n <input\n type=\"text\"\n class=\"form-field__input\"\n .value=${this._formName ?? ''}\n @input=${(e: Event) => this._formName = (e.target as HTMLInputElement).value}\n placeholder=\"${t('cron.namePlaceholder') ?? 'My scheduled task'}\"\n />\n </div>\n <div class=\"form-field\">\n <label class=\"form-field__label\">${t('cron.schedule')}</label>\n <div style=\"display: flex; gap: 0.5rem; align-items: center;\">\n <input\n type=\"text\"\n class=\"form-field__input\"\n style=\"flex: 2; min-width: 0;\"\n .value=${this._formSchedule ?? '*/5 * * * *'}\n @input=${(e: Event) => this._formSchedule = (e.target as HTMLInputElement).value}\n placeholder=\"*/5 * * * *\"\n />\n <select\n class=\"form-field__select\"\n style=\"flex: 1; min-width: 0;\"\n .value=${this._formSchedule ?? '*/5 * * * *'}\n @change=${(e: Event) => {\n const value = (e.target as HTMLSelectElement).value;\n if (value) {\n this._formSchedule = value;\n }\n }}\n >\n <option value=\"\">${t('cron.schedulePresets.custom')}</option>\n <option value=\"*/1 * * * *\">${t('cron.schedulePresets.everyMinute')}</option>\n <option value=\"*/5 * * * *\">${t('cron.schedulePresets.every5Minutes')}</option>\n <option value=\"*/10 * * * *\">${t('cron.schedulePresets.every10Minutes')}</option>\n <option value=\"*/15 * * * *\">${t('cron.schedulePresets.every15Minutes')}</option>\n <option value=\"*/30 * * * *\">${t('cron.schedulePresets.every30Minutes')}</option>\n <option value=\"0 * * * *\">${t('cron.schedulePresets.everyHour')}</option>\n <option value=\"0 */2 * * *\">${t('cron.schedulePresets.every2Hours')}</option>\n <option value=\"0 */4 * * *\">${t('cron.schedulePresets.every4Hours')}</option>\n <option value=\"0 */6 * * *\">${t('cron.schedulePresets.every6Hours')}</option>\n <option value=\"0 */12 * * *\">${t('cron.schedulePresets.every12Hours')}</option>\n <option value=\"0 0 * * *\">${t('cron.schedulePresets.everyDayMidnight')}</option>\n <option value=\"0 9 * * *\">${t('cron.schedulePresets.everyDay9AM')}</option>\n <option value=\"0 21 * * *\">${t('cron.schedulePresets.everyDay9PM')}</option>\n </select>\n </div>\n <p class=\"form-field__hint\">\n ${t('cron.scheduleHintPreset')}\n </p>\n </div>\n <div class=\"form-field\">\n <label class=\"form-field__label\">${t('cron.mode')}</label>\n <select\n class=\"form-field__select\"\n .value=${this._formSessionTarget ?? 'main'}\n @change=${(e: Event) => this._formSessionTarget = (e.target as HTMLSelectElement).value as 'main' | 'isolated'}\n >\n <option value=\"main\">${t('cron.modeDirectOption') || 'Direct (send message directly)'}</option>\n <option value=\"isolated\">${t('cron.modeAgentOption') || 'AI Agent (process with AI then send)'}</option>\n </select>\n <p class=\"form-field__hint\">\n ${this._formSessionTarget === 'main' \n ? t('cron.modeDirect')\n : t('cron.modeAgent')}\n </p>\n </div>\n ${this._formSessionTarget === 'isolated' ? html`\n <div class=\"form-field\">\n <model-selector\n .value=${this._formModel}\n .filter=${'configured'}\n .token=${this.config?.token}\n .label=${t('cron.model')}\n @change=${(e: CustomEvent<ModelSelectEvent>) => this._formModel = e.detail.modelId}\n ></model-selector>\n </div>\n ` : nothing}\n <div class=\"form-field\">\n <label class=\"form-field__label\">Channel</label>\n <select\n class=\"form-field__select\"\n .value=${this._formChannel ?? 'telegram'}\n @change=${(e: Event) => {\n this._formChannel = (e.target as HTMLSelectElement).value;\n // Reload chat IDs for selected channel\n this._loadSessionChatIds();\n // Clear chat ID when channel changes\n this._formChatId = '';\n }}\n >\n ${this._channels.map(ch => html`\n <option value=${ch.name} ?disabled=${!ch.enabled}>\n ${ch.name} ${!ch.enabled ? '(disabled)' : ''}\n </option>\n `)}\n </select>\n </div>\n <div class=\"form-field\">\n <div style=\"display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem;\">\n <label class=\"form-field__label\" style=\"margin: 0;\">Chat ID *</label>\n <button \n type=\"button\" \n class=\"btn btn-secondary btn-sm\" \n @click=${() => this._loadSessionChatIds()}\n title=\"Refresh chat list\"\n style=\"padding: 0.25rem 0.5rem; font-size: 0.75rem;\"\n >\n ${getIcon('refresh')} Refresh\n </button>\n </div>\n <div style=\"display: flex; gap: 0.5rem; align-items: center;\">\n <input\n type=\"text\"\n class=\"form-field__input\"\n style=\"flex: 2; min-width: 0;\"\n .value=${this._formChatId ?? ''}\n @input=${(e: Event) => this._formChatId = (e.target as HTMLInputElement).value}\n placeholder=\"e.g., 123456789\"\n />\n <select\n class=\"form-field__select\"\n style=\"flex: 1; min-width: 0;\"\n .value=${this._formChatId ?? ''}\n @change=${(e: Event) => {\n const value = (e.target as HTMLSelectElement).value;\n if (value) {\n this._formChatId = value;\n }\n }}\n >\n <option value=\"\">-- Select --</option>\n ${this._sessionChatIds.length > 0 ? this._sessionChatIds.map(item => html`\n <option value=${item.chatId}>\n ${item.channel}: ${item.chatId} (${this._formatLastActive(item.lastActive)})\n </option>\n `) : html`\n <option value=\"\" disabled>No recent chats</option>\n `}\n </select>\n </div>\n <p class=\"form-field__hint\">\n ${this._sessionChatIds.length > 0 \n ? t('cron.enterManuallyOrSelect')\n : t('cron.noRecentChats')}\n </p>\n </div>\n <div class=\"form-field\">\n <label class=\"form-field__label\">${t('cron.message')}</label>\n <textarea \n class=\"form-field__textarea\"\n .value=${this._formMessage ?? ''}\n @input=${(e: Event) => this._formMessage = (e.target as HTMLTextAreaElement).value}\n placeholder=\"${t('cron.messagePlaceholder') ?? 'What should the assistant do?'}\"\n rows=\"4\"\n ></textarea>\n </div>\n </div>\n <div class=\"modal__actions\">\n <button class=\"btn btn-secondary\" @click=${this._closeForm}>${t('common.cancel')}</button>\n <button \n class=\"btn btn-primary\" \n @click=${this._submitForm}\n ?disabled=${this._formSubmitting || !this._formSchedule || !this._formChatId || !this._formMessage}\n >\n ${this._formSubmitting ? t('common.loading') : (this._formMode === 'edit' ? t('cron.save') : t('cron.create'))}\n </button>\n </div>\n </div>\n </div>\n ` : nothing}\n\n <!-- Detail Drawer -->\n ${this._detailOpen ? html`\n <div class=\"drawer-backdrop\" @click=${this._closeDetail}>\n <div class=\"drawer drawer--open\" @click=${(e: Event) => e.stopPropagation()}>\n <div class=\"drawer-header\">\n <div class=\"drawer-header__info\">\n <div class=\"drawer-header__title\">${this._detailJob?.name || this._detailJob?.id}</div>\n </div>\n <button class=\"btn-icon\" @click=${this._closeDetail}>${getIcon('x')}</button>\n </div>\n <div class=\"drawer-content ${this._detailLoading ? 'drawer-content--loading' : ''}\">\n ${this._detailLoading ? html`\n <div class=\"spinner\"></div>\n ` : html`\n <div class=\"session-detail\">\n <div class=\"session-detail__row\">\n <span class=\"session-detail__label\">${t('cron.scheduleLabel')}</span>\n <code>${this._detailJob?.schedule}</code>\n </div>\n <div class=\"session-detail__row\">\n <span class=\"session-detail__label\">${t('cron.messageLabel')}</span>\n <span>${this._detailJob?.message}</span>\n </div>\n <div class=\"session-detail__row\">\n <span class=\"session-detail__label\">${t('cron.status')}</span>\n <span>${this._detailJob?.enabled ? t('cron.enabled') : t('cron.disabled')}</span>\n </div>\n <div class=\"session-detail__row\">\n <span class=\"session-detail__label\">${t('cron.nextRun')}</span>\n <span>${this._detailJob?.next_run ? this._formatNextRun(this._detailJob.next_run) : 'N/A'}</span>\n </div>\n </div>\n `}\n </div>\n </div>\n </div>\n ` : nothing}\n\n <!-- Confirm Dialog -->\n <confirm-dialog\n .open=${this._confirmOpen}\n .title=${this._confirmTitle}\n .message=${this._confirmMessage}\n .confirmText=${this._confirmAction === 'delete' ? t('cron.delete') : t('cron.runNow')}\n .cancelText=${t('common.cancel')}\n .type=${this._confirmAction === 'delete' ? 'danger' : 'warning'}\n @confirm=${this._handleConfirm}\n ></confirm-dialog>\n `;\n }\n\n // ========== Helpers ==========\n\n private _formatNextRun(date: Date | string): string {\n const d = typeof date === 'string' ? new Date(date) : date;\n const now = new Date();\n const diff = d.getTime() - now.getTime();\n \n if (diff < 0) return t('cron.timeLabels.overdue');\n if (diff < 60000) return t('cron.timeLabels.lessThanMinute');\n if (diff < 3600000) {\n const mins = Math.floor(diff / 60000);\n return t('cron.timeLabels.minutes', { count: mins });\n }\n if (diff < 86400000) {\n const hours = Math.floor(diff / 3600000);\n return t('cron.timeLabels.hours', { count: hours });\n }\n return d.toLocaleString();\n }\n\n private _formatLastActive(date: string): string {\n const d = new Date(date);\n const now = new Date();\n const diff = now.getTime() - d.getTime();\n \n if (diff < 0) return t('cron.lastActiveLabels.justNow');\n if (diff < 60000) return t('cron.lastActiveLabels.justNow');\n if (diff < 3600000) {\n const mins = Math.floor(diff / 60000);\n return t('cron.lastActiveLabels.minutesAgo', { count: mins });\n }\n if (diff < 86400000) {\n const hours = Math.floor(diff / 3600000);\n return t('cron.lastActiveLabels.hoursAgo', { count: hours });\n }\n if (diff < 604800000) {\n const days = Math.floor(diff / 86400000);\n return t('cron.lastActiveLabels.daysAgo', { count: days });\n }\n return d.toLocaleDateString();\n }\n\n private _formatTime(date: string): string {\n return new Date(date).toLocaleString();\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'cron-manager': CronManager;\n }\n}\n","// Log API - HTTP client for log management\n\nexport interface LogEntry {\n timestamp: string;\n level: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';\n message: string;\n module?: string;\n prefix?: string;\n service?: string;\n plugin?: string;\n requestId?: string;\n sessionId?: string;\n userId?: string;\n meta?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface LogQuery {\n level?: string[];\n from?: string;\n to?: string;\n q?: string;\n module?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface LogFile {\n name: string;\n size: number;\n modified: string;\n}\n\nexport interface LogStats {\n byLevel: Record<string, number>;\n}\n\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';\n\nexport const LOG_LEVELS: LogLevel[] = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];\n\nexport const LOG_LEVEL_COLORS: Record<LogLevel, string> = {\n trace: '#9ca3af',\n debug: '#6b7280',\n info: '#3b82f6',\n warn: '#f59e0b',\n error: '#ef4444',\n fatal: '#dc2626',\n};\n\nexport class LogAPIClient {\n private baseUrl: string;\n private token?: string;\n\n constructor(baseUrl: string, token?: string) {\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n this.token = token;\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (this.token) {\n headers['Authorization'] = `Bearer ${this.token}`;\n }\n\n const response = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: 'Request failed' }));\n throw new Error(error.error || `HTTP ${response.status}`);\n }\n\n return response.json();\n }\n\n // ========== Log API Methods ==========\n\n async queryLogs(query?: LogQuery): Promise<{ logs: LogEntry[]; count: number }> {\n const params = new URLSearchParams();\n if (query?.level?.length) params.set('level', query.level.join(','));\n if (query?.from) params.set('from', query.from);\n if (query?.to) params.set('to', query.to);\n if (query?.q) params.set('q', query.q);\n if (query?.module) params.set('module', query.module);\n if (query?.limit) params.set('limit', String(query.limit));\n if (query?.offset) params.set('offset', String(query.offset));\n\n const queryString = params.toString();\n const path = `/api/logs${queryString ? `?${queryString}` : ''}`;\n return await this.request<{ logs: LogEntry[]; count: number }>('GET', path);\n }\n\n async getLogFiles(): Promise<LogFile[]> {\n const result = await this.request<{ files: LogFile[] }>('GET', '/api/logs/files');\n return result.files || [];\n }\n\n async getLogStats(): Promise<LogStats> {\n return await this.request<LogStats>('GET', '/api/logs/stats');\n }\n\n async getLogLevels(): Promise<LogLevel[]> {\n const result = await this.request<{ levels: LogLevel[] }>('GET', '/api/logs/levels');\n return result.levels || [];\n }\n\n async getLogModules(): Promise<string[]> {\n const result = await this.request<{ modules: string[] }>('GET', '/api/logs/modules');\n return result.modules || [];\n }\n\n async getLogDir(): Promise<string> {\n const result = await this.request<{ dir: string }>('GET', '/api/logs/dir');\n return result.dir;\n }\n}\n","// Log Manager Page Component\n\nimport { html, LitElement, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { getIcon } from '../utils/icons';\nimport { t } from '../utils/i18n';\nimport {\n LogAPIClient,\n type LogEntry,\n type LogFile,\n type LogLevel,\n LOG_LEVELS,\n LOG_LEVEL_COLORS,\n} from '../utils/log-api';\n\nexport interface LogManagerConfig {\n /** @deprecated No longer needed - always uses current origin */\n url?: string;\n token?: string;\n}\n\n@customElement('log-manager')\nexport class LogManager extends LitElement {\n @property({ attribute: false }) config?: LogManagerConfig;\n\n @state() private _logs: LogEntry[] = [];\n @state() private _loading = false;\n @state() private _hasMore = false;\n @state() private _files: LogFile[] = [];\n @state() private _modules: string[] = [];\n @state() private _showFilesPanel = false;\n\n // Filters\n @state() private _selectedLevels: Set<LogLevel> = new Set();\n @state() private _searchQuery = '';\n @state() private _selectedModule = '';\n @state() private _dateFrom = '';\n @state() private _dateTo = '';\n @state() private _offset = 0;\n @state() private _error: string | null = null;\n\n // Detail view\n @state() private _selectedLog: LogEntry | null = null;\n @state() private _autoRefresh = false;\n @state() private _refreshInterval?: number;\n\n private _api!: LogAPIClient;\n private _limit = 50;\n private _initialized = false;\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._tryInitialize();\n }\n\n override willUpdate(changedProperties: Map<string, unknown>): void {\n super.willUpdate(changedProperties);\n if (changedProperties.has('config')) {\n this._tryInitialize();\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._stopAutoRefresh();\n }\n\n override firstUpdated(): void {\n // Ensure initialization happens even if config was set before connectedCallback\n this._tryInitialize();\n }\n\n private _tryInitialize(): void {\n if (this._initialized) {\n return;\n }\n const httpUrl = window.location.origin;\n this._api = new LogAPIClient(httpUrl, this.config?.token);\n this._initialized = true;\n this._loadLogs();\n this._loadFiles();\n this._loadModules();\n }\n\n private async _loadLogs(reset = false): Promise<void> {\n if (this._loading) return;\n\n this._loading = true;\n this._error = null;\n\n if (reset) {\n this._offset = 0;\n this._logs = [];\n }\n\n try {\n const query = {\n level: this._selectedLevels.size > 0 ? Array.from(this._selectedLevels) : undefined,\n from: this._dateFrom || undefined,\n to: this._dateTo || undefined,\n q: this._searchQuery || undefined,\n module: this._selectedModule || undefined,\n limit: this._limit,\n offset: this._offset,\n };\n\n const result = await this._api.queryLogs(query);\n\n if (reset) {\n this._logs = result.logs;\n } else {\n this._logs = [...this._logs, ...result.logs];\n }\n\n console.log('[LogManager] Total logs in state:', this._logs.length);\n this._hasMore = result.logs.length === this._limit;\n this._offset = this._offset + result.logs.length;\n } catch (err) {\n this._error = err instanceof Error ? err.message : 'Failed to load logs';\n console.error('[LogManager] Load error:', err);\n } finally {\n this._loading = false;\n }\n }\n\n private async _loadFiles(): Promise<void> {\n try {\n this._files = await this._api.getLogFiles();\n } catch (err) {\n console.error('[LogManager] Files error:', err);\n }\n }\n\n private async _loadModules(): Promise<void> {\n try {\n this._modules = await this._api.getLogModules();\n } catch (err) {\n console.error('[LogManager] Modules error:', err);\n }\n }\n\n private _toggleLevel(level: LogLevel): void {\n if (this._selectedLevels.has(level)) {\n this._selectedLevels.delete(level);\n } else {\n this._selectedLevels.add(level);\n }\n this._selectedLevels = new Set(this._selectedLevels);\n this._loadLogs(true);\n }\n\n private _handleSearch(e: InputEvent): void {\n const target = e.target as HTMLInputElement;\n this._searchQuery = target.value;\n this._debouncedSearch();\n }\n\n private _debouncedSearch = this._debounce(() => {\n this._loadLogs(true);\n }, 300);\n\n private _debounce(fn: () => void, ms: number): () => void {\n let timeout: ReturnType<typeof setTimeout>;\n return () => {\n clearTimeout(timeout);\n timeout = setTimeout(fn, ms);\n };\n }\n\n private _handleModuleChange(e: Event): void {\n const target = e.target as HTMLSelectElement;\n this._selectedModule = target.value;\n this._loadLogs(true);\n }\n\n private _handleDateFromChange(e: InputEvent): void {\n const target = e.target as HTMLInputElement;\n this._dateFrom = target.value;\n this._loadLogs(true);\n }\n\n private _handleDateToChange(e: InputEvent): void {\n const target = e.target as HTMLInputElement;\n this._dateTo = target.value;\n this._loadLogs(true);\n }\n\n private _clearFilters(): void {\n this._selectedLevels.clear();\n this._selectedLevels = new Set();\n this._searchQuery = '';\n this._selectedModule = '';\n this._dateFrom = '';\n this._dateTo = '';\n this._loadLogs(true);\n }\n\n private _selectLog(log: LogEntry): void {\n this._selectedLog = log;\n }\n\n private _closeDetail(): void {\n this._selectedLog = null;\n }\n\n private _toggleAutoRefresh(): void {\n this._autoRefresh = !this._autoRefresh;\n if (this._autoRefresh) {\n this._startAutoRefresh();\n } else {\n this._stopAutoRefresh();\n }\n }\n\n private _startAutoRefresh(): void {\n this._refreshInterval = window.setInterval(() => {\n this._loadLogs(true);\n }, 5000);\n }\n\n private _stopAutoRefresh(): void {\n if (this._refreshInterval) {\n clearInterval(this._refreshInterval);\n this._refreshInterval = undefined;\n }\n }\n\n private _handleLoadMore(): void {\n this._loadLogs();\n }\n\n private _formatTimestamp(timestamp: string): string {\n try {\n const date = new Date(timestamp);\n return date.toLocaleString([], {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n } catch {\n return timestamp;\n }\n }\n\n private _formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n }\n\n override render(): unknown {\n return html`\n <div class=\"log-manager\">\n ${this._renderHeader()}\n <div class=\"log-manager__main\">\n ${this._renderFilters()}\n ${this._renderLogTable()}\n ${this._renderFilesPanel()}\n </div>\n ${this._error ? html`<div class=\"error-banner\">${this._error}</div>` : ''}\n </div>\n\n ${this._selectedLog ? this._renderDetailDrawer() : ''}\n `;\n }\n\n private _renderHeader(): unknown {\n return html`\n <div class=\"log-manager__header\">\n <div class=\"log-manager__title\">\n <span class=\"title-icon\">${getIcon('fileText')}</span>\n <div class=\"title-text\">\n <h1>${t('logs.title')}</h1>\n <span class=\"title-subtitle\">System logs and diagnostics</span>\n </div>\n </div>\n <div class=\"log-manager__actions\">\n <button\n class=\"btn-icon\"\n @click=${this._toggleFilesPanel}\n title=\"Toggle log files\"\n >\n ${getIcon('folder')}\n ${this._files.length > 0 ? html`<span class=\"badge\">${this._files.length}</span>` : ''}\n </button>\n <button\n class=\"btn-icon ${this._autoRefresh ? 'btn-icon--active' : ''}\"\n @click=${this._toggleAutoRefresh}\n title=${this._autoRefresh ? t('logs.pause') : t('logs.autoRefresh')}\n >\n ${getIcon(this._autoRefresh ? 'pause' : 'play')}\n </button>\n <button\n class=\"btn-icon\"\n @click=${() => this._loadLogs(true)}\n title=${t('logs.refresh')}\n >\n ${getIcon('refreshCw')}\n </button>\n </div>\n </div>\n `;\n }\n\n private _renderFilters(): unknown {\n return html`\n <div class=\"log-manager__filters\">\n <div class=\"log-manager__filters-row\">\n <div class=\"filter-group\">\n <label class=\"filter-label\">${t('logs.level')}</label>\n <div class=\"level-filters\">\n ${LOG_LEVELS.map((level) => html`\n <button\n class=\"level-badge ${this._selectedLevels.has(level) ? 'level-badge--active' : ''}\"\n style=\"--level-color: ${LOG_LEVEL_COLORS[level]}\"\n @click=${() => this._toggleLevel(level)}\n >\n ${level}\n </button>\n `)}\n </div>\n </div>\n\n <div class=\"filter-group\">\n <label class=\"filter-label\">${t('logs.search')}</label>\n <div class=\"search-box\">\n ${getIcon('search')}\n <input\n type=\"text\"\n placeholder=\"${t('logs.searchPlaceholder')}\"\n .value=${this._searchQuery}\n @input=${this._handleSearch}\n />\n </div>\n </div>\n </div>\n\n <div class=\"filter-row\">\n <div class=\"filter-group\">\n <label class=\"filter-label\">Module</label>\n <select @change=${this._handleModuleChange}>\n <option value=\"\">All modules</option>\n ${this._modules.map((m) => html`<option value=\"${m}\">${m}</option>`)}\n </select>\n </div>\n\n <div class=\"filter-group\">\n <label class=\"filter-label\">From</label>\n <input\n type=\"datetime-local\"\n .value=${this._dateFrom}\n @input=${this._handleDateFromChange}\n />\n </div>\n\n <div class=\"filter-group\">\n <label class=\"filter-label\">To</label>\n <input\n type=\"datetime-local\"\n .value=${this._dateTo}\n @input=${this._handleDateToChange}\n />\n </div>\n\n <button class=\"btn btn-ghost\" @click=${this._clearFilters}>\n ${getIcon('x')}\n Clear\n </button>\n </div>\n </div>\n `;\n }\n\n\n\n private _renderLogTable(): unknown {\n if (this._loading && this._logs.length === 0) {\n return this._renderLoading();\n }\n\n if (this._logs.length === 0) {\n return html`\n <div class=\"log-manager__empty\">\n <div class=\"empty-state\">\n <div class=\"empty-state__icon\">${getIcon('fileText')}</div>\n <div class=\"empty-state__title\">${t('logs.noLogs')}</div>\n <div class=\"empty-state__description\">\n ${t('logs.noLogsDescription')}\n </div>\n </div>\n </div>\n `;\n }\n\n return html`\n <div class=\"log-table-container\">\n <table class=\"log-table\">\n <thead>\n <tr>\n <th>${t('logs.time')}</th>\n <th>${t('logs.level')}</th>\n <th>${t('logs.module')}</th>\n <th>${t('logs.message')}</th>\n </tr>\n </thead>\n <tbody>\n ${this._logs.length === 0 ? html`\n <tr>\n <td colspan=\"4\" style=\"padding: 2rem; text-align: center; color: var(--text-muted);\">\n No logs to display\n </td>\n </tr>\n ` : this._logs.map((log) => html`\n <tr class=\"log-row log-row--${log.level || 'info'}\" @click=${() => this._selectLog(log)}>\n <td class=\"log-cell log-cell--time\">${this._formatTimestamp(log.timestamp)}</td>\n <td class=\"log-cell log-cell--level\">\n <span\n class=\"level-badge level-badge--small\"\n style=\"--level-color: ${LOG_LEVEL_COLORS[log.level as LogLevel] || LOG_LEVEL_COLORS.info}\"\n >\n ${log.level || 'info'}\n </span>\n </td>\n <td class=\"log-cell log-cell--module\">${log.module || log.prefix || log.service || '-'}</td>\n <td class=\"log-cell log-cell--message\">${log.message || JSON.stringify(log)}</td>\n </tr>\n `)}\n </tbody>\n </table>\n\n ${this._hasMore ? html`\n <div class=\"log-table__load-more\">\n <button class=\"btn btn-secondary\" @click=${this._handleLoadMore} ?disabled=${this._loading}>\n ${this._loading ? html`<span class=\"spinner\"></span>` : getIcon('chevronDown')}\n Load More\n </button>\n </div>\n ` : ''}\n </div>\n `;\n }\n\n private _toggleFilesPanel(): void {\n this._showFilesPanel = !this._showFilesPanel;\n }\n\n private _renderFilesPanel(): unknown {\n return html`\n ${this._showFilesPanel ? html`\n <div class=\"drawer-overlay\" @click=${this._toggleFilesPanel}></div>\n ` : ''}\n <div class=\"files-panel ${this._showFilesPanel ? 'files-panel--open' : ''}\">\n <div class=\"files-panel__header\">\n <span class=\"files-panel__title\">\n ${getIcon('folder')}\n Log Files\n </span>\n <button class=\"btn btn-icon\" @click=${this._toggleFilesPanel}>\n ${getIcon('x')}\n </button>\n </div>\n <div class=\"files-panel__content\">\n ${this._files.length === 0 ? html`\n <div class=\"files-panel__empty\">No log files found</div>\n ` : html`\n <div class=\"file-list\">\n ${this._files.map((file) => html`\n <div class=\"file-item\">\n <span class=\"file-name\">${getIcon('file')}${file.name}</span>\n <span class=\"file-meta\">\n <span class=\"file-size\">${this._formatFileSize(file.size)}</span>\n <span class=\"file-time\">${this._formatTimestamp(file.modified)}</span>\n </span>\n </div>\n `)}\n </div>\n `}\n </div>\n </div>\n `;\n }\n\n private _renderDetailDrawer(): unknown {\n if (!this._selectedLog) return '';\n\n const log = this._selectedLog;\n\n return html`\n <div class=\"drawer-overlay\" @click=${this._closeDetail}></div>\n <div class=\"drawer drawer--right\">\n <div class=\"drawer-header\">\n <h3 class=\"drawer-header__title\">${t('logs.details')}</h3>\n <button class=\"btn btn-icon\" @click=${this._closeDetail}>${getIcon('x')}</button>\n </div>\n <div class=\"drawer__content\">\n <div class=\"log-detail\">\n <div class=\"log-detail__field\">\n <label>${t('logs.time')}</label>\n <code>${log.timestamp}</code>\n </div>\n <div class=\"log-detail__field\">\n <label>${t('logs.level')}</label>\n <span\n class=\"level-badge\"\n style=\"--level-color: ${LOG_LEVEL_COLORS[log.level]}\"\n >\n ${log.level}\n </span>\n </div>\n <div class=\"log-detail__field\">\n <label>${t('logs.module')}</label>\n <code>${log.module}</code>\n </div>\n <div class=\"log-detail__field\">\n <label>${t('logs.message')}</label>\n <pre class=\"log-detail__message\">${log.message}</pre>\n </div>\n ${log.meta ? html`\n <div class=\"log-detail__field\">\n <label>Metadata</label>\n <pre class=\"log-detail__meta\">${JSON.stringify(log.meta, null, 2)}</pre>\n </div>\n ` : ''}\n </div>\n </div>\n </div>\n `;\n }\n\n private _renderLoading(): unknown {\n return html`\n <div class=\"log-manager__loading\">\n <div class=\"skeleton-table\">\n ${Array.from({ length: 10 }).map(() => html`\n <div class=\"skeleton-row\">\n <div class=\"skeleton skeleton--time\"></div>\n <div class=\"skeleton skeleton--level\"></div>\n <div class=\"skeleton skeleton--module\"></div>\n <div class=\"skeleton skeleton--message\"></div>\n </div>\n `)}\n </div>\n </div>\n `;\n }\n}\n\nexport default LogManager;\n","/**\n * OAuth API client - Async flow support\n */\n\nexport interface OAuthProvider {\n id: string;\n name: string;\n usesCallbackServer?: boolean;\n}\n\nexport interface OAuthStatus {\n configured: boolean;\n expires?: number;\n}\n\nexport interface OAuthSessionStatus {\n sessionId: string;\n provider: string;\n status: 'pending' | 'waiting_auth' | 'waiting_code' | 'completed' | 'failed' | 'cancelled';\n authUrl?: string;\n instructions?: string;\n deviceCode?: string;\n verificationUri?: string;\n message?: string;\n error?: string;\n expiresAt: number;\n}\n\nexport interface OAuthStartResult {\n sessionId: string;\n provider: string;\n status: string;\n}\n\n/**\n * Get list of available OAuth providers\n */\nexport async function fetchOAuthProviders(token?: string): Promise<OAuthProvider[]> {\n const response = await fetch(`${window.location.origin}/api/auth/oauth`, {\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch OAuth providers: ${response.status}`);\n }\n\n const data = await response.json();\n return data.payload.providers;\n}\n\n/**\n * Check OAuth status for a provider\n */\nexport async function fetchOAuthStatus(provider: string, token?: string): Promise<OAuthStatus> {\n const response = await fetch(`${window.location.origin}/api/auth/oauth/${provider}`, {\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch OAuth status: ${response.status}`);\n }\n\n const data = await response.json();\n return data.payload;\n}\n\n/**\n * Start async OAuth login flow for a provider\n * Returns immediately with session ID\n */\nexport async function startAsyncOAuthLogin(provider: string, token?: string): Promise<OAuthStartResult> {\n const response = await fetch(`${window.location.origin}/api/auth/oauth-async/start`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n },\n body: JSON.stringify({ provider }),\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new Error(error.error || `OAuth login failed: ${response.status}`);\n }\n\n const data = await response.json();\n return data.payload;\n}\n\n/**\n * Poll OAuth session status\n */\nexport async function fetchOAuthSessionStatus(sessionId: string, token?: string): Promise<OAuthSessionStatus> {\n const response = await fetch(`${window.location.origin}/api/auth/oauth-async/${sessionId}/status`, {\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch OAuth session status: ${response.status}`);\n }\n\n const data = await response.json();\n return data.payload;\n}\n\n/**\n * Submit manual authorization code\n */\nexport async function submitOAuthCode(sessionId: string, code: string, token?: string): Promise<void> {\n const response = await fetch(`${window.location.origin}/api/auth/oauth-async/${sessionId}/code`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n },\n body: JSON.stringify({ code }),\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new Error(error.error || `Failed to submit code: ${response.status}`);\n }\n}\n\n/**\n * Cancel OAuth flow\n */\nexport async function cancelOAuth(sessionId: string, token?: string): Promise<void> {\n const response = await fetch(`${window.location.origin}/api/auth/oauth-async/${sessionId}/cancel`, {\n method: 'POST',\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw new Error(`Failed to cancel OAuth: ${response.status}`);\n }\n}\n\n/**\n * Clean up OAuth session\n */\nexport async function cleanupOAuthSession(sessionId: string, token?: string): Promise<void> {\n const response = await fetch(`${window.location.origin}/api/auth/oauth-async/${sessionId}`, {\n method: 'DELETE',\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw new Error(`Failed to cleanup session: ${response.status}`);\n }\n}\n\n/**\n * Revoke OAuth credentials for a provider\n */\nexport async function revokeOAuth(provider: string, token?: string): Promise<void> {\n const response = await fetch(`${window.location.origin}/api/auth/oauth/${provider}`, {\n method: 'DELETE',\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw new Error(`Failed to revoke OAuth: ${response.status}`);\n }\n}\n","/**\n * Provider config component with API key input and OAuth login support.\n */\n\nimport { html, LitElement, css } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { getIcon } from '../utils/icons.js';\nimport { \n startAsyncOAuthLogin, \n fetchOAuthSessionStatus, \n submitOAuthCode, \n cancelOAuth,\n cleanupOAuthSession,\n revokeOAuth \n} from '../utils/oauth-api.js';\n\nexport interface ProviderConfigChangeEvent {\n provider: string;\n apiKey: string;\n}\n\nexport interface ProviderOAuthEvent {\n provider: string;\n success: boolean;\n message?: string;\n error?: string;\n}\n\n@customElement('provider-config')\nexport class ProviderConfig extends LitElement {\n @property({ type: String }) provider!: string;\n @property({ type: String }) apiKey: string = '';\n @property({ type: Boolean }) configured: boolean = false;\n @property({ type: Boolean }) supportsOAuth: boolean = false;\n @property({ type: String }) displayName: string = '';\n @property({ type: String }) category: string = 'common';\n @property({ type: String }) token?: string;\n \n @state() private _showKey: boolean = false;\n @state() private _copied: boolean = false;\n @state() private _loading: boolean = false;\n @state() private _localValue: string = '';\n @state() private _oauthStatus?: 'idle' | 'waiting' | 'waiting_code' | 'success' | 'error';\n @state() private _oauthMessage?: string;\n @state() private _sessionId?: string;\n @state() private _authUrl?: string;\n @state() private _pollingInterval?: number;\n \n static styles = css`\n :host { display: block; }\n\n .provider-item {\n background: var(--bg-secondary, #f5f5f4);\n border: 1px solid var(--border-color, #e7e5e4);\n border-radius: var(--radius-md, 0.5rem);\n padding: 1rem;\n margin-bottom: 0.75rem;\n transition: all var(--transition-fast, 150ms) ease;\n }\n\n .provider-item:hover { border-color: var(--accent-primary, #4f46e5); }\n .provider-item.configured { border-left: 3px solid var(--accent-success, #059669); }\n\n .provider-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 0.75rem;\n }\n\n .provider-name {\n font-weight: 600;\n font-size: 0.875rem;\n color: var(--text-primary, #1c1917);\n }\n\n .provider-category {\n font-size: 0.6875rem;\n padding: 0.125rem 0.5rem;\n border-radius: var(--radius-sm, 0.375rem);\n background: var(--text-muted, #a8a29e);\n color: white;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .provider-category.oauth { background: #f59e0b; }\n .provider-category.enterprise { background: #8b5cf6; }\n .provider-category.specialty { background: #06b6d4; }\n\n .badge {\n font-size: 0.75rem;\n padding: 0.125rem 0.5rem;\n border-radius: var(--radius-sm, 0.375rem);\n background: var(--bg-tertiary, #e7e5e4);\n color: var(--text-secondary, #57534e);\n }\n\n .badge.success {\n background: var(--accent-success-light, #d1fae5);\n color: var(--accent-success, #059669);\n }\n\n .provider-input {\n display: flex;\n gap: 0.5rem;\n align-items: stretch;\n }\n\n .input-wrapper {\n flex: 1;\n position: relative;\n display: flex;\n align-items: center;\n }\n\n .api-key-input {\n width: 100%;\n height: 100%;\n padding: 0.5rem 0.75rem;\n padding-right: 4.5rem;\n border: 1px solid var(--border-color, #e7e5e4);\n border-radius: var(--radius-md, 0.5rem);\n font-size: 0.8125rem;\n font-family: var(--font-mono, monospace);\n background: var(--bg-primary, #fafaf9);\n color: var(--text-primary, #1c1917);\n transition: all var(--transition-fast, 150ms);\n box-sizing: border-box;\n }\n\n .api-key-input:focus {\n outline: none;\n border-color: var(--accent-primary, #4f46e5);\n box-shadow: 0 0 0 2px var(--accent-primary-light, #e0e7ff);\n }\n\n .input-actions {\n position: absolute;\n right: 0.25rem;\n display: flex;\n gap: 0.125rem;\n align-items: center;\n }\n\n .btn-icon {\n padding: 0.375rem;\n border: none;\n background: transparent;\n cursor: pointer;\n border-radius: var(--radius-sm, 0.375rem);\n color: var(--text-muted, #a8a29e);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--transition-fast, 150ms);\n flex-shrink: 0;\n }\n\n .btn-icon:hover {\n background: var(--bg-secondary, #f5f5f4);\n color: var(--text-primary, #1c1917);\n }\n\n .btn-icon svg {\n width: 16px;\n height: 16px;\n }\n\n .btn-oauth {\n padding: 0.5rem 1rem;\n border: 1px solid var(--accent-primary, #4f46e5);\n background: transparent;\n color: var(--accent-primary, #4f46e5);\n border-radius: var(--radius-md, 0.5rem);\n font-size: 0.8125rem;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 0.375rem;\n white-space: nowrap;\n transition: all var(--transition-fast, 150ms);\n }\n\n .btn-oauth:hover {\n background: var(--accent-primary, #4f46e5);\n color: white;\n }\n\n .btn-oauth:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .help-text {\n margin-top: 0.5rem;\n font-size: 0.75rem;\n color: var(--text-secondary, #57534e);\n display: flex;\n align-items: center;\n gap: 0.375rem;\n white-space: pre-line;\n }\n\n .help-text.error-text {\n color: var(--accent-error, #dc2626);\n background: var(--accent-error-light, #fee2e2);\n padding: 0.5rem;\n border-radius: var(--radius-md, 0.5rem);\n }\n\n .spinner {\n width: 14px;\n height: 14px;\n border: 2px solid var(--border-color, #e7e5e4);\n border-top-color: var(--accent-primary, #4f46e5);\n border-radius: 50%;\n animation: spin 1s linear infinite;\n }\n\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n\n .oauth-actions {\n display: flex;\n gap: 0.5rem;\n margin-top: 0.75rem;\n }\n\n .btn {\n padding: 0.5rem 1rem;\n border-radius: var(--radius-md, 0.5rem);\n font-size: 0.8125rem;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 0.375rem;\n transition: all var(--transition-fast, 150ms);\n }\n\n .btn-primary {\n background: var(--accent-primary, #4f46e5);\n color: white;\n border: none;\n }\n\n .btn-primary:hover {\n background: var(--accent-primary-dark, #4338ca);\n }\n\n .btn-secondary {\n background: transparent;\n border: 1px solid var(--border-color, #e7e5e4);\n color: var(--text-secondary, #57534e);\n }\n\n .btn-secondary:hover {\n background: var(--bg-secondary, #f5f5f4);\n }\n\n .code-input {\n margin-top: 0.75rem;\n display: flex;\n gap: 0.5rem;\n }\n\n .code-input input {\n flex: 1;\n padding: 0.5rem 0.75rem;\n border: 1px solid var(--border-color, #e7e5e4);\n border-radius: var(--radius-md, 0.5rem);\n font-size: 0.8125rem;\n }\n `;\n \n disconnectedCallback() {\n super.disconnectedCallback();\n this._stopPolling();\n if (this._sessionId) {\n cleanupOAuthSession(this._sessionId, this.token).catch(() => {});\n }\n }\n \n private _onApiKeyChange(e: Event) {\n const target = e.target as HTMLInputElement;\n this.dispatchEvent(new CustomEvent<ProviderConfigChangeEvent>('change', {\n detail: { provider: this.provider, apiKey: target.value },\n bubbles: true,\n composed: true,\n }));\n }\n \n private async _onOAuthClick() {\n this._loading = true;\n this._oauthStatus = 'waiting';\n this._oauthMessage = 'Starting OAuth login...';\n this._sessionId = undefined;\n \n try {\n // Start async OAuth flow\n const result = await startAsyncOAuthLogin(this.provider, this.token);\n this._sessionId = result.sessionId;\n \n // Start polling for status\n this._startPolling();\n } catch (err) {\n this._oauthStatus = 'error';\n this._oauthMessage = err instanceof Error ? err.message : 'OAuth login failed';\n this._loading = false;\n \n this.dispatchEvent(new CustomEvent<ProviderOAuthEvent>('oauth', {\n detail: { provider: this.provider, success: false, error: this._oauthMessage },\n bubbles: true,\n composed: true,\n }));\n }\n }\n\n private _startPolling() {\n this._pollingInterval = window.setInterval(async () => {\n if (!this._sessionId) return;\n\n try {\n const status = await fetchOAuthSessionStatus(this._sessionId, this.token);\n \n this._oauthMessage = status.message;\n this._authUrl = status.authUrl;\n \n if (status.status === 'waiting_auth' || status.status === 'waiting_code') {\n this._oauthStatus = status.status === 'waiting_code' ? 'waiting_code' : 'waiting';\n \n // Open auth URL if available\n if (status.authUrl && !this._authUrl) {\n window.open(status.authUrl, '_blank');\n }\n } else if (status.status === 'completed') {\n this._stopPolling();\n this._oauthStatus = 'success';\n this._loading = false;\n \n this.dispatchEvent(new CustomEvent<ProviderOAuthEvent>('oauth', {\n detail: { provider: this.provider, success: true, message: status.message },\n bubbles: true,\n composed: true,\n }));\n \n // Reload page after short delay\n setTimeout(() => {\n window.location.reload();\n }, 1500);\n } else if (status.status === 'failed' || status.status === 'cancelled') {\n this._stopPolling();\n this._oauthStatus = 'error';\n this._loading = false;\n this._oauthMessage = status.error || status.message || 'OAuth flow failed';\n \n this.dispatchEvent(new CustomEvent<ProviderOAuthEvent>('oauth', {\n detail: { provider: this.provider, success: false, error: this._oauthMessage },\n bubbles: true,\n composed: true,\n }));\n }\n } catch (err) {\n console.error('Failed to poll OAuth status:', err);\n }\n }, 1000); // Poll every second\n }\n\n private _stopPolling() {\n if (this._pollingInterval) {\n clearInterval(this._pollingInterval);\n this._pollingInterval = undefined;\n }\n }\n\n private async _onSubmitCode(code: string) {\n if (!this._sessionId || !code) return;\n\n try {\n await submitOAuthCode(this._sessionId, code, this.token);\n this._oauthMessage = 'Processing authorization code...';\n } catch (err) {\n this._oauthStatus = 'error';\n this._oauthMessage = err instanceof Error ? err.message : 'Failed to submit code';\n }\n }\n\n private async _onCancelOAuth() {\n if (!this._sessionId) return;\n\n try {\n await cancelOAuth(this._sessionId, this.token);\n this._stopPolling();\n this._oauthStatus = 'idle';\n this._loading = false;\n this._oauthMessage = 'OAuth cancelled';\n this._sessionId = undefined;\n } catch (err) {\n console.error('Failed to cancel OAuth:', err);\n }\n }\n \n private _onRevokeOAuth() {\n if (confirm(`Revoke OAuth credentials for ${this.displayName}?`)) {\n revokeOAuth(this.provider, this.token).then(() => {\n window.location.reload();\n }).catch(err => {\n alert(`Failed to revoke: ${err instanceof Error ? err.message : 'Unknown error'}`);\n });\n }\n }\n \n private async _copyToClipboard() {\n if (!this.apiKey) return;\n \n try {\n await navigator.clipboard.writeText(this.apiKey);\n this._copied = true;\n setTimeout(() => {\n this._copied = false;\n }, 2000);\n } catch (err) {\n console.error('Failed to copy:', err);\n }\n }\n \n render() {\n const categoryClass = this.category.toLowerCase();\n const isMasked = this.apiKey === '••••••••••••';\n const inputValue = isMasked && !this._showKey ? '' : this.apiKey;\n const isOAuthConfigured = this.configured && !isMasked;\n \n return html`\n <div class=\"provider-item ${this.configured ? 'configured' : ''}\">\n <div class=\"provider-header\">\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <span class=\"provider-name\">${this.displayName || this.provider}</span>\n <span class=\"provider-category ${categoryClass}\">${this.category}</span>\n </div>\n ${this.configured \n ? html`<span class=\"badge success\">${getIcon('check')} Configured</span>` \n : html`<span class=\"badge\">Not configured</span>`\n }\n </div>\n \n <div class=\"provider-input\">\n <div class=\"input-wrapper\">\n <input\n class=\"api-key-input\"\n type=\"${this._showKey ? 'text' : 'password'}\"\n .value=${inputValue}\n placeholder=\"${isMasked ? 'Configured via environment variable' : (this.configured ? 'Configured (leave empty to keep)' : 'sk-...')}\"\n @change=${this._onApiKeyChange}\n ?disabled=${this._loading}\n />\n <div class=\"input-actions\">\n ${this.apiKey && !isMasked ? html`\n <button \n class=\"btn-icon\" \n @click=${this._copyToClipboard}\n title=\"${this._copied ? 'Copied!' : 'Copy API Key'}\"\n >\n ${getIcon(this._copied ? 'check' : 'copy')}\n </button>\n ` : ''}\n <button \n class=\"btn-icon\" \n @click=${() => this._showKey = !this._showKey}\n title=\"${this._showKey ? 'Hide' : 'Show'} API Key\"\n ?disabled=${isMasked}\n >\n ${getIcon(this._showKey ? 'eyeOff' : 'eye')}\n </button>\n </div>\n </div>\n \n ${this.supportsOAuth ? html`\n ${isOAuthConfigured\n ? html`\n <button \n class=\"btn-oauth\" \n @click=${this._onRevokeOAuth}\n ?disabled=${this._loading}\n style=\"border-color: var(--accent-error, #dc2626); color: var(--accent-error, #dc2626);\"\n >\n ${getIcon('logOut')} Revoke\n </button>\n `\n : html`\n <button \n class=\"btn-oauth\" \n @click=${this._onOAuthClick}\n ?disabled=${this._loading}\n >\n ${this._loading \n ? html`<span class=\"spinner\"></span> Processing...` \n : html`${getIcon('externalLink')} OAuth Login`\n }\n </button>\n `\n }\n ` : ''}\n </div>\n\n ${this._oauthMessage ? html`\n <div class=\"help-text ${this._oauthStatus === 'error' ? 'error-text' : ''}\">\n ${this._oauthStatus === 'success' ? getIcon('check') : (this._oauthStatus === 'error' ? getIcon('alertCircle') : getIcon('info'))}\n ${this._oauthMessage}\n </div>\n ` : ''}\n\n ${this._oauthStatus === 'waiting' || this._oauthStatus === 'waiting_code' ? html`\n <div class=\"oauth-actions\">\n ${this._authUrl ? html`\n <a \n class=\"btn btn-primary\" \n href=\"${this._authUrl}\" \n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n ${getIcon('externalLink')} Open Authorization Page\n </a>\n ` : ''}\n <button \n class=\"btn btn-secondary\" \n @click=${this._onCancelOAuth}\n >\n ${getIcon('x')} Cancel\n </button>\n </div>\n ` : ''}\n\n ${this._oauthStatus === 'waiting_code' ? html`\n <div class=\"code-input\">\n <input \n type=\"text\" \n placeholder=\"Paste redirect URL or authorization code...\"\n @keydown=${(e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n const input = e.target as HTMLInputElement;\n this._onSubmitCode(input.value);\n input.value = '';\n }\n }}\n />\n <button \n class=\"btn btn-primary\"\n @click=${() => {\n const input = this.shadowRoot?.querySelector('.code-input input') as HTMLInputElement;\n if (input?.value) {\n this._onSubmitCode(input.value);\n input.value = '';\n }\n }}\n >\n Submit\n </button>\n </div>\n ` : ''}\n \n ${isMasked ? html`\n <div class=\"help-text\">\n ${getIcon('info')} API key is configured via environment variable and cannot be displayed.\n Enter a new key above to override, or leave empty to keep the current configuration.\n </div>\n ` : ''}\n ${this.supportsOAuth && !isMasked && !isOAuthConfigured ? html`\n <div class=\"help-text\">\n This provider supports OAuth login. Click \"OAuth Login\" to authenticate via browser, \n or enter an API key manually above.\n </div>\n ` : ''}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'provider-config': ProviderConfig;\n }\n}\n","/**\n * Provider list component - categorized collapsible list.\n */\n\nimport { html, LitElement, css } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { getIcon } from '../utils/icons.js';\nimport './ProviderConfig.js';\n\nexport interface ProviderInfo {\n id: string;\n name: string;\n category: 'common' | 'specialty' | 'enterprise' | 'oauth';\n supportsOAuth: boolean;\n configured: boolean;\n apiKey?: string;\n}\n\nexport interface ProviderListChangeEvent {\n provider: string;\n apiKey: string;\n}\n\nexport interface ProviderListOAuthEvent {\n provider: string;\n}\n\n@customElement('provider-list')\nexport class ProviderList extends LitElement {\n @property({ type: Array }) providers: ProviderInfo[] = [];\n @property({ type: String }) token?: string;\n @property({ type: Boolean }) loading: boolean = false;\n\n @state() private _expandedCategories: Set<string> = new Set(['common']);\n\n static styles = css`\n :host { display: block; }\n\n .provider-list {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n }\n\n .category {\n border: 1px solid var(--border-color, #e7e5e4);\n border-radius: var(--radius-md, 0.5rem);\n overflow: hidden;\n background: var(--bg-primary, #fafaf9);\n }\n\n .category-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n background: var(--bg-secondary, #f5f5f4);\n cursor: pointer;\n user-select: none;\n transition: background var(--transition-fast, 150ms) ease;\n }\n\n .category-header:hover { background: var(--bg-tertiary, #e7e5e4); }\n\n .category-title {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-weight: 600;\n font-size: 0.875rem;\n color: var(--text-primary, #1c1917);\n }\n\n .category-badge {\n font-size: 0.6875rem;\n padding: 0.125rem 0.5rem;\n border-radius: var(--radius-full, 9999px);\n background: var(--text-muted, #a8a29e);\n color: white;\n font-weight: 500;\n }\n\n .category-badge.common { background: var(--accent-success, #059669); }\n .category-badge.specialty { background: var(--accent-info, #0891b2); }\n .category-badge.enterprise { background: #8b5cf6; }\n .category-badge.oauth { background: var(--accent-warning, #d97706); }\n\n .category-content {\n padding: 1rem;\n display: none;\n }\n\n .category-content.expanded { display: block; }\n\n .empty-state {\n padding: 1.5rem;\n text-align: center;\n color: var(--text-secondary, #57534e);\n }\n\n .loading-state {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 1.5rem;\n color: var(--text-secondary, #57534e);\n }\n\n .spinner {\n width: 16px;\n height: 16px;\n border: 2px solid var(--border-color, #e7e5e4);\n border-top-color: var(--accent-primary, #4f46e5);\n border-radius: 50%;\n animation: spin 1s linear infinite;\n }\n\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n\n .configured-count {\n font-size: 0.75rem;\n color: var(--text-secondary, #57534e);\n margin-left: 0.5rem;\n font-weight: 500;\n }\n `;\n\n private _toggleCategory(category: string) {\n if (this._expandedCategories.has(category)) {\n this._expandedCategories.delete(category);\n } else {\n this._expandedCategories.add(category);\n }\n this.requestUpdate();\n }\n\n private _onProviderChange(e: CustomEvent) {\n const { provider, apiKey } = e.detail;\n this.dispatchEvent(new CustomEvent<ProviderListChangeEvent>('change', {\n detail: { provider, apiKey },\n bubbles: true,\n composed: true,\n }));\n }\n\n private _onProviderOAuth(e: CustomEvent) {\n const { provider } = e.detail;\n this.dispatchEvent(new CustomEvent<ProviderListOAuthEvent>('oauth', {\n detail: { provider },\n bubbles: true,\n composed: true,\n }));\n }\n\n private _groupByCategory(providers: ProviderInfo[]): Map<string, ProviderInfo[]> {\n const groups = new Map<string, ProviderInfo[]>();\n const categories = ['common', 'specialty', 'enterprise', 'oauth'];\n categories.forEach(cat => groups.set(cat, []));\n\n providers.forEach(provider => {\n const category = provider.category || 'specialty';\n const list = groups.get(category) || [];\n list.push(provider);\n groups.set(category, list);\n });\n\n return groups;\n }\n\n private _getCategoryLabel(category: string): string {\n const labels: Record<string, string> = {\n common: 'Common Providers',\n specialty: 'Specialty Providers',\n enterprise: 'Enterprise / Cloud',\n oauth: 'OAuth Only',\n };\n return labels[category] || category;\n }\n\n render() {\n if (this.loading) {\n return html`\n <div class=\"loading-state\">\n <span class=\"spinner\"></span>\n <span>Loading providers...</span>\n </div>\n `;\n }\n\n if (this.providers.length === 0) {\n return html`\n <div class=\"empty-state\">\n <p>No providers available.</p>\n </div>\n `;\n }\n\n const groups = this._groupByCategory(this.providers);\n\n return html`\n <div class=\"provider-list\">\n ${Array.from(groups.entries()).map(([category, providers]) => {\n if (providers.length === 0) return null;\n\n const isExpanded = this._expandedCategories.has(category);\n const configuredCount = providers.filter(p => p.configured).length;\n\n return html`\n <div class=\"category\">\n <div\n class=\"category-header\"\n @click=${() => this._toggleCategory(category)}\n >\n <div class=\"category-title\">\n ${getIcon(isExpanded ? 'chevronDown' : 'chevronRight')}\n <span>${this._getCategoryLabel(category)}</span>\n <span class=\"category-badge ${category}\">\n ${providers.length}\n </span>\n ${configuredCount > 0 ? html`\n <span class=\"configured-count\">\n (${configuredCount} configured)\n </span>\n ` : ''}\n </div>\n </div>\n\n <div class=\"category-content ${isExpanded ? 'expanded' : ''}\">\n ${providers.map(provider => html`\n <provider-config\n .provider=${provider.id}\n .displayName=${provider.name}\n .apiKey=${provider.apiKey || ''}\n .configured=${provider.configured}\n .supportsOAuth=${provider.supportsOAuth}\n .category=${provider.category}\n .token=${this.token}\n @change=${this._onProviderChange}\n @oauth=${this._onProviderOAuth}\n ></provider-config>\n `)}\n </div>\n </div>\n `;\n })}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'provider-list': ProviderList;\n }\n}\n","/**\n * Registry client - simplified API client for models/providers.\n */\n\nexport interface Model {\n id: string;\n name: string;\n provider: string;\n contextWindow: number;\n maxTokens: number;\n reasoning: boolean;\n vision: boolean;\n cost: {\n input: number;\n output: number;\n };\n available: boolean;\n}\n\nexport interface Provider {\n id: string;\n name: string;\n configured: boolean;\n models: Model[];\n}\n\nexport type ProviderCategory = 'common' | 'specialty' | 'enterprise' | 'oauth';\n\nexport interface ProviderMeta {\n id: string;\n name: string;\n category: ProviderCategory;\n supportsOAuth: boolean;\n supportsApiKey: boolean;\n configured: boolean;\n}\n\nexport interface RegistryData {\n version: string;\n providers: Provider[];\n}\n\nexport async function fetchRegistry(token?: string): Promise<RegistryData> {\n const response = await fetch(`${window.location.origin}/api/registry`, {\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch registry: ${response.status}`);\n }\n\n const data = await response.json();\n return data.payload;\n}\n\nexport async function fetchAllModels(token?: string): Promise<Model[]> {\n const response = await fetch(`${window.location.origin}/api/providers`, {\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch models: ${response.status}`);\n }\n\n const data = await response.json();\n return data.payload.models;\n}\n\nexport async function fetchConfiguredModels(token?: string): Promise<Model[]> {\n const response = await fetch(`${window.location.origin}/api/models`, {\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch configured models: ${response.status}`);\n }\n\n const data = await response.json();\n return data.payload.models;\n}\n\nexport async function fetchProviders(token?: string): Promise<Provider[]> {\n const registry = await fetchRegistry(token);\n return registry.providers.sort((a, b) => {\n if (a.configured !== b.configured) {\n return a.configured ? -1 : 1;\n }\n return a.id.localeCompare(b.id);\n });\n}\n\nexport async function fetchProviderMeta(token?: string): Promise<ProviderMeta[]> {\n const response = await fetch(`${window.location.origin}/api/providers/meta`, {\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch provider meta: ${response.status}`);\n }\n\n const data = await response.json();\n return data.payload.providers;\n}\n\nexport async function reloadRegistry(token?: string): Promise<void> {\n const response = await fetch(`${window.location.origin}/api/registry/reload`, {\n method: 'POST',\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw new Error(`Failed to reload registry: ${response.status}`);\n }\n}\n\nlet _modelsCache: Model[] | null = null;\nlet _cacheExpiry: number = 0;\nconst CACHE_DURATION = 60000;\n\nexport async function fetchCachedModels(token?: string, forceRefresh = false): Promise<Model[]> {\n const now = Date.now();\n\n if (!forceRefresh && _modelsCache && now < _cacheExpiry) {\n return _modelsCache;\n }\n\n _modelsCache = await fetchConfiguredModels(token);\n _cacheExpiry = now + CACHE_DURATION;\n return _modelsCache;\n}\n\nexport function clearRegistryCache(): void {\n _modelsCache = null;\n _cacheExpiry = 0;\n}\n\n/** @deprecated Use fetchAllModels instead */\nexport async function fetchProvidersLegacy(token?: string) {\n return fetchAllModels(token);\n}\n\n/** @deprecated Use fetchConfiguredModels instead */\nexport async function fetchConfiguredProviders(token?: string) {\n const models = await fetchConfiguredModels(token);\n const providers = new Map<string, Model[]>();\n models.forEach(m => {\n const list = providers.get(m.provider) || [];\n list.push(m);\n providers.set(m.provider, list);\n });\n return Array.from(providers.entries()).map(([id, models]) => ({\n id,\n name: id,\n configured: true,\n models,\n }));\n}\n","/**\n * Models.json API client\n * \n * Client for the custom models configuration API\n */\n\nimport type { \n ModelsJsonConfig, \n ProviderConfig, \n CustomModel,\n ValidationResult,\n} from '../../../src/config/models-json';\n\nexport type { ModelsJsonConfig, ProviderConfig, CustomModel };\n\nexport interface ModelsJsonStatus {\n config: ModelsJsonConfig;\n path: string;\n exists: boolean;\n loadError?: string;\n}\n\nexport interface ApiKeyTestResult {\n type: 'literal' | 'env' | 'command';\n resolved?: string;\n error?: string;\n}\n\n/**\n * Fetch models.json configuration\n */\nexport async function fetchModelsJson(token?: string): Promise<ModelsJsonStatus> {\n const response = await fetch(`${window.location.origin}/api/models-json`, {\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch models.json: ${response.status}`);\n }\n\n const data = await response.json();\n if (!data.ok) {\n throw new Error(data.error || 'Failed to fetch models.json');\n }\n\n return data.payload;\n}\n\n/**\n * Validate models.json configuration\n */\nexport async function validateModelsJson(\n config: ModelsJsonConfig,\n token?: string\n): Promise<ValidationResult> {\n const response = await fetch(`${window.location.origin}/api/models-json/validate`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n },\n body: JSON.stringify({ config }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to validate: ${response.status}`);\n }\n\n const data = await response.json();\n if (!data.ok) {\n throw new Error(data.error || 'Failed to validate');\n }\n\n return data.payload;\n}\n\n/**\n * Save models.json configuration\n */\nexport async function saveModelsJson(\n config: ModelsJsonConfig,\n token?: string\n): Promise<{ saved: boolean; modelCount: number }> {\n const response = await fetch(`${window.location.origin}/api/models-json`, {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n },\n body: JSON.stringify({ config }),\n });\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.error || `Failed to save: ${response.status}`);\n }\n\n const data = await response.json();\n if (!data.ok) {\n throw new Error(data.error || 'Failed to save');\n }\n\n return data.payload;\n}\n\n/**\n * Reload models.json configuration\n */\nexport async function reloadModelsJson(token?: string): Promise<{ \n modelCount: number; \n error?: string;\n}> {\n const response = await fetch(`${window.location.origin}/api/models-json/reload`, {\n method: 'POST',\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw new Error(`Failed to reload: ${response.status}`);\n }\n\n const data = await response.json();\n if (!data.ok) {\n throw new Error(data.error || 'Failed to reload');\n }\n\n return data.payload;\n}\n\n/**\n * Test API key resolution\n */\nexport async function testApiKey(\n value: string,\n token?: string\n): Promise<ApiKeyTestResult> {\n const response = await fetch(`${window.location.origin}/api/models-json/test-api-key`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n },\n body: JSON.stringify({ value }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to test API key: ${response.status}`);\n }\n\n const data = await response.json();\n if (!data.ok) {\n throw new Error(data.error || 'Failed to test API key');\n }\n\n return data.payload;\n}\n\n// ============================================\n// Helper Functions\n// ============================================\n\n/**\n * Create a new custom provider config\n */\nexport function createCustomProvider(\n baseUrl: string,\n apiKey: string,\n api: string = 'openai-completions'\n): ProviderConfig {\n return {\n baseUrl,\n apiKey,\n api,\n models: [],\n };\n}\n\n/**\n * Create a new custom model\n */\nexport function createCustomModel(\n id: string,\n name?: string,\n overrides?: Partial<CustomModel>\n): CustomModel {\n return {\n id,\n name: name || id,\n input: ['text'],\n contextWindow: 128000,\n maxTokens: 16384,\n cost: {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n },\n ...overrides,\n };\n}\n\n/**\n * Add a model to a provider\n */\nexport function addModelToProvider(\n provider: ProviderConfig,\n model: CustomModel\n): ProviderConfig {\n return {\n ...provider,\n models: [...(provider.models || []), model],\n };\n}\n\n/**\n * Remove a model from a provider\n */\nexport function removeModelFromProvider(\n provider: ProviderConfig,\n modelId: string\n): ProviderConfig {\n return {\n ...provider,\n models: (provider.models || []).filter(m => m.id !== modelId),\n };\n}\n\n/**\n * Check if a value is a shell command\n */\nexport function isShellCommand(value: string): boolean {\n return value.startsWith('!');\n}\n\n/**\n * Check if a value looks like an environment variable\n */\nexport function isEnvVar(value: string): boolean {\n return /^[A-Z][A-Z0-9_]*$/.test(value);\n}\n\n/**\n * Get the type of API key value\n */\nexport function getApiKeyType(value: string): 'shell' | 'env' | 'literal' {\n if (isShellCommand(value)) return 'shell';\n if (isEnvVar(value)) return 'env';\n return 'literal';\n}\n\n/**\n * Format API key for display (mask sensitive parts)\n */\nexport function maskApiKey(value: string): string {\n if (!value) return '';\n if (value.length <= 8) return '••••';\n return value.slice(0, 4) + '••••' + value.slice(-4);\n}\n","/**\n * ModelEditDialog Component\n * \n * A modal dialog for adding/editing custom models with full configuration options\n */\n\nimport { html, LitElement, css } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { getIcon } from '../utils/icons.js';\nimport type { CustomModel } from '../config/models-json-client.js';\nimport { createCustomModel } from '../config/models-json-client.js';\n\n// API types for dropdown\nconst API_TYPES = [\n { value: 'openai-completions', label: 'OpenAI Completions' },\n { value: 'openai-responses', label: 'OpenAI Responses' },\n { value: 'anthropic-messages', label: 'Anthropic Messages' },\n { value: 'google-generative-ai', label: 'Google Generative AI' },\n { value: 'azure-openai-responses', label: 'Azure OpenAI' },\n { value: 'bedrock-converse-stream', label: 'AWS Bedrock' },\n];\n\nconst INPUT_TYPES = [\n { value: 'text', label: 'Text Only' },\n { value: 'text,image', label: 'Text + Vision' },\n];\n\nexport interface ModelEditDialogResult {\n confirmed: boolean;\n model?: CustomModel;\n}\n\n@customElement('model-edit-dialog')\nexport class ModelEditDialog extends LitElement {\n @property({ type: Object }) model?: CustomModel;\n @property({ type: String }) providerId?: string;\n @property({ type: Boolean }) isOpen = false;\n @property({ type: Boolean }) isNew = false;\n\n @state() private _formData: Partial<CustomModel> = {};\n @state() private _errors: Map<string, string> = new Map();\n @state() private _activeTab: 'basic' | 'advanced' | 'compat' = 'basic';\n\n static styles = css`\n :host { display: block; }\n \n .dialog-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 1rem;\n }\n \n .dialog {\n background: var(--bg-primary, white);\n border-radius: var(--radius-lg, 0.75rem);\n width: 100%;\n max-width: 600px;\n max-height: 85vh;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);\n }\n \n .dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1rem 1.5rem;\n border-bottom: 1px solid var(--border-color, #e2e8f0);\n }\n \n .dialog-title {\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--text-primary, #0f172a);\n }\n \n .dialog-subtitle {\n font-size: 0.875rem;\n color: var(--text-muted, #64748b);\n margin-top: 0.25rem;\n }\n \n .close-btn {\n padding: 0.5rem;\n background: transparent;\n border: none;\n cursor: pointer;\n border-radius: var(--radius-md, 0.375rem);\n color: var(--text-muted, #64748b);\n display: flex;\n align-items: center;\n justify-content: center;\n }\n \n .close-btn:hover {\n background: var(--bg-secondary, #f1f5f9);\n color: var(--text-primary, #0f172a);\n }\n \n .dialog-tabs {\n display: flex;\n gap: 0;\n padding: 0 1.5rem;\n border-bottom: 1px solid var(--border-color, #e2e8f0);\n background: var(--bg-secondary, #f8fafc);\n }\n \n .tab-btn {\n padding: 0.75rem 1rem;\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n cursor: pointer;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--text-muted, #64748b);\n transition: all 0.15s;\n }\n \n .tab-btn:hover {\n color: var(--text-primary, #0f172a);\n }\n \n .tab-btn.active {\n color: var(--accent-primary, #3b82f6);\n border-bottom-color: var(--accent-primary, #3b82f6);\n }\n \n .dialog-body {\n flex: 1;\n overflow-y: auto;\n padding: 1.5rem;\n }\n \n .form-grid {\n display: grid;\n gap: 1.25rem;\n }\n \n .form-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 1rem;\n }\n \n .field-group {\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n }\n \n .field-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--text-primary, #0f172a);\n display: flex;\n align-items: center;\n gap: 0.25rem;\n }\n \n .field-label .required {\n color: #dc2626;\n }\n \n .field-hint {\n font-size: 0.75rem;\n color: var(--text-muted, #64748b);\n }\n \n .text-input, .select-input, .textarea-input {\n padding: 0.625rem 0.875rem;\n border: 1px solid var(--border-color, #e2e8f0);\n border-radius: var(--radius-md, 0.375rem);\n background: var(--bg-primary, white);\n color: var(--text-primary, #0f172a);\n font-size: 0.875rem;\n transition: all 0.15s;\n }\n \n .text-input:focus, .select-input:focus, .textarea-input:focus {\n outline: none;\n border-color: var(--accent-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n }\n \n .text-input.error, .select-input.error {\n border-color: #dc2626;\n }\n \n .text-input::placeholder {\n color: var(--text-muted, #94a3b8);\n }\n \n .textarea-input {\n resize: vertical;\n min-height: 80px;\n }\n \n .checkbox-label {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n font-size: 0.875rem;\n color: var(--text-primary, #0f172a);\n }\n \n .checkbox-input {\n width: 1rem;\n height: 1rem;\n cursor: pointer;\n }\n \n .error-message {\n font-size: 0.75rem;\n color: #dc2626;\n display: flex;\n align-items: center;\n gap: 0.25rem;\n }\n \n .section-title {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--text-primary, #0f172a);\n margin-bottom: 0.75rem;\n padding-bottom: 0.5rem;\n border-bottom: 1px solid var(--border-color, #e2e8f0);\n }\n \n .cost-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n \n .cost-input-group {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n }\n \n .cost-input-group .text-input {\n flex: 1;\n }\n \n .cost-unit {\n font-size: 0.75rem;\n color: var(--text-muted, #64748b);\n white-space: nowrap;\n }\n \n .compat-section {\n background: var(--bg-secondary, #f8fafc);\n padding: 1rem;\n border-radius: var(--radius-md, 0.375rem);\n margin-bottom: 1rem;\n }\n \n .compat-title {\n font-size: 0.875rem;\n font-weight: 600;\n margin-bottom: 0.75rem;\n color: var(--text-primary, #0f172a);\n }\n \n .dialog-footer {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 1rem 1.5rem;\n border-top: 1px solid var(--border-color, #e2e8f0);\n background: var(--bg-secondary, #f8fafc);\n }\n \n .btn {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.625rem 1rem;\n border-radius: var(--radius-md, 0.375rem);\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n border: none;\n transition: all 0.15s;\n }\n \n .btn-primary {\n background: var(--accent-primary, #3b82f6);\n color: white;\n }\n \n .btn-primary:hover {\n background: var(--accent-primary-hover, #2563eb);\n }\n \n .btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n \n .btn-secondary {\n background: white;\n color: var(--text-primary, #0f172a);\n border: 1px solid var(--border-color, #e2e8f0);\n }\n \n .btn-secondary:hover {\n background: var(--bg-secondary, #f1f5f9);\n }\n \n .hidden {\n display: none !important;\n }\n \n @media (max-width: 640px) {\n .form-row {\n grid-template-columns: 1fr;\n }\n \n .cost-grid {\n grid-template-columns: 1fr;\n }\n }\n `;\n\n open(model?: CustomModel, isNew = false) {\n this.isNew = isNew;\n this.model = model;\n this._formData = model ? { ...model } : createCustomModel('');\n this._errors.clear();\n this._activeTab = 'basic';\n this.isOpen = true;\n }\n\n close() {\n this.isOpen = false;\n this.dispatchEvent(new CustomEvent<ModelEditDialogResult>('close', {\n detail: { confirmed: false },\n bubbles: true,\n composed: true,\n }));\n }\n\n private _validate(): boolean {\n this._errors.clear();\n \n if (!this._formData.id || this._formData.id.trim() === '') {\n this._errors.set('id', 'Model ID is required');\n }\n \n if (this._formData.contextWindow !== undefined && this._formData.contextWindow <= 0) {\n this._errors.set('contextWindow', 'Must be greater than 0');\n }\n \n if (this._formData.maxTokens !== undefined && this._formData.maxTokens <= 0) {\n this._errors.set('maxTokens', 'Must be greater than 0');\n }\n \n this.requestUpdate();\n return this._errors.size === 0;\n }\n\n private _handleSave() {\n if (!this._validate()) return;\n \n const result: CustomModel = {\n id: this._formData.id || '',\n name: this._formData.name || this._formData.id || '',\n reasoning: this._formData.reasoning || false,\n input: this._formData.input || ['text'],\n contextWindow: this._formData.contextWindow || 128000,\n maxTokens: this._formData.maxTokens || 16384,\n cost: this._formData.cost || {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n },\n ...this._formData,\n };\n \n this.dispatchEvent(new CustomEvent<ModelEditDialogResult>('close', {\n detail: { confirmed: true, model: result },\n bubbles: true,\n composed: true,\n }));\n this.isOpen = false;\n }\n\n private _updateField<K extends keyof CustomModel>(field: K, value: CustomModel[K]) {\n this._formData = { ...this._formData, [field]: value };\n if (this._errors.has(field)) {\n this._errors.delete(field);\n this.requestUpdate();\n }\n }\n\n render() {\n if (!this.isOpen) return '';\n \n const title = this.isNew ? 'Add New Model' : 'Edit Model';\n const subtitle = this.providerId ? `Provider: ${this.providerId}` : '';\n \n return html`\n <div class=\"dialog-overlay\" @click=${(e: Event) => {\n if (e.target === e.currentTarget) this.close();\n }}>\n <div class=\"dialog\">\n <div class=\"dialog-header\">\n <div>\n <div class=\"dialog-title\">${title}</div>\n ${subtitle ? html`<div class=\"dialog-subtitle\">${subtitle}</div>` : ''}\n </div>\n <button class=\"close-btn\" @click=${this.close}>\n ${getIcon('x')}\n </button>\n </div>\n \n <div class=\"dialog-tabs\">\n <button \n class=\"tab-btn ${this._activeTab === 'basic' ? 'active' : ''}\"\n @click=${() => this._activeTab = 'basic'}\n >\n Basic\n </button>\n <button \n class=\"tab-btn ${this._activeTab === 'advanced' ? 'active' : ''}\"\n @click=${() => this._activeTab = 'advanced'}\n >\n Advanced\n </button>\n <button \n class=\"tab-btn ${this._activeTab === 'compat' ? 'active' : ''}\"\n @click=${() => this._activeTab = 'compat'}\n >\n Compatibility\n </button>\n </div>\n \n <div class=\"dialog-body\">\n ${this._activeTab === 'basic' ? this._renderBasicTab() : ''}\n ${this._activeTab === 'advanced' ? this._renderAdvancedTab() : ''}\n ${this._activeTab === 'compat' ? this._renderCompatTab() : ''}\n </div>\n \n <div class=\"dialog-footer\">\n <button class=\"btn btn-secondary\" @click=${this.close}>\n Cancel\n </button>\n <button class=\"btn btn-primary\" @click=${this._handleSave}>\n ${this.isNew ? 'Add Model' : 'Save Changes'}\n </button>\n </div>\n </div>\n </div>\n `;\n }\n\n private _renderBasicTab() {\n return html`\n <div class=\"form-grid\">\n <div class=\"field-group\">\n <label class=\"field-label\">\n Model ID <span class=\"required\">*</span>\n </label>\n <input\n class=\"text-input ${this._errors.has('id') ? 'error' : ''}\"\n type=\"text\"\n .value=${this._formData.id || ''}\n placeholder=\"e.g., llama3.1:8b, gpt-4o\"\n @input=${(e: Event) => this._updateField('id', (e.target as HTMLInputElement).value)}\n />\n <span class=\"field-hint\">Unique identifier used in API calls</span>\n ${this._errors.has('id') ? html`\n <span class=\"error-message\">${getIcon('alertCircle')} ${this._errors.get('id')}</span>\n ` : ''}\n </div>\n \n <div class=\"field-group\">\n <label class=\"field-label\">Display Name</label>\n <input\n class=\"text-input\"\n type=\"text\"\n .value=${this._formData.name || ''}\n placeholder=\"e.g., Llama 3.1 8B\"\n @input=${(e: Event) => this._updateField('name', (e.target as HTMLInputElement).value)}\n />\n <span class=\"field-hint\">Human-readable name (defaults to ID)</span>\n </div>\n \n <div class=\"form-row\">\n <div class=\"field-group\">\n <label class=\"field-label\">Input Types</label>\n <select\n class=\"select-input\"\n .value=${(this._formData.input || ['text']).join(',')}\n @change=${(e: Event) => {\n const value = (e.target as HTMLSelectElement).value;\n this._updateField('input', value.split(',') as ('text' | 'image')[]);\n }}\n >\n ${INPUT_TYPES.map(type => html`\n <option value=${type.value}>${type.label}</option>\n `)}\n </select>\n </div>\n \n <div class=\"field-group\">\n <label class=\"checkbox-label\" style=\"margin-top: 1.5rem;\">\n <input\n class=\"checkbox-input\"\n type=\"checkbox\"\n .checked=${this._formData.reasoning || false}\n @change=${(e: Event) => this._updateField('reasoning', (e.target as HTMLInputElement).checked)}\n />\n Supports Reasoning\n </label>\n </div>\n </div>\n \n <div class=\"section-title\">Context & Tokens</div>\n \n <div class=\"form-row\">\n <div class=\"field-group\">\n <label class=\"field-label\">Context Window</label>\n <input\n class=\"text-input ${this._errors.has('contextWindow') ? 'error' : ''}\"\n type=\"number\"\n .value=${this._formData.contextWindow || 128000}\n min=\"1\"\n @input=${(e: Event) => this._updateField('contextWindow', parseInt((e.target as HTMLInputElement).value))}\n />\n <span class=\"field-hint\">Maximum context size in tokens</span>\n ${this._errors.has('contextWindow') ? html`\n <span class=\"error-message\">${this._errors.get('contextWindow')}</span>\n ` : ''}\n </div>\n \n <div class=\"field-group\">\n <label class=\"field-label\">Max Output Tokens</label>\n <input\n class=\"text-input ${this._errors.has('maxTokens') ? 'error' : ''}\"\n type=\"number\"\n .value=${this._formData.maxTokens || 16384}\n min=\"1\"\n @input=${(e: Event) => this._updateField('maxTokens', parseInt((e.target as HTMLInputElement).value))}\n />\n <span class=\"field-hint\">Maximum tokens in response</span>\n ${this._errors.has('maxTokens') ? html`\n <span class=\"error-message\">${this._errors.get('maxTokens')}</span>\n ` : ''}\n </div>\n </div>\n </div>\n `;\n }\n\n private _renderAdvancedTab() {\n const cost = this._formData.cost || { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };\n \n return html`\n <div class=\"form-grid\">\n <div class=\"section-title\">Cost per Million Tokens (USD)</div>\n \n <div class=\"cost-grid\">\n <div class=\"field-group\">\n <label class=\"field-label\">Input</label>\n <div class=\"cost-input-group\">\n <input\n class=\"text-input\"\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n .value=${cost.input}\n @input=${(e: Event) => {\n const value = parseFloat((e.target as HTMLInputElement).value) || 0;\n this._updateField('cost', { ...cost, input: value });\n }}\n />\n <span class=\"cost-unit\">$/M tokens</span>\n </div>\n </div>\n \n <div class=\"field-group\">\n <label class=\"field-label\">Output</label>\n <div class=\"cost-input-group\">\n <input\n class=\"text-input\"\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n .value=${cost.output}\n @input=${(e: Event) => {\n const value = parseFloat((e.target as HTMLInputElement).value) || 0;\n this._updateField('cost', { ...cost, output: value });\n }}\n />\n <span class=\"cost-unit\">$/M tokens</span>\n </div>\n </div>\n \n <div class=\"field-group\">\n <label class=\"field-label\">Cache Read</label>\n <div class=\"cost-input-group\">\n <input\n class=\"text-input\"\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n .value=${cost.cacheRead}\n @input=${(e: Event) => {\n const value = parseFloat((e.target as HTMLInputElement).value) || 0;\n this._updateField('cost', { ...cost, cacheRead: value });\n }}\n />\n <span class=\"cost-unit\">$/M tokens</span>\n </div>\n </div>\n \n <div class=\"field-group\">\n <label class=\"field-label\">Cache Write</label>\n <div class=\"cost-input-group\">\n <input\n class=\"text-input\"\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n .value=${cost.cacheWrite}\n @input=${(e: Event) => {\n const value = parseFloat((e.target as HTMLInputElement).value) || 0;\n this._updateField('cost', { ...cost, cacheWrite: value });\n }}\n />\n <span class=\"cost-unit\">$/M tokens</span>\n </div>\n </div>\n </div>\n \n <div class=\"section-title\">Custom Headers</div>\n \n <div class=\"field-group\">\n <label class=\"field-label\">Headers (JSON)</label>\n <textarea\n class=\"textarea-input\"\n .value=${this._formData.headers ? JSON.stringify(this._formData.headers, null, 2) : ''}\n placeholder='{\"X-Custom-Header\": \"value\"}'\n @change=${(e: Event) => {\n try {\n const value = (e.target as HTMLTextAreaElement).value;\n this._updateField('headers', value ? JSON.parse(value) : undefined);\n } catch {\n // Invalid JSON, ignore\n }\n }}\n ></textarea>\n <span class=\"field-hint\">Optional custom headers for this model (JSON format)</span>\n </div>\n </div>\n `;\n }\n\n private _renderCompatTab() {\n const compat = (this._formData.compat || {}) as Record<string, unknown>;\n \n return html`\n <div class=\"form-grid\">\n <div class=\"compat-section\">\n <div class=\"compat-title\">OpenAI Completions Compatibility</div>\n \n <div class=\"field-group\" style=\"margin-bottom: 0.75rem;\">\n <label class=\"checkbox-label\">\n <input\n class=\"checkbox-input\"\n type=\"checkbox\"\n .checked=${compat.supportsStore || false}\n @change=${(e: Event) => this._updateCompat('supportsStore', (e.target as HTMLInputElement).checked)}\n />\n Supports Store\n </label>\n </div>\n \n <div class=\"field-group\" style=\"margin-bottom: 0.75rem;\">\n <label class=\"checkbox-label\">\n <input\n class=\"checkbox-input\"\n type=\"checkbox\"\n .checked=${compat.supportsDeveloperRole || false}\n @change=${(e: Event) => this._updateCompat('supportsDeveloperRole', (e.target as HTMLInputElement).checked)}\n />\n Supports Developer Role\n </label>\n </div>\n \n <div class=\"field-group\" style=\"margin-bottom: 0.75rem;\">\n <label class=\"checkbox-label\">\n <input\n class=\"checkbox-input\"\n type=\"checkbox\"\n .checked=${compat.supportsUsageInStreaming !== false}\n @change=${(e: Event) => this._updateCompat('supportsUsageInStreaming', (e.target as HTMLInputElement).checked)}\n />\n Supports Usage in Streaming\n </label>\n </div>\n \n <div class=\"field-group\">\n <label class=\"field-label\">Max Tokens Field</label>\n <select\n class=\"select-input\"\n .value=${compat.maxTokensField || ''}\n @change=${(e: Event) => this._updateCompat('maxTokensField', (e.target as HTMLSelectElement).value || undefined)}\n >\n <option value=\"\">Auto-detect</option>\n <option value=\"max_completion_tokens\">max_completion_tokens</option>\n <option value=\"max_tokens\">max_tokens</option>\n </select>\n </div>\n </div>\n \n <div class=\"compat-section\">\n <div class=\"compat-title\">Routing (OpenRouter / Vercel Gateway)</div>\n \n <div class=\"field-group\">\n <label class=\"field-label\">Provider Order (comma-separated)</label>\n <input\n class=\"text-input\"\n type=\"text\"\n .value=${(compat.openRouterRouting as { order?: string[] })?.order?.join(', ') || ''}\n placeholder=\"anthropic, openai, ...\"\n @change=${(e: Event) => {\n const value = (e.target as HTMLInputElement).value;\n const order = value ? value.split(',').map(s => s.trim()).filter(Boolean) : undefined;\n this._updateCompat('openRouterRouting', order ? { order } : undefined);\n }}\n />\n </div>\n \n <div class=\"field-group\">\n <label class=\"field-label\">Allowed Providers Only (comma-separated)</label>\n <input\n class=\"text-input\"\n type=\"text\"\n .value=${(compat.openRouterRouting as { only?: string[] })?.only?.join(', ') || ''}\n placeholder=\"amazon-bedrock, ...\"\n @change=${(e: Event) => {\n const value = (e.target as HTMLInputElement).value;\n const only = value ? value.split(',').map(s => s.trim()).filter(Boolean) : undefined;\n this._updateCompat('openRouterRouting', only ? { only } : undefined);\n }}\n />\n </div>\n </div>\n </div>\n `;\n }\n\n private _updateCompat(key: string, value: unknown) {\n const compat = { ...(this._formData.compat || {}) };\n if (value === undefined) {\n delete compat[key];\n } else {\n compat[key] = value;\n }\n this._updateField('compat', Object.keys(compat).length > 0 ? compat : undefined);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'model-edit-dialog': ModelEditDialog;\n }\n}\n","/**\n * ProviderEditDialog Component\n * \n * A modal dialog for adding/editing custom providers with full configuration options\n */\n\nimport { html, LitElement, css } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { getIcon } from '../utils/icons.js';\nimport type { ProviderConfig } from '../config/models-json-client.js';\n\n// API types for dropdown\nconst API_TYPES = [\n { value: 'openai-completions', label: 'OpenAI Completions (Most compatible)' },\n { value: 'openai-responses', label: 'OpenAI Responses' },\n { value: 'anthropic-messages', label: 'Anthropic Messages' },\n { value: 'google-generative-ai', label: 'Google Generative AI' },\n { value: 'azure-openai-responses', label: 'Azure OpenAI' },\n { value: 'bedrock-converse-stream', label: 'AWS Bedrock' },\n { value: 'openai-codex-responses', label: 'OpenAI Codex' },\n { value: 'google-gemini-cli', label: 'Google Gemini CLI' },\n { value: 'google-vertex', label: 'Google Vertex AI' },\n];\n\n// Preset providers with default configurations\nconst PROVIDER_PRESETS: Record<string, Partial<ProviderConfig>> = {\n ollama: {\n baseUrl: 'http://localhost:11434/v1',\n api: 'openai-completions',\n apiKey: 'ollama',\n },\n lmstudio: {\n baseUrl: 'http://localhost:1234/v1',\n api: 'openai-completions',\n apiKey: 'lmstudio',\n },\n openrouter: {\n baseUrl: 'https://openrouter.ai/api/v1',\n api: 'openai-completions',\n apiKey: '',\n },\n 'vercel-ai-gateway': {\n baseUrl: 'https://ai-gateway.vercel.sh/v1',\n api: 'openai-completions',\n apiKey: '',\n },\n vllm: {\n baseUrl: 'http://localhost:8000/v1',\n api: 'openai-completions',\n apiKey: '',\n },\n custom: {\n baseUrl: '',\n api: 'openai-completions',\n apiKey: '',\n },\n};\n\nexport interface ProviderEditDialogResult {\n confirmed: boolean;\n providerId?: string;\n config?: ProviderConfig;\n}\n\n@customElement('provider-edit-dialog')\nexport class ProviderEditDialog extends LitElement {\n @property({ type: Object }) config?: ProviderConfig;\n @property({ type: String }) providerId?: string;\n @property({ type: Boolean }) isOpen = false;\n @property({ type: Boolean }) isNew = false;\n\n @state() private _formData: Partial<ProviderConfig> = {};\n @state() private _providerId = '';\n @state() private _errors: Map<string, string> = new Map();\n @state() private _selectedPreset = 'custom';\n @state() private _showAdvanced = false;\n\n static styles = css`\n :host { display: block; }\n \n .dialog-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 1rem;\n animation: fadeIn 0.15s ease;\n }\n \n @keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n \n .dialog {\n background: var(--bg-primary, white);\n border-radius: var(--radius-lg, 0.75rem);\n width: 100%;\n max-width: 560px;\n max-height: 90vh;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);\n animation: slideUp 0.2s ease;\n }\n \n @keyframes slideUp {\n from { \n opacity: 0;\n transform: translateY(20px);\n }\n to { \n opacity: 1;\n transform: translateY(0);\n }\n }\n \n .dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1.25rem 1.5rem;\n border-bottom: 1px solid var(--border-color, #e2e8f0);\n background: linear-gradient(to right, var(--bg-primary, white), var(--bg-secondary, #f8fafc));\n }\n \n .dialog-title {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--text-primary, #0f172a);\n }\n \n .dialog-subtitle {\n font-size: 0.875rem;\n color: var(--text-muted, #64748b);\n margin-top: 0.25rem;\n }\n \n .close-btn {\n padding: 0.5rem;\n background: transparent;\n border: none;\n cursor: pointer;\n border-radius: var(--radius-md, 0.375rem);\n color: var(--text-muted, #64748b);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.15s;\n }\n \n .close-btn:hover {\n background: var(--bg-secondary, #f1f5f9);\n color: var(--text-primary, #0f172a);\n }\n \n .dialog-body {\n flex: 1;\n overflow-y: auto;\n padding: 1.5rem;\n }\n \n .form-grid {\n display: grid;\n gap: 1.25rem;\n }\n \n .form-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 1rem;\n }\n \n .field-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n }\n \n .field-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--text-primary, #0f172a);\n display: flex;\n align-items: center;\n gap: 0.25rem;\n }\n \n .field-label .required {\n color: #dc2626;\n }\n \n .field-hint {\n font-size: 0.75rem;\n color: var(--text-muted, #64748b);\n line-height: 1.4;\n }\n \n .text-input, .select-input, .textarea-input {\n padding: 0.625rem 0.875rem;\n border: 1px solid var(--border-color, #e2e8f0);\n border-radius: var(--radius-md, 0.375rem);\n background: var(--bg-primary, white);\n color: var(--text-primary, #0f172a);\n font-size: 0.875rem;\n transition: all 0.15s;\n }\n \n .text-input:hover, .select-input:hover, .textarea-input:hover {\n border-color: var(--border-hover, #cbd5e1);\n }\n \n .text-input:focus, .select-input:focus, .textarea-input:focus {\n outline: none;\n border-color: var(--accent-primary, #3b82f6);\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n }\n \n .text-input.error, .select-input.error {\n border-color: #dc2626;\n background-color: #fef2f2;\n }\n \n .text-input::placeholder {\n color: var(--text-muted, #94a3b8);\n }\n \n .textarea-input {\n resize: vertical;\n min-height: 80px;\n font-family: monospace;\n font-size: 0.8125rem;\n }\n \n .select-input {\n cursor: pointer;\n }\n \n .checkbox-label {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n font-size: 0.875rem;\n color: var(--text-primary, #0f172a);\n padding: 0.5rem 0;\n }\n \n .checkbox-input {\n width: 1.125rem;\n height: 1.125rem;\n cursor: pointer;\n accent-color: var(--accent-primary, #3b82f6);\n }\n \n .error-message {\n font-size: 0.75rem;\n color: #dc2626;\n display: flex;\n align-items: center;\n gap: 0.25rem;\n animation: shake 0.3s ease;\n }\n \n @keyframes shake {\n 0%, 100% { transform: translateX(0); }\n 25% { transform: translateX(-4px); }\n 75% { transform: translateX(4px); }\n }\n \n .section-title {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--text-primary, #0f172a);\n margin: 1.5rem 0 0.75rem;\n padding-bottom: 0.5rem;\n border-bottom: 1px solid var(--border-color, #e2e8f0);\n display: flex;\n align-items: center;\n gap: 0.5rem;\n }\n \n .section-title:first-child {\n margin-top: 0;\n }\n \n .preset-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.75rem;\n margin-bottom: 1rem;\n }\n \n .preset-btn {\n padding: 0.875rem;\n border: 1px solid var(--border-color, #e2e8f0);\n border-radius: var(--radius-md, 0.375rem);\n background: var(--bg-primary, white);\n cursor: pointer;\n text-align: left;\n transition: all 0.15s;\n }\n \n .preset-btn:hover {\n border-color: var(--accent-primary, #3b82f6);\n background: var(--bg-secondary, #f8fafc);\n }\n \n .preset-btn.active {\n border-color: var(--accent-primary, #3b82f6);\n background: rgba(59, 130, 246, 0.05);\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);\n }\n \n .preset-name {\n font-weight: 600;\n font-size: 0.875rem;\n color: var(--text-primary, #0f172a);\n }\n \n .preset-desc {\n font-size: 0.75rem;\n color: var(--text-muted, #64748b);\n margin-top: 0.25rem;\n }\n \n .input-with-suffix {\n position: relative;\n display: flex;\n align-items: center;\n }\n \n .input-with-suffix .text-input {\n flex: 1;\n padding-right: 3rem;\n }\n \n .input-suffix {\n position: absolute;\n right: 0.75rem;\n font-size: 0.75rem;\n color: var(--text-muted, #94a3b8);\n pointer-events: none;\n }\n \n .toggle-advanced {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem;\n margin: 1rem 0;\n background: transparent;\n border: 1px dashed var(--border-color, #e2e8f0);\n border-radius: var(--radius-md, 0.375rem);\n color: var(--text-muted, #64748b);\n cursor: pointer;\n font-size: 0.875rem;\n transition: all 0.15s;\n }\n \n .toggle-advanced:hover {\n border-color: var(--accent-primary, #3b82f6);\n color: var(--accent-primary, #3b82f6);\n }\n \n .advanced-section {\n animation: slideDown 0.2s ease;\n }\n \n @keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n \n .dialog-footer {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 1rem 1.5rem;\n border-top: 1px solid var(--border-color, #e2e8f0);\n background: var(--bg-secondary, #f8fafc);\n }\n \n .btn {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.625rem 1.25rem;\n border-radius: var(--radius-md, 0.375rem);\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n border: none;\n transition: all 0.15s;\n }\n \n .btn-primary {\n background: var(--accent-primary, #3b82f6);\n color: white;\n }\n \n .btn-primary:hover {\n background: var(--accent-primary-hover, #2563eb);\n }\n \n .btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n \n .btn-secondary {\n background: white;\n color: var(--text-primary, #0f172a);\n border: 1px solid var(--border-color, #e2e8f0);\n }\n \n .btn-secondary:hover {\n background: var(--bg-secondary, #f1f5f9);\n }\n \n .hidden {\n display: none !important;\n }\n \n @media (max-width: 640px) {\n .form-row {\n grid-template-columns: 1fr;\n }\n \n .preset-grid {\n grid-template-columns: 1fr;\n }\n \n .dialog {\n max-height: 95vh;\n }\n }\n \n .info-box {\n padding: 0.875rem;\n background: #eff6ff;\n border: 1px solid #bfdbfe;\n border-radius: var(--radius-md, 0.375rem);\n margin-bottom: 1rem;\n }\n \n .info-box-title {\n font-weight: 600;\n font-size: 0.875rem;\n color: #1e40af;\n margin-bottom: 0.25rem;\n display: flex;\n align-items: center;\n gap: 0.375rem;\n }\n \n .info-box-text {\n font-size: 0.8125rem;\n color: #3b82f6;\n }\n `;\n\n open(config?: ProviderConfig, providerId?: string, isNew = false) {\n this.isNew = isNew;\n this.config = config;\n this.providerId = providerId;\n this._formData = config ? { ...config } : {};\n this._providerId = providerId || '';\n this._errors.clear();\n this._showAdvanced = false;\n this._selectedPreset = 'custom';\n this.isOpen = true;\n }\n\n close() {\n this.isOpen = false;\n this.dispatchEvent(new CustomEvent<ProviderEditDialogResult>('close', {\n detail: { confirmed: false },\n bubbles: true,\n composed: true,\n }));\n }\n\n private _validate(): boolean {\n this._errors.clear();\n \n if (this.isNew) {\n if (!this._providerId || this._providerId.trim() === '') {\n this._errors.set('providerId', 'Provider ID is required');\n } else if (!/^[a-z0-9-_]+$/i.test(this._providerId)) {\n this._errors.set('providerId', 'Only letters, numbers, hyphens, and underscores allowed');\n }\n }\n \n if (this._formData.baseUrl) {\n try {\n new URL(this._formData.baseUrl);\n } catch {\n this._errors.set('baseUrl', 'Must be a valid URL');\n }\n }\n \n this.requestUpdate();\n return this._errors.size === 0;\n }\n\n private _handleSave() {\n if (!this._validate()) return;\n \n const result: ProviderConfig = {\n baseUrl: this._formData.baseUrl || '',\n apiKey: this._formData.apiKey || '',\n api: this._formData.api || 'openai-completions',\n authHeader: this._formData.authHeader,\n headers: this._formData.headers,\n models: this._formData.models || [],\n modelOverrides: this._formData.modelOverrides,\n };\n \n this.dispatchEvent(new CustomEvent<ProviderEditDialogResult>('close', {\n detail: { \n confirmed: true, \n providerId: this.isNew ? this._providerId : this.providerId,\n config: result,\n },\n bubbles: true,\n composed: true,\n }));\n this.isOpen = false;\n }\n\n private _updateField<K extends keyof ProviderConfig>(field: K, value: ProviderConfig[K]) {\n this._formData = { ...this._formData, [field]: value };\n if (this._errors.has(field)) {\n this._errors.delete(field);\n this.requestUpdate();\n }\n }\n\n private _applyPreset(presetKey: string) {\n this._selectedPreset = presetKey;\n const preset = PROVIDER_PRESETS[presetKey];\n if (preset) {\n this._formData = { ...this._formData, ...preset };\n \n // Auto-fill provider ID for new providers based on preset\n if (this.isNew && !this._providerId && presetKey !== 'custom') {\n this._providerId = presetKey;\n }\n }\n this.requestUpdate();\n }\n\n render() {\n if (!this.isOpen) return '';\n \n const title = this.isNew ? 'Add New Provider' : 'Edit Provider';\n \n return html`\n <div class=\"dialog-overlay\" @click=${(e: Event) => {\n if (e.target === e.currentTarget) this.close();\n }}>\n <div class=\"dialog\">\n <div class=\"dialog-header\">\n <div>\n <div class=\"dialog-title\">${title}</div>\n ${!this.isNew ? html`\n <div class=\"dialog-subtitle\">Editing: ${this.providerId}</div>\n ` : ''}\n </div>\n <button class=\"close-btn\" @click=${this.close}>\n ${getIcon('x')}\n </button>\n </div>\n \n <div class=\"dialog-body\">\n ${this.isNew ? this._renderNewProviderForm() : this._renderEditForm()}\n </div>\n \n <div class=\"dialog-footer\">\n <button class=\"btn btn-secondary\" @click=${this.close}>\n Cancel\n </button>\n <button class=\"btn btn-primary\" @click=${this._handleSave}>\n ${this.isNew ? 'Add Provider' : 'Save Changes'}\n </button>\n </div>\n </div>\n </div>\n `;\n }\n\n private _renderNewProviderForm() {\n return html`\n <div class=\"form-grid\">\n ${this._renderPresetSelection()}\n \n <div class=\"section-title\">\n ${getIcon('settings')} Provider Configuration\n </div>\n \n <div class=\"field-group\">\n <label class=\"field-label\">\n Provider ID <span class=\"required\">*</span>\n </label>\n <input\n class=\"text-input ${this._errors.has('providerId') ? 'error' : ''}\"\n type=\"text\"\n .value=${this._providerId}\n placeholder=\"e.g., ollama, my-openai-proxy\"\n @input=${(e: Event) => {\n this._providerId = (e.target as HTMLInputElement).value.toLowerCase();\n if (this._errors.has('providerId')) {\n this._errors.delete('providerId');\n this.requestUpdate();\n }\n }}\n />\n <span class=\"field-hint\">\n Unique identifier (lowercase, alphanumeric, hyphens, underscores)\n </span>\n ${this._errors.has('providerId') ? html`\n <span class=\"error-message\">${getIcon('alertCircle')} ${this._errors.get('providerId')}</span>\n ` : ''}\n </div>\n \n ${this._renderCommonFields()}\n </div>\n `;\n }\n\n private _renderEditForm() {\n return html`\n <div class=\"form-grid\">\n ${this._renderCommonFields()}\n </div>\n `;\n }\n\n private _renderPresetSelection() {\n return html`\n <div class=\"info-box\">\n <div class=\"info-box-title\">${getIcon('info')} Quick Setup</div>\n <div class=\"info-box-text\">Select a preset to auto-fill common configurations, or choose \"Custom\" for manual setup.</div>\n </div>\n \n <div class=\"preset-grid\">\n ${Object.entries(PROVIDER_PRESETS).map(([key, preset]) => html`\n <button \n class=\"preset-btn ${this._selectedPreset === key ? 'active' : ''}\"\n @click=${() => this._applyPreset(key)}\n >\n <div class=\"preset-name\">${this._formatPresetName(key)}</div>\n <div class=\"preset-desc\">${this._getPresetDescription(key)}</div>\n </button>\n `)}\n </div>\n `;\n }\n\n private _renderCommonFields() {\n return html`\n <div class=\"field-group\">\n <label class=\"field-label\">API Type</label>\n <select\n class=\"select-input\"\n .value=${this._formData.api || 'openai-completions'}\n @change=${(e: Event) => this._updateField('api', (e.target as HTMLSelectElement).value as any)}\n >\n ${API_TYPES.map(api => html`\n <option value=${api.value}>${api.label}</option>\n `)}\n </select>\n <span class=\"field-hint\">The API protocol this provider uses</span>\n </div>\n \n <div class=\"field-group\">\n <label class=\"field-label\">\n Base URL ${this.isNew ? html`<span class=\"required\">*</span>` : ''}\n </label>\n <div class=\"input-with-suffix\">\n <input\n class=\"text-input ${this._errors.has('baseUrl') ? 'error' : ''}\"\n type=\"text\"\n .value=${this._formData.baseUrl || ''}\n placeholder=\"https://api.example.com/v1\"\n @input=${(e: Event) => this._updateField('baseUrl', (e.target as HTMLInputElement).value)}\n />\n ${this._formData.baseUrl?.includes('/v1') ? html`\n <span class=\"input-suffix\">/v1</span>\n ` : ''}\n </div>\n <span class=\"field-hint\">The API endpoint URL (should end with /v1 for OpenAI-compatible)</span>\n ${this._errors.has('baseUrl') ? html`\n <span class=\"error-message\">${getIcon('alertCircle')} ${this._errors.get('baseUrl')}</span>\n ` : ''}\n </div>\n \n <div class=\"field-group\">\n <label class=\"field-label\">API Key</label>\n <input\n class=\"text-input\"\n type=\"text\"\n .value=${this._formData.apiKey || ''}\n placeholder=\"sk-... or ENV_VAR or !command\"\n @input=${(e: Event) => this._updateField('apiKey', (e.target as HTMLInputElement).value)}\n />\n <span class=\"field-hint\">\n Supports: literal value, ENV_VAR (uppercase), or !shell command\n </span>\n </div>\n \n <button \n class=\"toggle-advanced\"\n @click=${() => this._showAdvanced = !this._showAdvanced}\n >\n ${getIcon(this._showAdvanced ? 'chevronUp' : 'chevronDown')}\n ${this._showAdvanced ? 'Hide Advanced Options' : 'Show Advanced Options'}\n </button>\n \n ${this._showAdvanced ? html`\n <div class=\"advanced-section\">\n <div class=\"field-group\" style=\"margin-bottom: 1rem;\">\n <label class=\"checkbox-label\">\n <input\n class=\"checkbox-input\"\n type=\"checkbox\"\n .checked=${this._formData.authHeader || false}\n @change=${(e: Event) => this._updateField('authHeader', (e.target as HTMLInputElement).checked)}\n />\n Add Authorization header automatically\n </label>\n <span class=\"field-hint\">Adds \"Authorization: Bearer {apiKey}\" header to requests</span>\n </div>\n \n <div class=\"field-group\">\n <label class=\"field-label\">Custom Headers (JSON)</label>\n <textarea\n class=\"textarea-input\"\n .value=${this._formData.headers ? JSON.stringify(this._formData.headers, null, 2) : ''}\n placeholder='{\"X-Custom-Header\": \"value\"}'\n @change=${(e: Event) => {\n try {\n const value = (e.target as HTMLTextAreaElement).value;\n this._updateField('headers', value ? JSON.parse(value) : undefined);\n } catch {\n // Invalid JSON, ignore\n }\n }}\n ></textarea>\n <span class=\"field-hint\">Optional custom headers in JSON format</span>\n </div>\n </div>\n ` : ''}\n `;\n }\n\n private _formatPresetName(key: string): string {\n const names: Record<string, string> = {\n ollama: 'Ollama',\n lmstudio: 'LM Studio',\n openrouter: 'OpenRouter',\n 'vercel-ai-gateway': 'Vercel AI Gateway',\n vllm: 'vLLM',\n custom: 'Custom',\n };\n return names[key] || key;\n }\n\n private _getPresetDescription(key: string): string {\n const descriptions: Record<string, string> = {\n ollama: 'Local LLMs via Ollama',\n lmstudio: 'LM Studio local server',\n openrouter: 'Multi-provider API',\n 'vercel-ai-gateway': 'Vercel AI Gateway',\n vllm: 'vLLM inference server',\n custom: 'Manual configuration',\n };\n return descriptions[key] || '';\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'provider-edit-dialog': ProviderEditDialog;\n }\n}\n","/**\n * ModelJsonEditor Component\n * \n * Visual editor for models.json configuration\n */\n\nimport { html, LitElement, css } from 'lit';\nimport { customElement, property, state, query } from 'lit/decorators.js';\nimport { getIcon } from '../utils/icons.js';\nimport { t } from '../utils/i18n.js';\nimport type { \n ModelsJsonConfig, \n ProviderConfig, \n CustomModel,\n ValidationResult,\n} from '../config/models-json-client.js';\nimport {\n validateModelsJson,\n saveModelsJson,\n reloadModelsJson,\n testApiKey,\n getApiKeyType,\n maskApiKey,\n createCustomModel,\n} from '../config/models-json-client.js';\nimport './ModelEditDialog.js';\nimport type { ModelEditDialog, ModelEditDialogResult } from './ModelEditDialog.js';\nimport './ProviderEditDialog.js';\nimport type { ProviderEditDialog, ProviderEditDialogResult } from './ProviderEditDialog.js';\n\n// API types for dropdown\nconst API_TYPES = [\n { value: 'openai-completions', label: 'OpenAI Completions' },\n { value: 'openai-responses', label: 'OpenAI Responses' },\n { value: 'anthropic-messages', label: 'Anthropic Messages' },\n { value: 'google-generative-ai', label: 'Google Generative AI' },\n { value: 'azure-openai-responses', label: 'Azure OpenAI' },\n { value: 'bedrock-converse-stream', label: 'AWS Bedrock' },\n];\n\ninterface EditorState {\n expandedProviders: Set<string>;\n editingModel: { provider: string; modelId: string } | null;\n showRawJson: boolean;\n}\n\n@customElement('model-json-editor')\nexport class ModelJsonEditor extends LitElement {\n @property({ attribute: false }) config: ModelsJsonConfig = { providers: {} };\n @property({ type: String }) token?: string;\n @property({ type: String }) error?: string;\n \n @state() private _loading = false;\n @state() private _saving = false;\n @state() private _validation: ValidationResult | null = null;\n @state() private _editorState: EditorState = {\n expandedProviders: new Set(),\n editingModel: null,\n showRawJson: false,\n };\n @state() private _showPasswords: Set<string> = new Set();\n @state() private _testResults: Map<string, { type: string; resolved?: string; error?: string }> = new Map();\n @query('model-edit-dialog') private _editDialog!: ModelEditDialog;\n @query('provider-edit-dialog') private _providerEditDialog!: ProviderEditDialog;\n\n static styles = css`\n :host { display: block; }\n \n .editor-header {\n display: flex;\n gap: 0.5rem;\n margin-bottom: 1rem;\n flex-wrap: wrap;\n }\n \n .provider-card {\n border: 1px solid var(--border-color, #e2e8f0);\n border-radius: var(--radius-md, 0.5rem);\n margin-bottom: 0.75rem;\n overflow: hidden;\n }\n \n .provider-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n background: var(--bg-secondary, #f8fafc);\n cursor: pointer;\n user-select: none;\n }\n \n .provider-header:hover {\n background: var(--bg-tertiary, #f1f5f9);\n }\n \n .provider-title {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-weight: 600;\n }\n \n .provider-badge {\n font-size: 0.75rem;\n padding: 0.125rem 0.5rem;\n border-radius: 9999px;\n background: var(--accent-primary, #3b82f6);\n color: white;\n }\n \n .provider-content {\n padding: 1rem;\n display: none;\n }\n \n .provider-content.expanded {\n display: block;\n }\n \n .field-group {\n margin-bottom: 1rem;\n }\n \n .field-label {\n display: block;\n font-size: 0.875rem;\n font-weight: 500;\n margin-bottom: 0.25rem;\n color: var(--text-secondary, #475569);\n }\n \n .text-input, .select-input, .textarea-input {\n width: 100%;\n padding: 0.5rem 0.75rem;\n border: 1px solid var(--border-color, #e2e8f0);\n border-radius: var(--radius-md, 0.375rem);\n background: var(--bg-primary, white);\n color: var(--text-primary, #0f172a);\n font-size: 0.875rem;\n }\n \n .text-input:focus, .select-input:focus, .textarea-input:focus {\n outline: none;\n border-color: var(--accent-primary, #3b82f6);\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);\n }\n \n .input-with-actions {\n display: flex;\n gap: 0.5rem;\n }\n \n .input-with-actions .text-input {\n flex: 1;\n }\n \n .btn {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.5rem 0.75rem;\n border-radius: var(--radius-md, 0.375rem);\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n border: none;\n transition: all 0.15s;\n }\n \n .btn-primary {\n background: var(--accent-primary, #3b82f6);\n color: white;\n }\n \n .btn-primary:hover {\n background: var(--accent-primary-hover, #2563eb);\n }\n \n .btn-secondary {\n background: var(--bg-secondary, #f1f5f9);\n color: var(--text-primary, #0f172a);\n border: 1px solid var(--border-color, #e2e8f0);\n }\n \n .btn-secondary:hover {\n background: var(--bg-tertiary, #e2e8f0);\n }\n \n .btn-ghost {\n background: transparent;\n color: var(--text-secondary, #64748b);\n }\n \n .btn-ghost:hover {\n background: var(--bg-secondary, #f1f5f9);\n }\n \n .btn-icon {\n padding: 0.375rem;\n background: transparent;\n border: none;\n cursor: pointer;\n border-radius: var(--radius-md, 0.375rem);\n color: var(--text-secondary, #64748b);\n }\n \n .btn-icon:hover {\n background: var(--bg-secondary, #f1f5f9);\n color: var(--text-primary, #0f172a);\n }\n \n .btn-sm {\n padding: 0.375rem 0.5rem;\n font-size: 0.75rem;\n }\n \n .models-section {\n margin-top: 1rem;\n padding-top: 1rem;\n border-top: 1px solid var(--border-color, #e2e8f0);\n }\n \n .model-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 0.75rem;\n background: var(--bg-secondary, #f8fafc);\n border-radius: var(--radius-md, 0.375rem);\n margin-bottom: 0.5rem;\n }\n \n .model-actions {\n display: flex;\n gap: 0.25rem;\n }\n \n .empty-state {\n padding: 1.5rem;\n text-align: center;\n color: var(--text-muted, #94a3b8);\n }\n \n .error-alert {\n padding: 0.75rem 1rem;\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: var(--radius-md, 0.375rem);\n color: #dc2626;\n margin-bottom: 1rem;\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n }\n \n .success-alert {\n padding: 0.75rem 1rem;\n background: #f0fdf4;\n border: 1px solid #bbf7d0;\n border-radius: var(--radius-md, 0.375rem);\n color: #16a34a;\n margin-bottom: 1rem;\n }\n \n .validation-errors {\n margin-top: 1rem;\n padding: 0.75rem;\n background: #fefce8;\n border: 1px solid #fde047;\n border-radius: var(--radius-md, 0.375rem);\n }\n \n .validation-error {\n font-size: 0.875rem;\n color: #854d0e;\n margin-bottom: 0.25rem;\n }\n \n .api-key-type {\n font-size: 0.75rem;\n padding: 0.125rem 0.375rem;\n border-radius: 9999px;\n background: var(--bg-tertiary, #e2e8f0);\n color: var(--text-secondary, #64748b);\n }\n \n .api-key-type.shell {\n background: #dbeafe;\n color: #1e40af;\n }\n \n .api-key-type.env {\n background: #dcfce7;\n color: #166534;\n }\n \n .test-result {\n font-size: 0.75rem;\n margin-top: 0.25rem;\n }\n \n .test-result.success {\n color: #16a34a;\n }\n \n .test-result.error {\n color: #dc2626;\n }\n \n .raw-json {\n font-family: monospace;\n font-size: 0.75rem;\n white-space: pre-wrap;\n background: var(--bg-secondary, #f8fafc);\n padding: 1rem;\n border-radius: var(--radius-md, 0.375rem);\n overflow: auto;\n max-height: 400px;\n }\n \n .grid-2 {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 0.75rem;\n }\n\n /* Stats Badge Styles */\n .stats-badge {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.375rem 0.75rem;\n background: var(--bg-secondary, #f1f5f9);\n border-radius: var(--radius-md, 0.375rem);\n font-size: 0.875rem;\n }\n\n .stat-item {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n }\n\n .stat-item.empty {\n opacity: 0.5;\n }\n\n .stat-number {\n font-weight: 600;\n color: var(--accent-primary, #3b82f6);\n }\n\n .stat-item.empty .stat-number {\n color: var(--text-muted, #94a3b8);\n }\n\n .stat-label {\n color: var(--text-muted, #64748b);\n }\n\n .stat-separator {\n color: var(--border-color, #e2e8f0);\n }\n\n /* Enhanced Empty State Styles */\n .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 3rem 2rem;\n text-align: center;\n background: linear-gradient(135deg, var(--bg-secondary, #f8fafc) 0%, var(--bg-primary, white) 100%);\n border: 2px dashed var(--border-color, #e2e8f0);\n border-radius: var(--radius-lg, 0.75rem);\n margin: 1rem 0;\n }\n\n .empty-icon {\n width: 64px;\n height: 64px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--bg-primary, white);\n border-radius: 50%;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n margin-bottom: 1.5rem;\n color: var(--accent-primary, #3b82f6);\n }\n\n .empty-icon svg {\n width: 32px;\n height: 32px;\n }\n\n .empty-title {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--text-primary, #0f172a);\n margin: 0 0 0.5rem;\n }\n\n .empty-description {\n font-size: 0.9375rem;\n color: var(--text-muted, #64748b);\n max-width: 400px;\n margin: 0 0 1.5rem;\n line-height: 1.6;\n }\n\n .empty-actions {\n margin-bottom: 1.5rem;\n }\n\n .empty-suggestions {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n justify-content: center;\n }\n\n .suggestion-tag {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.5rem 0.875rem;\n background: var(--bg-primary, white);\n border: 1px solid var(--border-color, #e2e8f0);\n border-radius: var(--radius-full, 9999px);\n font-size: 0.8125rem;\n color: var(--text-secondary, #475569);\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .suggestion-tag:hover {\n border-color: var(--accent-primary, #3b82f6);\n background: rgba(59, 130, 246, 0.05);\n color: var(--accent-primary, #3b82f6);\n transform: translateY(-1px);\n }\n\n .suggestion-tag svg {\n width: 14px;\n height: 14px;\n }\n\n @media (max-width: 640px) {\n .empty-state {\n padding: 2rem 1rem;\n }\n\n .empty-title {\n font-size: 1.125rem;\n }\n\n .empty-description {\n font-size: 0.875rem;\n }\n\n .stats-badge {\n font-size: 0.8125rem;\n padding: 0.25rem 0.5rem;\n }\n }\n\n .dialog-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n }\n \n .dialog {\n background: var(--bg-primary, white);\n border-radius: var(--radius-lg, 0.5rem);\n width: 90%;\n max-width: 500px;\n max-height: 80vh;\n overflow: auto;\n padding: 1.5rem;\n }\n \n .dialog-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 1rem;\n }\n \n .dialog-title {\n font-size: 1.125rem;\n font-weight: 600;\n }\n \n .dialog-actions {\n display: flex;\n justify-content: flex-end;\n gap: 0.5rem;\n margin-top: 1rem;\n }\n `;\n\n // ============================================\n // Event Handlers\n // ============================================\n\n private _toggleProvider(providerId: string) {\n const expanded = new Set(this._editorState.expandedProviders);\n if (expanded.has(providerId)) {\n expanded.delete(providerId);\n } else {\n expanded.add(providerId);\n }\n this._editorState = { ...this._editorState, expandedProviders: expanded };\n }\n\n private _updateProvider(providerId: string, updates: Partial<ProviderConfig>) {\n const newConfig = { ...this.config };\n newConfig.providers = { ...newConfig.providers };\n newConfig.providers[providerId] = {\n ...newConfig.providers[providerId],\n ...updates,\n };\n this._emitChange(newConfig);\n }\n\n private _addProvider() {\n const handleClose = (e: CustomEvent<ProviderEditDialogResult>) => {\n this._providerEditDialog.removeEventListener('close', handleClose as EventListener);\n \n if (e.detail.confirmed && e.detail.providerId && e.detail.config) {\n const newConfig = { ...this.config };\n newConfig.providers = { ...newConfig.providers };\n newConfig.providers[e.detail.providerId] = e.detail.config;\n \n const expanded = new Set(this._editorState.expandedProviders);\n expanded.add(e.detail.providerId);\n \n this._editorState = { ...this._editorState, expandedProviders: expanded };\n this._emitChange(newConfig);\n }\n };\n \n this._providerEditDialog.addEventListener('close', handleClose as EventListener);\n this._providerEditDialog.open(undefined, undefined, true);\n }\n\n private _quickAddProvider(preset: string) {\n // Quick add with preset - directly open the dialog with preset applied\n const handleClose = (e: CustomEvent<ProviderEditDialogResult>) => {\n this._providerEditDialog.removeEventListener('close', handleClose as EventListener);\n \n if (e.detail.confirmed && e.detail.providerId && e.detail.config) {\n const newConfig = { ...this.config };\n newConfig.providers = { ...newConfig.providers };\n newConfig.providers[e.detail.providerId] = e.detail.config;\n \n const expanded = new Set(this._editorState.expandedProviders);\n expanded.add(e.detail.providerId);\n \n this._editorState = { ...this._editorState, expandedProviders: expanded };\n this._emitChange(newConfig);\n }\n };\n \n this._providerEditDialog.addEventListener('close', handleClose as EventListener);\n \n // Open with preset configuration\n const presets: Record<string, Partial<ProviderConfig>> = {\n ollama: { baseUrl: 'http://localhost:11434/v1', api: 'openai-completions', apiKey: 'ollama' },\n openrouter: { baseUrl: 'https://openrouter.ai/api/v1', api: 'openai-completions', apiKey: '' },\n lmstudio: { baseUrl: 'http://localhost:1234/v1', api: 'openai-completions', apiKey: 'lmstudio' },\n };\n \n const presetConfig = presets[preset];\n if (presetConfig) {\n this._providerEditDialog.open({ ...presetConfig, models: [] }, preset, true);\n } else {\n this._providerEditDialog.open(undefined, undefined, true);\n }\n }\n\n private _removeProvider(providerId: string) {\n if (!confirm(`Remove provider \"${providerId}\"?`)) return;\n \n const newConfig = { ...this.config };\n newConfig.providers = { ...newConfig.providers };\n delete newConfig.providers[providerId];\n this._emitChange(newConfig);\n }\n\n private _addModel(providerId: string) {\n this._editorState = { ...this._editorState, editingModel: { provider: providerId, modelId: '' } };\n \n const handleClose = (e: CustomEvent<ModelEditDialogResult>) => {\n this._editDialog.removeEventListener('close', handleClose as EventListener);\n \n if (e.detail.confirmed && e.detail.model) {\n const provider = this.config.providers[providerId];\n this._updateProvider(providerId, {\n models: [...(provider.models || []), e.detail.model],\n });\n }\n };\n \n this._editDialog.addEventListener('close', handleClose as EventListener);\n this._editDialog.open(undefined, true);\n }\n\n private _removeModel(providerId: string, modelId: string) {\n const provider = this.config.providers[providerId];\n this._updateProvider(providerId, {\n models: (provider.models || []).filter(m => m.id !== modelId),\n });\n }\n\n private _updateModel(providerId: string, modelId: string, updates: Partial<CustomModel>) {\n const provider = this.config.providers[providerId];\n this._updateProvider(providerId, {\n models: (provider.models || []).map(m =>\n m.id === modelId ? { ...m, ...updates } : m\n ),\n });\n }\n\n private _emitChange(config: ModelsJsonConfig) {\n this.dispatchEvent(new CustomEvent<{ config: ModelsJsonConfig }>('change', {\n detail: { config },\n bubbles: true,\n composed: true,\n }));\n }\n\n private async _validate() {\n this._loading = true;\n try {\n this._validation = await validateModelsJson(this.config, this.token);\n } catch (err) {\n console.error('Validation failed:', err);\n } finally {\n this._loading = false;\n }\n }\n\n private async _save() {\n this._saving = true;\n try {\n await saveModelsJson(this.config, this.token);\n this.dispatchEvent(new CustomEvent('save', { bubbles: true, composed: true }));\n } catch (err) {\n console.error('Save failed:', err);\n alert(err instanceof Error ? err.message : 'Failed to save');\n } finally {\n this._saving = false;\n }\n }\n\n private async _reload() {\n this._loading = true;\n try {\n const result = await reloadModelsJson(this.token);\n this.dispatchEvent(new CustomEvent('reload', { \n detail: result,\n bubbles: true, \n composed: true \n }));\n } catch (err) {\n console.error('Reload failed:', err);\n } finally {\n this._loading = false;\n }\n }\n\n private async _testApiKey(providerId: string, value: string) {\n try {\n const result = await testApiKey(value, this.token);\n this._testResults = new Map(this._testResults);\n this._testResults.set(providerId, result);\n this.requestUpdate();\n } catch (err) {\n console.error('API key test failed:', err);\n }\n }\n\n private _togglePassword(providerId: string) {\n const show = new Set(this._showPasswords);\n if (show.has(providerId)) {\n show.delete(providerId);\n } else {\n show.add(providerId);\n }\n this._showPasswords = show;\n }\n\n // ============================================\n // Rendering\n // ============================================\n\n render() {\n const editingModel = this._editorState.editingModel;\n const currentModel = editingModel \n ? this.config.providers[editingModel.provider]?.models?.find(m => m.id === editingModel.modelId)\n : undefined;\n \n return html`\n ${this.error ? html`\n <div class=\"error-alert\">\n ${getIcon('alertCircle')}\n <span>${this.error}</span>\n </div>\n ` : ''}\n \n ${this._renderHeader()}\n ${this._renderProviders()}\n ${this._renderValidationErrors()}\n ${this._editorState.showRawJson ? this._renderRawJson() : ''}\n \n <model-edit-dialog\n .providerId=${editingModel?.provider}\n ></model-edit-dialog>\n \n <provider-edit-dialog></provider-edit-dialog>\n `;\n }\n\n private _renderHeader() {\n const providerCount = Object.keys(this.config.providers).length;\n const modelCount = Object.values(this.config.providers).reduce(\n (sum, p) => sum + (p.models?.length || 0), 0\n );\n\n return html`\n <div class=\"editor-header\">\n <button class=\"btn btn-primary\" @click=${this._addProvider}>\n ${getIcon('plus')} Add Provider\n </button>\n <button class=\"btn btn-secondary\" @click=${this._validate} ?disabled=${this._loading}>\n ${this._loading ? 'Validating...' : 'Validate'}\n </button>\n <button class=\"btn btn-secondary\" @click=${this._save} ?disabled=${this._saving}>\n ${this._saving ? 'Saving...' : 'Save'}\n </button>\n <button class=\"btn btn-secondary\" @click=${this._reload} ?disabled=${this._loading}>\n ${getIcon('refreshCw')} Reload\n </button>\n <button class=\"btn btn-ghost\" @click=${() => this._editorState = { ...this._editorState, showRawJson: !this._editorState.showRawJson }}>\n ${this._editorState.showRawJson ? 'Hide JSON' : 'Show JSON'}\n </button>\n <div class=\"stats-badge\">\n <span class=\"stat-item ${providerCount === 0 ? 'empty' : ''}\">\n <span class=\"stat-number\">${providerCount}</span>\n <span class=\"stat-label\">provider${providerCount !== 1 ? 's' : ''}</span>\n </span>\n <span class=\"stat-separator\">|</span>\n <span class=\"stat-item ${modelCount === 0 ? 'empty' : ''}\">\n <span class=\"stat-number\">${modelCount}</span>\n <span class=\"stat-label\">model${modelCount !== 1 ? 's' : ''}</span>\n </span>\n </div>\n </div>\n `;\n }\n\n private _renderProviders() {\n const providers = Object.entries(this.config.providers);\n \n if (providers.length === 0) {\n return html`\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n ${getIcon('cpu')}\n </div>\n <h3 class=\"empty-title\">No Custom Providers</h3>\n <p class=\"empty-description\">\n Add custom model providers like Ollama, vLLM, OpenRouter, or other OpenAI-compatible APIs.\n </p>\n <div class=\"empty-actions\">\n <button class=\"btn btn-primary\" @click=${this._addProvider}>\n ${getIcon('plus')} Add Your First Provider\n </button>\n </div>\n <div class=\"empty-suggestions\">\n <div class=\"suggestion-tag\" @click=${() => this._quickAddProvider('ollama')}>\n ${getIcon('zap')} Ollama\n </div>\n <div class=\"suggestion-tag\" @click=${() => this._quickAddProvider('openrouter')}>\n ${getIcon('globe')} OpenRouter\n </div>\n <div class=\"suggestion-tag\" @click=${() => this._quickAddProvider('lmstudio')}>\n ${getIcon('monitor')} LM Studio\n </div>\n </div>\n </div>\n `;\n }\n\n return html`\n ${providers.map(([id, config]) => this._renderProvider(id, config))}\n `;\n }\n\n private _renderProvider(id: string, config: ProviderConfig) {\n const isExpanded = this._editorState.expandedProviders.has(id);\n const modelCount = config.models?.length || 0;\n const isPasswordVisible = this._showPasswords.has(id);\n const testResult = this._testResults.get(id);\n const apiKeyType = config.apiKey ? getApiKeyType(config.apiKey) : null;\n\n return html`\n <div class=\"provider-card\">\n <div class=\"provider-header\" @click=${() => this._toggleProvider(id)}>\n <div class=\"provider-title\">\n ${getIcon(isExpanded ? 'chevronDown' : 'chevronRight')}\n <span>${id}</span>\n ${modelCount > 0 ? html`<span class=\"provider-badge\">${modelCount} models</span>` : ''}\n ${apiKeyType ? html`<span class=\"api-key-type ${apiKeyType}\">${apiKeyType}</span>\n ` : ''}\n </div>\n <button class=\"btn-icon\" @click=${(e: Event) => { e.stopPropagation(); this._removeProvider(id); }}>\n ${getIcon('trash')}\n </button>\n </div>\n \n <div class=\"provider-content ${isExpanded ? 'expanded' : ''}\">\n ${this._renderProviderConfig(id, config, isPasswordVisible, testResult)}\n ${this._renderModelsSection(id, config)}\n </div>\n </div>\n `;\n }\n\n private _renderProviderConfig(\n id: string, \n config: ProviderConfig, \n isPasswordVisible: boolean,\n testResult?: { type: string; resolved?: string; error?: string }\n ) {\n return html`\n <div class=\"grid-2\">\n <div class=\"field-group\">\n <label class=\"field-label\">Base URL</label>\n <input\n class=\"text-input\"\n type=\"text\"\n .value=${config.baseUrl || ''}\n placeholder=\"https://api.example.com/v1\"\n @change=${(e: Event) => this._updateProvider(id, { baseUrl: (e.target as HTMLInputElement).value })}\n >\n </div>\n \n <div class=\"field-group\">\n <label class=\"field-label\">API Type</label>\n <select\n class=\"select-input\"\n .value=${config.api || 'openai-completions'}\n @change=${(e: Event) => this._updateProvider(id, { api: (e.target as HTMLSelectElement).value })}\n >\n ${API_TYPES.map(api => html`<option value=${api.value}>${api.label}</option>\n `)}\n </select>\n </div>\n </div>\n \n <div class=\"field-group\">\n <label class=\"field-label\">API Key</label>\n <div class=\"input-with-actions\">\n <input\n class=\"text-input\"\n type=${isPasswordVisible ? 'text' : 'password'}\n .value=${config.apiKey || ''}\n placeholder=\"sk-... or ENV_VAR or !command\"\n @change=${(e: Event) => {\n this._updateProvider(id, { apiKey: (e.target as HTMLInputElement).value });\n this._testResults.delete(id);\n }}\n >\n <button class=\"btn btn-secondary btn-sm\" @click=${() => this._togglePassword(id)}>\n ${isPasswordVisible ? 'Hide' : 'Show'}\n </button>\n <button class=\"btn btn-secondary btn-sm\" @click=${() => this._testApiKey(id, config.apiKey || '')}>\n Test\n </button>\n </div>\n ${testResult ? html`\n <div class=\"test-result ${testResult.error ? 'error' : 'success'}\">\n ${testResult.error \n ? `Error: ${testResult.error}` \n : `Resolved (${testResult.type}): ${maskApiKey(testResult.resolved || '')}`\n }\n </div>\n ` : ''}\n <small style=\"color: var(--text-muted, #94a3b8)\">\n Supports: literal value, ENV_VAR name (uppercase), or !shell command\n </small>\n </div>\n \n <div class=\"field-group\">\n <label class=\"toggle-label\" style=\"display: flex; align-items: center; gap: 0.5rem; cursor: pointer;\">\n <input\n type=\"checkbox\"\n .checked=${config.authHeader || false}\n @change=${(e: Event) => this._updateProvider(id, { authHeader: (e.target as HTMLInputElement).checked })}\n >\n <span>Add Authorization header automatically</span>\n </label>\n </div>\n `;\n }\n\n private _renderModelsSection(providerId: string, config: ProviderConfig) {\n const models = config.models || [];\n\n return html`\n <div class=\"models-section\">\n <div style=\"display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem;\">\n <span style=\"font-weight: 600;\">Models</span>\n <button class=\"btn btn-primary btn-sm\" @click=${() => this._addModel(providerId)}>\n ${getIcon('plus')} Add Model\n </button>\n </div>\n \n ${models.length === 0 ? html`\n <p style=\"color: var(--text-muted, #94a3b8); font-size: 0.875rem;\">\n No custom models. Models from this provider will inherit from built-in configuration.\n </p>\n ` : html`\n ${models.map(model => this._renderModel(providerId, model))}\n `}\n </div>\n `;\n }\n\n private _renderModel(providerId: string, model: CustomModel) {\n return html`\n <div class=\"model-item\">\n <div>\n <div style=\"font-weight: 500;\">${model.id}</div>\n ${model.name && model.name !== model.id ? html`\n <div style=\"font-size: 0.75rem; color: var(--text-muted, #94a3b8);\">${model.name}</div>\n ` : ''}\n </div>\n <div class=\"model-actions\">\n <button class=\"btn-icon\" @click=${() => this._editModel(providerId, model)}>\n ${getIcon('edit')}\n </button>\n <button class=\"btn-icon\" @click=${() => this._removeModel(providerId, model.id)}>\n ${getIcon('trash')}\n </button>\n </div>\n </div>\n `;\n }\n\n private _editModel(providerId: string, model: CustomModel) {\n this._editorState = { ...this._editorState, editingModel: { provider: providerId, modelId: model.id } };\n \n const handleClose = (e: CustomEvent<ModelEditDialogResult>) => {\n this._editDialog.removeEventListener('close', handleClose as EventListener);\n \n if (e.detail.confirmed && e.detail.model) {\n const provider = this.config.providers[providerId];\n const updatedModels = (provider.models || []).map(m =>\n m.id === model.id ? e.detail.model! : m\n );\n this._updateProvider(providerId, { models: updatedModels });\n }\n };\n \n this._editDialog.addEventListener('close', handleClose as EventListener);\n this._editDialog.open(model, false);\n }\n\n private _renderValidationErrors() {\n if (!this._validation || this._validation.errors.length === 0) return '';\n \n return html`\n <div class=\"validation-errors\">\n <div style=\"font-weight: 600; margin-bottom: 0.5rem;\">\n ${this._validation.valid ? 'Warnings' : 'Validation Errors'}\n </div>\n ${this._validation.errors.map(err => html`\n <div class=\"validation-error\">\n ${err.path}: ${err.message} (${err.severity})\n </div>\n `)}\n </div>\n `;\n }\n\n private _renderRawJson() {\n return html`\n <div class=\"raw-json\">${JSON.stringify(this.config, null, 2)}</div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'model-json-editor': ModelJsonEditor;\n }\n}\n","/**\n * Settings page component (refactored) - uses ProviderList and ModelSelector.\n */\n\nimport { html, LitElement } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { getIcon } from '../utils/icons.js';\nimport { t } from '../utils/i18n.js';\nimport '../components/ProviderList.js';\nimport '../components/ModelSelector.js';\nimport { fetchConfiguredModels, fetchProviderMeta, type Model } from '../config/registry-client.js';\nimport type { ProviderInfo, ProviderListChangeEvent, ProviderListOAuthEvent } from '../components/ProviderList.js';\nimport '../components/ModelJsonEditor.js';\nimport type { ModelsJsonConfig } from '../config/models-json-client.js';\nimport { fetchModelsJson, saveModelsJson } from '../config/models-json-client.js';\n\nexport interface SettingsPageConfig {\n token?: string;\n}\n\ntype DmPolicy = 'pairing' | 'allowlist' | 'open' | 'disabled';\ntype GroupPolicy = 'open' | 'disabled' | 'allowlist';\ntype StreamMode = 'off' | 'partial' | 'block';\ntype ReplyToMode = 'off' | 'first' | 'all';\n\ninterface TelegramAccount {\n accountId: string;\n name: string;\n enabled: boolean;\n token: string;\n allowFrom: (string | number)[];\n groupAllowFrom?: (string | number)[];\n dmPolicy: DmPolicy;\n groupPolicy: GroupPolicy;\n replyToMode: ReplyToMode;\n apiRoot: string;\n proxy: string;\n historyLimit: number;\n textChunkLimit: number;\n streamMode: StreamMode;\n}\n\ninterface TelegramConfig {\n enabled: boolean;\n token: string;\n apiRoot: string;\n debug: boolean;\n allowFrom: (string | number)[];\n groupAllowFrom: (string | number)[];\n dmPolicy: DmPolicy;\n groupPolicy: GroupPolicy;\n replyToMode: ReplyToMode;\n streamMode: StreamMode;\n historyLimit: number;\n textChunkLimit: number;\n proxy: string;\n accounts: Record<string, TelegramAccount>;\n advancedMode: boolean;\n}\n\ninterface SettingsData {\n model: string;\n maxTokens: number;\n temperature: number;\n maxToolIterations: number;\n workspace: string;\n providers: Record<string, string>;\n telegram: TelegramConfig;\n whatsapp: {\n enabled: boolean;\n bridgeUrl: string;\n allowFrom: string[];\n };\n gateway: {\n heartbeat: {\n enabled: boolean;\n intervalMs: number;\n };\n auth?: {\n mode: 'none' | 'token';\n token?: string;\n };\n };\n}\n\n@customElement('settings-page')\nexport class SettingsPage extends LitElement {\n @property({ attribute: false }) config?: SettingsPageConfig;\n\n @state() private _activeSection: 'agent' | 'providers' | 'models' | 'channels' | 'gateway' = 'agent';\n @state() private _loading = false;\n @state() private _saving = false;\n @state() private _saveSuccess = false;\n @state() private _dirty = false;\n \n // Telegram token UI state\n @state() private _showTelegramToken: boolean = false;\n @state() private _copiedTelegramToken: boolean = false;\n // Gateway token UI state\n @state() private _showGatewayToken: boolean = false;\n @state() private _copiedGatewayToken: boolean = false;\n\n @state() private _settings: SettingsData = {\n model: '',\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n workspace: '~/.xopcbot/workspace',\n providers: {},\n telegram: {\n enabled: false,\n token: '',\n apiRoot: '',\n debug: false,\n allowFrom: [],\n groupAllowFrom: [],\n dmPolicy: 'pairing',\n groupPolicy: 'open',\n replyToMode: 'off',\n streamMode: 'partial',\n historyLimit: 50,\n textChunkLimit: 4000,\n proxy: '',\n accounts: {},\n advancedMode: false,\n },\n whatsapp: {\n enabled: false,\n bridgeUrl: 'ws://localhost:3001',\n allowFrom: [],\n },\n gateway: {\n heartbeat: {\n enabled: true,\n intervalMs: 60000,\n },\n auth: {\n mode: 'token',\n token: '',\n },\n },\n };\n\n @state() private _providers: ProviderInfo[] = [];\n @state() private _loadingProviders = false;\n @state() private _models: Model[] = [];\n \n // Models.json state\n @state() private _modelsJsonConfig: ModelsJsonConfig = { providers: {} };\n @state() private _modelsJsonError?: string;\n @state() private _loadingModelsJson = false;\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n connectedCallback() {\n super.connectedCallback();\n this._loadSettings();\n this._loadProviders();\n this._loadModelsJson();\n }\n\n private async _loadModelsJson() {\n this._loadingModelsJson = true;\n const token = this.config?.token;\n\n try {\n const { config, loadError } = await fetchModelsJson(token);\n this._modelsJsonConfig = config;\n this._modelsJsonError = loadError;\n } catch (err) {\n console.error('Failed to load models.json:', err);\n this._modelsJsonError = err instanceof Error ? err.message : 'Failed to load models.json';\n } finally {\n this._loadingModelsJson = false;\n }\n }\n\n private async _loadSettings() {\n this._loading = true;\n const token = this.config?.token;\n\n try {\n const response = await fetch(`${window.location.origin}/api/config`, {\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (response.ok) {\n const data = await response.json();\n const config = data.payload?.config;\n\n if (config) {\n let modelValue = config.agents?.defaults?.model;\n if (modelValue && typeof modelValue === 'object') {\n modelValue = modelValue.primary || '';\n }\n\n this._settings = {\n model: modelValue || 'anthropic/claude-sonnet-4-5',\n maxTokens: config.agents?.defaults?.maxTokens || 8192,\n temperature: config.agents?.defaults?.temperature ?? 0.7,\n maxToolIterations: config.agents?.defaults?.maxToolIterations || 20,\n workspace: config.agents?.defaults?.workspace || '~/.xopcbot/workspace',\n providers: config.providers || {},\n telegram: {\n enabled: config.channels?.telegram?.enabled || false,\n token: config.channels?.telegram?.token || '',\n apiRoot: config.channels?.telegram?.apiRoot || '',\n debug: config.channels?.telegram?.debug || false,\n allowFrom: config.channels?.telegram?.allowFrom || [],\n groupAllowFrom: config.channels?.telegram?.groupAllowFrom || [],\n dmPolicy: config.channels?.telegram?.dmPolicy || 'pairing',\n groupPolicy: config.channels?.telegram?.groupPolicy || 'open',\n replyToMode: config.channels?.telegram?.replyToMode || 'off',\n streamMode: config.channels?.telegram?.streamMode || 'partial',\n historyLimit: config.channels?.telegram?.historyLimit || 50,\n textChunkLimit: config.channels?.telegram?.textChunkLimit || 4000,\n proxy: config.channels?.telegram?.proxy || '',\n accounts: config.channels?.telegram?.accounts || {},\n advancedMode: false,\n },\n whatsapp: {\n enabled: config.channels?.whatsapp?.enabled || false,\n bridgeUrl: config.channels?.whatsapp?.bridgeUrl || 'ws://localhost:3001',\n allowFrom: config.channels?.whatsapp?.allowFrom || [],\n },\n gateway: {\n heartbeat: {\n enabled: config.gateway?.heartbeat?.enabled ?? true,\n intervalMs: config.gateway?.heartbeat?.intervalMs || 60000,\n },\n auth: {\n mode: config.gateway?.auth?.mode || 'token',\n token: config.gateway?.auth?.token || '',\n },\n },\n };\n }\n }\n } catch (err) {\n console.error('Failed to load settings:', err);\n } finally {\n this._loading = false;\n }\n }\n\n private async _loadProviders() {\n this._loadingProviders = true;\n const token = this.config?.token;\n\n try {\n // Load models and provider metadata in parallel\n const [models, providerMeta] = await Promise.all([\n fetchConfiguredModels(token),\n fetchProviderMeta(token),\n ]);\n \n this._models = models;\n\n // Use metadata from backend to build provider list\n // If provider has configured models, mark as configured\n const configuredProviders = new Set(models.map(m => m.provider));\n \n this._providers = providerMeta.map(meta => ({\n id: meta.id,\n name: meta.name,\n category: meta.category,\n supportsOAuth: meta.supportsOAuth,\n // Check if either has API key configured OR has available models\n configured: meta.configured || configuredProviders.has(meta.id),\n }));\n } catch (err) {\n console.error('Failed to load providers:', err);\n } finally {\n this._loadingProviders = false;\n }\n }\n\n private _updateSettings(path: string, value: unknown) {\n const keys = path.split('.');\n const newSettings = { ...this._settings };\n let current: Record<string, unknown> = newSettings;\n\n for (let i = 0; i < keys.length - 1; i++) {\n current[keys[i]] = { ...(current[keys[i]] as Record<string, unknown>) };\n current = current[keys[i]] as Record<string, unknown>;\n }\n\n current[keys[keys.length - 1]] = value;\n this._settings = newSettings as SettingsData;\n this._dirty = true;\n }\n\n private _onProviderChange(e: CustomEvent<ProviderListChangeEvent>) {\n const { provider, apiKey } = e.detail;\n this._updateSettings('providers', {\n ...this._settings.providers,\n [provider]: apiKey,\n });\n }\n\n private _onProviderOAuth(e: CustomEvent<ProviderListOAuthEvent>) {\n const { provider, success, message, error } = e.detail;\n \n if (success) {\n console.log('OAuth login successful for:', provider, message);\n // Page will reload automatically\n } else if (error) {\n console.error('OAuth login failed for:', provider, error);\n alert(`OAuth login failed: ${error}`);\n }\n }\n\n private _toggleTelegramTokenVisibility() {\n this._showTelegramToken = !this._showTelegramToken;\n }\n\n private async _copyTelegramToken() {\n if (!this._settings.telegram.token) return;\n try {\n await navigator.clipboard.writeText(this._settings.telegram.token);\n this._copiedTelegramToken = true;\n setTimeout(() => {\n this._copiedTelegramToken = false;\n }, 2000);\n } catch (err) {\n console.error('Failed to copy:', err);\n }\n }\n\n private _toggleGatewayTokenVisibility() {\n this._showGatewayToken = !this._showGatewayToken;\n }\n\n private async _copyGatewayToken() {\n if (!this._settings.gateway.auth?.token) return;\n try {\n await navigator.clipboard.writeText(this._settings.gateway.auth.token);\n this._copiedGatewayToken = true;\n setTimeout(() => {\n this._copiedGatewayToken = false;\n }, 2000);\n } catch (err) {\n console.error('Failed to copy:', err);\n }\n }\n\n private async _saveSettings() {\n this._saving = true;\n this._saveSuccess = false;\n const token = this.config?.token;\n\n const updates = {\n agents: {\n defaults: {\n model: this._settings.model,\n maxTokens: this._settings.maxTokens,\n temperature: this._settings.temperature,\n maxToolIterations: this._settings.maxToolIterations,\n workspace: this._settings.workspace,\n },\n },\n providers: this._settings.providers,\n channels: {\n telegram: {\n enabled: this._settings.telegram.enabled,\n token: this._settings.telegram.token,\n apiRoot: this._settings.telegram.apiRoot || undefined,\n debug: this._settings.telegram.debug,\n allowFrom: this._settings.telegram.allowFrom,\n groupAllowFrom: this._settings.telegram.groupAllowFrom.length > 0 ? this._settings.telegram.groupAllowFrom : undefined,\n dmPolicy: this._settings.telegram.dmPolicy,\n groupPolicy: this._settings.telegram.groupPolicy,\n replyToMode: this._settings.telegram.replyToMode,\n streamMode: this._settings.telegram.streamMode,\n historyLimit: this._settings.telegram.historyLimit,\n textChunkLimit: this._settings.telegram.textChunkLimit,\n proxy: this._settings.telegram.proxy || undefined,\n accounts: Object.keys(this._settings.telegram.accounts).length > 0 ? this._settings.telegram.accounts : undefined,\n },\n whatsapp: {\n enabled: this._settings.whatsapp.enabled,\n bridgeUrl: this._settings.whatsapp.bridgeUrl,\n allowFrom: this._settings.whatsapp.allowFrom,\n },\n },\n gateway: {\n heartbeat: this._settings.gateway.heartbeat,\n auth: this._settings.gateway.auth?.token ? {\n mode: this._settings.gateway.auth.mode,\n token: this._settings.gateway.auth.token || undefined,\n } : {\n mode: this._settings.gateway.auth?.mode || 'token',\n },\n },\n };\n\n try {\n // Save config.json\n const response = await fetch(`${window.location.origin}/api/config`, {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n },\n body: JSON.stringify(updates),\n });\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.error || 'Failed to save settings');\n }\n\n // Also save models.json if it was modified\n if (this._modelsJsonConfig) {\n try {\n await saveModelsJson(this._modelsJsonConfig, token);\n } catch (modelsErr) {\n console.warn('Failed to save models.json:', modelsErr);\n // Don't fail the whole save if models.json fails\n }\n }\n\n this._dirty = false;\n this._saveSuccess = true;\n setTimeout(() => (this._saveSuccess = false), 3000);\n } catch (err) {\n console.error('Failed to save settings:', err);\n alert(err instanceof Error ? err.message : 'Failed to save settings');\n } finally {\n this._saving = false;\n }\n }\n\n private _renderNav() {\n const sections = [\n { id: 'agent', title: t('settings.sections.agent'), icon: 'bot' },\n { id: 'providers', title: t('settings.sections.providers'), icon: 'cloud' },\n { id: 'models', title: t('settings.sections.models') || 'Models', icon: 'cpu' },\n { id: 'channels', title: t('settings.sections.channels'), icon: 'plug' },\n { id: 'gateway', title: t('settings.sections.gateway'), icon: 'globe' },\n ] as const;\n\n return html`\n <nav class=\"sidebar-nav\">\n ${sections.map(\n (section) => html`\n <button\n class=\"sidebar-item ${this._activeSection === section.id ? 'active' : ''}\"\n @click=${() => (this._activeSection = section.id)}\n >\n ${getIcon(section.icon)}\n <span>${section.title}</span>\n </button>\n `\n )}\n </nav>\n `;\n }\n\n private _renderAgentSection() {\n return html`\n <div class=\"section-content\">\n <div class=\"section-header\">\n <h2>${t('settings.sections.agent')}</h2>\n </div>\n\n <div class=\"fields-grid\">\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">${t('settings.fields.model')}</label>\n </div>\n <model-selector\n .value=${this._settings.model}\n .filter=${'configured'}\n .token=${this.config?.token}\n @change=${(e: CustomEvent) => this._updateSettings('model', e.detail.modelId)}\n ></model-selector>\n <p class=\"field-desc\">${t('settings.descriptionsFields.model')}</p>\n </div>\n\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">${t('settings.fields.workspace')}</label>\n </div>\n <input\n class=\"text-input\"\n type=\"text\"\n .value=${this._settings.workspace}\n @change=${(e: Event) =>\n this._updateSettings('workspace', (e.target as HTMLInputElement).value)\n }\n />\n </div>\n\n <div style=\"display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;\">\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">${t('settings.fields.maxTokens')}</label>\n </div>\n <input\n class=\"text-input\"\n type=\"number\"\n .value=${this._settings.maxTokens}\n @change=${(e: Event) =>\n this._updateSettings('maxTokens', parseInt((e.target as HTMLInputElement).value))\n }\n />\n </div>\n\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">${t('settings.fields.temperature')}</label>\n </div>\n <input\n class=\"text-input\"\n type=\"number\"\n step=\"0.1\"\n min=\"0\"\n max=\"2\"\n .value=${this._settings.temperature}\n @change=${(e: Event) =>\n this._updateSettings('temperature', parseFloat((e.target as HTMLInputElement).value))\n }\n />\n </div>\n </div>\n\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">${t('settings.fields.maxToolIterations')}</label>\n </div>\n <input\n class=\"text-input\"\n type=\"number\"\n .value=${this._settings.maxToolIterations}\n @change=${(e: Event) =>\n this._updateSettings(\n 'maxToolIterations',\n parseInt((e.target as HTMLInputElement).value)\n )\n }\n />\n </div>\n </div>\n </div>\n `;\n }\n\n private _renderModelsSection() {\n return html`\n <div class=\"section-content\">\n <div class=\"section-header\">\n <h2>${t('settings.sections.models') || 'Custom Models'}</h2>\n <p class=\"section-desc\">\n Configure custom model providers (Ollama, vLLM, OpenRouter, etc.) via models.json.\n <a href=\"https://github.com/xopc/xopcbot/blob/main/docs/models.md\" target=\"_blank\">Learn more</a>\n </p>\n </div>\n\n ${this._modelsJsonError ? html`\n <div class=\"alert alert-error\" style=\"margin-bottom: 1rem; padding: 0.75rem; background: #fef2f2; border: 1px solid #fecaca; border-radius: 0.375rem; color: #dc2626;\">\n ${getIcon('alertCircle')}\n <span>${this._modelsJsonError}</span>\n </div>\n ` : ''}\n\n ${this._loadingModelsJson ? html`\n <div class=\"loading-state\">\n <span class=\"spinner\"></span>\n <p>Loading models.json...</p>\n </div>\n ` : html`\n <model-json-editor\n .config=${this._modelsJsonConfig}\n .token=${this.config?.token}\n @change=${(e: CustomEvent<{ config: typeof this._modelsJsonConfig }>) => {\n this._modelsJsonConfig = e.detail.config;\n this._dirty = true;\n }}\n @save=${() => {\n this._saveSuccess = true;\n setTimeout(() => this._saveSuccess = false, 3000);\n this._loadModelsJson();\n }}\n @reload=${() => {\n this._loadModelsJson();\n }}\n ></model-json-editor>\n `}\n </div>\n `;\n }\n\n private _renderProvidersSection() {\n const providers: ProviderInfo[] = this._providers.map((p) => ({\n id: p.id,\n name: p.name,\n category: p.category,\n supportsOAuth: p.supportsOAuth,\n // Use configured from providerMeta (which checks env vars + config + registry)\n configured: p.configured,\n // Show API key only if set in config file (don't show env var values)\n // If configured via env var, show placeholder to indicate it's set\n apiKey: this._settings.providers[p.id] || (p.configured ? '••••••••••••' : ''),\n }));\n\n return html`\n <div class=\"section-content\">\n <div class=\"section-header\">\n <h2>${t('settings.sections.providers')}</h2>\n <p class=\"section-desc\">\n Configure API keys for the providers you want to use. Models from configured providers\n will be available for selection.\n </p>\n </div>\n\n <provider-list\n .providers=${providers}\n .loading=${this._loadingProviders}\n .token=${this.config?.token}\n @change=${this._onProviderChange}\n @oauth=${this._onProviderOAuth}\n ></provider-list>\n </div>\n `;\n }\n\n private _renderChannelsSection() {\n return html`\n <div class=\"section-content\">\n <div class=\"section-header\">\n <h2>${t('settings.sections.channels')}</h2>\n </div>\n\n <div class=\"fields-grid\">\n ${this._renderTelegramSection()}\n ${this._renderWhatsAppSection()}\n </div>\n </div>\n `;\n }\n\n private _renderTelegramSection() {\n const dmPolicyOptions: { value: DmPolicy; label: string }[] = [\n { value: 'pairing', label: 'Pairing (Start bot to authorize)' },\n { value: 'allowlist', label: 'Allowlist (Only configured IDs)' },\n { value: 'open', label: 'Open (Accept all DMs)' },\n { value: 'disabled', label: 'Disabled (No DMs)' },\n ];\n\n const groupPolicyOptions: { value: GroupPolicy; label: string }[] = [\n { value: 'open', label: 'Open (All groups)' },\n { value: 'disabled', label: 'Disabled (No groups)' },\n { value: 'allowlist', label: 'Allowlist (Only configured groups)' },\n ];\n\n const replyToModeOptions: { value: ReplyToMode; label: string }[] = [\n { value: 'off', label: 'Off' },\n { value: 'first', label: 'First (Reply to first message)' },\n { value: 'all', label: 'All (Reply to all messages)' },\n ];\n\n const streamModeOptions: { value: StreamMode; label: string }[] = [\n { value: 'off', label: 'Off (No streaming)' },\n { value: 'partial', label: 'Partial (Chunked updates)' },\n { value: 'block', label: 'Block (Edit final message)' },\n ];\n\n return html`\n <div class=\"channel-section\">\n <label class=\"toggle-label\">\n <input\n class=\"toggle-input\"\n type=\"checkbox\"\n .checked=${this._settings.telegram.enabled}\n @change=${(e: Event) =>\n this._updateSettings(\n 'telegram.enabled',\n (e.target as HTMLInputElement).checked\n )\n }\n />\n <span class=\"toggle-switch\"></span>\n <span class=\"toggle-text\">Enable Telegram</span>\n </label>\n\n ${this._settings.telegram.enabled\n ? html`\n <div class=\"channel-fields\" style=\"margin-top: 1.5rem; padding-left: 1rem; border-left: 2px solid var(--border-color);\">\n <!-- Simple Mode -->\n <!-- Bot Token (Required) -->\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">Bot Token <span class=\"required-mark\">*</span></label>\n </div>\n <div class=\"input-with-actions\">\n <input\n class=\"text-input\"\n type=\"${this._showTelegramToken ? 'text' : 'password'}\"\n .value=${this._settings.telegram.token}\n @change=${(e: Event) =>\n this._updateSettings(\n 'telegram.token',\n (e.target as HTMLInputElement).value\n )\n }\n placeholder=\"123456789:ABCdefGHIjklMNOpqrsTUVwxyz\"\n />\n <div class=\"input-actions\">\n ${this._settings.telegram.token ? html`\n <button\n class=\"btn-icon\"\n @click=${this._copyTelegramToken}\n title=\"${this._copiedTelegramToken ? 'Copied!' : 'Copy Token'}\"\n >\n ${getIcon(this._copiedTelegramToken ? 'check' : 'copy')}\n </button>\n ` : ''}\n <button\n class=\"btn-icon\"\n @click=${this._toggleTelegramTokenVisibility}\n title=\"${this._showTelegramToken ? 'Hide' : 'Show'} Token\"\n >\n ${getIcon(this._showTelegramToken ? 'eyeOff' : 'eye')}\n </button>\n </div>\n </div>\n <p class=\"field-desc\">Get your token from @BotFather</p>\n </div>\n\n <!-- Allow From -->\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">Allow From (User IDs)</label>\n </div>\n <textarea\n class=\"textarea-input\"\n .value=${this._settings.telegram.allowFrom.join(', ')}\n @change=${(e: Event) =>\n this._updateSettings(\n 'telegram.allowFrom',\n (e.target as HTMLTextAreaElement).value\n .split(/[,\\n]/)\n .map((s) => s.trim())\n .filter(Boolean)\n )\n }\n placeholder=\"123456789, 987654321\"\n rows=\"2\"\n ></textarea>\n <p class=\"field-desc\">Comma-separated user IDs allowed to use the bot</p>\n </div>\n\n <!-- Expand/Collapse Advanced Settings -->\n <div class=\"field-group\" style=\"margin-top: 1rem;\">\n <button\n class=\"btn btn-ghost\"\n @click=${() => this._updateSettings('telegram.advancedMode', !this._settings.telegram.advancedMode)}\n style=\"display: flex; align-items: center; gap: 0.5rem;\"\n >\n ${getIcon(this._settings.telegram.advancedMode ? 'chevronUp' : 'chevronDown')}\n <span>${this._settings.telegram.advancedMode ? 'Hide' : 'Show'} Advanced Settings</span>\n </button>\n </div>\n\n <!-- Advanced Settings (Expandable) -->\n ${this._settings.telegram.advancedMode\n ? html`\n <div style=\"margin-top: 1.5rem; padding-top: 1.5rem; border-top: 1px solid var(--border-color);\">\n <!-- API Root (Optional) -->\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">API Root</label>\n </div>\n <input\n class=\"text-input\"\n type=\"text\"\n .value=${this._settings.telegram.apiRoot}\n @change=${(e: Event) =>\n this._updateSettings(\n 'telegram.apiRoot',\n (e.target as HTMLInputElement).value\n )\n }\n placeholder=\"https://api.telegram.org\"\n />\n <p class=\"field-desc\">Custom API endpoint (leave empty for default)</p>\n </div>\n\n <!-- Proxy (Optional) -->\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">Proxy</label>\n </div>\n <input\n class=\"text-input\"\n type=\"text\"\n .value=${this._settings.telegram.proxy}\n @change=${(e: Event) =>\n this._updateSettings(\n 'telegram.proxy',\n (e.target as HTMLInputElement).value\n )\n }\n placeholder=\"http://proxy.example.com:8080\"\n />\n <p class=\"field-desc\">HTTP/HTTPS proxy URL (optional)</p>\n </div>\n\n <!-- DM Policy -->\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">DM Policy</label>\n </div>\n <select\n class=\"select-input\"\n .value=${this._settings.telegram.dmPolicy}\n @change=${(e: Event) =>\n this._updateSettings(\n 'telegram.dmPolicy',\n (e.target as HTMLSelectElement).value as DmPolicy\n )\n }\n >\n ${dmPolicyOptions.map(\n (opt) =>\n html`<option value=${opt.value}>${opt.label}</option>`\n )}\n </select>\n <p class=\"field-desc\">How to handle direct messages</p>\n </div>\n\n <!-- Group Policy -->\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">Group Policy</label>\n </div>\n <select\n class=\"select-input\"\n .value=${this._settings.telegram.groupPolicy}\n @change=${(e: Event) =>\n this._updateSettings(\n 'telegram.groupPolicy',\n (e.target as HTMLSelectElement).value as GroupPolicy\n )\n }\n >\n ${groupPolicyOptions.map(\n (opt) =>\n html`<option value=${opt.value}>${opt.label}</option>`\n )}\n </select>\n <p class=\"field-desc\">How to handle group messages</p>\n </div>\n\n <!-- Reply To Mode -->\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">Reply To Mode</label>\n </div>\n <select\n class=\"select-input\"\n .value=${this._settings.telegram.replyToMode}\n @change=${(e: Event) =>\n this._updateSettings(\n 'telegram.replyToMode',\n (e.target as HTMLSelectElement).value as ReplyToMode\n )\n }\n >\n ${replyToModeOptions.map(\n (opt) =>\n html`<option value=${opt.value}>${opt.label}</option>`\n )}\n </select>\n </div>\n\n <!-- Stream Mode -->\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">Stream Mode</label>\n </div>\n <select\n class=\"select-input\"\n .value=${this._settings.telegram.streamMode}\n @change=${(e: Event) =>\n this._updateSettings(\n 'telegram.streamMode',\n (e.target as HTMLSelectElement).value as StreamMode\n )\n }\n >\n ${streamModeOptions.map(\n (opt) =>\n html`<option value=${opt.value}>${opt.label}</option>`\n )}\n </select>\n </div>\n\n <!-- Group Allow From -->\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">Allow From Groups (Group IDs)</label>\n </div>\n <textarea\n class=\"textarea-input\"\n .value=${this._settings.telegram.groupAllowFrom.join(', ')}\n @change=${(e: Event) =>\n this._updateSettings(\n 'telegram.groupAllowFrom',\n (e.target as HTMLTextAreaElement).value\n .split(/[,\\n]/)\n .map((s) => s.trim())\n .filter(Boolean)\n )\n }\n placeholder=\"-1001234567890, -1009876543210\"\n rows=\"2\"\n ></textarea>\n <p class=\"field-desc\">Comma-separated group IDs allowed to use the bot</p>\n </div>\n\n <!-- History Limit & Text Chunk Limit -->\n <div style=\"display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;\">\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">History Limit</label>\n </div>\n <input\n class=\"text-input\"\n type=\"number\"\n .value=${this._settings.telegram.historyLimit}\n @change=${(e: Event) =>\n this._updateSettings(\n 'telegram.historyLimit',\n parseInt((e.target as HTMLInputElement).value) || 50\n )\n }\n min=\"10\"\n max=\"200\"\n />\n <p class=\"field-desc\">Messages per session</p>\n </div>\n\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">Text Chunk Limit</label>\n </div>\n <input\n class=\"text-input\"\n type=\"number\"\n .value=${this._settings.telegram.textChunkLimit}\n @change=${(e: Event) =>\n this._updateSettings(\n 'telegram.textChunkLimit',\n parseInt((e.target as HTMLInputElement).value) || 4000\n )\n }\n min=\"1000\"\n max=\"10000\"\n step=\"100\"\n />\n <p class=\"field-desc\">Max characters per message</p>\n </div>\n </div>\n\n <!-- Debug Mode -->\n <div class=\"field-group\">\n <label class=\"toggle-label\">\n <input\n class=\"toggle-input\"\n type=\"checkbox\"\n .checked=${this._settings.telegram.debug}\n @change=${(e: Event) =>\n this._updateSettings(\n 'telegram.debug',\n (e.target as HTMLInputElement).checked\n )\n }\n />\n <span class=\"toggle-switch\"></span>\n <span class=\"toggle-text\">Debug Mode</span>\n </label>\n <p class=\"field-desc\">Enable verbose logging for troubleshooting</p>\n </div>\n </div>\n `\n : ''}\n </div>\n `\n : ''}\n </div>\n `;\n }\n\n private _renderWhatsAppSection() {\n return html`\n <div class=\"channel-section\" style=\"margin-top: 2rem;\">\n <label class=\"toggle-label\">\n <input\n class=\"toggle-input\"\n type=\"checkbox\"\n .checked=${this._settings.whatsapp.enabled}\n @change=${(e: Event) =>\n this._updateSettings(\n 'whatsapp.enabled',\n (e.target as HTMLInputElement).checked\n )\n }\n />\n <span class=\"toggle-switch\"></span>\n <span class=\"toggle-text\">Enable WhatsApp</span>\n </label>\n\n ${this._settings.whatsapp.enabled\n ? html`\n <div class=\"channel-fields\" style=\"margin-top: 1.5rem; padding-left: 1rem; border-left: 2px solid var(--border-color);\">\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">Bridge URL</label>\n </div>\n <input\n class=\"text-input\"\n type=\"text\"\n .value=${this._settings.whatsapp.bridgeUrl}\n @change=${(e: Event) =>\n this._updateSettings(\n 'whatsapp.bridgeUrl',\n (e.target as HTMLInputElement).value\n )\n }\n placeholder=\"ws://localhost:3001\"\n />\n </div>\n\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">Allow From</label>\n </div>\n <textarea\n class=\"textarea-input\"\n .value=${this._settings.whatsapp.allowFrom.join(', ')}\n @change=${(e: Event) =>\n this._updateSettings(\n 'whatsapp.allowFrom',\n (e.target as HTMLTextAreaElement).value\n .split(/[,\\n]/)\n .map((s) => s.trim())\n .filter(Boolean)\n )\n }\n placeholder=\"1234567890, 9876543210\"\n rows=\"2\"\n ></textarea>\n <p class=\"field-desc\">Comma-separated phone numbers allowed to use the bot</p>\n </div>\n </div>\n `\n : ''}\n </div>\n `;\n }\n\n private _renderGatewaySection() {\n return html`\n <div class=\"section-content\">\n <div class=\"section-header\">\n <h2>${t('settings.sections.gateway')}</h2>\n </div>\n\n <div class=\"fields-grid\">\n <!-- Auth Token -->\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">Access Token</label>\n </div>\n <div class=\"input-with-actions\">\n <input\n class=\"text-input\"\n type=\"${this._showGatewayToken ? 'text' : 'password'}\"\n .value=${this._settings.gateway.auth?.token || ''}\n @change=${(e: Event) =>\n this._updateSettings('gateway.auth.token', (e.target as HTMLInputElement).value)\n }\n placeholder=\"Enter access token or leave empty to generate\"\n />\n <div class=\"input-actions\">\n ${this._settings.gateway.auth?.token ? html`\n <button\n class=\"btn-icon\"\n @click=${this._copyGatewayToken}\n title=\"${this._copiedGatewayToken ? 'Copied!' : 'Copy Token'}\"\n >\n ${getIcon(this._copiedGatewayToken ? 'check' : 'copy')}\n </button>\n ` : ''}\n <button\n class=\"btn-icon\"\n @click=${this._toggleGatewayTokenVisibility}\n title=\"${this._showGatewayToken ? 'Hide' : 'Show'} Token\"\n >\n ${getIcon(this._showGatewayToken ? 'eyeOff' : 'eye')}\n </button>\n </div>\n </div>\n <p class=\"field-desc\">Token used to authenticate API requests. Leave empty to auto-generate.</p>\n </div>\n\n <!-- Heartbeat Enable -->\n <div class=\"field-group\">\n <label class=\"toggle-label\">\n <input\n class=\"toggle-input\"\n type=\"checkbox\"\n .checked=${this._settings.gateway.heartbeat.enabled}\n @change=${(e: Event) =>\n this._updateSettings(\n 'gateway.heartbeat.enabled',\n (e.target as HTMLInputElement).checked\n )\n }\n />\n <span class=\"toggle-switch\"></span>\n <span class=\"toggle-text\">Enable Heartbeat</span>\n </label>\n </div>\n\n <!-- Heartbeat Interval -->\n <div class=\"field-group\">\n <div class=\"field-header\">\n <label class=\"field-label\">Heartbeat Interval (ms)</label>\n </div>\n <input\n class=\"text-input\"\n type=\"number\"\n .value=${this._settings.gateway.heartbeat.intervalMs}\n @change=${(e: Event) =>\n this._updateSettings(\n 'gateway.heartbeat.intervalMs',\n parseInt((e.target as HTMLInputElement).value)\n )\n }\n />\n </div>\n </div>\n </div>\n `;\n }\n\n private _renderContent() {\n switch (this._activeSection) {\n case 'agent':\n return this._renderAgentSection();\n case 'providers':\n return this._renderProvidersSection();\n case 'models':\n return this._renderModelsSection();\n case 'channels':\n return this._renderChannelsSection();\n case 'gateway':\n return this._renderGatewaySection();\n default:\n return html`<div>Select a section</div>`;\n }\n }\n\n render() {\n if (this._loading) {\n return html`\n <div class=\"loading-state\">\n <span class=\"spinner\"></span>\n <p>Loading settings...</p>\n </div>\n `;\n }\n\n return html`\n <div class=\"settings-page\">\n <aside class=\"settings-sidebar\">${this._renderNav()}</aside>\n\n <main class=\"settings-main\">\n ${this._renderContent()}\n\n ${this._dirty\n ? html`\n <div class=\"floating-save\">\n <span class=\"dirty-count\">You have unsaved changes</span>\n <button\n class=\"btn btn-primary\"\n ?disabled=${this._saving}\n @click=${this._saveSettings}\n >\n ${this._saving ? html`<span class=\"spinner-sm\"></span> Saving...` : 'Save Changes'}\n </button>\n </div>\n `\n : ''}\n\n ${this._saveSuccess\n ? html`<div class=\"save-success\">Settings saved successfully!</div>`\n : ''}\n </main>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'settings-page': SettingsPage;\n }\n}\n","import { html, LitElement } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { getIcon } from '../utils/icons';\nimport { t } from '../utils/i18n';\n\nexport interface TokenDialogConfig {\n serverUrl: string;\n onSave: (token: string) => void;\n onCancel?: () => void;\n}\n\n@customElement('token-dialog')\nexport class TokenDialog extends LitElement {\n @property({ attribute: false }) config?: TokenDialogConfig;\n @state() private _token = '';\n @state() private _showToken = false;\n @state() private _loading = false;\n @state() private _error = '';\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n private _handleSave(): void {\n if (!this._token.trim()) {\n this._error = 'Please enter a token';\n return;\n }\n this.config?.onSave(this._token.trim());\n }\n\n private _handleKeydown(e: KeyboardEvent): void {\n if (e.key === 'Enter') {\n this._handleSave();\n }\n }\n\n override render(): unknown {\n return html`\n <div class=\"token-dialog-overlay\" @click=${this._handleOverlayClick}>\n <div class=\"token-dialog\" @click=${(e: Event) => e.stopPropagation()}>\n <div class=\"token-dialog-header\">\n <h3>🔐 Authentication Required</h3>\n <p>Please enter your gateway authentication token to continue.</p>\n </div>\n\n <div class=\"token-dialog-body\">\n <div class=\"field-group\">\n <label class=\"field-label\">Gateway URL</label>\n <input\n type=\"text\"\n class=\"text-input\"\n .value=${this.config?.serverUrl || ''}\n disabled\n />\n </div>\n\n <div class=\"field-group\">\n <label class=\"field-label\">Token</label>\n <div class=\"token-input-wrapper\">\n <input\n type=${this._showToken ? 'text' : 'password'}\n class=\"text-input\"\n .value=${this._token}\n placeholder=\"Enter your gateway token (e.g., ea4c67bf...)\"\n @input=${(e: Event) => {\n this._token = (e.target as HTMLInputElement).value;\n this._error = '';\n }}\n @keydown=${this._handleKeydown}\n />\n <button\n class=\"btn btn-icon toggle-visibility\"\n @click=${() => this._showToken = !this._showToken}\n title=${this._showToken ? 'Hide token' : 'Show token'}\n >\n ${this._showToken ? getIcon('eyeOff') : getIcon('eye')}\n </button>\n </div>\n ${this._error ? html`<span class=\"field-error\">${this._error}</span>` : ''}\n </div>\n\n <div class=\"token-hint\">\n <p>💡 <strong>How to get your token:</strong></p>\n <ol>\n <li>Run <code>xopcbot gateway token</code> in your terminal</li>\n <li>Or run <code>xopcbot gateway token --generate</code> to create a new one</li>\n <li>Copy the token and paste it here</li>\n </ol>\n </div>\n </div>\n\n <div class=\"token-dialog-footer\">\n <button\n class=\"btn btn-primary\"\n ?disabled=${this._loading}\n @click=${this._handleSave}\n >\n ${this._loading ? html`\n <span class=\"spinner-sm\"></span>\n Connecting...\n ` : html`\n ${getIcon('check')}\n Connect\n `}\n </button>\n </div>\n </div>\n </div>\n `;\n }\n\n private _handleOverlayClick(e: Event): void {\n // Close on overlay click if cancel is allowed\n if (this.config?.onCancel) {\n this.config.onCancel();\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'token-dialog': TokenDialog;\n }\n}\n","import { html, nothing } from 'lit';\nimport type { TemplateResult } from 'lit';\nimport { getIcon } from './utils/icons';\nimport { t } from './utils/i18n';\n\n// Get tab groups with i18n labels\nexport function getTabGroups() {\n return [\n { label: t('nav.chat'), tabs: ['chat'] as const },\n { label: t('nav.management'), tabs: ['sessions', 'cron', 'logs'] as const },\n { label: t('nav.settings'), tabs: ['settings'] as const },\n ];\n}\n\nexport type Tab = 'chat' | 'sessions' | 'cron' | 'logs' | 'settings';\n\nexport interface NavItem {\n id: Tab;\n label: string;\n icon: string;\n}\n\n// Get tab label (supports i18n)\nexport function getTabLabel(tab: Tab): string {\n return t(`nav.${tab}`);\n}\n\n// Tab icon map (no subtitle needed)\nconst TAB_ICONS: Record<Tab, string> = {\n chat: 'messageSquare',\n sessions: 'folderOpen',\n cron: 'clock',\n logs: 'fileText',\n settings: 'settings',\n};\n\n// Chat route with optional session key\nexport type ChatRoute = \n | { type: 'recent' } // Most recent session\n | { type: 'session'; sessionKey: string }\n | { type: 'new' }; // Create new session\n\n// Parse hash to get chat route\nexport function parseChatHash(hash: string): ChatRoute | null {\n const cleanHash = hash.replace(/^#\\/?chat\\/?/, '');\n \n if (!cleanHash || cleanHash === '/') {\n return { type: 'recent' };\n }\n \n const path = cleanHash.replace(/^\\/?/, '');\n \n if (path === 'new') {\n return { type: 'new' };\n }\n \n // Validate session key format (should be alphanumeric with colons)\n if (path && path.length > 0) {\n return { type: 'session', sessionKey: decodeURIComponent(path) };\n }\n \n return { type: 'recent' };\n}\n\n// Get hash from chat route\nexport function getChatHash(route: ChatRoute): string {\n switch (route.type) {\n case 'recent':\n return '#/chat';\n case 'new':\n return '#/chat/new';\n case 'session':\n return `#/chat/${encodeURIComponent(route.sessionKey)}`;\n }\n}\n\n// Render navigation item\nexport function renderNavItem(\n tab: Tab,\n isActive: boolean,\n onClick: () => void\n): TemplateResult {\n const icon = TAB_ICONS[tab];\n const label = getTabLabel(tab);\n \n return html`\n <button \n class=\"nav-item ${isActive ? 'nav-item--active' : ''}\"\n @click=${onClick}\n role=\"tab\"\n aria-selected=${isActive}\n >\n <span class=\"nav-item__icon\">${getIcon(icon)}</span>\n <span class=\"nav-item__text\">${label}</span>\n </button>\n `;\n}\n\n// Render a collapsed navigation group\nexport function renderNavGroup(\n label: string,\n items: TemplateResult[],\n isCollapsed: boolean = false\n): TemplateResult {\n return html`\n <div class=\"nav-group ${isCollapsed ? 'nav-group--collapsed' : ''}\">\n <div class=\"nav-label nav-label--static\">\n <span class=\"nav-label__text\">${label}</span>\n </div>\n <div class=\"nav-group__items\">\n ${items}\n </div>\n </div>\n `;\n}\n","/**\n * LocalStorage utilities for xopcbot UI settings.\n * Uses individual keys instead of object storage.\n */\n\n// Individual storage keys\nconst TOKEN_KEY = 'xopcbot.token';\nconst THEME_KEY = 'xopcbot.theme';\nconst LANGUAGE_KEY = 'xopcbot.language';\n\nexport type Theme = 'light' | 'dark' | 'system';\nexport type Language = 'en' | 'zh';\n\n/**\n * Get the gateway token.\n * No gatewayUrl needed - always uses current origin.\n */\nexport function getToken(): string {\n try {\n return localStorage.getItem(TOKEN_KEY) || '';\n } catch {\n return '';\n }\n}\n\n/**\n * Set the gateway token.\n */\nexport function setToken(token: string): void {\n try {\n localStorage.setItem(TOKEN_KEY, token);\n } catch (err) {\n console.error('Failed to save token:', err);\n }\n}\n\n/**\n * Get the theme.\n */\nexport function getTheme(): Theme {\n try {\n const theme = localStorage.getItem(THEME_KEY) as Theme;\n return theme === 'light' || theme === 'dark' || theme === 'system' ? theme : 'system';\n } catch {\n return 'system';\n }\n}\n\n/**\n * Set the theme.\n */\nexport function setTheme(theme: Theme): void {\n try {\n localStorage.setItem(THEME_KEY, theme);\n } catch (err) {\n console.error('Failed to save theme:', err);\n }\n}\n\n/**\n * Get the language.\n */\nexport function getLanguage(): Language {\n try {\n const lang = localStorage.getItem(LANGUAGE_KEY) as Language;\n return lang === 'en' || lang === 'zh' ? lang : 'en';\n } catch {\n return 'en';\n }\n}\n\n/**\n * Set the language.\n */\nexport function setLanguage(lang: Language): void {\n try {\n localStorage.setItem(LANGUAGE_KEY, lang);\n } catch (err) {\n console.error('Failed to save language:', err);\n }\n}\n\n/**\n * Clear all settings.\n */\nexport function clearSettings(): void {\n try {\n localStorage.removeItem(TOKEN_KEY);\n localStorage.removeItem(THEME_KEY);\n localStorage.removeItem(LANGUAGE_KEY);\n } catch (err) {\n console.error('Failed to clear settings:', err);\n }\n}\n\n// Legacy compatibility - for old code that uses loadSettings/saveSettings\nexport interface UiSettings {\n gatewayUrl: string;\n token: string;\n theme: Theme;\n language: Language;\n}\n\n/**\n * @deprecated Use individual getters/setters instead\n */\nexport function loadSettings(): UiSettings {\n return {\n gatewayUrl: '', // No longer used - always uses current origin\n token: getToken(),\n theme: getTheme(),\n language: getLanguage(),\n };\n}\n\n/**\n * @deprecated Use individual setters instead\n */\nexport function saveSettings(settings: Partial<UiSettings>): void {\n if (settings.token !== undefined) setToken(settings.token);\n if (settings.theme !== undefined) setTheme(settings.theme);\n if (settings.language !== undefined) setLanguage(settings.language);\n}\n\n// Legacy aliases\nexport const getGatewayToken = getToken;\nexport const setGatewayToken = setToken;\n","import { html, LitElement, nothing } from 'lit';\nimport { customElement, property, state, query } from 'lit/decorators.js';\nimport './gateway-chat';\nimport './pages/SessionManager';\nimport './pages/CronManager';\n// Pages\nimport './pages/LogManager';\nimport './pages/SettingsPage';\n// Components\nimport './components/TokenDialog';\nimport type { TokenDialog } from './components/TokenDialog';\nimport {\n getTabGroups,\n type Tab,\n renderNavItem,\n parseChatHash,\n getChatHash,\n type ChatRoute\n} from './navigation';\nimport { getIcon } from './utils/icons';\nimport { t, setLanguage, getCurrentLanguage, initI18n } from './utils/i18n';\nimport { getToken, setToken, getTheme, setTheme, getLanguage, setLanguage as setStoredLanguage } from './utils/storage';\nimport type { XopcbotGatewayChat } from './gateway-chat';\n\nexport type { Tab } from './navigation';\n\nexport interface AppSettings {\n navCollapsed: boolean;\n theme: 'light' | 'dark' | 'system';\n}\n\n// SettingsPage component is imported at top\n\n@customElement('xopcbot-app')\nexport class XopcbotApp extends LitElement {\n @state() private _gatewayConfig: {\n url: string;\n token?: string;\n } = {\n url: window.location.origin,\n token: getToken() || undefined,\n };\n\n @state() private _activeTab: Tab = 'chat';\n @state() private _navCollapsed = false;\n @state() private _navMobileOpen = false; // Mobile overlay state\n @state() private _theme: 'light' | 'dark' | 'system' = 'system';\n @state() private _language: 'en' | 'zh' = 'en';\n @state() private _chatRoute: ChatRoute = { type: 'recent' };\n @state() private _showTokenDialog = false;\n\n @query('xopcbot-gateway-chat') private _chatElement!: XopcbotGatewayChat;\n\n // Legacy property support\n get gatewayConfig() { return this._gatewayConfig; }\n set gatewayConfig(value) { this._gatewayConfig = value || { url: window.location.origin }; }\n\n constructor() {\n super();\n }\n\n private _initializeToken(): void {\n // Check URL for token parameter\n const urlParams = new URLSearchParams(window.location.search);\n const urlToken = urlParams.get('token');\n\n // If token in URL, save it to localStorage and remove from URL\n if (urlToken) {\n setToken(urlToken);\n // Remove token from URL without reloading\n const newUrl = window.location.pathname + window.location.hash;\n window.history.replaceState({}, '', newUrl);\n }\n\n // Read token from localStorage\n const token = getToken();\n\n // Update gatewayConfig with storage token\n this._gatewayConfig = {\n url: window.location.origin,\n token: token || undefined,\n };\n\n // Check if we need to show token dialog\n this._showTokenDialog = !token;\n }\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n\n // Initialize token in connectedCallback to ensure localStorage is available\n this._initializeToken();\n\n this._loadTheme();\n this._loadLanguage();\n this._loadRouteFromHash();\n\n // Listen for system theme changes\n window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {\n if (this._theme === 'system') {\n this._applyTheme();\n }\n });\n\n // Listen for language changes\n window.addEventListener('languagechange', () => {\n this.requestUpdate();\n });\n\n // Listen for hash changes (browser back/forward)\n window.addEventListener('hashchange', () => {\n this._loadRouteFromHash();\n });\n }\n\n /**\n * Load current tab from URL hash\n */\n private _loadRouteFromHash(): void {\n const hash = location.hash.slice(1);\n \n // Check if it's a chat route with session\n if (hash.startsWith('chat')) {\n const chatRoute = parseChatHash(hash);\n if (chatRoute) {\n if (this._activeTab !== 'chat') {\n this._activeTab = 'chat';\n }\n // Only update if route changed\n if (JSON.stringify(this._chatRoute) !== JSON.stringify(chatRoute)) {\n this._chatRoute = chatRoute;\n }\n }\n return;\n }\n \n const tab = hash as Tab;\n const validTabs: Tab[] = ['sessions', 'cron', 'logs', 'settings'];\n \n if (validTabs.includes(tab)) {\n if (this._activeTab !== tab) {\n this._activeTab = tab;\n }\n }\n }\n\n /**\n * Update URL hash when switching tabs\n */\n private _switchTab(tab: Tab): void {\n this._activeTab = tab;\n \n // Update URL hash without triggering hashchange\n let newHash: string;\n if (tab === 'chat') {\n newHash = getChatHash(this._chatRoute);\n } else {\n newHash = `#${tab}`;\n }\n \n if (location.hash !== newHash) {\n history.pushState(null, '', newHash);\n }\n \n // Close mobile nav if open\n this._navMobileOpen = false;\n }\n\n /**\n * Update chat route and URL\n */\n private _updateChatRoute(route: ChatRoute): void {\n this._chatRoute = route;\n const newHash = getChatHash(route);\n history.pushState(null, '', newHash);\n }\n\n private _loadTheme(): void {\n this._theme = getTheme();\n this._applyTheme();\n }\n\n private _loadLanguage(): void {\n this._language = getLanguage();\n setLanguage(this._language);\n }\n\n private _applyTheme(): void {\n const html = document.documentElement;\n\n // Remove both classes first\n html.classList.remove('light', 'dark');\n\n let isDark = false;\n if (this._theme === 'dark') {\n isDark = true;\n } else if (this._theme === 'system') {\n isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;\n }\n // For 'light' or when system is light, isDark remains false\n\n if (isDark) {\n html.classList.add('dark');\n } else {\n html.classList.add('light');\n }\n\n // Dispatch event for other components\n window.dispatchEvent(new CustomEvent('themechange', {\n detail: { theme: isDark ? 'dark' : 'light' }\n }));\n }\n\n private _setTheme(theme: 'light' | 'dark' | 'system'): void {\n this._theme = theme;\n setTheme(theme);\n this._applyTheme();\n }\n\n private _setLanguage(lang: 'en' | 'zh'): void {\n this._language = lang;\n setLanguage(lang);\n setStoredLanguage(lang);\n this.requestUpdate();\n }\n\n private _renderThemeToggle(): unknown {\n return html`\n <div class=\"pill-toggle\">\n <button\n class=\"pill-btn ${this._theme === 'light' ? 'active' : ''}\"\n @click=${() => this._setTheme('light')}\n title=\"Light\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"5\"></circle>\n <line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\"></line>\n <line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\"></line>\n <line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\"></line>\n <line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\"></line>\n <line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\"></line>\n <line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\"></line>\n <line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\"></line>\n <line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\"></line>\n </svg>\n </button>\n <button\n class=\"pill-btn ${this._theme === 'dark' ? 'active' : ''}\"\n @click=${() => this._setTheme('dark')}\n title=\"Dark\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\"></path>\n </svg>\n </button>\n <button\n class=\"pill-btn ${this._theme === 'system' ? 'active' : ''}\"\n @click=${() => this._setTheme('system')}\n title=\"System\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\"></rect>\n <line x1=\"8\" y1=\"21\" x2=\"16\" y2=\"21\"></line>\n <line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\"></line>\n </svg>\n </button>\n </div>\n `;\n }\n\n private _renderLanguageToggle(): unknown {\n return html`\n <div class=\"pill-toggle\">\n <button\n class=\"pill-btn ${this._language === 'en' ? 'active' : ''}\"\n @click=${() => this._setLanguage('en')}\n title=\"English\"\n >\n EN\n </button>\n <button\n class=\"pill-btn ${this._language === 'zh' ? 'active' : ''}\"\n @click=${() => this._setLanguage('zh')}\n title=\"中文\"\n >\n 中\n </button>\n </div>\n `;\n }\n\n private _toggleNav(): void {\n const isMobile = window.innerWidth < 768;\n if (isMobile) {\n // Mobile: toggle overlay\n this._navMobileOpen = !this._navMobileOpen;\n } else {\n // Desktop: toggle collapsed state\n this._navCollapsed = !this._navCollapsed;\n }\n }\n\n private _closeNavMobile(): void {\n this._navMobileOpen = false;\n }\n\n private _handleTokenSave(token: string): void {\n // Save to localStorage\n setToken(token);\n \n // Update gateway config - always use current origin\n this._gatewayConfig = {\n url: window.location.origin,\n token,\n };\n \n // Hide dialog\n this._showTokenDialog = false;\n \n // Force re-render (not needed for @state but kept for clarity)\n this.requestUpdate();\n }\n\n override render(): unknown {\n // Show token dialog if no token\n if (this._showTokenDialog) {\n return html`\n <token-dialog\n .config=${{\n serverUrl: window.location.origin,\n onSave: (token: string) => this._handleTokenSave(token),\n }}\n ></token-dialog>\n `;\n }\n return html`\n <div class=\"shell ${this._activeTab === 'chat' ? 'shell--chat' : ''} ${this._navCollapsed ? 'shell--nav-collapsed' : ''}\">\n <!-- Topbar -->\n <header class=\"topbar\">\n <div class=\"topbar-left\">\n <button\n class=\"nav-collapse-toggle\"\n @click=${this._toggleNav}\n title=\"${this._navCollapsed ? 'Expand sidebar' : 'Collapse sidebar'}\"\n aria-label=\"${this._navCollapsed ? 'Expand sidebar' : 'Collapse sidebar'}\"\n >\n <span class=\"nav-collapse-toggle__icon\">${getIcon('menu')}</span>\n </button>\n\n <div class=\"brand\">\n <div class=\"brand-logo\">\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"24\" height=\"24\" rx=\"6\" fill=\"url(#logo-gradient)\"/>\n <path d=\"M8 12L11 15L16 9\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <defs>\n <linearGradient id=\"logo-gradient\" x1=\"0\" y1=\"0\" x2=\"24\" y2=\"24\" gradientUnits=\"userSpaceOnUse\">\n <stop stop-color=\"#3b82f6\"/>\n <stop offset=\"1\" stop-color=\"#8b5cf6\"/>\n </linearGradient>\n </defs>\n </svg>\n </div>\n <div class=\"brand-text\">\n <div class=\"brand-title\">XOPCBOT</div>\n <div class=\"brand-sub\">Gateway</div>\n </div>\n </div>\n </div>\n\n <div class=\"topbar-status\">\n ${this._renderLanguageToggle()}\n ${this._renderThemeToggle()}\n </div>\n </header>\n\n <!-- Mobile Overlay Backdrop -->\n ${this._navMobileOpen ? html`\n <div class=\"nav-overlay\" @click=${this._closeNavMobile}></div>\n ` : nothing}\n\n <div class=\"shell-main\">\n <!-- Sidebar Navigation -->\n <aside class=\"nav ${this._navCollapsed ? 'nav--collapsed' : ''} ${this._navMobileOpen ? 'nav--mobile-open' : ''}\">\n ${getTabGroups().map((group) => {\n const hasActiveTab = group.tabs.some((tab) => tab === this._activeTab);\n return html`\n <div class=\"nav-group\">\n <div class=\"nav-label nav-label--static\">\n <span class=\"nav-label__text\">${group.label}</span>\n </div>\n <div class=\"nav-group__items\">\n ${group.tabs.map((tab) =>\n renderNavItem(\n tab,\n this._activeTab === tab,\n () => {\n this._switchTab(tab);\n }\n )\n )}\n </div>\n </div>\n `;\n })}\n </aside>\n\n <!-- Main Content -->\n <main class=\"content ${this._activeTab === 'chat' ? 'content--chat' : ''}\">\n ${this._activeTab === 'chat' ? this._renderChat() : nothing}\n ${this._activeTab === 'sessions' ? this._renderSessions() : nothing}\n ${this._activeTab === 'cron' ? this._renderCron() : nothing}\n ${this._activeTab === 'logs' ? this._renderLogs() : nothing}\n ${this._activeTab === 'settings' ? this._renderSettings() : nothing}\n </main>\n </div>\n </div>\n `;\n }\n\n private _renderChat(): unknown {\n const token = getToken();\n return html`\n <xopcbot-gateway-chat\n .config=${{ url: window.location.origin, token: token || undefined }}\n .route=${this._chatRoute}\n .enableAttachments=${true}\n .enableModelSelector=${true}\n .enableThinkingSelector=${true}\n @route-change=${(e: CustomEvent<ChatRoute>) => this._updateChatRoute(e.detail)}\n ></xopcbot-gateway-chat>\n `;\n }\n\n private _renderSessions(): unknown {\n const token = getToken() || this._gatewayConfig?.token;\n\n return html`\n <session-manager\n .config=${{ token }}\n ></session-manager>\n `;\n }\n\n private _renderCron(): unknown {\n const token = getToken() || this._gatewayConfig?.token;\n\n return html`\n <cron-manager\n .config=${{ token }}\n ></cron-manager>\n `;\n }\n\n private _renderLogs(): unknown {\n const token = getToken() || this._gatewayConfig?.token;\n\n return html`\n <log-manager\n .config=${{ token }}\n ></log-manager>\n `;\n }\n\n private _renderSettings(): unknown {\n const token = getToken() || this._gatewayConfig?.token;\n\n return html`\n <settings-page\n .config=${{ token }}\n ></settings-page>\n `;\n }\n\n // Public method to show chat\n public showChat(): void {\n this._activeTab = 'chat';\n }\n\n // Get chat element for external access\n public get chatElement(): XopcbotGatewayChat | undefined {\n return this._chatElement;\n }\n}\n\n// Export as both named and default for flexibility\nexport { XopcbotApp as default };\n","/**\n * Simple Markdown Renderer Component\n * Lightweight markdown rendering without external dependencies\n */\n\nimport { html, LitElement, unsafeCSS } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\n\nconst styles = `\n:host { display: block; }\n\n.markdown-body {\n font-size: 0.9375rem;\n line-height: 1.6;\n color: var(--text-primary);\n}\n\n.markdown-body h1,\n.markdown-body h2,\n.markdown-body h3,\n.markdown-body h4,\n.markdown-body h5,\n.markdown-body h6 {\n margin-top: 1.5em;\n margin-bottom: 0.75em;\n font-weight: 600;\n line-height: 1.3;\n}\n\n.markdown-body h1 { font-size: 1.5em; border-bottom: 1px solid var(--border-color); padding-bottom: 0.3em; }\n.markdown-body h2 { font-size: 1.3em; border-bottom: 1px solid var(--border-color); padding-bottom: 0.3em; }\n.markdown-body h3 { font-size: 1.1em; }\n.markdown-body p { margin-bottom: 1em; }\n\n.markdown-body ul,\n.markdown-body ol {\n margin-bottom: 1em;\n padding-left: 2em;\n}\n\n.markdown-body li { margin-bottom: 0.25em; }\n\n.markdown-body code {\n font-family: var(--font-mono);\n font-size: 0.875em;\n background: var(--bg-secondary);\n padding: 0.15em 0.4em;\n border-radius: var(--radius-sm);\n color: var(--accent-primary);\n}\n\n.markdown-body pre {\n background: var(--bg-secondary);\n border-radius: var(--radius-md);\n padding: 1em;\n overflow-x: auto;\n margin-bottom: 1em;\n}\n\n.markdown-body pre code {\n background: transparent;\n padding: 0;\n color: var(--text-primary);\n font-size: 0.8125rem;\n}\n\n.markdown-body blockquote {\n margin: 0 0 1em;\n padding: 0.75em 1em;\n border-left: 4px solid var(--accent-primary);\n color: var(--text-secondary);\n background: var(--bg-secondary);\n border-radius: 0 var(--radius-md) var(--radius-md) 0;\n}\n\n.markdown-body a {\n color: var(--accent-primary);\n text-decoration: none;\n}\n\n.markdown-body a:hover { text-decoration: underline; }\n\n.markdown-body hr {\n height: 1px;\n background: var(--border-color);\n border: none;\n margin: 1.5em 0;\n}\n\n.markdown-body table {\n width: 100%;\n border-collapse: collapse;\n margin-bottom: 1em;\n}\n\n.markdown-body th,\n.markdown-body td {\n padding: 0.5em 0.75em;\n border: 1px solid var(--border-color);\n text-align: left;\n}\n\n.markdown-body th {\n background: var(--bg-secondary);\n font-weight: 600;\n}\n\n.markdown-body strong { font-weight: 600; }\n.markdown-body em { font-style: italic; }\n`;\n\n/**\n * Simple markdown parser\n * Supports: headers, bold, italic, code, code blocks, links, lists, blockquotes, tables, hr\n */\nfunction parseMarkdown(text: string): string {\n let html = text\n // Escape HTML\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n \n // Code blocks\n .replace(/```(\\w+)?\\n([\\s\\S]*?)```/g, (_, lang, code) => {\n return `\\u003cpre\\u003e\\u003ccode class=\"language-${lang || 'text'}\"\\u003e${code.trim()}\\u003c/code\\u003e\\u003c/pre\\u003e`;\n })\n \n // Inline code\n .replace(/`([^`]+)`/g, '\\u003ccode\\u003e$1\\u003c/code\\u003e')\n \n // Headers\n .replace(/^###### (.*$)/gim, '\\u003ch6\\u003e$1\\u003c/h6\\u003e')\n .replace(/^##### (.*$)/gim, '\\u003ch5\\u003e$1\\u003c/h5\\u003e')\n .replace(/^#### (.*$)/gim, '\\u003ch4\\u003e$1\\u003c/h4\\u003e')\n .replace(/^### (.*$)/gim, '\\u003ch3\\u003e$1\\u003c/h3\\u003e')\n .replace(/^## (.*$)/gim, '\\u003ch2\\u003e$1\\u003c/h2\\u003e')\n .replace(/^# (.*$)/gim, '\\u003ch1\\u003e$1\\u003c/h1\\u003e')\n \n // Bold and italic\n .replace(/\\*\\*\\*(.*?)\\*\\*\\*/g, '\\u003cstrong\\u003e\\u003cem\\u003e$1\\u003c/em\\u003e\\u003c/strong\\u003e')\n .replace(/\\*\\*(.*?)\\*\\*/g, '\\u003cstrong\\u003e$1\\u003c/strong\\u003e')\n .replace(/\\*(.*?)\\*/g, '\\u003cem\\u003e$1\\u003c/em\\u003e')\n .replace(/___(.*?)___/g, '\\u003cstrong\\u003e\\u003cem\\u003e$1\\u003c/em\\u003e\\u003c/strong\\u003e')\n .replace(/__(.*?)__/g, '\\u003cstrong\\u003e$1\\u003c/strong\\u003e')\n .replace(/_(.*?)_/g, '\\u003cem\\u003e$1\\u003c/em\\u003e')\n \n // Links\n .replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '\\u003ca href=\"$2\" target=\"_blank\" rel=\"noopener\"\\u003e$1\\u003c/a\\u003e')\n \n // Horizontal rule\n .replace(/^---$/gim, '\\u003chr\\u003e')\n \n // Blockquotes\n .replace(/^\\> (.*$)/gim, '\\u003cblockquote\\u003e$1\\u003c/blockquote\\u003e')\n \n // Lists\n .replace(/^\\* (.*$)/gim, '\\u003cli\\u003e$1\\u003c/li\\u003e')\n .replace(/^- (.*$)/gim, '\\u003cli\\u003e$1\\u003c/li\\u003e')\n .replace(/^\\d+\\. (.*$)/gim, '\\u003cli\\u003e$1\\u003c/li\\u003e');\n\n // Wrap consecutive list items\n html = html\n .replace(/(\\u003cli\\u003e.*\\u003c\\/li\\u003e\\n?)+/g, (match) => {\n if (match.includes('*') || match.includes('-')) {\n return `\\u003cul\\u003e${match}\\u003c/ul\\u003e`;\n }\n return `\\u003col\\u003e${match}\\u003c/ol\\u003e`;\n });\n\n // Wrap in paragraphs (simple approach)\n const lines = html.split('\\n');\n let result = '';\n let inParagraph = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) {\n if (inParagraph) {\n result += '\\u003c/p\\u003e\\n';\n inParagraph = false;\n }\n continue;\n }\n\n // Skip if already wrapped in block element\n if (/^\\u003c(h\\d|pre|ul|ol|blockquote|hr)/.test(trimmed)) {\n if (inParagraph) {\n result += '\\u003c/p\\u003e\\n';\n inParagraph = false;\n }\n result += line + '\\n';\n } else {\n if (!inParagraph) {\n result += '\\u003cp\\u003e';\n inParagraph = true;\n }\n result += line + ' ';\n }\n }\n\n if (inParagraph) {\n result += '\\u003c/p\\u003e\\n';\n }\n\n return result;\n}\n\n@customElement('markdown-renderer')\nexport class MarkdownRenderer extends LitElement {\n @property({ type: String }) content = '';\n\n static styles = unsafeCSS(styles);\n\n render() {\n if (!this.content) {\n return html`\\u003cdiv class=\"markdown-body\"\\u003e\\u003c/div\\u003e`;\n }\n\n const htmlContent = parseMarkdown(this.content);\n\n return html`\n \\u003cdiv class=\"markdown-body\" ${unsafeHTML(htmlContent)}\\u003e\\u003c/div\\u003e\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'markdown-renderer': MarkdownRenderer;\n }\n}\n","import { html, LitElement, type TemplateResult } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { \n User, Bot, Plug, Globe, Search, Clock, Puzzle, \n X, Save, ChevronRight, Check, AlertCircle,\n Settings, Eye, EyeOff, Loader2\n} from 'lucide';\nimport { t } from '../utils/i18n';\n\nexport interface SettingsSection {\n id: string;\n title: string;\n icon: string;\n fields: SettingsField[];\n}\n\nexport interface SettingsField {\n key: string;\n label: string;\n type: 'text' | 'password' | 'number' | 'boolean' | 'select' | 'textarea';\n description?: string;\n placeholder?: string;\n options?: Array<{ value: string; label: string }>;\n validation?: {\n required?: boolean;\n min?: number;\n max?: number;\n pattern?: string;\n };\n}\n\nexport interface SettingsValue {\n [key: string]: any;\n}\n\n@customElement('xopcbot-settings')\nexport class XopcbotSettings extends LitElement {\n @property({ attribute: false }) sections: SettingsSection[] = [];\n @property({ attribute: false }) values: SettingsValue = {};\n @property({ type: Boolean }) loading = false;\n @property({ attribute: false }) onSave?: (values: SettingsValue) => void;\n @property({ attribute: false }) onClose?: () => void;\n\n @state() private _activeSection: string = '';\n @state() private _dirtyFields: Set<string> = new Set();\n @state() private _showPasswords: Set<string> = new Set();\n @state() private _errors: Map<string, string> = new Map();\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._updateActiveSection();\n }\n\n override willUpdate(changedProperties: Map<string, unknown>): void {\n if (changedProperties.has('sections')) {\n this._updateActiveSection();\n }\n }\n\n private _updateActiveSection(): void {\n if (this.sections.length > 0 && !this._activeSection) {\n this._activeSection = this.sections[0].id;\n }\n }\n\n private _getIcon(iconName: string): TemplateResult {\n const icons: Record<string, TemplateResult> = {\n user: html`<User class=\"w-5 h-5\" />`,\n bot: html`<Bot class=\"w-5 h-5\" />`,\n plug: html`<Plug class=\"w-5 h-5\" />`,\n globe: html`<Globe class=\"w-5 h-5\" />`,\n search: html`<Search class=\"w-5 h-5\" />`,\n clock: html`<Clock class=\"w-5 h-5\" />`,\n puzzle: html`<Puzzle class=\"w-5 h-5\" />`,\n settings: html`<Settings class=\"w-5 h-5\" />`,\n };\n return icons[iconName] || html`<Settings class=\"w-5 h-5\" />`;\n }\n\n override render(): unknown {\n return html`\n <div class=\"settings-overlay\" @click=${(e: Event) => e.target === e.currentTarget && this.onClose?.()}>\n <div class=\"settings-dialog\">\n ${this.renderHeader()}\n <div class=\"settings-content\">\n ${this.renderSidebar()}\n ${this.renderMain()}\n </div>\n ${this.renderFooter()}\n </div>\n </div>\n `;\n }\n\n private renderHeader(): unknown {\n return html`\n <div class=\"settings-header\">\n <div class=\"settings-title\">\n <Settings class=\"w-5 h-5\" />\n <span>Settings</span>\n </div>\n <button class=\"close-btn\" @click=${() => this.onClose?.()}>\n <X class=\"w-5 h-5\" />\n </button>\n </div>\n `;\n }\n\n private renderSidebar(): unknown {\n return html`\n <nav class=\"settings-sidebar\">\n ${this.sections.map((section) => html`\n <button\n class=\"sidebar-item ${this._activeSection === section.id ? 'active' : ''}\"\n @click=${() => this._activeSection = section.id}\n >\n ${this._getIcon(section.icon)}\n <span>${section.title}</span>\n <ChevronRight class=\"w-4 h-4 chevron\" />\n </button>\n `)}\n </nav>\n `;\n }\n\n private renderMain(): unknown {\n const section = this.sections.find(s => s.id === this._activeSection);\n if (!section) return html`<div class=\"settings-main\">${t('settings.noSection')}</div>`;\n\n const descKey = `settings.descriptions.${section.id}` as const;\n\n return html`\n <div class=\"settings-main\">\n <div class=\"section-header\">\n <h2>${section.title}</h2>\n <p class=\"section-description\">${t(descKey)}</p>\n </div>\n \n <div class=\"fields-grid\">\n ${section.fields.map(field => this.renderField(field, section.id))}\n </div>\n </div>\n `;\n }\n\n private renderField(field: SettingsField, sectionId: string): unknown {\n const fullKey = `${sectionId}.${field.key}`;\n const value = this._getValue(field.key);\n const isDirty = this._dirtyFields.has(fullKey);\n const error = this._errors.get(fullKey);\n const showPassword = this._showPasswords.has(fullKey);\n\n return html`\n <div class=\"field-group ${error ? 'has-error' : ''}\">\n <div class=\"field-header\">\n <label class=\"field-label\">${field.label}</label>\n ${field.validation?.required ? html`<span class=\"required-mark\">*</span>` : ''}\n </div>\n \n ${field.description ? html`<p class=\"field-description\">${field.description}</p>` : ''}\n\n ${field.type === 'boolean' ? this.renderBooleanField(field, value, fullKey) : ''}\n \n ${field.type === 'select' ? this.renderSelectField(field, value, fullKey) : ''}\n \n ${field.type === 'textarea' ? this.renderTextareaField(field, value, fullKey) : ''}\n \n ${['text', 'password', 'number'].includes(field.type) \n ? this.renderInputField(field, value, fullKey, showPassword) \n : ''}\n\n ${error ? html`\n <div class=\"field-error\">\n <AlertCircle class=\"w-4 h-4\" />\n <span>${error}</span>\n </div>\n ` : ''}\n\n ${isDirty && !error ? html`\n <div class=\"field-dirty\">${t('settings.unsavedChanges')}</div>\n ` : ''}\n </div>\n `;\n }\n\n private renderInputField(field: SettingsField, value: any, fullKey: string, showPassword: boolean): unknown {\n const inputType = field.type === 'password' \n ? (showPassword ? 'text' : 'password') \n : field.type;\n\n return html`\n <div class=\"input-wrapper\">\n <input\n type=${inputType}\n class=\"text-input ${field.type === 'password' ? 'has-toggle' : ''}\"\n .value=${String(value ?? '')}\n placeholder=${field.placeholder || ''}\n minlength=${field.validation?.min}\n maxlength=${field.validation?.max}\n pattern=${field.validation?.pattern || ''}\n @input=${(e: Event) => this._handleInput(field, fullKey, (e.target as HTMLInputElement).value)}\n />\n ${field.type === 'password' ? html`\n <button \n type=\"button\" \n class=\"password-toggle\"\n @click=${() => this._togglePassword(fullKey)}\n >\n ${showPassword ? html`<EyeOff class=\"w-4 h-4\" />` : html`<Eye class=\"w-4 h-4\" />`}\n </button>\n ` : ''}\n </div>\n `;\n }\n\n private renderTextareaField(field: SettingsField, value: any, fullKey: string): unknown {\n return html`\n <textarea\n class=\"textarea-input\"\n .value=${String(value ?? '')}\n placeholder=${field.placeholder || ''}\n rows=\"4\"\n @input=${(e: Event) => this._handleInput(field, fullKey, (e.target as HTMLTextAreaElement).value)}\n ></textarea>\n `;\n }\n\n private renderSelectField(field: SettingsField, value: any, fullKey: string): unknown {\n return html`\n <select\n class=\"select-input\"\n .value=${String(value ?? '')}\n @change=${(e: Event) => this._handleInput(field, fullKey, (e.target as HTMLSelectElement).value)}\n >\n ${field.options?.map(opt => html`\n <option value=${opt.value} ?selected=${value === opt.value}>${opt.label}</option>\n `)}\n </select>\n `;\n }\n\n private renderBooleanField(field: SettingsField, value: any, fullKey: string): unknown {\n return html`\n <label class=\"toggle-label\">\n <input\n type=\"checkbox\"\n class=\"toggle-input\"\n .checked=${Boolean(value)}\n @change=${(e: Event) => this._handleInput(field, fullKey, (e.target as HTMLInputElement).checked)}\n />\n <span class=\"toggle-switch\"></span>\n <span class=\"toggle-text\">${field.description || t('settings.enableFeature')}</span>\n </label>\n `;\n }\n\n private renderFooter(): unknown {\n const hasDirty = this._dirtyFields.size > 0;\n\n return html`\n <div class=\"settings-footer\">\n <button class=\"btn btn-ghost\" @click=${() => this.onClose?.()}>\n ${t('settings.cancel')}\n </button>\n <button \n class=\"btn btn-primary\" \n ?disabled=${this.loading || !hasDirty}\n @click=${() => this._save()}\n >\n ${this.loading ? html`\n <Loader2 class=\"w-4 h-4 animate-spin\" />\n ${t('settings.saving')}\n ` : html`\n <Save class=\"w-4 h-4\" />\n ${t('settings.saveChanges')}\n `}\n </button>\n </div>\n `;\n }\n\n private _getValue(key: string): any {\n return this.values[key];\n }\n\n private _handleInput(field: SettingsField, fullKey: string, value: any): void {\n // Validate\n if (field.validation?.required && !value) {\n this._errors.set(fullKey, t('settings.required', { field: field.label }));\n } else if (field.validation?.pattern && value) {\n const regex = new RegExp(field.validation.pattern);\n if (!regex.test(value)) {\n this._errors.set(fullKey, t('settings.invalidFormat'));\n } else {\n this._errors.delete(fullKey);\n }\n } else {\n this._errors.delete(fullKey);\n }\n\n this._dirtyFields.add(fullKey);\n this.requestUpdate();\n }\n\n private _togglePassword(fullKey: string): void {\n if (this._showPasswords.has(fullKey)) {\n this._showPasswords.delete(fullKey);\n } else {\n this._showPasswords.add(fullKey);\n }\n this.requestUpdate();\n }\n\n private _save(): void {\n // Final validation\n if (this._errors.size > 0) {\n return;\n }\n\n if (this.onSave) {\n this.onSave(this.values);\n }\n }\n}\n","import { html, LitElement } from 'lit';\nimport { customElement, property, state, query } from 'lit/decorators.js';\nimport { Agent, type AgentEvent } from '@mariozechner/pi-agent-core';\n\n// Import styles\nimport './styles.css';\n\nimport './components/MessageEditor';\nimport './components/MessageList';\nimport './components/StreamingMessageContainer';\nimport './gateway-chat';\nimport './app';\nimport { i18n, setLanguage, translations } from './utils/i18n';\nimport type { Attachment } from './utils/attachment-utils';\nimport type { MessageEditor } from './components/MessageEditor';\nimport type { StreamingMessageContainer } from './components/StreamingMessageContainer';\n\n// Utils\nexport { t, i18n, setLanguage, getCurrentLanguage, initI18n, type Language } from './utils/i18n';\nexport type { Attachment } from './utils/attachment-utils';\nexport { formatUsage, formatTokenCount, formatCost } from './utils/format';\nexport { getIcon, loadIcon, getDocumentIcon } from './utils/icons';\n\n// Components\nexport { MessageEditor } from './components/MessageEditor';\nexport { \n MessageList, \n MessageBubble, \n AttachmentRenderer, \n UsageBadge \n} from './components/index';\nexport type { \n Attachment as MessageAttachment, \n Message, \n MessageContent \n} from './components/MessageList/types';\nexport { StreamingMessageContainer } from './components/StreamingMessageContainer';\n\n// Dialogs\nexport { XopcbotSettings, type SettingsSection, type SettingsField, type SettingsValue } from './dialogs/SettingsDialog';\n\n// Gateway Chat - with type-safe events\nexport { \n XopcbotGatewayChat, \n type GatewayClientConfig,\n type GatewayEvent,\n type ChatPayload,\n type ConfigPayload,\n type ErrorPayload,\n type GatewayResponse,\n type GatewayRequest\n} from './gateway-chat';\n\n// App\nexport { XopcbotApp, type Tab, type AppSettings } from './app';\n\n@customElement('xopcbot-chat')\nexport class XopcbotChat extends LitElement {\n @property({ attribute: false }) agent?: Agent;\n @property({ type: Boolean }) enableAttachments = true;\n @property({ type: Boolean }) enableModelSelector = true;\n @property({ type: Boolean }) enableThinkingSelector = true;\n\n @query('message-editor') private _messageEditor!: MessageEditor;\n @query('streaming-message-container') private _streamingContainer!: StreamingMessageContainer;\n\n private _autoScroll = true;\n private _lastScrollTop = 0;\n private _scrollContainer?: HTMLElement;\n private _resizeObserver?: ResizeObserver;\n private _unsubscribeSession?: () => void;\n\n createRenderRoot(): HTMLElement | DocumentFragment {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.style.display = 'flex';\n this.style.flexDirection = 'column';\n this.style.height = '100%';\n this.style.minHeight = '0';\n\n this.setupSessionSubscription();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._resizeObserver?.disconnect();\n this._scrollContainer?.removeEventListener('scroll', this._handleScroll);\n this._unsubscribeSession?.();\n }\n\n private setupSessionSubscription(): void {\n if (this._unsubscribeSession) {\n this._unsubscribeSession();\n }\n if (!this.agent) return;\n\n this._unsubscribeSession = this.agent.subscribe(async (ev: AgentEvent) => {\n switch (ev.type) {\n case 'message_start':\n case 'message_end':\n case 'turn_start':\n case 'turn_end':\n case 'agent_start':\n this.requestUpdate();\n break;\n case 'agent_end':\n if (this._streamingContainer) {\n this._streamingContainer.isStreaming = false;\n this._streamingContainer.setMessage(null, true);\n }\n this.requestUpdate();\n break;\n case 'message_update':\n if (this._streamingContainer) {\n this._streamingContainer.isStreaming = this.agent?.state.isStreaming || false;\n this._streamingContainer.setMessage(ev.message, !this._streamingContainer.isStreaming);\n }\n this.requestUpdate();\n break;\n }\n });\n }\n\n private _handleScroll = (): void => {\n if (!this._scrollContainer) return;\n\n const currentScrollTop = this._scrollContainer.scrollTop;\n const scrollHeight = this._scrollContainer.scrollHeight;\n const clientHeight = this._scrollContainer.clientHeight;\n const distanceFromBottom = scrollHeight - currentScrollTop - clientHeight;\n\n if (clientHeight < this._lastClientHeight) {\n this._lastClientHeight = clientHeight;\n return;\n }\n\n if (currentScrollTop !== 0 && currentScrollTop < this._lastScrollTop && distanceFromBottom > 50) {\n this._autoScroll = false;\n } else if (distanceFromBottom < 10) {\n this._autoScroll = true;\n }\n\n this._lastScrollTop = currentScrollTop;\n this._lastClientHeight = clientHeight;\n };\n\n public setInput(text: string, attachments?: Attachment[]): void {\n if (this._messageEditor) {\n this._messageEditor.value = text;\n this._messageEditor.attachments = attachments || [];\n }\n }\n\n public setAutoScroll(enabled: boolean): void {\n this._autoScroll = enabled;\n }\n\n public async sendMessage(input: string, attachments?: Attachment[]): Promise<void> {\n if ((!input.trim() && attachments?.length === 0) || this.agent?.state.isStreaming) return;\n if (!this.agent) throw new Error('No agent set');\n if (!this.agent.state.model) throw new Error('No model set');\n\n this._messageEditor.value = '';\n this._messageEditor.attachments = [];\n this._autoScroll = true;\n\n if (attachments && attachments.length > 0) {\n await this.agent.prompt({\n role: 'user-with-attachments',\n content: input,\n attachments,\n timestamp: Date.now(),\n });\n } else {\n await this.agent.prompt(input);\n }\n }\n\n private renderMessages(): unknown {\n if (!this.agent) {\n return html`<div class=\"p-4 text-center text-muted-foreground\">${i18n('No session available')}</div>`;\n }\n\n const state = this.agent.state;\n return html`\n <div class=\"flex flex-col gap-3\">\n <message-list\n .messages=${this.agent.state.messages}\n .tools=${state.tools}\n .pendingToolCalls=${this.agent ? this.agent.state.pendingToolCalls : new Set<string>()}\n .isStreaming=${state.isStreaming}\n ></message-list>\n\n <streaming-message-container\n class=\"${state.isStreaming ? '' : 'hidden'}\"\n .tools=${state.tools}\n .isStreaming=${state.isStreaming}\n .pendingToolCalls=${state.pendingToolCalls}\n .isStreaming=${state.isStreaming}\n ></streaming-message-container>\n </div>\n `;\n }\n\n override render(): unknown {\n if (!this.agent) {\n return html`<div class=\"p-4 text-center text-muted-foreground\">${i18n('No agent set')}</div>`;\n }\n\n const state = this.agent.state;\n return html`\n <div class=\"flex flex-col h-full bg-background text-foreground\">\n <div class=\"flex-1 overflow-y-auto\">\n <div class=\"max-w-3xl mx-auto p-4 pb-0\">${this.renderMessages()}</div>\n </div>\n\n <div class=\"shrink-0\">\n <div class=\"max-w-3xl mx-auto px-2\">\n <message-editor\n .isStreaming=${state.isStreaming}\n .currentModel=${state.model}\n .thinkingLevel=${state.thinkingLevel}\n .showAttachmentButton=${this.enableAttachments}\n .showModelSelector=${this.enableModelSelector}\n .showThinkingSelector=${this.enableThinkingSelector}\n .onSend=${(input: string, attachments: Attachment[]) => this.sendMessage(input, attachments)}\n .onAbort=${() => this.agent?.abort()}\n ></message-editor>\n </div>\n </div>\n </div>\n `;\n }\n}\n"],"file":"main-Br2tw-87.js"}