agim-cli 1.4.9 → 1.5.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 (535) hide show
  1. package/CHANGELOG.md +415 -402
  2. package/README.md +4 -4
  3. package/bin/agim_rpc.py +12 -12
  4. package/dist/cli-ui/cmd-handlers.d.ts +3 -3
  5. package/dist/cli-ui/cmd-handlers.d.ts.map +1 -1
  6. package/dist/cli-ui/cmd-handlers.js +11 -19
  7. package/dist/cli-ui/cmd-handlers.js.map +1 -1
  8. package/dist/cli-ui/config-wizard.js +27 -27
  9. package/dist/cli-ui/config-wizard.js.map +1 -1
  10. package/dist/cli-ui/env-file.d.ts +4 -4
  11. package/dist/cli-ui/env-file.js +13 -13
  12. package/dist/cli-ui/env-file.js.map +1 -1
  13. package/dist/cli-ui/i18n.d.ts +2 -2
  14. package/dist/cli-ui/i18n.js +9 -9
  15. package/dist/cli-ui/i18n.js.map +1 -1
  16. package/dist/cli-ui/lang-picker.js +1 -1
  17. package/dist/cli-ui/lang-picker.js.map +1 -1
  18. package/dist/cli-ui/paths.d.ts.map +1 -1
  19. package/dist/cli-ui/paths.js +2 -4
  20. package/dist/cli-ui/paths.js.map +1 -1
  21. package/dist/cli-ui/service.d.ts +7 -7
  22. package/dist/cli-ui/service.d.ts.map +1 -1
  23. package/dist/cli-ui/service.js +57 -72
  24. package/dist/cli-ui/service.js.map +1 -1
  25. package/dist/cli-ui/tui/app.js +2 -2
  26. package/dist/cli-ui/tui/app.js.map +1 -1
  27. package/dist/cli-ui/tui/index.js +6 -6
  28. package/dist/cli-ui/tui/index.js.map +1 -1
  29. package/dist/cli-ui/tui/mouse-stdin.js +1 -1
  30. package/dist/cli-ui/tui/mouse-stdin.js.map +1 -1
  31. package/dist/cli-ui/tui/stream-reveal.d.ts +2 -2
  32. package/dist/cli-ui/tui/stream-reveal.d.ts.map +1 -1
  33. package/dist/cli-ui/tui/stream-reveal.js +4 -4
  34. package/dist/cli-ui/tui/stream-reveal.js.map +1 -1
  35. package/dist/cli.js +24 -45
  36. package/dist/cli.js.map +1 -1
  37. package/dist/core/a2a-notify.js +5 -5
  38. package/dist/core/a2a-notify.js.map +1 -1
  39. package/dist/core/a2a.d.ts +2 -2
  40. package/dist/core/a2a.d.ts.map +1 -1
  41. package/dist/core/a2a.js +12 -12
  42. package/dist/core/a2a.js.map +1 -1
  43. package/dist/core/access-token.d.ts +1 -1
  44. package/dist/core/access-token.js +7 -7
  45. package/dist/core/access-token.js.map +1 -1
  46. package/dist/core/acp-server.js +5 -5
  47. package/dist/core/acp-server.js.map +1 -1
  48. package/dist/core/admin-allowlist.js +5 -5
  49. package/dist/core/admin-allowlist.js.map +1 -1
  50. package/dist/core/agent-base.d.ts +1 -1
  51. package/dist/core/agent-base.js +3 -3
  52. package/dist/core/agent-base.js.map +1 -1
  53. package/dist/core/agent-cwd.d.ts +5 -6
  54. package/dist/core/agent-cwd.d.ts.map +1 -1
  55. package/dist/core/agent-cwd.js +15 -16
  56. package/dist/core/agent-cwd.js.map +1 -1
  57. package/dist/core/agim-paths.d.ts +1 -4
  58. package/dist/core/agim-paths.d.ts.map +1 -1
  59. package/dist/core/agim-paths.js +18 -35
  60. package/dist/core/agim-paths.js.map +1 -1
  61. package/dist/core/approval-bus.d.ts +4 -4
  62. package/dist/core/approval-bus.d.ts.map +1 -1
  63. package/dist/core/approval-bus.js +14 -14
  64. package/dist/core/approval-bus.js.map +1 -1
  65. package/dist/core/approval-router.js +2 -2
  66. package/dist/core/artifacts.js +3 -3
  67. package/dist/core/artifacts.js.map +1 -1
  68. package/dist/core/ask-user-rpc.js +1 -1
  69. package/dist/core/ask-user-rpc.js.map +1 -1
  70. package/dist/core/audit-log.js +2 -2
  71. package/dist/core/audit-log.js.map +1 -1
  72. package/dist/core/bgjob-reader.d.ts +1 -1
  73. package/dist/core/bgjob-reader.js +4 -4
  74. package/dist/core/bgjob-reader.js.map +1 -1
  75. package/dist/core/commands/approval.js +2 -2
  76. package/dist/core/commands/approval.js.map +1 -1
  77. package/dist/core/commands/heartbeat.js +2 -2
  78. package/dist/core/commands/heartbeat.js.map +1 -1
  79. package/dist/core/commands/memo.js +1 -1
  80. package/dist/core/commands/memo.js.map +1 -1
  81. package/dist/core/commands/model.js +1 -1
  82. package/dist/core/commands/model.js.map +1 -1
  83. package/dist/core/commands/plan.js +3 -3
  84. package/dist/core/commands/plan.js.map +1 -1
  85. package/dist/core/commands/router-compare.js +3 -3
  86. package/dist/core/commands/router-compare.js.map +1 -1
  87. package/dist/core/commands/service.d.ts.map +1 -1
  88. package/dist/core/commands/service.js +1 -3
  89. package/dist/core/commands/service.js.map +1 -1
  90. package/dist/core/commands/sessions.js +4 -4
  91. package/dist/core/commands/sessions.js.map +1 -1
  92. package/dist/core/commands/skill.js +1 -1
  93. package/dist/core/commands/skill.js.map +1 -1
  94. package/dist/core/commands/stats.js +1 -1
  95. package/dist/core/commands/stats.js.map +1 -1
  96. package/dist/core/commands/web.js +5 -5
  97. package/dist/core/commands/web.js.map +1 -1
  98. package/dist/core/config-schema.js +1 -1
  99. package/dist/core/coord-systems.d.ts +1 -1
  100. package/dist/core/coord-systems.js +4 -4
  101. package/dist/core/coord-systems.js.map +1 -1
  102. package/dist/core/event-bus.d.ts +5 -5
  103. package/dist/core/event-bus.d.ts.map +1 -1
  104. package/dist/core/event-bus.js +3 -3
  105. package/dist/core/event-bus.js.map +1 -1
  106. package/dist/core/feature-flags.d.ts +2 -2
  107. package/dist/core/feature-flags.js +4 -4
  108. package/dist/core/feature-flags.js.map +1 -1
  109. package/dist/core/goal-rpc.js +2 -2
  110. package/dist/core/goal-rpc.js.map +1 -1
  111. package/dist/core/goals.d.ts +1 -1
  112. package/dist/core/goals.js +3 -3
  113. package/dist/core/goals.js.map +1 -1
  114. package/dist/core/heartbeat-store.d.ts +1 -1
  115. package/dist/core/heartbeat-store.d.ts.map +1 -1
  116. package/dist/core/heartbeat-store.js +3 -3
  117. package/dist/core/heartbeat-store.js.map +1 -1
  118. package/dist/core/heartbeat.js +4 -4
  119. package/dist/core/heartbeat.js.map +1 -1
  120. package/dist/core/intent-llm.d.ts +2 -2
  121. package/dist/core/intent-llm.js +5 -5
  122. package/dist/core/intent-llm.js.map +1 -1
  123. package/dist/core/job-board.d.ts +5 -5
  124. package/dist/core/job-board.d.ts.map +1 -1
  125. package/dist/core/job-board.js +17 -17
  126. package/dist/core/job-board.js.map +1 -1
  127. package/dist/core/llm/agent-loop.d.ts +3 -3
  128. package/dist/core/llm/agent-loop.js +14 -14
  129. package/dist/core/llm/agent-loop.js.map +1 -1
  130. package/dist/core/llm/{imhub-dispatcher.d.ts → agim-dispatcher.d.ts} +4 -4
  131. package/dist/core/llm/agim-dispatcher.d.ts.map +1 -0
  132. package/dist/core/llm/{imhub-dispatcher.js → agim-dispatcher.js} +43 -43
  133. package/dist/core/llm/agim-dispatcher.js.map +1 -0
  134. package/dist/core/llm/agim-rpc-server.js +17 -17
  135. package/dist/core/llm/agim-rpc-server.js.map +1 -1
  136. package/dist/core/llm/auto-compact.d.ts +3 -3
  137. package/dist/core/llm/auto-compact.d.ts.map +1 -1
  138. package/dist/core/llm/auto-compact.js +5 -5
  139. package/dist/core/llm/auto-compact.js.map +1 -1
  140. package/dist/core/llm/builtin-dispatcher.js +3 -3
  141. package/dist/core/llm/builtin-dispatcher.js.map +1 -1
  142. package/dist/core/llm/exec-dispatcher.d.ts +2 -2
  143. package/dist/core/llm/exec-dispatcher.d.ts.map +1 -1
  144. package/dist/core/llm/exec-dispatcher.js +20 -22
  145. package/dist/core/llm/exec-dispatcher.js.map +1 -1
  146. package/dist/core/llm/fs-dispatcher.js +8 -8
  147. package/dist/core/llm/fs-dispatcher.js.map +1 -1
  148. package/dist/core/llm/goal-critic.js +4 -4
  149. package/dist/core/llm/goal-critic.js.map +1 -1
  150. package/dist/core/llm/hallucination-detector.js +2 -2
  151. package/dist/core/llm/hallucination-detector.js.map +1 -1
  152. package/dist/core/llm/mcp-client.d.ts +1 -1
  153. package/dist/core/llm/mcp-client.js +3 -3
  154. package/dist/core/llm/mcp-client.js.map +1 -1
  155. package/dist/core/llm/mcp-registry.js +3 -3
  156. package/dist/core/llm/mcp-registry.js.map +1 -1
  157. package/dist/core/llm/openai-compat-provider.d.ts +1 -1
  158. package/dist/core/llm/openai-compat-provider.js +2 -2
  159. package/dist/core/llm/openai-compat-provider.js.map +1 -1
  160. package/dist/core/llm/provider-base.d.ts +1 -1
  161. package/dist/core/llm/secrets.d.ts +2 -2
  162. package/dist/core/llm/secrets.d.ts.map +1 -1
  163. package/dist/core/llm/tool-dispatcher.d.ts +1 -1
  164. package/dist/core/llm/web-dispatcher.d.ts +1 -1
  165. package/dist/core/llm/web-dispatcher.js +15 -15
  166. package/dist/core/llm/web-dispatcher.js.map +1 -1
  167. package/dist/core/logger.d.ts +1 -1
  168. package/dist/core/logger.js +3 -3
  169. package/dist/core/logger.js.map +1 -1
  170. package/dist/core/memo-rpc.js +3 -3
  171. package/dist/core/memo-rpc.js.map +1 -1
  172. package/dist/core/memory-consolidate.js +4 -4
  173. package/dist/core/memory-consolidate.js.map +1 -1
  174. package/dist/core/memory-distill.js +4 -4
  175. package/dist/core/memory-distill.js.map +1 -1
  176. package/dist/core/memory-distiller.js +9 -9
  177. package/dist/core/memory-distiller.js.map +1 -1
  178. package/dist/core/memory-vector.js +9 -9
  179. package/dist/core/memory-vector.js.map +1 -1
  180. package/dist/core/memory.js +2 -2
  181. package/dist/core/memory.js.map +1 -1
  182. package/dist/core/memos.js +6 -6
  183. package/dist/core/memos.js.map +1 -1
  184. package/dist/core/message-sink.js +13 -13
  185. package/dist/core/message-sink.js.map +1 -1
  186. package/dist/core/notification-evaluator.d.ts +2 -2
  187. package/dist/core/notification-evaluator.js +4 -4
  188. package/dist/core/notification-evaluator.js.map +1 -1
  189. package/dist/core/onboarding.js +3 -3
  190. package/dist/core/onboarding.js.map +1 -1
  191. package/dist/core/outbox.js +2 -2
  192. package/dist/core/outbox.js.map +1 -1
  193. package/dist/core/persona.d.ts +1 -1
  194. package/dist/core/persona.d.ts.map +1 -1
  195. package/dist/core/persona.js +2 -2
  196. package/dist/core/persona.js.map +1 -1
  197. package/dist/core/plan-history.js +1 -1
  198. package/dist/core/plan-history.js.map +1 -1
  199. package/dist/core/plan-intent.js +5 -5
  200. package/dist/core/plan-intent.js.map +1 -1
  201. package/dist/core/plan-mode-state.d.ts +1 -1
  202. package/dist/core/plan-mode-state.js +4 -4
  203. package/dist/core/plan-mode-state.js.map +1 -1
  204. package/dist/core/push-rpc.d.ts +1 -1
  205. package/dist/core/push-rpc.js +6 -6
  206. package/dist/core/push-rpc.js.map +1 -1
  207. package/dist/core/registry.d.ts +4 -4
  208. package/dist/core/registry.js +10 -10
  209. package/dist/core/registry.js.map +1 -1
  210. package/dist/core/reminders.js +1 -1
  211. package/dist/core/reminders.js.map +1 -1
  212. package/dist/core/restart-flow.d.ts.map +1 -1
  213. package/dist/core/restart-flow.js +5 -7
  214. package/dist/core/restart-flow.js.map +1 -1
  215. package/dist/core/router.d.ts +1 -1
  216. package/dist/core/router.js +5 -5
  217. package/dist/core/router.js.map +1 -1
  218. package/dist/core/schedule.d.ts +2 -2
  219. package/dist/core/schedule.js +4 -4
  220. package/dist/core/schedule.js.map +1 -1
  221. package/dist/core/self-protect.js +3 -3
  222. package/dist/core/self-protect.js.map +1 -1
  223. package/dist/core/sender-allowlist.js +7 -7
  224. package/dist/core/sender-allowlist.js.map +1 -1
  225. package/dist/core/sensitive-paths.d.ts.map +1 -1
  226. package/dist/core/sensitive-paths.js +1 -2
  227. package/dist/core/sensitive-paths.js.map +1 -1
  228. package/dist/core/session.js +2 -2
  229. package/dist/core/session.js.map +1 -1
  230. package/dist/core/skills/builtin/ECC_NOTICE.md +1 -1
  231. package/dist/core/skills/builtin/agim-memory/SKILL.md +1 -1
  232. package/dist/core/skills/builtin/agim-reminders/SKILL.md +2 -2
  233. package/dist/core/skills/builtin/agim-self/SKILL.md +9 -9
  234. package/dist/core/skills/builtin/agim-skill-discovery/SKILL.md +5 -5
  235. package/dist/core/skills/builtin/image-generation/SKILL.md +2 -2
  236. package/dist/core/skills/builtin/long-goal/SKILL.md +7 -7
  237. package/dist/core/skills/builtin/my/SKILL.md +2 -2
  238. package/dist/core/skills/builtin/skill-creator/SKILL.md +2 -2
  239. package/dist/core/skills/loader.d.ts +4 -4
  240. package/dist/core/skills/loader.js +22 -22
  241. package/dist/core/skills/loader.js.map +1 -1
  242. package/dist/core/skills-rpc.js +1 -1
  243. package/dist/core/skills-rpc.js.map +1 -1
  244. package/dist/core/transcribe.js +13 -13
  245. package/dist/core/transcribe.js.map +1 -1
  246. package/dist/core/tunnel.js +1 -1
  247. package/dist/core/tunnel.js.map +1 -1
  248. package/dist/core/types.d.ts +2 -2
  249. package/dist/core/types.d.ts.map +1 -1
  250. package/dist/core/user-coord-prefs.js +1 -1
  251. package/dist/core/user-coord-prefs.js.map +1 -1
  252. package/dist/core/viewer-config.d.ts +8 -8
  253. package/dist/core/viewer-config.js +17 -17
  254. package/dist/core/viewer-config.js.map +1 -1
  255. package/dist/core/viewer-local.js +4 -4
  256. package/dist/core/viewer-local.js.map +1 -1
  257. package/dist/core/viewer-remote.js +1 -1
  258. package/dist/core/viewer-remote.js.map +1 -1
  259. package/dist/plugins/agents/acp/url-guard.d.ts +1 -1
  260. package/dist/plugins/agents/acp/url-guard.js +2 -2
  261. package/dist/plugins/agents/acp/url-guard.js.map +1 -1
  262. package/dist/plugins/agents/antigravity/ensure-mcp-config.d.ts +6 -6
  263. package/dist/plugins/agents/antigravity/ensure-mcp-config.d.ts.map +1 -1
  264. package/dist/plugins/agents/antigravity/ensure-mcp-config.js +12 -12
  265. package/dist/plugins/agents/antigravity/ensure-mcp-config.js.map +1 -1
  266. package/dist/plugins/agents/antigravity/index.js +10 -10
  267. package/dist/plugins/agents/antigravity/index.js.map +1 -1
  268. package/dist/plugins/agents/claude-code/index.d.ts +2 -2
  269. package/dist/plugins/agents/claude-code/index.js +16 -16
  270. package/dist/plugins/agents/claude-code/index.js.map +1 -1
  271. package/dist/plugins/agents/claude-code/mcp-approval-server.js +13 -13
  272. package/dist/plugins/agents/claude-code/mcp-approval-server.js.map +1 -1
  273. package/dist/plugins/agents/codex/build-mcp-cli-args.d.ts +4 -4
  274. package/dist/plugins/agents/codex/build-mcp-cli-args.js +14 -14
  275. package/dist/plugins/agents/codex/build-mcp-cli-args.js.map +1 -1
  276. package/dist/plugins/agents/codex/index.d.ts +3 -3
  277. package/dist/plugins/agents/codex/index.js +14 -14
  278. package/dist/plugins/agents/codex/index.js.map +1 -1
  279. package/dist/plugins/agents/cursor/ensure-mcp-config.d.ts +5 -5
  280. package/dist/plugins/agents/cursor/ensure-mcp-config.d.ts.map +1 -1
  281. package/dist/plugins/agents/cursor/ensure-mcp-config.js +11 -11
  282. package/dist/plugins/agents/cursor/ensure-mcp-config.js.map +1 -1
  283. package/dist/plugins/agents/cursor/index.d.ts +1 -1
  284. package/dist/plugins/agents/cursor/index.js +12 -12
  285. package/dist/plugins/agents/cursor/index.js.map +1 -1
  286. package/dist/plugins/agents/native/index.js +14 -14
  287. package/dist/plugins/agents/native/index.js.map +1 -1
  288. package/dist/plugins/agents/native/tool-registry.d.ts +3 -3
  289. package/dist/plugins/agents/native/tool-registry.d.ts.map +1 -1
  290. package/dist/plugins/agents/native/tool-registry.js +5 -5
  291. package/dist/plugins/agents/native/tool-registry.js.map +1 -1
  292. package/dist/plugins/agents/opencode/ensure-mcp-config.d.ts +1 -1
  293. package/dist/plugins/agents/opencode/ensure-mcp-config.js +9 -9
  294. package/dist/plugins/agents/opencode/ensure-mcp-config.js.map +1 -1
  295. package/dist/plugins/agents/opencode/index.js +3 -3
  296. package/dist/plugins/agents/opencode/index.js.map +1 -1
  297. package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts +4 -0
  298. package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts.map +1 -1
  299. package/dist/plugins/agents/opencode/opencode-http-adapter.js +16 -12
  300. package/dist/plugins/agents/opencode/opencode-http-adapter.js.map +1 -1
  301. package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts +2 -2
  302. package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts.map +1 -1
  303. package/dist/plugins/agents/opencode/opencode-stdio-adapter.js +7 -5
  304. package/dist/plugins/agents/opencode/opencode-stdio-adapter.js.map +1 -1
  305. package/dist/plugins/agents/opencode/serve-manager.d.ts +1 -1
  306. package/dist/plugins/agents/opencode/serve-manager.d.ts.map +1 -1
  307. package/dist/plugins/agents/opencode/serve-manager.js +10 -10
  308. package/dist/plugins/agents/opencode/serve-manager.js.map +1 -1
  309. package/dist/plugins/agents/pi-native/factory.js +10 -10
  310. package/dist/plugins/agents/pi-native/factory.js.map +1 -1
  311. package/dist/plugins/agents/pi-native/index.d.ts +3 -3
  312. package/dist/plugins/agents/pi-native/index.d.ts.map +1 -1
  313. package/dist/plugins/agents/pi-native/index.js +2 -2
  314. package/dist/plugins/agents/pi-native/index.js.map +1 -1
  315. package/dist/plugins/agents/pi-native/tool-bridge.js +1 -1
  316. package/dist/plugins/agents/pi-native/tool-bridge.js.map +1 -1
  317. package/dist/plugins/agents/pi-native/tools.js +4 -4
  318. package/dist/plugins/agents/pi-native/tools.js.map +1 -1
  319. package/dist/plugins/messengers/dingtalk/dingtalk-adapter.d.ts +1 -1
  320. package/dist/plugins/messengers/dingtalk/dingtalk-adapter.js +2 -2
  321. package/dist/plugins/messengers/dingtalk/dingtalk-adapter.js.map +1 -1
  322. package/dist/plugins/messengers/email/email-adapter.js +15 -15
  323. package/dist/plugins/messengers/email/email-adapter.js.map +1 -1
  324. package/dist/plugins/messengers/telegram/media-download.d.ts +1 -1
  325. package/dist/plugins/messengers/telegram/media-download.js +4 -4
  326. package/dist/plugins/messengers/telegram/media-download.js.map +1 -1
  327. package/dist/plugins/messengers/telegram/telegram-adapter.d.ts +1 -1
  328. package/dist/plugins/messengers/telegram/telegram-adapter.js +3 -3
  329. package/dist/plugins/messengers/telegram/telegram-adapter.js.map +1 -1
  330. package/dist/plugins/messengers/wechat/context-store.js +1 -1
  331. package/dist/plugins/messengers/wechat/context-store.js.map +1 -1
  332. package/dist/plugins/messengers/wechat/ilink-adapter.js +1 -1
  333. package/dist/plugins/messengers/wechat/ilink-adapter.js.map +1 -1
  334. package/dist/plugins/messengers/wechat/ilink-client.js +1 -1
  335. package/dist/plugins/messengers/wechat/ilink-client.js.map +1 -1
  336. package/dist/plugins/messengers/wechat/media-download.js +1 -1
  337. package/dist/plugins/messengers/wechat/media-download.js.map +1 -1
  338. package/dist/scripts/migrate-gcj02-to-wgs84.js +1 -1
  339. package/dist/scripts/migrate-gcj02-to-wgs84.js.map +1 -1
  340. package/dist/web/public/assets/{a2a-CZxwvgvh.js → a2a-D7MoJ1iT.js} +2 -2
  341. package/dist/web/public/assets/{a2a-CZxwvgvh.js.map → a2a-D7MoJ1iT.js.map} +1 -1
  342. package/dist/web/public/assets/{activity-BnlFGipw.js → activity-BAgb2WZC.js} +2 -2
  343. package/dist/web/public/assets/{activity-BnlFGipw.js.map → activity-BAgb2WZC.js.map} +1 -1
  344. package/dist/web/public/assets/{admins-CH84Rw1d.js → admins-CZYANmhn.js} +2 -2
  345. package/dist/web/public/assets/{admins-CH84Rw1d.js.map → admins-CZYANmhn.js.map} +1 -1
  346. package/dist/web/public/assets/{agents-CFB4Uj6b.js → agents-BXThDW6f.js} +2 -2
  347. package/dist/web/public/assets/agents-BXThDW6f.js.map +1 -0
  348. package/dist/web/public/assets/{approvals-DnzjbDR6.js → approvals-ByPXIYVl.js} +2 -2
  349. package/dist/web/public/assets/{approvals-DnzjbDR6.js.map → approvals-ByPXIYVl.js.map} +1 -1
  350. package/dist/web/public/assets/{arrow-down-DxlRHrs8.js → arrow-down-B8DkdbEY.js} +2 -2
  351. package/dist/web/public/assets/{arrow-down-DxlRHrs8.js.map → arrow-down-B8DkdbEY.js.map} +1 -1
  352. package/dist/web/public/assets/{arrow-up-CAiQ2jy-.js → arrow-up-i_dEdXkz.js} +2 -2
  353. package/dist/web/public/assets/{arrow-up-CAiQ2jy-.js.map → arrow-up-i_dEdXkz.js.map} +1 -1
  354. package/dist/web/public/assets/{asks-DyUQopay.js → asks-yD_inOnM.js} +2 -2
  355. package/dist/web/public/assets/{asks-DyUQopay.js.map → asks-yD_inOnM.js.map} +1 -1
  356. package/dist/web/public/assets/{audit-BVHTMS82.js → audit-teCIRtgN.js} +2 -2
  357. package/dist/web/public/assets/{audit-BVHTMS82.js.map → audit-teCIRtgN.js.map} +1 -1
  358. package/dist/web/public/assets/{bell-D7iS7ctN.js → bell-CeWDMs8_.js} +2 -2
  359. package/dist/web/public/assets/{bell-D7iS7ctN.js.map → bell-CeWDMs8_.js.map} +1 -1
  360. package/dist/web/public/assets/{bgjobs-BYCQhd_1.js → bgjobs-Rc05aEy9.js} +2 -2
  361. package/dist/web/public/assets/bgjobs-Rc05aEy9.js.map +1 -0
  362. package/dist/web/public/assets/{brain-CCF25Egu.js → brain-BQqv0Zhc.js} +2 -2
  363. package/dist/web/public/assets/{brain-CCF25Egu.js.map → brain-BQqv0Zhc.js.map} +1 -1
  364. package/dist/web/public/assets/{briefcase-BMLMD8nM.js → briefcase-DUXbR4xs.js} +2 -2
  365. package/dist/web/public/assets/{briefcase-BMLMD8nM.js.map → briefcase-DUXbR4xs.js.map} +1 -1
  366. package/dist/web/public/assets/{chat-DPkKy5y_.js → chat-DQpQLW9j.js} +2 -2
  367. package/dist/web/public/assets/{chat-DPkKy5y_.js.map → chat-DQpQLW9j.js.map} +1 -1
  368. package/dist/web/public/assets/{chevron-left-BDO3vw8G.js → chevron-left-RC6mMSiX.js} +2 -2
  369. package/dist/web/public/assets/{chevron-left-BDO3vw8G.js.map → chevron-left-RC6mMSiX.js.map} +1 -1
  370. package/dist/web/public/assets/{chevron-right-5ZUC2opg.js → chevron-right-DrkYVi19.js} +2 -2
  371. package/dist/web/public/assets/{chevron-right-5ZUC2opg.js.map → chevron-right-DrkYVi19.js.map} +1 -1
  372. package/dist/web/public/assets/{circle-check-COhM5JsK.js → circle-check-DZnkaUdk.js} +2 -2
  373. package/dist/web/public/assets/{circle-check-COhM5JsK.js.map → circle-check-DZnkaUdk.js.map} +1 -1
  374. package/dist/web/public/assets/{circle-check-big-DHAHqUlS.js → circle-check-big-BC8ntMsz.js} +2 -2
  375. package/dist/web/public/assets/{circle-check-big-DHAHqUlS.js.map → circle-check-big-BC8ntMsz.js.map} +1 -1
  376. package/dist/web/public/assets/{circle-x-7VaoZ7dY.js → circle-x-DHK7ypFY.js} +2 -2
  377. package/dist/web/public/assets/{circle-x-7VaoZ7dY.js.map → circle-x-DHK7ypFY.js.map} +1 -1
  378. package/dist/web/public/assets/{clock-ZPVXnd6V.js → clock-DXHhWqJH.js} +2 -2
  379. package/dist/web/public/assets/{clock-ZPVXnd6V.js.map → clock-DXHhWqJH.js.map} +1 -1
  380. package/dist/web/public/assets/{confirm-dialog-CgpJL9oN.js → confirm-dialog-gPKJnvEW.js} +2 -2
  381. package/dist/web/public/assets/{confirm-dialog-CgpJL9oN.js.map → confirm-dialog-gPKJnvEW.js.map} +1 -1
  382. package/dist/web/public/assets/{copy-BaZl52tH.js → copy-DtQxgcR0.js} +2 -2
  383. package/dist/web/public/assets/{copy-BaZl52tH.js.map → copy-DtQxgcR0.js.map} +1 -1
  384. package/dist/web/public/assets/{data-table-BLYG79TX.js → data-table-DOKUic1J.js} +2 -2
  385. package/dist/web/public/assets/{data-table-BLYG79TX.js.map → data-table-DOKUic1J.js.map} +1 -1
  386. package/dist/web/public/assets/distill-p6P7-1UR.js +7 -0
  387. package/dist/web/public/assets/distill-p6P7-1UR.js.map +1 -0
  388. package/dist/web/public/assets/{download-bzCepctg.js → download-CqNiIHa8.js} +2 -2
  389. package/dist/web/public/assets/{download-bzCepctg.js.map → download-CqNiIHa8.js.map} +1 -1
  390. package/dist/web/public/assets/email-DwbfTUlV.js +7 -0
  391. package/dist/web/public/assets/email-DwbfTUlV.js.map +1 -0
  392. package/dist/web/public/assets/{empty-state-96qpPTNg.js → empty-state-CTwOQemt.js} +2 -2
  393. package/dist/web/public/assets/{empty-state-96qpPTNg.js.map → empty-state-CTwOQemt.js.map} +1 -1
  394. package/dist/web/public/assets/{external-link-J4nIlCem.js → external-link-BY7Ye8yi.js} +2 -2
  395. package/dist/web/public/assets/{external-link-J4nIlCem.js.map → external-link-BY7Ye8yi.js.map} +1 -1
  396. package/dist/web/public/assets/{eye-BvsBLK42.js → eye-6RUADoDS.js} +2 -2
  397. package/dist/web/public/assets/{eye-BvsBLK42.js.map → eye-6RUADoDS.js.map} +1 -1
  398. package/dist/web/public/assets/{facts-DMucDXYd.js → facts-DXE0aJmb.js} +2 -2
  399. package/dist/web/public/assets/{facts-DMucDXYd.js.map → facts-DXE0aJmb.js.map} +1 -1
  400. package/dist/web/public/assets/{goals-B9ETHgL0.js → goals-C1LCm3qL.js} +2 -2
  401. package/dist/web/public/assets/{goals-B9ETHgL0.js.map → goals-C1LCm3qL.js.map} +1 -1
  402. package/dist/web/public/assets/{health-DLzZ7KHc.js → health-wqCp-K_o.js} +2 -2
  403. package/dist/web/public/assets/{health-DLzZ7KHc.js.map → health-wqCp-K_o.js.map} +1 -1
  404. package/dist/web/public/assets/{heart-pulse-CVEeD2sz.js → heart-pulse-DfqI4GF7.js} +2 -2
  405. package/dist/web/public/assets/{heart-pulse-CVEeD2sz.js.map → heart-pulse-DfqI4GF7.js.map} +1 -1
  406. package/dist/web/public/assets/{heartbeat-B1BEBHge.js → heartbeat-Bumv4XtQ.js} +2 -2
  407. package/dist/web/public/assets/{heartbeat-B1BEBHge.js.map → heartbeat-Bumv4XtQ.js.map} +1 -1
  408. package/dist/web/public/assets/{hot-Yc7iad0D.js → hot-B-CMjQIr.js} +2 -2
  409. package/dist/web/public/assets/{hot-Yc7iad0D.js.map → hot-B-CMjQIr.js.map} +1 -1
  410. package/dist/web/public/assets/{index-DY2Zglku.js → index-DHh1LYlA.js} +29 -29
  411. package/dist/web/public/assets/{index-DY2Zglku.js.map → index-DHh1LYlA.js.map} +1 -1
  412. package/dist/web/public/assets/{injection-Ca-9gbo0.js → injection-Dn_XqgLG.js} +2 -2
  413. package/dist/web/public/assets/{injection-Ca-9gbo0.js.map → injection-Dn_XqgLG.js.map} +1 -1
  414. package/dist/web/public/assets/{installed-Zz34apdi.js → installed-Cet-1M2Q.js} +2 -2
  415. package/dist/web/public/assets/{installed-Zz34apdi.js.map → installed-Cet-1M2Q.js.map} +1 -1
  416. package/dist/web/public/assets/{jobs-CtVRpl0r.js → jobs-CfEzOOAC.js} +2 -2
  417. package/dist/web/public/assets/{jobs-CtVRpl0r.js.map → jobs-CfEzOOAC.js.map} +1 -1
  418. package/dist/web/public/assets/{layout-DnANw2Q2.js → layout-BX43KyXM.js} +2 -2
  419. package/dist/web/public/assets/{layout-DnANw2Q2.js.map → layout-BX43KyXM.js.map} +1 -1
  420. package/dist/web/public/assets/{layout-Cxch59sI.js → layout-BcYZlaqf.js} +2 -2
  421. package/dist/web/public/assets/{layout-Cxch59sI.js.map → layout-BcYZlaqf.js.map} +1 -1
  422. package/dist/web/public/assets/{layout-BTCLgkgN.js → layout-Cb7looUv.js} +2 -2
  423. package/dist/web/public/assets/{layout-BTCLgkgN.js.map → layout-Cb7looUv.js.map} +1 -1
  424. package/dist/web/public/assets/{layout-yIZG87fq.js → layout-D7xH78OU.js} +2 -2
  425. package/dist/web/public/assets/{layout-yIZG87fq.js.map → layout-D7xH78OU.js.map} +1 -1
  426. package/dist/web/public/assets/{layout-CtDc2i7w.js → layout-D_3ZcVG7.js} +2 -2
  427. package/dist/web/public/assets/{layout-CtDc2i7w.js.map → layout-D_3ZcVG7.js.map} +1 -1
  428. package/dist/web/public/assets/llm-BZ9qqp-D.js +27 -0
  429. package/dist/web/public/assets/llm-BZ9qqp-D.js.map +1 -0
  430. package/dist/web/public/assets/{loader-circle-D8L1w9c1.js → loader-circle-DgdBWYl0.js} +2 -2
  431. package/dist/web/public/assets/{loader-circle-D8L1w9c1.js.map → loader-circle-DgdBWYl0.js.map} +1 -1
  432. package/dist/web/public/assets/{map-pin--GMunU9n.js → map-pin-3QS1A0-I.js} +2 -2
  433. package/dist/web/public/assets/{map-pin--GMunU9n.js.map → map-pin-3QS1A0-I.js.map} +1 -1
  434. package/dist/web/public/assets/{mcp-DhnXhO9B.js → mcp-DwKZULET.js} +2 -2
  435. package/dist/web/public/assets/{mcp-DhnXhO9B.js.map → mcp-DwKZULET.js.map} +1 -1
  436. package/dist/web/public/assets/{memos-DQZc7llR.js → memos-BBtqFcoH.js} +2 -2
  437. package/dist/web/public/assets/{memos-DQZc7llR.js.map → memos-BBtqFcoH.js.map} +1 -1
  438. package/dist/web/public/assets/{messengers-DwSmauLs.js → messengers-i7WvNT3o.js} +2 -2
  439. package/dist/web/public/assets/messengers-i7WvNT3o.js.map +1 -0
  440. package/dist/web/public/assets/{mobile-CUZ359rQ.js → mobile-Bq0FH9JV.js} +2 -2
  441. package/dist/web/public/assets/{mobile-CUZ359rQ.js.map → mobile-Bq0FH9JV.js.map} +1 -1
  442. package/dist/web/public/assets/{network-BBdRdrH_.js → network--s113Jkm.js} +2 -2
  443. package/dist/web/public/assets/{network-BBdRdrH_.js.map → network--s113Jkm.js.map} +1 -1
  444. package/dist/web/public/assets/{outbox-CmN0U35l.js → outbox-BbfC5kuG.js} +2 -2
  445. package/dist/web/public/assets/{outbox-CmN0U35l.js.map → outbox-BbfC5kuG.js.map} +1 -1
  446. package/dist/web/public/assets/{pagination-DcsgDXXM.js → pagination-DkdCTctJ.js} +2 -2
  447. package/dist/web/public/assets/{pagination-DcsgDXXM.js.map → pagination-DkdCTctJ.js.map} +1 -1
  448. package/dist/web/public/assets/{persona-ig2ac4mY.js → persona-BvtcZh6G.js} +2 -2
  449. package/dist/web/public/assets/{persona-ig2ac4mY.js.map → persona-BvtcZh6G.js.map} +1 -1
  450. package/dist/web/public/assets/{plans-Bzbk8eUr.js → plans-i3a6lrqF.js} +2 -2
  451. package/dist/web/public/assets/{plans-Bzbk8eUr.js.map → plans-i3a6lrqF.js.map} +1 -1
  452. package/dist/web/public/assets/{play-Di1jqulh.js → play-CPoE_JnS.js} +2 -2
  453. package/dist/web/public/assets/{play-Di1jqulh.js.map → play-CPoE_JnS.js.map} +1 -1
  454. package/dist/web/public/assets/{plus-C2zyJ1mF.js → plus-CfzKV_0u.js} +2 -2
  455. package/dist/web/public/assets/{plus-C2zyJ1mF.js.map → plus-CfzKV_0u.js.map} +1 -1
  456. package/dist/web/public/assets/policy-Cm88P8LO.js +2 -0
  457. package/dist/web/public/assets/policy-Cm88P8LO.js.map +1 -0
  458. package/dist/web/public/assets/{qr-code-C-ACsKv_.js → qr-code-DMkV8nv2.js} +2 -2
  459. package/dist/web/public/assets/{qr-code-C-ACsKv_.js.map → qr-code-DMkV8nv2.js.map} +1 -1
  460. package/dist/web/public/assets/{refresh-ccw-7HdadG5V.js → refresh-ccw-nBMm5Xal.js} +2 -2
  461. package/dist/web/public/assets/{refresh-ccw-7HdadG5V.js.map → refresh-ccw-nBMm5Xal.js.map} +1 -1
  462. package/dist/web/public/assets/{reminders-BDeiVYTC.js → reminders-DjEujanC.js} +2 -2
  463. package/dist/web/public/assets/{reminders-BDeiVYTC.js.map → reminders-DjEujanC.js.map} +1 -1
  464. package/dist/web/public/assets/{save-BYFmz9gD.js → save-DbrrCFDM.js} +2 -2
  465. package/dist/web/public/assets/{save-BYFmz9gD.js.map → save-DbrrCFDM.js.map} +1 -1
  466. package/dist/web/public/assets/{schedules-BddzBrxI.js → schedules-DzwDWykc.js} +2 -2
  467. package/dist/web/public/assets/{schedules-BddzBrxI.js.map → schedules-DzwDWykc.js.map} +1 -1
  468. package/dist/web/public/assets/search-5q3dkINm.js +17 -0
  469. package/dist/web/public/assets/search-5q3dkINm.js.map +1 -0
  470. package/dist/web/public/assets/{search-DxkvV-8p.js → search-DbE4VEm9.js} +2 -2
  471. package/dist/web/public/assets/{search-DxkvV-8p.js.map → search-DbE4VEm9.js.map} +1 -1
  472. package/dist/web/public/assets/security-BIcnUrAs.js +2 -0
  473. package/dist/web/public/assets/security-BIcnUrAs.js.map +1 -0
  474. package/dist/web/public/assets/{service-BsY8CaNG.js → service-CnorFHzZ.js} +2 -2
  475. package/dist/web/public/assets/{service-BsY8CaNG.js.map → service-CnorFHzZ.js.map} +1 -1
  476. package/dist/web/public/assets/{shield-alert-DXGk9Rak.js → shield-alert-WOa69jy3.js} +2 -2
  477. package/dist/web/public/assets/{shield-alert-DXGk9Rak.js.map → shield-alert-WOa69jy3.js.map} +1 -1
  478. package/dist/web/public/assets/{status-badge-D0nbFSom.js → status-badge-D5xhwquL.js} +2 -2
  479. package/dist/web/public/assets/{status-badge-D0nbFSom.js.map → status-badge-D5xhwquL.js.map} +1 -1
  480. package/dist/web/public/assets/{subtasks-DFiAXvDp.js → subtasks-DMRyk6YS.js} +2 -2
  481. package/dist/web/public/assets/{subtasks-DFiAXvDp.js.map → subtasks-DMRyk6YS.js.map} +1 -1
  482. package/dist/web/public/assets/{table-_WsrnZ_T.js → table-Dx65w6V0.js} +2 -2
  483. package/dist/web/public/assets/{table-_WsrnZ_T.js.map → table-Dx65w6V0.js.map} +1 -1
  484. package/dist/web/public/assets/{topn-C2PHE4tX.js → topn-L7Juczp3.js} +2 -2
  485. package/dist/web/public/assets/{topn-C2PHE4tX.js.map → topn-L7Juczp3.js.map} +1 -1
  486. package/dist/web/public/assets/{trash-2-1Km439fW.js → trash-2-7xrfqd-v.js} +2 -2
  487. package/dist/web/public/assets/{trash-2-1Km439fW.js.map → trash-2-7xrfqd-v.js.map} +1 -1
  488. package/dist/web/public/assets/{use-agim-skills-COSqZrdH.js → use-agim-skills-pFjfgqMF.js} +2 -2
  489. package/dist/web/public/assets/{use-agim-skills-COSqZrdH.js.map → use-agim-skills-pFjfgqMF.js.map} +1 -1
  490. package/dist/web/public/assets/{use-background-tasks-wCL7jn68.js → use-background-tasks-D1--hHjp.js} +2 -2
  491. package/dist/web/public/assets/{use-background-tasks-wCL7jn68.js.map → use-background-tasks-D1--hHjp.js.map} +1 -1
  492. package/dist/web/public/assets/{use-memory-B9oRyQC8.js → use-memory-Bz1Zao7g.js} +2 -2
  493. package/dist/web/public/assets/{use-memory-B9oRyQC8.js.map → use-memory-Bz1Zao7g.js.map} +1 -1
  494. package/dist/web/public/assets/{use-observability-DGkN80qa.js → use-observability-DtqSWVjM.js} +2 -2
  495. package/dist/web/public/assets/{use-observability-DGkN80qa.js.map → use-observability-DtqSWVjM.js.map} +1 -1
  496. package/dist/web/public/assets/{use-settings-Co-iafXD.js → use-settings-DKbDqCEJ.js} +2 -2
  497. package/dist/web/public/assets/{use-settings-Co-iafXD.js.map → use-settings-DKbDqCEJ.js.map} +1 -1
  498. package/dist/web/public/assets/{use-workspace-BDXP5XO1.js → use-workspace-CConjEx0.js} +2 -2
  499. package/dist/web/public/assets/{use-workspace-BDXP5XO1.js.map → use-workspace-CConjEx0.js.map} +1 -1
  500. package/dist/web/public/assets/vector-D8sEa2W-.js +2 -0
  501. package/dist/web/public/assets/vector-D8sEa2W-.js.map +1 -0
  502. package/dist/web/public/assets/viewer-aSIjAKVA.js +12 -0
  503. package/dist/web/public/assets/viewer-aSIjAKVA.js.map +1 -0
  504. package/dist/web/public/assets/{workspace-BbCchiHE.js → workspace-BqwWoinI.js} +2 -2
  505. package/dist/web/public/assets/{workspace-BbCchiHE.js.map → workspace-BqwWoinI.js.map} +1 -1
  506. package/dist/web/public/assets/{workspaces-5HE7pjdA.js → workspaces-ChsJcrav.js} +2 -2
  507. package/dist/web/public/assets/{workspaces-5HE7pjdA.js.map → workspaces-ChsJcrav.js.map} +1 -1
  508. package/dist/web/public/index.html +1 -1
  509. package/dist/web/public/loc.html +1 -1
  510. package/dist/web/public/login.html +2 -2
  511. package/dist/web/server.d.ts +2 -2
  512. package/dist/web/server.js +118 -119
  513. package/dist/web/server.js.map +1 -1
  514. package/package.json +2 -3
  515. package/dist/core/llm/imhub-dispatcher.d.ts.map +0 -1
  516. package/dist/core/llm/imhub-dispatcher.js.map +0 -1
  517. package/dist/web/public/assets/agents-CFB4Uj6b.js.map +0 -1
  518. package/dist/web/public/assets/bgjobs-BYCQhd_1.js.map +0 -1
  519. package/dist/web/public/assets/distill-D9p8O8Jf.js +0 -7
  520. package/dist/web/public/assets/distill-D9p8O8Jf.js.map +0 -1
  521. package/dist/web/public/assets/email-Douv-rZ5.js +0 -7
  522. package/dist/web/public/assets/email-Douv-rZ5.js.map +0 -1
  523. package/dist/web/public/assets/llm-CMMa85Ig.js +0 -27
  524. package/dist/web/public/assets/llm-CMMa85Ig.js.map +0 -1
  525. package/dist/web/public/assets/messengers-DwSmauLs.js.map +0 -1
  526. package/dist/web/public/assets/policy-yD1c2Pcn.js +0 -2
  527. package/dist/web/public/assets/policy-yD1c2Pcn.js.map +0 -1
  528. package/dist/web/public/assets/search-B8PlbtLg.js +0 -17
  529. package/dist/web/public/assets/search-B8PlbtLg.js.map +0 -1
  530. package/dist/web/public/assets/security-DpOGp3nS.js +0 -2
  531. package/dist/web/public/assets/security-DpOGp3nS.js.map +0 -1
  532. package/dist/web/public/assets/vector-BfIEx8xX.js +0 -2
  533. package/dist/web/public/assets/vector-BfIEx8xX.js.map +0 -1
  534. package/dist/web/public/assets/viewer-BPMZkT05.js +0 -12
  535. package/dist/web/public/assets/viewer-BPMZkT05.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"llm-CMMa85Ig.js","sources":["../../node_modules/lucide-react/dist/esm/icons/cpu.js","../../node_modules/lucide-react/dist/esm/icons/file-stack.js","../../node_modules/lucide-react/dist/esm/icons/gauge.js","../../node_modules/lucide-react/dist/esm/icons/waves.js","../../node_modules/lucide-react/dist/esm/icons/zap.js","../../src/routes/settings/native-agent.tsx","../../src/routes/settings/llm.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.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 createLucideIcon from '../createLucideIcon.js';\n\nconst Cpu = createLucideIcon(\"Cpu\", [\n [\"rect\", { width: \"16\", height: \"16\", x: \"4\", y: \"4\", rx: \"2\", key: \"14l7u7\" }],\n [\"rect\", { width: \"6\", height: \"6\", x: \"9\", y: \"9\", rx: \"1\", key: \"5aljv4\" }],\n [\"path\", { d: \"M15 2v2\", key: \"13l42r\" }],\n [\"path\", { d: \"M15 20v2\", key: \"15mkzm\" }],\n [\"path\", { d: \"M2 15h2\", key: \"1gxd5l\" }],\n [\"path\", { d: \"M2 9h2\", key: \"1bbxkp\" }],\n [\"path\", { d: \"M20 15h2\", key: \"19e6y8\" }],\n [\"path\", { d: \"M20 9h2\", key: \"19tzq7\" }],\n [\"path\", { d: \"M9 2v2\", key: \"165o2o\" }],\n [\"path\", { d: \"M9 20v2\", key: \"i2bqo8\" }]\n]);\n\nexport { Cpu as default };\n//# sourceMappingURL=cpu.js.map\n","/**\n * @license lucide-react v0.469.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 createLucideIcon from '../createLucideIcon.js';\n\nconst FileStack = createLucideIcon(\"FileStack\", [\n [\"path\", { d: \"M21 7h-3a2 2 0 0 1-2-2V2\", key: \"9rb54x\" }],\n [\n \"path\",\n {\n d: \"M21 6v6.5c0 .8-.7 1.5-1.5 1.5h-7c-.8 0-1.5-.7-1.5-1.5v-9c0-.8.7-1.5 1.5-1.5H17Z\",\n key: \"1059l0\"\n }\n ],\n [\"path\", { d: \"M7 8v8.8c0 .3.2.6.4.8.2.2.5.4.8.4H15\", key: \"16874u\" }],\n [\"path\", { d: \"M3 12v8.8c0 .3.2.6.4.8.2.2.5.4.8.4H11\", key: \"k2ox98\" }]\n]);\n\nexport { FileStack as default };\n//# sourceMappingURL=file-stack.js.map\n","/**\n * @license lucide-react v0.469.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 createLucideIcon from '../createLucideIcon.js';\n\nconst Gauge = createLucideIcon(\"Gauge\", [\n [\"path\", { d: \"m12 14 4-4\", key: \"9kzdfg\" }],\n [\"path\", { d: \"M3.34 19a10 10 0 1 1 17.32 0\", key: \"19p75a\" }]\n]);\n\nexport { Gauge as default };\n//# sourceMappingURL=gauge.js.map\n","/**\n * @license lucide-react v0.469.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 createLucideIcon from '../createLucideIcon.js';\n\nconst Waves = createLucideIcon(\"Waves\", [\n [\n \"path\",\n {\n d: \"M2 6c.6.5 1.2 1 2.5 1C7 7 7 5 9.5 5c2.6 0 2.4 2 5 2 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1\",\n key: \"knzxuh\"\n }\n ],\n [\n \"path\",\n {\n d: \"M2 12c.6.5 1.2 1 2.5 1 2.5 0 2.5-2 5-2 2.6 0 2.4 2 5 2 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1\",\n key: \"2jd2cc\"\n }\n ],\n [\n \"path\",\n {\n d: \"M2 18c.6.5 1.2 1 2.5 1 2.5 0 2.5-2 5-2 2.6 0 2.4 2 5 2 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1\",\n key: \"rd2r6e\"\n }\n ]\n]);\n\nexport { Waves as default };\n//# sourceMappingURL=waves.js.map\n","/**\n * @license lucide-react v0.469.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 createLucideIcon from '../createLucideIcon.js';\n\nconst Zap = createLucideIcon(\"Zap\", [\n [\n \"path\",\n {\n d: \"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z\",\n key: \"1xq2db\"\n }\n ]\n]);\n\nexport { Zap as default };\n//# sourceMappingURL=zap.js.map\n","/**\n * /settings/native-agent — focused env editor for Agim Agent +\n * notification evaluator + heartbeat (Stage 6).\n *\n * All three subsystems are env-driven; their env keys are already in\n * ENV_EDITABLE_KEYS so the generic /api/env GET+PUT pair works. This\n * page just gives them a curated form so operators don't have to dig\n * through the 200+-key generic env editor.\n *\n * The actual model API selection (which LLM, which role) lives on\n * /settings/llm; this module covers behavioral knobs.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport {\n Bell, Cpu, FileStack, Gauge, HeartPulse, Loader2, Network,\n RefreshCcw, Save, ShieldAlert, Waves, X,\n} from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Select, SelectContent, SelectItem, SelectTrigger, SelectValue,\n} from '@/components/ui/select'\nimport { useEnv, useUpdateEnv } from '@/hooks/use-settings'\n\ntype ApprovalMode = 'allow-all' | 'read-only' | 'allow-list' | 'deny-all'\n\ninterface Draft {\n // Agim Agent\n role: string\n mode: ApprovalMode\n autoAllow: string\n denyList: string\n // Notification evaluator\n evalEnabled: boolean\n evalSources: string\n // Heartbeat\n hbEnabled: boolean\n hbTickMs: string\n hbDefaultMin: string\n // v1.2.126 — runtime caps (each one optional / empty = use default)\n toolResultCap: string\n toolTimeoutMs: string\n blankRetryMax: string\n lengthRecoveryMax: string\n // v1.2.127 — A2A 子 Agent 派生\n a2aMaxDepth: string\n a2aTimeoutMs: string\n callAgentInProcess: boolean\n callAgentMaxPerTurn: string\n // v1.2.127 — 早停 + 复盘\n semanticStuckLoop: boolean\n criticEnabled: boolean\n criticRole: string\n planModeDefault: boolean\n // v1.2.135 — heuristic auto-enter on plan-intent keywords\n planIntentAuto: boolean\n planIntentPhrases: string\n // v1.2.127 — Auto-compact 4 旋钮(OpenHands Condenser)\n compactTriggerChars: string\n compactKeepTurns: string\n compactKeepFirst: string\n compactSummaryChars: string\n // v1.2.127 — 流式 + 迭代\n streamPartial: boolean\n maxIter: string\n}\n\nfunction draftFromEnv(env: Record<string, string>): Draft {\n return {\n role: env.IMHUB_NATIVE_AGENT_ROLE ?? '',\n mode: (env.IMHUB_NATIVE_AGENT_MODE as ApprovalMode | undefined) || 'read-only',\n autoAllow: env.IMHUB_NATIVE_AGENT_AUTOALLOW ?? '',\n denyList: env.IMHUB_NATIVE_AGENT_DENYLIST ?? '',\n evalEnabled: isTruthy(env.IMHUB_NOTIFICATION_EVALUATOR),\n evalSources: env.IMHUB_NOTIFICATION_EVALUATOR_SOURCES ?? '',\n hbEnabled: isTruthy(env.IMHUB_HEARTBEAT_ENABLED),\n hbTickMs: env.IMHUB_HEARTBEAT_TICK_INTERVAL_MS ?? '',\n hbDefaultMin: env.IMHUB_HEARTBEAT_DEFAULT_INTERVAL_MIN ?? '',\n toolResultCap: env.IMHUB_NATIVE_TOOL_RESULT_MAX_CHARS ?? '',\n toolTimeoutMs: env.IMHUB_NATIVE_TOOL_TIMEOUT_MS ?? '',\n blankRetryMax: env.IMHUB_NATIVE_BLANK_RETRY_MAX ?? '',\n lengthRecoveryMax: env.IMHUB_NATIVE_LENGTH_RECOVERY_MAX ?? '',\n a2aMaxDepth: env.IMHUB_A2A_MAX_DEPTH ?? '',\n a2aTimeoutMs: env.IMHUB_A2A_TIMEOUT_DEFAULT_MS ?? '',\n // Default ON: only 'off' / '0' / 'no' / 'false' disable.\n callAgentInProcess: !isFalsy(env.IMHUB_NATIVE_CALL_AGENT_IN_PROCESS),\n callAgentMaxPerTurn: env.IMHUB_NATIVE_CALL_AGENT_MAX_PER_TURN ?? '',\n semanticStuckLoop: !isFalsy(env.IMHUB_NATIVE_SEMANTIC_STUCK_LOOP),\n criticEnabled: isTruthy(env.IMHUB_NATIVE_CRITIC),\n criticRole: env.IMHUB_NATIVE_CRITIC_ROLE ?? '',\n planModeDefault: isTruthy(env.IMHUB_NATIVE_PLAN_MODE),\n planIntentAuto: isTruthy(env.IMHUB_PLAN_INTENT_AUTO),\n planIntentPhrases: env.IMHUB_PLAN_INTENT_PHRASES ?? '',\n compactTriggerChars: env.IMHUB_NATIVE_COMPACT_TRIGGER_CHARS ?? '',\n compactKeepTurns: env.IMHUB_NATIVE_COMPACT_KEEP_TURNS ?? '',\n compactKeepFirst: env.IMHUB_NATIVE_COMPACT_KEEP_FIRST ?? '',\n compactSummaryChars: env.IMHUB_NATIVE_COMPACT_SUMMARY_CHARS ?? '',\n streamPartial: !isFalsy(env.IMHUB_NATIVE_STREAM_PARTIAL),\n maxIter: env.IMHUB_NATIVE_AGENT_MAX_ITER ?? '',\n }\n}\n\n/** Mirror of the native-side parser: 'off' / '0' / 'no' / 'false'\n * (case-insensitive) disables a feature whose default is ON. Empty\n * string means \"not set\" — caller decides whether that's ON or OFF\n * depending on the variable's default. */\nfunction isFalsy(v: string | undefined): boolean {\n if (!v) return false\n const s = v.toLowerCase().trim()\n return s === 'off' || s === 'false' || s === '0' || s === 'no'\n}\n\nfunction isTruthy(v: string | undefined): boolean {\n if (!v) return false\n const s = v.toLowerCase()\n return s === '1' || s === 'true' || s === 'yes' || s === 'on'\n}\n\nfunction SubtitleWithLlmLink(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const subtitle = t('nativeAgent.subtitle')\n const link = t('nativeAgent.llmLink')\n const idx = subtitle.indexOf(link)\n if (idx === -1) {\n return <p className=\"text-sm text-text-dim\">{subtitle}</p>\n }\n return (\n <p className=\"text-sm text-text-dim\">\n {subtitle.slice(0, idx)}\n <a className=\"underline\" href={link}>{link}</a>\n {subtitle.slice(idx + link.length)}\n </p>\n )\n}\n\nexport default function SettingsNativeAgentRoute(): JSX.Element {\n return <NativeAgentSettingsPanel />\n}\n\nexport interface NativeAgentSettingsPanelProps {\n embedded?: boolean\n}\n\nexport function NativeAgentSettingsPanel({ embedded = false }: NativeAgentSettingsPanelProps): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const envQuery = useEnv({ reveal: false })\n const updateEnv = useUpdateEnv()\n\n const envData = envQuery.data?.env ?? {}\n const current = useMemo(() => draftFromEnv(envData), [envData])\n const [draft, setDraft] = useState<Draft>(current)\n const [syncedHash, setSyncedHash] = useState('')\n\n useEffect(() => {\n const hash = JSON.stringify(current)\n if (hash !== syncedHash) {\n setDraft(current)\n setSyncedHash(hash)\n }\n }, [current, syncedHash])\n\n const isDirty = JSON.stringify(draft) !== JSON.stringify(current)\n\n function setField<K extends keyof Draft>(k: K, v: Draft[K]): void {\n setDraft((d) => ({ ...d, [k]: v }))\n }\n\n async function onSave(): Promise<void> {\n const updates: Record<string, string | null> = {}\n if (draft.role !== current.role) {\n updates.IMHUB_NATIVE_AGENT_ROLE = draft.role.trim() || null\n }\n if (draft.mode !== current.mode) {\n updates.IMHUB_NATIVE_AGENT_MODE = draft.mode\n }\n if (draft.autoAllow !== current.autoAllow) {\n updates.IMHUB_NATIVE_AGENT_AUTOALLOW = draft.autoAllow.trim() || null\n }\n if (draft.denyList !== current.denyList) {\n updates.IMHUB_NATIVE_AGENT_DENYLIST = draft.denyList.trim() || null\n }\n if (draft.evalEnabled !== current.evalEnabled) {\n updates.IMHUB_NOTIFICATION_EVALUATOR = draft.evalEnabled ? 'on' : null\n }\n if (draft.evalSources !== current.evalSources) {\n updates.IMHUB_NOTIFICATION_EVALUATOR_SOURCES = draft.evalSources.trim() || null\n }\n if (draft.hbEnabled !== current.hbEnabled) {\n updates.IMHUB_HEARTBEAT_ENABLED = draft.hbEnabled ? 'on' : null\n }\n if (draft.hbTickMs !== current.hbTickMs) {\n updates.IMHUB_HEARTBEAT_TICK_INTERVAL_MS = draft.hbTickMs.trim() || null\n }\n if (draft.hbDefaultMin !== current.hbDefaultMin) {\n updates.IMHUB_HEARTBEAT_DEFAULT_INTERVAL_MIN = draft.hbDefaultMin.trim() || null\n }\n if (draft.toolResultCap !== current.toolResultCap) {\n updates.IMHUB_NATIVE_TOOL_RESULT_MAX_CHARS = draft.toolResultCap.trim() || null\n }\n if (draft.toolTimeoutMs !== current.toolTimeoutMs) {\n updates.IMHUB_NATIVE_TOOL_TIMEOUT_MS = draft.toolTimeoutMs.trim() || null\n }\n if (draft.blankRetryMax !== current.blankRetryMax) {\n updates.IMHUB_NATIVE_BLANK_RETRY_MAX = draft.blankRetryMax.trim() || null\n }\n if (draft.lengthRecoveryMax !== current.lengthRecoveryMax) {\n updates.IMHUB_NATIVE_LENGTH_RECOVERY_MAX = draft.lengthRecoveryMax.trim() || null\n }\n // v1.2.127 — A2A\n if (draft.a2aMaxDepth !== current.a2aMaxDepth) {\n updates.IMHUB_A2A_MAX_DEPTH = draft.a2aMaxDepth.trim() || null\n }\n if (draft.a2aTimeoutMs !== current.a2aTimeoutMs) {\n updates.IMHUB_A2A_TIMEOUT_DEFAULT_MS = draft.a2aTimeoutMs.trim() || null\n }\n if (draft.callAgentInProcess !== current.callAgentInProcess) {\n // Default ON: write only when operator turned OFF; ON = delete the env.\n updates.IMHUB_NATIVE_CALL_AGENT_IN_PROCESS = draft.callAgentInProcess ? null : 'off'\n }\n if (draft.callAgentMaxPerTurn !== current.callAgentMaxPerTurn) {\n updates.IMHUB_NATIVE_CALL_AGENT_MAX_PER_TURN = draft.callAgentMaxPerTurn.trim() || null\n }\n // v1.2.127 — 早停 + 复盘\n if (draft.semanticStuckLoop !== current.semanticStuckLoop) {\n updates.IMHUB_NATIVE_SEMANTIC_STUCK_LOOP = draft.semanticStuckLoop ? null : 'off'\n }\n if (draft.criticEnabled !== current.criticEnabled) {\n updates.IMHUB_NATIVE_CRITIC = draft.criticEnabled ? 'on' : null\n }\n if (draft.criticRole !== current.criticRole) {\n updates.IMHUB_NATIVE_CRITIC_ROLE = draft.criticRole.trim() || null\n }\n if (draft.planModeDefault !== current.planModeDefault) {\n updates.IMHUB_NATIVE_PLAN_MODE = draft.planModeDefault ? '1' : null\n }\n if (draft.planIntentAuto !== current.planIntentAuto) {\n updates.IMHUB_PLAN_INTENT_AUTO = draft.planIntentAuto ? 'on' : null\n }\n if (draft.planIntentPhrases !== current.planIntentPhrases) {\n updates.IMHUB_PLAN_INTENT_PHRASES = draft.planIntentPhrases.trim() || null\n }\n // v1.2.127 — Auto-compact\n if (draft.compactTriggerChars !== current.compactTriggerChars) {\n updates.IMHUB_NATIVE_COMPACT_TRIGGER_CHARS = draft.compactTriggerChars.trim() || null\n }\n if (draft.compactKeepTurns !== current.compactKeepTurns) {\n updates.IMHUB_NATIVE_COMPACT_KEEP_TURNS = draft.compactKeepTurns.trim() || null\n }\n if (draft.compactKeepFirst !== current.compactKeepFirst) {\n updates.IMHUB_NATIVE_COMPACT_KEEP_FIRST = draft.compactKeepFirst.trim() || null\n }\n if (draft.compactSummaryChars !== current.compactSummaryChars) {\n updates.IMHUB_NATIVE_COMPACT_SUMMARY_CHARS = draft.compactSummaryChars.trim() || null\n }\n // v1.2.127 — 流式 + 迭代\n if (draft.streamPartial !== current.streamPartial) {\n updates.IMHUB_NATIVE_STREAM_PARTIAL = draft.streamPartial ? null : 'off'\n }\n if (draft.maxIter !== current.maxIter) {\n updates.IMHUB_NATIVE_AGENT_MAX_ITER = draft.maxIter.trim() || null\n }\n if (Object.keys(updates).length === 0) return\n try {\n await updateEnv.mutateAsync({ updates })\n toast.success(t('nativeAgent.savedToast'))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n function onDiscard(): void {\n setDraft(current)\n }\n\n return (\n <div className={embedded ? 'flex flex-col gap-6' : 'mx-auto flex max-w-4xl flex-col gap-6'}>\n {!embedded && (\n <>\n <header className=\"flex items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('nativeAgent.title')}</h1>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void envQuery.refetch()}\n disabled={envQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {envQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('nativeAgent.refresh')}</span>\n </Button>\n </header>\n <SubtitleWithLlmLink />\n </>\n )}\n\n {envQuery.isLoading ? (\n <div className=\"h-64 rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <>\n <NativeAgentCard draft={draft} setField={setField} />\n <RuntimeCapsCard draft={draft} setField={setField} />\n <A2ACard draft={draft} setField={setField} />\n <CriticCard draft={draft} setField={setField} />\n <CompactCard draft={draft} setField={setField} />\n <StreamCard draft={draft} setField={setField} />\n <EvaluatorCard draft={draft} setField={setField} />\n <HeartbeatCard draft={draft} setField={setField} />\n </>\n )}\n\n {isDirty && (\n <div className={embedded\n ? 'flex items-center gap-2 rounded-md border border-border bg-surface px-4 py-3 shadow'\n : 'sticky bottom-2 flex items-center gap-2 rounded-md border border-border bg-surface px-4 py-3 shadow'}\n >\n <Badge variant=\"info\">{t('nativeAgent.unsaved')}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={onDiscard}\n disabled={updateEnv.isPending}\n >\n <X className=\"h-4 w-4\" /> {t('nativeAgent.discard')}\n </Button>\n <Button\n size=\"sm\"\n onClick={() => void onSave()}\n disabled={updateEnv.isPending}\n >\n {updateEnv.isPending\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <Save className=\"h-4 w-4\" />}\n {t('nativeAgent.save')}\n </Button>\n </div>\n )}\n </div>\n )\n}\n\ninterface CardProps {\n draft: Draft\n setField: <K extends keyof Draft>(k: K, v: Draft[K]) => void\n}\n\nfunction NativeAgentCard({ draft, setField }: CardProps): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"flex items-center gap-2 border-b border-border px-4 py-3\">\n <Cpu className=\"h-4 w-4 text-text-dim\" />\n <h2 className=\"text-sm font-semibold\">{t('nativeAgent.agentCard')}</h2>\n </header>\n <div className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-2\">\n <Field\n label={t('nativeAgent.roleOverride')}\n hint={t('nativeAgent.roleHint')}\n >\n <Input\n value={draft.role}\n onChange={(e) => setField('role', e.target.value)}\n placeholder=\"native-chat\"\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field\n label={t('nativeAgent.approvalMode')}\n hint={t('nativeAgent.approvalHint')}\n >\n <Select\n value={draft.mode}\n onValueChange={(v) => setField('mode', v as ApprovalMode)}\n >\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"read-only\">{t('nativeAgent.modeReadOnly')}</SelectItem>\n <SelectItem value=\"allow-list\">{t('nativeAgent.modeAllowList')}</SelectItem>\n <SelectItem value=\"allow-all\">{t('nativeAgent.modeAllowAll')}</SelectItem>\n <SelectItem value=\"deny-all\">{t('nativeAgent.modeDenyAll')}</SelectItem>\n </SelectContent>\n </Select>\n </Field>\n <Field\n label={t('nativeAgent.autoAllow')}\n hint={t('nativeAgent.autoAllowHint')}\n >\n <Input\n value={draft.autoAllow}\n onChange={(e) => setField('autoAllow', e.target.value)}\n placeholder=\"native_,mcp_filesystem_\"\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field\n label={t('nativeAgent.denyList')}\n hint={t('nativeAgent.denyListHint')}\n >\n <Input\n value={draft.denyList}\n onChange={(e) => setField('denyList', e.target.value)}\n placeholder=\"mcp_shell_,mcp_dangerous_\"\n className=\"font-mono text-xs\"\n />\n </Field>\n </div>\n </section>\n )\n}\n\nfunction EvaluatorCard({ draft, setField }: CardProps): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"flex items-center gap-2 border-b border-border px-4 py-3\">\n <Bell className=\"h-4 w-4 text-text-dim\" />\n <h2 className=\"text-sm font-semibold\">{t('nativeAgent.evaluatorCard')}</h2>\n {draft.evalEnabled\n ? <Badge variant=\"success\">{t('nativeAgent.on')}</Badge>\n : <Badge variant=\"outline\">{t('nativeAgent.off')}</Badge>}\n </header>\n <p className=\"px-4 pt-2 text-xs text-text-dim\">{t('nativeAgent.evalDesc')}</p>\n <div className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-2\">\n <Field label={t('nativeAgent.enableGate')}>\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={draft.evalEnabled}\n onChange={(e) => setField('evalEnabled', e.target.checked)}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n <span>{t('nativeAgent.filterViaLlm')}</span>\n </label>\n </Field>\n <Field\n label={t('nativeAgent.evalSources')}\n hint={t('nativeAgent.evalSourcesHint')}\n >\n <Input\n value={draft.evalSources}\n onChange={(e) => setField('evalSources', e.target.value)}\n placeholder=\"push,heartbeat\"\n className=\"font-mono text-xs\"\n disabled={!draft.evalEnabled}\n />\n </Field>\n </div>\n </section>\n )\n}\n\nfunction HeartbeatCard({ draft, setField }: CardProps): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"flex items-center gap-2 border-b border-border px-4 py-3\">\n <HeartPulse className=\"h-4 w-4 text-text-dim\" />\n <h2 className=\"text-sm font-semibold\">{t('nativeAgent.heartbeatCard')}</h2>\n {draft.hbEnabled\n ? <Badge variant=\"success\">{t('nativeAgent.on')}</Badge>\n : <Badge variant=\"outline\">{t('nativeAgent.off')}</Badge>}\n </header>\n <p className=\"px-4 pt-2 text-xs text-text-dim\">{t('nativeAgent.hbDesc')}</p>\n <div className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-3\">\n <Field label={t('nativeAgent.enableScheduler')}>\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={draft.hbEnabled}\n onChange={(e) => setField('hbEnabled', e.target.checked)}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n <span>{t('nativeAgent.startScanLoop')}</span>\n </label>\n </Field>\n <Field\n label={t('nativeAgent.tickInterval')}\n hint={t('nativeAgent.tickHint')}\n >\n <Input\n type=\"number\"\n value={draft.hbTickMs}\n onChange={(e) => setField('hbTickMs', e.target.value)}\n placeholder=\"60000\"\n className=\"font-mono text-xs\"\n disabled={!draft.hbEnabled}\n />\n </Field>\n <Field\n label={t('nativeAgent.defaultInterval')}\n hint={t('nativeAgent.defaultIntervalHint')}\n >\n <Input\n type=\"number\"\n value={draft.hbDefaultMin}\n onChange={(e) => setField('hbDefaultMin', e.target.value)}\n placeholder=\"15\"\n className=\"font-mono text-xs\"\n disabled={!draft.hbEnabled}\n />\n </Field>\n </div>\n </section>\n )\n}\n\nfunction RuntimeCapsCard({ draft, setField }: CardProps): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"flex items-center gap-2 border-b border-border px-4 py-3\">\n <Gauge className=\"h-4 w-4 text-text-dim\" />\n <h2 className=\"text-sm font-semibold\">{t('nativeAgent.runtimeCard')}</h2>\n </header>\n <p className=\"px-4 pt-2 text-xs text-text-dim\">{t('nativeAgent.runtimeDesc')}</p>\n <div className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-2\">\n <Field\n label={t('nativeAgent.toolResultCap')}\n hint={t('nativeAgent.toolResultCapHint')}\n >\n <Input\n type=\"number\"\n value={draft.toolResultCap}\n onChange={(e) => setField('toolResultCap', e.target.value)}\n placeholder=\"64000\"\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field\n label={t('nativeAgent.toolTimeoutMs')}\n hint={t('nativeAgent.toolTimeoutHint')}\n >\n <Input\n type=\"number\"\n value={draft.toolTimeoutMs}\n onChange={(e) => setField('toolTimeoutMs', e.target.value)}\n placeholder=\"60000\"\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field\n label={t('nativeAgent.blankRetryMax')}\n hint={t('nativeAgent.blankRetryHint')}\n >\n <Input\n type=\"number\"\n value={draft.blankRetryMax}\n onChange={(e) => setField('blankRetryMax', e.target.value)}\n placeholder=\"1\"\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field\n label={t('nativeAgent.lengthRecoveryMax')}\n hint={t('nativeAgent.lengthRecoveryHint')}\n >\n <Input\n type=\"number\"\n value={draft.lengthRecoveryMax}\n onChange={(e) => setField('lengthRecoveryMax', e.target.value)}\n placeholder=\"1\"\n className=\"font-mono text-xs\"\n />\n </Field>\n </div>\n </section>\n )\n}\n\nfunction A2ACard({ draft, setField }: CardProps): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"flex items-center gap-2 border-b border-border px-4 py-3\">\n <Network className=\"h-4 w-4 text-text-dim\" />\n <h2 className=\"text-sm font-semibold\">{t('nativeAgent.a2aCard')}</h2>\n </header>\n <p className=\"px-4 pt-2 text-xs text-text-dim\">{t('nativeAgent.a2aDesc')}</p>\n <div className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-2\">\n <Field\n label={t('nativeAgent.a2aMaxDepth')}\n hint={t('nativeAgent.a2aMaxDepthHint')}\n >\n <Input\n type=\"number\"\n value={draft.a2aMaxDepth}\n onChange={(e) => setField('a2aMaxDepth', e.target.value)}\n placeholder=\"1\"\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field\n label={t('nativeAgent.a2aTimeoutMs')}\n hint={t('nativeAgent.a2aTimeoutMsHint')}\n >\n <Input\n type=\"number\"\n value={draft.a2aTimeoutMs}\n onChange={(e) => setField('a2aTimeoutMs', e.target.value)}\n placeholder=\"1800000\"\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field\n label={t('nativeAgent.callAgentInProcess')}\n hint={t('nativeAgent.callAgentInProcessHint')}\n >\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={draft.callAgentInProcess}\n onChange={(e) => setField('callAgentInProcess', e.target.checked)}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n <span>{draft.callAgentInProcess ? t('nativeAgent.on') : t('nativeAgent.off')}</span>\n </label>\n </Field>\n <Field\n label={t('nativeAgent.callAgentMaxPerTurn')}\n hint={t('nativeAgent.callAgentMaxPerTurnHint')}\n >\n <Input\n type=\"number\"\n value={draft.callAgentMaxPerTurn}\n onChange={(e) => setField('callAgentMaxPerTurn', e.target.value)}\n placeholder=\"2\"\n className=\"font-mono text-xs\"\n />\n </Field>\n </div>\n </section>\n )\n}\n\nfunction CriticCard({ draft, setField }: CardProps): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"flex items-center gap-2 border-b border-border px-4 py-3\">\n <ShieldAlert className=\"h-4 w-4 text-text-dim\" />\n <h2 className=\"text-sm font-semibold\">{t('nativeAgent.criticCard')}</h2>\n </header>\n <p className=\"px-4 pt-2 text-xs text-text-dim\">{t('nativeAgent.criticDesc')}</p>\n <div className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-2\">\n <Field\n label={t('nativeAgent.semanticStuckLoop')}\n hint={t('nativeAgent.semanticStuckLoopHint')}\n >\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={draft.semanticStuckLoop}\n onChange={(e) => setField('semanticStuckLoop', e.target.checked)}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n <span>{draft.semanticStuckLoop ? t('nativeAgent.on') : t('nativeAgent.off')}</span>\n </label>\n </Field>\n <Field\n label={t('nativeAgent.criticEnabled')}\n hint={t('nativeAgent.criticEnabledHint')}\n >\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={draft.criticEnabled}\n onChange={(e) => setField('criticEnabled', e.target.checked)}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n <span>{draft.criticEnabled ? t('nativeAgent.on') : t('nativeAgent.off')}</span>\n </label>\n </Field>\n <Field\n label={t('nativeAgent.criticRole')}\n hint={t('nativeAgent.criticRoleHint')}\n >\n <Input\n value={draft.criticRole}\n onChange={(e) => setField('criticRole', e.target.value)}\n placeholder=\"(use main backend)\"\n className=\"font-mono text-xs\"\n disabled={!draft.criticEnabled}\n />\n </Field>\n <Field\n label={t('nativeAgent.planModeDefault')}\n hint={t('nativeAgent.planModeDefaultHint')}\n >\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={draft.planModeDefault}\n onChange={(e) => setField('planModeDefault', e.target.checked)}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n <span>{draft.planModeDefault ? t('nativeAgent.on') : t('nativeAgent.off')}</span>\n </label>\n </Field>\n <Field\n label={t('nativeAgent.planIntentAuto')}\n hint={t('nativeAgent.planIntentAutoHint')}\n >\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={draft.planIntentAuto}\n onChange={(e) => setField('planIntentAuto', e.target.checked)}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n <span>{draft.planIntentAuto ? t('nativeAgent.on') : t('nativeAgent.off')}</span>\n </label>\n </Field>\n <Field\n label={t('nativeAgent.planIntentPhrases')}\n hint={t('nativeAgent.planIntentPhrasesHint')}\n >\n <Input\n value={draft.planIntentPhrases}\n onChange={(e) => setField('planIntentPhrases', e.target.value)}\n placeholder=\"先想想,plan only,don't act yet\"\n className=\"font-mono text-xs\"\n disabled={!draft.planIntentAuto}\n />\n </Field>\n </div>\n </section>\n )\n}\n\nfunction CompactCard({ draft, setField }: CardProps): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"flex items-center gap-2 border-b border-border px-4 py-3\">\n <FileStack className=\"h-4 w-4 text-text-dim\" />\n <h2 className=\"text-sm font-semibold\">{t('nativeAgent.compactCard')}</h2>\n </header>\n <p className=\"px-4 pt-2 text-xs text-text-dim\">{t('nativeAgent.compactDesc')}</p>\n <div className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-2\">\n <Field\n label={t('nativeAgent.compactTriggerChars')}\n hint={t('nativeAgent.compactTriggerCharsHint')}\n >\n <Input\n type=\"number\"\n value={draft.compactTriggerChars}\n onChange={(e) => setField('compactTriggerChars', e.target.value)}\n placeholder=\"60000\"\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field\n label={t('nativeAgent.compactKeepTurns')}\n hint={t('nativeAgent.compactKeepTurnsHint')}\n >\n <Input\n type=\"number\"\n value={draft.compactKeepTurns}\n onChange={(e) => setField('compactKeepTurns', e.target.value)}\n placeholder=\"6\"\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field\n label={t('nativeAgent.compactKeepFirst')}\n hint={t('nativeAgent.compactKeepFirstHint')}\n >\n <Input\n type=\"number\"\n value={draft.compactKeepFirst}\n onChange={(e) => setField('compactKeepFirst', e.target.value)}\n placeholder=\"1\"\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field\n label={t('nativeAgent.compactSummaryChars')}\n hint={t('nativeAgent.compactSummaryCharsHint')}\n >\n <Input\n type=\"number\"\n value={draft.compactSummaryChars}\n onChange={(e) => setField('compactSummaryChars', e.target.value)}\n placeholder=\"1500\"\n className=\"font-mono text-xs\"\n />\n </Field>\n </div>\n </section>\n )\n}\n\nfunction StreamCard({ draft, setField }: CardProps): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"flex items-center gap-2 border-b border-border px-4 py-3\">\n <Waves className=\"h-4 w-4 text-text-dim\" />\n <h2 className=\"text-sm font-semibold\">{t('nativeAgent.streamCard')}</h2>\n </header>\n <p className=\"px-4 pt-2 text-xs text-text-dim\">{t('nativeAgent.streamDesc')}</p>\n <div className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-2\">\n <Field\n label={t('nativeAgent.streamPartial')}\n hint={t('nativeAgent.streamPartialHint')}\n >\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={draft.streamPartial}\n onChange={(e) => setField('streamPartial', e.target.checked)}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n <span>{draft.streamPartial ? t('nativeAgent.on') : t('nativeAgent.off')}</span>\n </label>\n </Field>\n <Field\n label={t('nativeAgent.maxIter')}\n hint={t('nativeAgent.maxIterHint')}\n >\n <Input\n type=\"number\"\n value={draft.maxIter}\n onChange={(e) => setField('maxIter', e.target.value)}\n placeholder=\"50\"\n className=\"font-mono text-xs\"\n />\n </Field>\n </div>\n </section>\n )\n}\n\ninterface FieldProps {\n label: string\n hint?: string\n children: React.ReactNode\n}\nfunction Field({ label, hint, children }: FieldProps): JSX.Element {\n return (\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">{label}</Label>\n {children}\n {hint && <p className=\"text-[11px] text-text-dim\">{hint}</p>}\n </div>\n )\n}\n","/**\n * /settings/llm — Agim Agent model APIs + runtime settings.\n *\n * Front-end for the `/api/llm/*` REST surface that landed in Stage 4.\n * Operators add an OpenAI-compatible or Anthropic API, paste an API\n * key, optionally bind roles (cheap / evaluator / native-chat), and\n * tune built-in Agim Agent runtime behavior without hand-editing\n * ~/.agim/config.json.\n *\n * Intentionally minimal styling — focused on doing the job; matches\n * the existing settings pages' shadcn look without bespoke chrome.\n */\n\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { CheckCircle2, Loader2, Plus, RefreshCcw, Trash2, Zap } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Select, SelectContent, SelectItem, SelectTrigger, SelectValue,\n} from '@/components/ui/select'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useLlmList, useLlmAddBackend, useLlmRemoveBackend, useLlmPutRoles, useLlmPing,\n} from '@/hooks/use-llm-admin'\nimport { NativeAgentSettingsPanel } from '@/routes/settings/native-agent'\n\nconst KNOWN_ROLES = ['cheap', 'evaluator', 'native-chat'] as const\nconst UNBIND_SENTINEL = '__unbind__'\n\ninterface ProviderPreset {\n provider: 'openai-compat' | 'anthropic'\n baseUrl: string\n modelHint: string\n}\n\nconst PRESET_KEYS = ['deepseek', 'moonshot', 'zhipu', 'openai', 'anthropic', 'custom'] as const\n\nconst PRESETS: ProviderPreset[] = [\n { provider: 'openai-compat',\n baseUrl: 'https://api.deepseek.com/v1', modelHint: 'deepseek-chat' },\n { provider: 'openai-compat',\n baseUrl: 'https://api.moonshot.cn/v1', modelHint: 'moonshot-v1-8k' },\n { provider: 'openai-compat',\n baseUrl: 'https://open.bigmodel.cn/api/paas/v4', modelHint: 'glm-4-air' },\n { provider: 'openai-compat',\n baseUrl: 'https://api.openai.com/v1', modelHint: 'gpt-4o-mini' },\n { provider: 'anthropic',\n // No trailing /v1: the Anthropic provider appends `/v1/messages` itself.\n baseUrl: 'https://api.anthropic.com', modelHint: 'claude-3-5-sonnet-20241022' },\n { provider: 'openai-compat',\n baseUrl: '', modelHint: '' },\n]\n\nexport default function SettingsLlmRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const listQuery = useLlmList()\n return (\n <div className=\"mx-auto flex max-w-5xl flex-col gap-6\">\n <header className=\"flex items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('llm.title')}</h1>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('llm.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('llm.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-64 rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <>\n <BackendsCard data={listQuery.data} />\n <AddBackendCard />\n <RolesCard data={listQuery.data} />\n <section id=\"agim-agent\" className=\"rounded-md border border-border bg-surface px-4 py-3\">\n <h2 className=\"text-sm font-semibold\">{t('llm.agimAgentRuntimeTitle')}</h2>\n <p className=\"mt-1 text-xs text-text-dim\">{t('llm.agimAgentRuntimeHint')}</p>\n </section>\n <NativeAgentSettingsPanel embedded />\n </>\n )}\n </div>\n )\n}\n\n/* ─────────────── Backends list ─────────────── */\n\nfunction BackendsCard({ data }: { data: ReturnType<typeof useLlmList>['data'] }): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const removeBackend = useLlmRemoveBackend()\n const ping = useLlmPing()\n const [pingResults, setPingResults] = useState<Record<string, string>>({})\n\n async function onRemove(name: string): Promise<void> {\n if (!confirm(t('llm.removeConfirm', { name }))) return\n try {\n const r = await removeBackend.mutateAsync(name)\n toast.success(t('llm.removedToast', { count: r.removedRoles }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n async function onPing(name: string): Promise<void> {\n setPingResults((m) => ({ ...m, [name]: t('llm.pinging') }))\n try {\n const r = await ping.mutateAsync(name)\n const msg = r.ok\n ? `✓ ${r.durationMs}ms · tokens ${r.tokensIn}→${r.tokensOut}`\n : `✗ ${r.error}`\n setPingResults((m) => ({ ...m, [name]: msg }))\n } catch (err) {\n setPingResults((m) => ({ ...m, [name]: `✗ ${((err as Error)?.message ?? String(err))}` }))\n }\n }\n\n const rows = data?.backends ?? []\n if (rows.length === 0) {\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('llm.backendsEmpty')}\n </section>\n )\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold\">{t('llm.backendsTitle', { count: rows.length })}</h2>\n </header>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('llm.col.name')}</TableHead>\n <TableHead>{t('llm.col.provider')}</TableHead>\n <TableHead>{t('llm.col.model')}</TableHead>\n <TableHead>{t('llm.col.baseUrl')}</TableHead>\n <TableHead>{t('llm.col.apiKey')}</TableHead>\n <TableHead>{t('llm.col.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((b) => {\n const keyBadge = b.secret.source === 'none'\n ? <Badge variant=\"outline\">{t('llm.secretMissing')}</Badge>\n : <Badge variant=\"success\">{b.secret.source}</Badge>\n return (\n <TableRow key={b.name}>\n <TableCell className=\"font-mono text-xs\">{b.name}</TableCell>\n <TableCell>{b.provider}</TableCell>\n <TableCell className=\"font-mono text-xs\">{b.model}</TableCell>\n <TableCell className=\"break-all font-mono text-[11px] text-text-dim\">{b.baseUrl ?? '—'}</TableCell>\n <TableCell>{keyBadge}</TableCell>\n <TableCell className=\"flex flex-col gap-1 sm:flex-row sm:items-center\">\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onPing(b.name)}\n disabled={ping.isPending || b.secret.source === 'none'}\n title={b.secret.source === 'none' ? t('llm.setKeyFirst') : t('llm.pingHint')}\n >\n <Zap className=\"h-4 w-4\" />\n <span>{t('llm.ping')}</span>\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onRemove(b.name)}\n disabled={removeBackend.isPending}\n className=\"text-danger hover:text-danger\"\n >\n <Trash2 className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">{t('llm.remove')}</span>\n </Button>\n {pingResults[b.name] && (\n <span className=\"ml-2 text-[11px] text-text-dim\">{pingResults[b.name]}</span>\n )}\n </TableCell>\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )\n}\n\n/* ─────────────── Role bindings ─────────────── */\n\nfunction RolesCard({ data }: { data: ReturnType<typeof useLlmList>['data'] }): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const putRoles = useLlmPutRoles()\n const backendNames = (data?.backends ?? []).map((b) => b.name)\n const current = data?.roles ?? {}\n\n async function onChangeRole(role: string, value: string): Promise<void> {\n const next: Record<string, string | null> = {\n [role]: value === UNBIND_SENTINEL ? null : value,\n }\n try {\n await putRoles.mutateAsync(next)\n toast.success(t('llm.roleUpdated', { role }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold\">{t('llm.rolesTitle')}</h2>\n <p className=\"mt-1 text-xs text-text-dim\">{t('llm.rolesOptionalHint')}</p>\n </header>\n <div className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-3\">\n {KNOWN_ROLES.map((role) => (\n <div key={role} className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">{role}</Label>\n <Select\n value={current[role] ?? UNBIND_SENTINEL}\n onValueChange={(v) => void onChangeRole(role, v)}\n disabled={backendNames.length === 0 || putRoles.isPending}\n >\n <SelectTrigger className=\"font-mono text-xs\">\n <SelectValue placeholder={t('llm.unset')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={UNBIND_SENTINEL}>{t('llm.unbound')}</SelectItem>\n {backendNames.map((n) => (\n <SelectItem key={n} value={n}>{n}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n <p className=\"text-[11px] text-text-dim\">\n {t(`llm.roleHint.${role}`)}\n </p>\n </div>\n ))}\n </div>\n </section>\n )\n}\n\n/* ─────────────── Add backend form ─────────────── */\n\nfunction AddBackendCard(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const addBackend = useLlmAddBackend()\n const [presetIdx, setPresetIdx] = useState(0)\n const [name, setName] = useState('')\n const [baseUrl, setBaseUrl] = useState(PRESETS[0]?.baseUrl ?? '')\n const [model, setModel] = useState(PRESETS[0]?.modelHint ?? '')\n const [apiKey, setApiKey] = useState('')\n const [formError, setFormError] = useState<string | null>(null)\n\n function fail(message: string): void {\n setFormError(message)\n toast.error(message)\n }\n\n function onPickPreset(idx: number): void {\n setPresetIdx(idx)\n const p = PRESETS[idx]\n if (!p) return\n setBaseUrl(p.baseUrl)\n setModel(p.modelHint)\n }\n\n async function onSubmit(e: React.FormEvent): Promise<void> {\n e.preventDefault()\n const p = PRESETS[presetIdx]\n if (!p) { fail(t('llm.invalidPreset')); return }\n if (!name.trim()) { fail(t('llm.nameRequired')); return }\n if (!baseUrl.trim()) { fail(t('llm.baseUrlRequired')); return }\n if (!model.trim()) { fail(t('llm.modelRequired')); return }\n if (!apiKey.trim()) { fail(t('llm.apiKeyRequired')); return }\n try {\n await addBackend.mutateAsync({\n name: name.trim(),\n provider: p.provider,\n baseUrl: baseUrl.trim(),\n model: model.trim(),\n apiKey: apiKey.trim(),\n })\n setFormError(null)\n toast.success(t('llm.addedWithKey', { name: name.trim() }))\n setName(''); setApiKey('')\n } catch (err) {\n const message = ((err as Error)?.message ?? String(err))\n fail(message)\n }\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold\">{t('llm.addTitle')}</h2>\n </header>\n <form onSubmit={(e) => void onSubmit(e)} className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-2\">\n <div>\n <Label className=\"text-xs font-medium\">{t('llm.preset')}</Label>\n <Select value={String(presetIdx)} onValueChange={(v) => onPickPreset(Number(v))}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n {PRESETS.map((_p, i) => (\n <SelectItem key={PRESET_KEYS[i]} value={String(i)}>\n {t(`llm.presets.${PRESET_KEYS[i]}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div>\n <Label className=\"text-xs font-medium\">{t('llm.name')}</Label>\n <Input\n value={name} onChange={(e) => setName(e.target.value)}\n placeholder={t('llm.namePlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n <div className=\"sm:col-span-2\">\n <Label className=\"text-xs font-medium\">{t('llm.baseUrl')}</Label>\n <Input\n value={baseUrl} onChange={(e) => setBaseUrl(e.target.value)}\n placeholder={t('llm.baseUrlPlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n <div>\n <Label className=\"text-xs font-medium\">{t('llm.model')}</Label>\n <Input\n value={model} onChange={(e) => setModel(e.target.value)}\n placeholder={t('llm.modelPlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n <div>\n <Label className=\"text-xs font-medium\">{t('llm.apiKey')}</Label>\n <Input\n type=\"password\"\n value={apiKey} onChange={(e) => setApiKey(e.target.value)}\n placeholder={t('llm.apiKeyPlaceholder')}\n className=\"font-mono text-xs\"\n autoComplete=\"off\"\n />\n </div>\n <div className=\"sm:col-span-2 flex\">\n <div className=\"flex w-full flex-col gap-2 sm:items-end\">\n {formError && (\n <p className=\"text-xs text-danger\">{formError}</p>\n )}\n <Button\n type=\"submit\"\n disabled={addBackend.isPending}\n className=\"ml-auto\"\n >\n {addBackend.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Plus className=\"h-4 w-4\" />}\n {t('llm.addBackend')}\n </Button>\n </div>\n </div>\n </form>\n </section>\n )\n}\n\n/* helper — toast tag passthrough */\nfunction _unused(): typeof CheckCircle2 { return CheckCircle2 }\nvoid _unused\n"],"names":["Cpu","createLucideIcon","FileStack","Gauge","Waves","Zap","draftFromEnv","env","isTruthy","isFalsy","v","SubtitleWithLlmLink","useTranslation","subtitle","link","idx","jsx","jsxs","NativeAgentSettingsPanel","embedded","t","envQuery","useEnv","updateEnv","useUpdateEnv","envData","current","useMemo","draft","setDraft","useState","syncedHash","setSyncedHash","useEffect","hash","isDirty","setField","k","d","onSave","updates","toast","err","onDiscard","Fragment","Button","Loader2","RefreshCcw","NativeAgentCard","RuntimeCapsCard","A2ACard","CriticCard","CompactCard","StreamCard","EvaluatorCard","HeartbeatCard","Badge","X","Save","Field","Input","e","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Bell","HeartPulse","Network","ShieldAlert","label","hint","children","Label","KNOWN_ROLES","UNBIND_SENTINEL","PRESET_KEYS","PRESETS","SettingsLlmRoute","listQuery","useLlmList","BackendsCard","AddBackendCard","RolesCard","data","removeBackend","useLlmRemoveBackend","ping","useLlmPing","pingResults","setPingResults","onRemove","name","r","onPing","m","msg","rows","Table","TableHeader","TableRow","TableHead","TableBody","b","keyBadge","TableCell","Trash2","putRoles","useLlmPutRoles","backendNames","onChangeRole","role","value","next","n","addBackend","useLlmAddBackend","presetIdx","setPresetIdx","setName","baseUrl","setBaseUrl","model","setModel","apiKey","setApiKey","formError","setFormError","fail","message","onPickPreset","p","onSubmit","_p","i","Plus"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"messengers-DwSmauLs.js","sources":["../../src/routes/settings/messengers.tsx"],"sourcesContent":["/**\n * /settings/messengers — per-IM-platform connection config.\n *\n * Layout: one card per platform (WeChat / Telegram / Feishu /\n * DingTalk / Discord). Each card has:\n * * Title + hint\n * * Enable / disable toggle (reads / writes config.messengers[])\n * * When enabled, the platform's config fields (texted)\n * * For WeChat: a \"Scan QR\" button → modal with QR + 2s polling\n *\n * Save All button at the top batches every dirty platform into one\n * PUT /api/config. The discard button reverts the local draft to\n * server-side values.\n *\n * The WeChat QR flow is special: enabling WeChat requires scanning\n * a QR code (the slot in config.messengers gets added by the\n * backend on `confirmed`, so we just open the modal and re-fetch\n * config after a successful scan).\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Loader2, QrCode, RefreshCcw, Save, X } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '@/components/ui/dialog'\nimport {\n useConfig,\n useUpdateConfig,\n useStartWechatQr,\n useWechatQrStatus,\n} from '@/hooks/use-settings'\nimport { describeError } from '@/lib/api/errors'\nimport type { AppConfig } from '@/types/api'\n\n/** Slot names match what `config.messengers[]` contains.\n * WeChat uses 'wechat-ilink' (the iLink adapter ID). */\ntype Slot = 'wechat-ilink' | 'telegram' | 'feishu' | 'dingtalk' | 'discord'\n\ninterface PlatformDraft {\n enabled: boolean\n telegram?: { botToken?: string; channelId?: string }\n feishu?: { appId?: string; appSecret?: string; channelId?: string }\n dingtalk?: {\n clientId?: string\n clientSecret?: string\n channelId?: string\n // v1.2.37 (batch 1)\n dmPolicy?: 'open' | 'pairing' | 'allowlist'\n groupPolicy?: 'open' | 'allowlist' | 'disabled'\n allowFrom?: string[]\n groupAllowFrom?: string[]\n ackReaction?: 'off' | 'emoji' | 'kaomoji'\n // v1.2.41 (batch 4 follow-up) — full multi-account editor\n accounts?: Record<string, DingTalkAccountDraft>\n }\n discord?: { botToken?: string; channelId?: string }\n}\n\ntype Draft = Record<Slot, PlatformDraft>\n\nfunction buildDraft(cfg: AppConfig | undefined): Draft {\n const m = new Set(cfg?.messengers ?? [])\n return {\n 'wechat-ilink': { enabled: m.has('wechat-ilink') },\n telegram: { enabled: m.has('telegram'), telegram: { ...(cfg?.telegram ?? {}) } },\n feishu: { enabled: m.has('feishu'), feishu: { ...(cfg?.feishu ?? {}) } },\n dingtalk: { enabled: m.has('dingtalk'), dingtalk: { ...(cfg?.dingtalk ?? {}) } },\n discord: { enabled: m.has('discord'), discord: { ...(cfg?.discord ?? {}) } },\n }\n}\n\nfunction buildPatch(draft: Draft, cfg: AppConfig): Partial<AppConfig> {\n const messengers: string[] = []\n for (const k of Object.keys(draft) as Slot[]) if (draft[k].enabled) messengers.push(k)\n const patch: Partial<AppConfig> = {\n messengers,\n // Preserve unknown extra fields the AppConfig type permits.\n ...Object.fromEntries(\n Object.entries(cfg).filter(([k]) => ![\n 'messengers', 'telegram', 'feishu', 'dingtalk', 'discord',\n ].includes(k)),\n ),\n }\n // Only include platform blocks that are enabled. Omitting disabled\n // platforms avoids PUT /api/config merging `{}` and failing zod\n // (telegram.botToken / feishu.appSecret / discord.botToken require\n // min(1) when the key is present).\n if (draft.telegram.enabled && draft.telegram.telegram) {\n patch.telegram = draft.telegram.telegram\n }\n if (draft.feishu.enabled && draft.feishu.feishu) {\n patch.feishu = draft.feishu.feishu\n }\n if (draft.dingtalk.enabled && draft.dingtalk.dingtalk) {\n patch.dingtalk = draft.dingtalk.dingtalk\n }\n if (draft.discord.enabled && draft.discord.discord) {\n patch.discord = draft.discord.discord\n }\n return patch\n}\n\nexport default function SettingsMessengersRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const cfgQuery = useConfig()\n const updateCfg = useUpdateConfig()\n\n const [draft, setDraft] = useState<Draft>(() => buildDraft(cfgQuery.data))\n // Sync the draft once cfg lands. We don't re-sync on every cfg\n // refetch — that would discard unsaved edits.\n const [synced, setSynced] = useState(false)\n useEffect(() => {\n if (synced) return\n if (!cfgQuery.data) return\n setDraft(buildDraft(cfgQuery.data))\n setSynced(true)\n }, [cfgQuery.data, synced])\n\n const cfg = cfgQuery.data\n const isDirty = useMemo(() => {\n if (!cfg) return false\n return JSON.stringify(buildDraft(cfg)) !== JSON.stringify(draft)\n }, [cfg, draft])\n\n // WeChat QR modal state\n const [qrOpen, setQrOpen] = useState(false)\n\n // v1.2.71 — IMHUB_PLATFORM_BLACKLIST gate. Backend sends the\n // alias-expanded set in features.blacklistedPlatforms; we hide the\n // matching PlatformCard so blacklisted IMs disappear from the page\n // entirely (not just have empty data).\n const blockedPlatforms = new Set(cfg?.features?.blacklistedPlatforms ?? [])\n const isBlocked = (slot: Slot): boolean => blockedPlatforms.has(slot)\n\n function patchSlot(slot: Slot, partial: Partial<PlatformDraft>): void {\n setDraft((prev) => ({ ...prev, [slot]: { ...prev[slot], ...partial } }))\n }\n\n async function onSave(): Promise<void> {\n if (!cfg) return\n try {\n await updateCfg.mutateAsync(buildPatch(draft, cfg))\n toast.success(t('messengers.savedToast'))\n setSynced(false) // rebuild draft from refreshed cfg on next paint\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n function onDiscard(): void {\n if (cfg) setDraft(buildDraft(cfg))\n }\n\n return (\n <div className=\"mx-auto flex max-w-4xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('messengers.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => cfgQuery.refetch()}\n disabled={cfgQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {cfgQuery.isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('messengers.subtitle')}</p>\n </header>\n\n {/* Save bar */}\n <div className=\"flex flex-wrap items-center gap-2\">\n {isDirty ? (\n <>\n <Badge variant=\"info\">{t('messengers.dirtyHint')}</Badge>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n onClick={onDiscard}\n disabled={updateCfg.isPending}\n >\n <X className=\"h-4 w-4\" />\n {t('messengers.discardAll')}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={() => void onSave()}\n disabled={updateCfg.isPending}\n >\n {updateCfg.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Save className=\"h-4 w-4\" />}\n {updateCfg.isPending ? t('messengers.saving') : t('messengers.saveAll')}\n </Button>\n </>\n ) : (\n <span className=\"text-xs text-text-muted\">{t('env.noChanges')}</span>\n )}\n </div>\n\n {cfgQuery.isLoading ? (\n <div className=\"h-96 rounded-md bg-surface-2 animate-pulse\" />\n ) : !cfg ? null : (\n <div className=\"flex flex-col gap-3\">\n {!isBlocked('wechat-ilink') ? (\n <PlatformCard\n slot=\"wechat-ilink\"\n label={t('messengers.platform.wechat')}\n hint={t('messengers.hint.wechat')}\n enabled={draft['wechat-ilink'].enabled}\n onToggle={(v) => patchSlot('wechat-ilink', { enabled: v })}\n >\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => setQrOpen(true)}\n >\n <QrCode className=\"h-4 w-4\" />\n {t('messengers.scanQr')}\n </Button>\n </PlatformCard>\n ) : null}\n\n {cfg.features?.globalIm && !isBlocked('telegram') ? (\n <PlatformCard\n slot=\"telegram\"\n label={t('messengers.platform.telegram')}\n hint={t('messengers.hint.telegram')}\n enabled={draft.telegram.enabled}\n onToggle={(v) => patchSlot('telegram', { enabled: v })}\n >\n <FieldRow\n id=\"tg-token\" label={t('messengers.fields.botToken')}\n value={draft.telegram.telegram?.botToken ?? ''}\n type=\"password\"\n onChange={(v) => patchSlot('telegram', { telegram: { ...draft.telegram.telegram, botToken: v } })}\n />\n <FieldRow\n id=\"tg-channel\" label={t('messengers.fields.channelId')}\n value={draft.telegram.telegram?.channelId ?? ''}\n onChange={(v) => patchSlot('telegram', { telegram: { ...draft.telegram.telegram, channelId: v } })}\n />\n </PlatformCard>\n ) : null}\n\n {!isBlocked('feishu') ? (\n <PlatformCard\n slot=\"feishu\"\n label={t('messengers.platform.feishu')}\n hint={t('messengers.hint.feishu')}\n enabled={draft.feishu.enabled}\n onToggle={(v) => patchSlot('feishu', { enabled: v })}\n >\n <FieldRow\n id=\"fs-appid\" label={t('messengers.fields.appId')}\n value={draft.feishu.feishu?.appId ?? ''}\n onChange={(v) => patchSlot('feishu', { feishu: { ...draft.feishu.feishu, appId: v } })}\n />\n <FieldRow\n id=\"fs-secret\" label={t('messengers.fields.appSecret')}\n value={draft.feishu.feishu?.appSecret ?? ''}\n type=\"password\"\n onChange={(v) => patchSlot('feishu', { feishu: { ...draft.feishu.feishu, appSecret: v } })}\n />\n <FieldRow\n id=\"fs-channel\" label={t('messengers.fields.channelId')}\n value={draft.feishu.feishu?.channelId ?? ''}\n onChange={(v) => patchSlot('feishu', { feishu: { ...draft.feishu.feishu, channelId: v } })}\n />\n </PlatformCard>\n ) : null}\n\n {!isBlocked('dingtalk') ? (\n <PlatformCard\n slot=\"dingtalk\"\n label={t('messengers.platform.dingtalk')}\n hint={t('messengers.hint.dingtalk')}\n enabled={draft.dingtalk.enabled}\n onToggle={(v) => patchSlot('dingtalk', { enabled: v })}\n >\n <FieldRow\n id=\"dt-cid\" label={t('messengers.fields.clientId')}\n value={draft.dingtalk.dingtalk?.clientId ?? ''}\n onChange={(v) => patchSlot('dingtalk', { dingtalk: { ...draft.dingtalk.dingtalk, clientId: v } })}\n />\n <FieldRow\n id=\"dt-secret\" label={t('messengers.fields.clientSecret')}\n value={draft.dingtalk.dingtalk?.clientSecret ?? ''}\n type=\"password\"\n onChange={(v) => patchSlot('dingtalk', { dingtalk: { ...draft.dingtalk.dingtalk, clientSecret: v } })}\n />\n <FieldRow\n id=\"dt-channel\" label={t('messengers.fields.channelId')}\n value={draft.dingtalk.dingtalk?.channelId ?? ''}\n onChange={(v) => patchSlot('dingtalk', { dingtalk: { ...draft.dingtalk.dingtalk, channelId: v } })}\n />\n {/* v1.2.37 (batch 1) — access policy + ack-reaction */}\n <SelectRow<'open' | 'pairing' | 'allowlist'>\n id=\"dt-dm-policy\" label={t('messengers.dingtalk.dmPolicy')}\n value={draft.dingtalk.dingtalk?.dmPolicy ?? 'open'}\n onChange={(v) => patchSlot('dingtalk', { dingtalk: { ...draft.dingtalk.dingtalk, dmPolicy: v } })}\n options={[\n { value: 'open', label: t('messengers.dingtalk.policy.open') },\n { value: 'pairing', label: t('messengers.dingtalk.policy.pairing') },\n { value: 'allowlist', label: t('messengers.dingtalk.policy.allowlist') },\n ]}\n />\n <SelectRow<'open' | 'allowlist' | 'disabled'>\n id=\"dt-group-policy\" label={t('messengers.dingtalk.groupPolicy')}\n value={draft.dingtalk.dingtalk?.groupPolicy ?? 'open'}\n onChange={(v) => patchSlot('dingtalk', { dingtalk: { ...draft.dingtalk.dingtalk, groupPolicy: v } })}\n options={[\n { value: 'open', label: t('messengers.dingtalk.policy.open') },\n { value: 'allowlist', label: t('messengers.dingtalk.policy.allowlist') },\n { value: 'disabled', label: t('messengers.dingtalk.policy.disabled') },\n ]}\n />\n <FieldRow\n id=\"dt-allow-from\" label={t('messengers.dingtalk.allowFrom')}\n value={(draft.dingtalk.dingtalk?.allowFrom ?? []).join(',')}\n onChange={(v) => patchSlot('dingtalk', {\n dingtalk: {\n ...draft.dingtalk.dingtalk,\n allowFrom: v.split(',').map((s) => s.trim()).filter(Boolean),\n },\n })}\n />\n <FieldRow\n id=\"dt-group-allow-from\" label={t('messengers.dingtalk.groupAllowFrom')}\n value={(draft.dingtalk.dingtalk?.groupAllowFrom ?? []).join(',')}\n onChange={(v) => patchSlot('dingtalk', {\n dingtalk: {\n ...draft.dingtalk.dingtalk,\n groupAllowFrom: v.split(',').map((s) => s.trim()).filter(Boolean),\n },\n })}\n />\n <SelectRow<'off' | 'emoji' | 'kaomoji'>\n id=\"dt-ack\" label={t('messengers.dingtalk.ackReaction')}\n value={draft.dingtalk.dingtalk?.ackReaction ?? 'off'}\n onChange={(v) => patchSlot('dingtalk', { dingtalk: { ...draft.dingtalk.dingtalk, ackReaction: v } })}\n options={[\n { value: 'off', label: t('messengers.dingtalk.ack.off') },\n { value: 'emoji', label: t('messengers.dingtalk.ack.emoji') },\n { value: 'kaomoji', label: t('messengers.dingtalk.ack.kaomoji') },\n ]}\n />\n {/* v1.2.41 (batch 4 follow-up) — multi-account CRUD editor. */}\n <DingTalkAccountsEditor\n accounts={draft.dingtalk.dingtalk?.accounts ?? {}}\n onChange={(next) => patchSlot('dingtalk', {\n dingtalk: { ...draft.dingtalk.dingtalk, accounts: next },\n })}\n />\n </PlatformCard>\n ) : null}\n\n {cfg.features?.globalIm && !isBlocked('discord') ? (\n <PlatformCard\n slot=\"discord\"\n label={t('messengers.platform.discord')}\n hint={t('messengers.hint.discord')}\n enabled={draft.discord.enabled}\n onToggle={(v) => patchSlot('discord', { enabled: v })}\n >\n <FieldRow\n id=\"dc-token\" label={t('messengers.fields.botToken')}\n value={draft.discord.discord?.botToken ?? ''}\n type=\"password\"\n onChange={(v) => patchSlot('discord', { discord: { ...draft.discord.discord, botToken: v } })}\n />\n <FieldRow\n id=\"dc-channel\" label={t('messengers.fields.channelId')}\n value={draft.discord.discord?.channelId ?? ''}\n onChange={(v) => patchSlot('discord', { discord: { ...draft.discord.discord, channelId: v } })}\n />\n </PlatformCard>\n ) : null}\n </div>\n )}\n\n <WechatQrDialog\n open={qrOpen}\n onOpenChange={setQrOpen}\n onConfirmed={() => { void cfgQuery.refetch(); setSynced(false) }}\n />\n </div>\n )\n}\n\ninterface PlatformCardProps {\n slot: Slot\n label: string\n hint: string\n enabled: boolean\n onToggle: (v: boolean) => void\n children?: React.ReactNode\n}\n\nfunction PlatformCard({ label, hint, enabled, onToggle, children }: PlatformCardProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <div className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium text-text\">{label}</span>\n <Badge variant={enabled ? 'success' : 'outline'}>\n {enabled ? t('messengers.enabled') : t('messengers.disabled')}\n </Badge>\n </div>\n <p className=\"mt-1 text-xs text-text-dim\">{hint}</p>\n </div>\n <label className=\"inline-flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={enabled}\n onChange={(e) => onToggle(e.target.checked)}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n </label>\n </div>\n {enabled && children && (\n <div className=\"mt-3 flex flex-col gap-2\">\n {children}\n </div>\n )}\n </div>\n )\n}\n\ninterface FieldRowProps {\n id: string\n label: string\n value: string\n onChange: (v: string) => void\n type?: 'text' | 'password'\n}\n\nfunction FieldRow({ id, label, value, onChange, type = 'text' }: FieldRowProps): JSX.Element {\n return (\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[180px_1fr] sm:items-center sm:gap-2\">\n <Label htmlFor={id} className=\"text-xs text-text-dim\">{label}</Label>\n <Input\n id={id}\n type={type}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n autoComplete=\"off\"\n className=\"font-mono text-xs\"\n />\n </div>\n )\n}\n\n// v1.2.37 (batch 1) — dropdown sibling of FieldRow for enum settings.\ninterface SelectRowProps<T extends string> {\n id: string\n label: string\n value: T\n onChange: (v: T) => void\n options: Array<{ value: T; label: string }>\n}\nfunction SelectRow<T extends string>({ id, label, value, onChange, options }: SelectRowProps<T>): JSX.Element {\n return (\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[180px_1fr] sm:items-center sm:gap-2\">\n <Label htmlFor={id} className=\"text-xs text-text-dim\">{label}</Label>\n <select\n id={id}\n value={value}\n onChange={(e) => onChange(e.target.value as T)}\n className=\"rounded-md border border-input bg-background px-2 py-1 text-xs\"\n >\n {options.map((o) => (\n <option key={o.value} value={o.value}>{o.label}</option>\n ))}\n </select>\n </div>\n )\n}\n\ninterface WechatQrDialogProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n onConfirmed: () => void\n}\n\nfunction WechatQrDialog({ open, onOpenChange, onConfirmed }: WechatQrDialogProps): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const start = useStartWechatQr()\n const [token, setToken] = useState<string | null>(null)\n const [qrImage, setQrImage] = useState<string | null>(null)\n const [startError, setStartError] = useState<string | null>(null)\n\n // Kick off the start mutation each time the dialog opens; reset on close.\n useEffect(() => {\n if (!open) {\n setToken(null)\n setQrImage(null)\n setStartError(null)\n return\n }\n let active = true\n start.mutateAsync().then((r) => {\n if (!active) return\n setQrImage(r.qrImage)\n setToken(r.qrToken)\n }).catch((err) => {\n if (!active) return\n setStartError(err instanceof Error ? err.message : String(err))\n })\n return () => { active = false }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open])\n\n const statusQuery = useWechatQrStatus(open ? token : null)\n const status = statusQuery.data?.status\n\n useEffect(() => {\n if (status === 'confirmed') {\n toast.success(t('messengers.qr.confirmed'))\n onConfirmed()\n onOpenChange(false)\n }\n if (status === 'expired') {\n toast.error(t('messengers.qr.expired'))\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [status])\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>{t('messengers.qr.title')}</DialogTitle>\n <DialogDescription>{t('messengers.qr.description')}</DialogDescription>\n </DialogHeader>\n <div className=\"flex flex-col items-center gap-3\">\n {start.isPending && !qrImage ? (\n <>\n <Loader2 className=\"h-8 w-8 animate-spin text-text-dim\" />\n <p className=\"text-sm text-text-dim\">{t('messengers.qr.starting')}</p>\n </>\n ) : startError ? (\n <p className=\"text-sm text-danger\">{t('messengers.qr.loadFailed')}: {startError}</p>\n ) : qrImage ? (\n <>\n <img\n src={qrImage}\n alt={t('messengers.qr.title')}\n className=\"rounded-md border border-border\"\n />\n {status === 'expired'\n ? <p className=\"text-xs text-danger\">{t('messengers.qr.expired')}</p>\n : <p className=\"text-xs text-text-dim\">{status ? `· ${status} ·` : ''}</p>}\n </>\n ) : null}\n </div>\n </DialogContent>\n </Dialog>\n )\n}\n\n// ─── v1.2.41 — DingTalk multi-account CRUD editor ───────────────────\n// Renders below the main DingTalk card. Owns the in-memory accounts\n// dict and bubbles every change up via `onChange` so the page-level\n// dirty/save logic notices and lights up the Save button.\n//\n// Each row shows: id (read-only after creation), name, clientId,\n// clientSecret (password mode, masked on echo), dmPolicy / groupPolicy /\n// ackReaction selectors, allowFrom / groupAllowFrom CSVs, enabled\n// toggle, and a delete button. \"Add account\" appends a fresh row with\n// a generated id the operator can rename inline.\n\nexport interface DingTalkAccountDraft {\n name?: string\n clientId?: string\n clientSecret?: string\n dmPolicy?: 'open' | 'pairing' | 'allowlist'\n groupPolicy?: 'open' | 'allowlist' | 'disabled'\n allowFrom?: string[]\n groupAllowFrom?: string[]\n ackReaction?: 'off' | 'emoji' | 'kaomoji'\n enabled?: boolean\n}\n\ninterface DingTalkAccountsEditorProps {\n accounts: Record<string, DingTalkAccountDraft>\n onChange: (next: Record<string, DingTalkAccountDraft>) => void\n}\n\nfunction DingTalkAccountsEditor({ accounts, onChange }: DingTalkAccountsEditorProps): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const entries = Object.entries(accounts)\n\n const updateAccount = (id: string, patch: Partial<DingTalkAccountDraft>) => {\n onChange({ ...accounts, [id]: { ...accounts[id], ...patch } })\n }\n const deleteAccount = (id: string) => {\n const next = { ...accounts }\n delete next[id]\n onChange(next)\n }\n const renameAccount = (oldId: string, newId: string) => {\n if (!newId || newId === oldId) return\n if (accounts[newId]) {\n toast.error(t('messengers.dingtalk.accountRenameCollision', { id: newId }))\n return\n }\n const next: Record<string, DingTalkAccountDraft> = {}\n for (const [k, v] of Object.entries(accounts)) {\n next[k === oldId ? newId : k] = v\n }\n onChange(next)\n }\n const addAccount = () => {\n // Find an unused id of shape account-N.\n let n = entries.length + 1\n let candidate = `account-${n}`\n while (accounts[candidate]) { n += 1; candidate = `account-${n}` }\n onChange({ ...accounts, [candidate]: { enabled: true } })\n }\n\n return (\n <div className=\"mt-3 border-t border-input pt-3\">\n <div className=\"mb-2 flex items-center justify-between\">\n <div className=\"text-xs font-semibold text-text-dim\">\n {t('messengers.dingtalk.accountsTitle')}\n </div>\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={addAccount}>\n + {t('messengers.dingtalk.addAccount')}\n </Button>\n </div>\n\n {entries.length === 0 ? (\n <div className=\"text-xs text-text-dim italic\">\n {t('messengers.dingtalk.accountsEmpty')}\n </div>\n ) : (\n <div className=\"space-y-3\">\n {entries.map(([id, acct]) => (\n <div key={id} className=\"rounded-md border border-input p-2\">\n <div className=\"mb-2 flex items-center gap-2\">\n <Input\n id={`acct-id-${id}`}\n defaultValue={id}\n onBlur={(e) => renameAccount(id, e.target.value.trim())}\n className=\"font-mono text-xs w-40\"\n placeholder=\"account-id\"\n />\n <Input\n id={`acct-name-${id}`}\n value={acct.name ?? ''}\n onChange={(e) => updateAccount(id, { name: e.target.value })}\n className=\"text-xs flex-1\"\n placeholder={t('messengers.dingtalk.accountName')}\n />\n <label className=\"flex items-center gap-1 text-xs\">\n <input\n type=\"checkbox\"\n checked={acct.enabled !== false}\n onChange={(e) => updateAccount(id, { enabled: e.target.checked })}\n />\n {t('messengers.enabled')}\n </label>\n <Button\n type=\"button\" size=\"sm\" variant=\"ghost\"\n onClick={() => deleteAccount(id)}\n className=\"text-danger\"\n >\n <X className=\"size-4\" />\n </Button>\n </div>\n <div className=\"space-y-1\">\n <FieldRow\n id={`acct-cid-${id}`} label={t('messengers.fields.clientId')}\n value={acct.clientId ?? ''}\n onChange={(v) => updateAccount(id, { clientId: v })}\n />\n <FieldRow\n id={`acct-secret-${id}`} label={t('messengers.fields.clientSecret')}\n value={acct.clientSecret ?? ''}\n type=\"password\"\n onChange={(v) => updateAccount(id, { clientSecret: v })}\n />\n <SelectRow<'open' | 'pairing' | 'allowlist'>\n id={`acct-dm-${id}`} label={t('messengers.dingtalk.dmPolicy')}\n value={acct.dmPolicy ?? 'open'}\n onChange={(v) => updateAccount(id, { dmPolicy: v })}\n options={[\n { value: 'open', label: t('messengers.dingtalk.policy.open') },\n { value: 'pairing', label: t('messengers.dingtalk.policy.pairing') },\n { value: 'allowlist', label: t('messengers.dingtalk.policy.allowlist') },\n ]}\n />\n <SelectRow<'open' | 'allowlist' | 'disabled'>\n id={`acct-group-${id}`} label={t('messengers.dingtalk.groupPolicy')}\n value={acct.groupPolicy ?? 'open'}\n onChange={(v) => updateAccount(id, { groupPolicy: v })}\n options={[\n { value: 'open', label: t('messengers.dingtalk.policy.open') },\n { value: 'allowlist', label: t('messengers.dingtalk.policy.allowlist') },\n { value: 'disabled', label: t('messengers.dingtalk.policy.disabled') },\n ]}\n />\n <FieldRow\n id={`acct-allow-${id}`} label={t('messengers.dingtalk.allowFrom')}\n value={(acct.allowFrom ?? []).join(',')}\n onChange={(v) => updateAccount(id, {\n allowFrom: v.split(',').map((s) => s.trim()).filter(Boolean),\n })}\n />\n <FieldRow\n id={`acct-gallow-${id}`} label={t('messengers.dingtalk.groupAllowFrom')}\n value={(acct.groupAllowFrom ?? []).join(',')}\n onChange={(v) => updateAccount(id, {\n groupAllowFrom: v.split(',').map((s) => s.trim()).filter(Boolean),\n })}\n />\n <SelectRow<'off' | 'emoji' | 'kaomoji'>\n id={`acct-ack-${id}`} label={t('messengers.dingtalk.ackReaction')}\n value={acct.ackReaction ?? 'off'}\n onChange={(v) => updateAccount(id, { ackReaction: v })}\n options={[\n { value: 'off', label: t('messengers.dingtalk.ack.off') },\n { value: 'emoji', label: t('messengers.dingtalk.ack.emoji') },\n { value: 'kaomoji', label: t('messengers.dingtalk.ack.kaomoji') },\n ]}\n />\n </div>\n </div>\n ))}\n </div>\n )}\n <div className=\"mt-1 text-xs text-text-dim\">{t('messengers.dingtalk.accountsHint')}</div>\n </div>\n )\n}\n"],"names":["buildDraft","cfg","m","buildPatch","draft","messengers","k","patch","SettingsMessengersRoute","t","useTranslation","cfgQuery","useConfig","updateCfg","useUpdateConfig","setDraft","useState","synced","setSynced","useEffect","isDirty","useMemo","qrOpen","setQrOpen","blockedPlatforms","isBlocked","slot","patchSlot","partial","prev","onSave","toast","err","describeError","onDiscard","jsxs","jsx","Button","Loader2","RefreshCcw","Fragment","Badge","X","Save","PlatformCard","v","QrCode","FieldRow","SelectRow","s","DingTalkAccountsEditor","next","WechatQrDialog","label","hint","enabled","onToggle","children","e","id","value","onChange","type","Label","Input","options","o","open","onOpenChange","onConfirmed","start","useStartWechatQr","token","setToken","qrImage","setQrImage","startError","setStartError","active","r","status","useWechatQrStatus","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","accounts","entries","updateAccount","deleteAccount","renameAccount","oldId","newId","addAccount","n","candidate","acct"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{u as r,j as e,B as d,m,n as E,l as u,q as w,c as x,S as _,g as I,h as M,i as A,k as c}from"./index-DY2Zglku.js";import{u as C,b as B}from"./use-settings-Co-iafXD.js";import{L as S}from"./loader-circle-D8L1w9c1.js";import{R as U}from"./refresh-ccw-7HdadG5V.js";import"./react-DlP5eolq.js";function o(s){if(s==null)return!1;const a=s.toLowerCase();return a==="1"||a==="true"||a==="yes"||a==="on"}function F(){const{t:s}=r(["settings","common"]),a=C(),i=B();async function t(n,v){try{await i.mutateAsync({updates:{[n]:v}}),m.success(s("policy.savingToast"))}catch(y){m.error(E(y,s).message)}}const l=a.data?.env??{},h=o(l.IMHUB_DANGEROUSLY_SKIP_PERMISSIONS),g=o(l.IMHUB_MEMORY_ENABLED),j=o(l.IMHUB_VIEWER_ENABLED),N=(l.IMHUB_TIMEOUT_DEFAULT??"").toLowerCase()==="allow",b=(l.IMHUB_A2A_NOTIFY_MODE??"essential").toLowerCase();return e.jsxs("div",{className:"mx-auto flex max-w-4xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("policy.title")}),e.jsxs(d,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>a.refetch(),disabled:a.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[a.isFetching?e.jsx(S,{className:"h-4 w-4 animate-spin"}):e.jsx(U,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("policy.subtitle")})]}),a.isLoading?e.jsx("div",{className:"h-96 rounded-md bg-surface-2 animate-pulse"}):e.jsxs("div",{className:"flex flex-col gap-3",children:[e.jsx(O,{value:h,disabled:i.isPending,onChange:n=>void t("IMHUB_DANGEROUSLY_SKIP_PERMISSIONS",n?"1":"0")}),e.jsx(L,{allowOnTimeout:N,disabled:i.isPending,onChange:n=>void t("IMHUB_TIMEOUT_DEFAULT",n)}),e.jsx(p,{sectionKey:"memory",value:g,disabled:i.isPending,onChange:n=>void t("IMHUB_MEMORY_ENABLED",n?"1":"0")}),e.jsx(p,{sectionKey:"viewer",value:j,disabled:i.isPending,onChange:n=>void t("IMHUB_VIEWER_ENABLED",n?"1":"0")}),e.jsx(T,{value:b,disabled:i.isPending,onChange:n=>void t("IMHUB_A2A_NOTIFY_MODE",n)})]})]})}function O({value:s,disabled:a,onChange:i}){const{t}=r("settings");return e.jsx("section",{className:x("rounded-md border p-4",s?"border-danger/60 bg-danger-bg/30":"border-border bg-surface"),children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:t("policy.safety.title")}),s&&e.jsxs(u,{variant:"danger",children:[e.jsx(w,{className:"h-3 w-3"}),"ON"]})]}),e.jsx("p",{className:"mt-1 text-sm text-text-dim",children:t("policy.safety.description")}),!s&&e.jsx("p",{className:"mt-1 text-xs text-text-muted",children:t("policy.safety.tagWarn")}),e.jsx("code",{className:"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted",children:t("policy.safety.envKey")})]}),e.jsx(f,{value:s,disabled:a,onChange:i})]})})}function L({allowOnTimeout:s,disabled:a,onChange:i}){const{t}=r("settings");return e.jsx("section",{className:"rounded-md border border-border bg-surface p-4",children:e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:t("policy.approval.title")}),e.jsx("p",{className:"text-sm text-text-dim",children:t("policy.approval.description")}),e.jsx("code",{className:"self-start rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted",children:t("policy.approval.envKey")}),e.jsxs("div",{className:"mt-2 flex flex-wrap gap-2",children:[e.jsx(d,{type:"button",variant:s?"outline":"default",size:"sm",disabled:a,onClick:()=>i("deny"),children:t("policy.approval.valDeny")}),e.jsx(d,{type:"button",variant:s?"default":"outline",size:"sm",disabled:a,onClick:()=>i("allow"),children:t("policy.approval.valAllow")})]})]})})}function p({sectionKey:s,value:a,disabled:i,onChange:t}){const{t:l}=r("settings");return e.jsx("section",{className:"rounded-md border border-border bg-surface p-4",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:l(`policy.${s}.title`)}),e.jsx(u,{variant:a?"success":"outline",children:a?"ON":"OFF"})]}),e.jsx("p",{className:"mt-1 text-sm text-text-dim",children:l(`policy.${s}.description`)}),e.jsx("code",{className:"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted",children:l(`policy.${s}.envKey`)})]}),e.jsx(f,{value:a,disabled:i,onChange:t})]})})}function T({value:s,disabled:a,onChange:i}){const{t}=r("settings");return e.jsx("section",{className:"rounded-md border border-border bg-surface p-4",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("span",{className:"font-medium text-text",children:t("policy.a2aNotify.title")}),e.jsx("p",{className:"mt-1 text-sm text-text-dim",children:t("policy.a2aNotify.description")}),e.jsx("code",{className:"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted",children:t("policy.a2aNotify.envKey")})]}),e.jsxs(_,{value:s,onValueChange:i,disabled:a,children:[e.jsx(I,{className:"w-36",children:e.jsx(M,{})}),e.jsxs(A,{children:[e.jsx(c,{value:"essential",children:t("policy.a2aNotify.valEssential")}),e.jsx(c,{value:"verbose",children:t("policy.a2aNotify.valVerbose")}),e.jsx(c,{value:"off",children:t("policy.a2aNotify.valOff")})]})]})]})})}function f({value:s,disabled:a,onChange:i}){return e.jsx("button",{type:"button",role:"switch","aria-checked":s,disabled:a,onClick:()=>i(!s),className:x("relative inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full transition-colors","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-bg","disabled:cursor-not-allowed disabled:opacity-50",s?"bg-accent":"bg-surface-2 border border-border"),children:e.jsx("span",{className:x("inline-block h-5 w-5 rounded-full bg-white shadow transition-transform",s?"translate-x-5":"translate-x-0.5")})})}export{F as default};
2
- //# sourceMappingURL=policy-yD1c2Pcn.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"policy-yD1c2Pcn.js","sources":["../../src/routes/settings/policy.tsx"],"sourcesContent":["/**\n * /settings/policy — dedicated UI for the highest-frequency env\n * toggles. Each is a one-click switch (or 2-3 option select) that\n * persists to `~/.agim/.env` via PUT /api/env immediately.\n *\n * Surfaced here:\n * * IMHUB_DANGEROUSLY_SKIP_PERMISSIONS (safety)\n * * IMHUB_TIMEOUT_DEFAULT (approval bus default)\n * * IMHUB_MEMORY_ENABLED (memory subsystem)\n * * IMHUB_VIEWER_ENABLED (long-message viewer)\n * * IMHUB_A2A_NOTIFY_MODE (cross-agent notify verbosity)\n *\n * All five are still editable in /settings/env. This page exists\n * because:\n * 1. They're the ones operators flip most often\n * 2. The env editor's table doesn't communicate \"this is a\n * boolean / 2-state / 3-state value\" — operators have to\n * know the literal strings \"1\"/\"0\"/\"allow\"/\"deny\"/etc.\n * 3. Safety toggle deserves a visible warning + danger color\n */\n\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { AlertTriangle, Loader2, RefreshCcw } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport { useEnv, useUpdateEnv } from '@/hooks/use-settings'\nimport { describeError } from '@/lib/api/errors'\nimport { cn } from '@/lib/utils'\n\n/** Treat the env value as a boolean — '1' / 'true' / 'yes' / 'on'\n * → true; everything else → false. Matches the backend's casual\n * truthy parsing in core/* modules. */\nfunction envBool(v: string | undefined): boolean {\n if (v == null) return false\n const t = v.toLowerCase()\n return t === '1' || t === 'true' || t === 'yes' || t === 'on'\n}\n\nexport default function SettingsPolicyRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const envQuery = useEnv()\n const updateEnv = useUpdateEnv()\n\n async function setValue(key: string, value: string | null): Promise<void> {\n try {\n await updateEnv.mutateAsync({ updates: { [key]: value } })\n toast.success(t('policy.savingToast'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n const env = envQuery.data?.env ?? {}\n const skipPerms = envBool(env.IMHUB_DANGEROUSLY_SKIP_PERMISSIONS)\n const memEnabled = envBool(env.IMHUB_MEMORY_ENABLED)\n const viewerEnabled = envBool(env.IMHUB_VIEWER_ENABLED)\n const timeoutAllow = (env.IMHUB_TIMEOUT_DEFAULT ?? '').toLowerCase() === 'allow'\n const a2aMode = (env.IMHUB_A2A_NOTIFY_MODE ?? 'essential').toLowerCase()\n\n return (\n <div className=\"mx-auto flex max-w-4xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('policy.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => envQuery.refetch()}\n disabled={envQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {envQuery.isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('policy.subtitle')}</p>\n </header>\n\n {envQuery.isLoading ? (\n <div className=\"h-96 rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <div className=\"flex flex-col gap-3\">\n <SafetyCard\n value={skipPerms}\n disabled={updateEnv.isPending}\n onChange={(v) => void setValue('IMHUB_DANGEROUSLY_SKIP_PERMISSIONS', v ? '1' : '0')}\n />\n <ApprovalCard\n allowOnTimeout={timeoutAllow}\n disabled={updateEnv.isPending}\n onChange={(v) => void setValue('IMHUB_TIMEOUT_DEFAULT', v)}\n />\n <ToggleCard\n sectionKey=\"memory\"\n value={memEnabled}\n disabled={updateEnv.isPending}\n onChange={(v) => void setValue('IMHUB_MEMORY_ENABLED', v ? '1' : '0')}\n />\n <ToggleCard\n sectionKey=\"viewer\"\n value={viewerEnabled}\n disabled={updateEnv.isPending}\n onChange={(v) => void setValue('IMHUB_VIEWER_ENABLED', v ? '1' : '0')}\n />\n <A2ANotifyCard\n value={a2aMode}\n disabled={updateEnv.isPending}\n onChange={(v) => void setValue('IMHUB_A2A_NOTIFY_MODE', v)}\n />\n </div>\n )}\n </div>\n )\n}\n\n/* ─────────────── Cards ─────────────── */\n\ninterface SafetyCardProps {\n value: boolean\n disabled: boolean\n onChange: (v: boolean) => void\n}\n\nfunction SafetyCard({ value, disabled, onChange }: SafetyCardProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <section\n className={cn(\n 'rounded-md border p-4',\n value ? 'border-danger/60 bg-danger-bg/30' : 'border-border bg-surface',\n )}\n >\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium text-text\">{t('policy.safety.title')}</span>\n {value && (\n <Badge variant=\"danger\">\n <AlertTriangle className=\"h-3 w-3\" />\n ON\n </Badge>\n )}\n </div>\n <p className=\"mt-1 text-sm text-text-dim\">{t('policy.safety.description')}</p>\n {!value && (\n <p className=\"mt-1 text-xs text-text-muted\">{t('policy.safety.tagWarn')}</p>\n )}\n <code className=\"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted\">\n {t('policy.safety.envKey')}\n </code>\n </div>\n <Toggle value={value} disabled={disabled} onChange={onChange} />\n </div>\n </section>\n )\n}\n\ninterface ApprovalCardProps {\n allowOnTimeout: boolean\n disabled: boolean\n onChange: (value: 'allow' | 'deny') => void\n}\n\nfunction ApprovalCard({ allowOnTimeout, disabled, onChange }: ApprovalCardProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex flex-col gap-2\">\n <span className=\"font-medium text-text\">{t('policy.approval.title')}</span>\n <p className=\"text-sm text-text-dim\">{t('policy.approval.description')}</p>\n <code className=\"self-start rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted\">\n {t('policy.approval.envKey')}\n </code>\n <div className=\"mt-2 flex flex-wrap gap-2\">\n <Button\n type=\"button\"\n variant={!allowOnTimeout ? 'default' : 'outline'}\n size=\"sm\"\n disabled={disabled}\n onClick={() => onChange('deny')}\n >\n {t('policy.approval.valDeny')}\n </Button>\n <Button\n type=\"button\"\n variant={allowOnTimeout ? 'default' : 'outline'}\n size=\"sm\"\n disabled={disabled}\n onClick={() => onChange('allow')}\n >\n {t('policy.approval.valAllow')}\n </Button>\n </div>\n </div>\n </section>\n )\n}\n\ninterface ToggleCardProps {\n sectionKey: 'memory' | 'viewer'\n value: boolean\n disabled: boolean\n onChange: (v: boolean) => void\n}\n\nfunction ToggleCard({ sectionKey, value, disabled, onChange }: ToggleCardProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium text-text\">{t(`policy.${sectionKey}.title`)}</span>\n <Badge variant={value ? 'success' : 'outline'}>{value ? 'ON' : 'OFF'}</Badge>\n </div>\n <p className=\"mt-1 text-sm text-text-dim\">{t(`policy.${sectionKey}.description`)}</p>\n <code className=\"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted\">\n {t(`policy.${sectionKey}.envKey`)}\n </code>\n </div>\n <Toggle value={value} disabled={disabled} onChange={onChange} />\n </div>\n </section>\n )\n}\n\ninterface A2ANotifyCardProps {\n value: string\n disabled: boolean\n onChange: (v: string) => void\n}\n\nfunction A2ANotifyCard({ value, disabled, onChange }: A2ANotifyCardProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-1\">\n <span className=\"font-medium text-text\">{t('policy.a2aNotify.title')}</span>\n <p className=\"mt-1 text-sm text-text-dim\">{t('policy.a2aNotify.description')}</p>\n <code className=\"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted\">\n {t('policy.a2aNotify.envKey')}\n </code>\n </div>\n <Select value={value} onValueChange={onChange} disabled={disabled}>\n <SelectTrigger className=\"w-36\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"essential\">{t('policy.a2aNotify.valEssential')}</SelectItem>\n <SelectItem value=\"verbose\">{t('policy.a2aNotify.valVerbose')}</SelectItem>\n <SelectItem value=\"off\">{t('policy.a2aNotify.valOff')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </section>\n )\n}\n\ninterface ToggleProps {\n value: boolean\n disabled: boolean\n onChange: (v: boolean) => void\n}\n\n/** Thumb-style switch styled to the agim accent. Tailwind-only,\n * no Radix dep — keeps the click feel snappy. */\nfunction Toggle({ value, disabled, onChange }: ToggleProps): JSX.Element {\n return (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={value}\n disabled={disabled}\n onClick={() => onChange(!value)}\n className={cn(\n 'relative inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-bg',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n value ? 'bg-accent' : 'bg-surface-2 border border-border',\n )}\n >\n <span\n className={cn(\n 'inline-block h-5 w-5 rounded-full bg-white shadow transition-transform',\n value ? 'translate-x-5' : 'translate-x-0.5',\n )}\n />\n </button>\n )\n}\n"],"names":["envBool","v","t","SettingsPolicyRoute","useTranslation","envQuery","useEnv","updateEnv","useUpdateEnv","setValue","key","value","toast","err","describeError","env","skipPerms","memEnabled","viewerEnabled","timeoutAllow","a2aMode","jsxs","jsx","Button","Loader2","RefreshCcw","SafetyCard","ApprovalCard","ToggleCard","A2ANotifyCard","disabled","onChange","cn","Badge","AlertTriangle","Toggle","allowOnTimeout","sectionKey","Select","SelectTrigger","SelectValue","SelectContent","SelectItem"],"mappings":"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"}
@@ -1,17 +0,0 @@
1
- import{o as E,u as R,j as e,B as j,l as b,X as P,m as g,L as I,I as L}from"./index-DY2Zglku.js";import{r as C}from"./react-DlP5eolq.js";import{u as _,s as z,b as F,t as U}from"./use-settings-Co-iafXD.js";import{L as T}from"./loader-circle-D8L1w9c1.js";import{R as V}from"./refresh-ccw-7HdadG5V.js";import{S as q}from"./save-BYFmz9gD.js";import{A as J}from"./arrow-up-CAiQ2jy-.js";import{A as W}from"./arrow-down-DxlRHrs8.js";import{C as G}from"./circle-check-COhM5JsK.js";import{C as Q}from"./circle-x-7VaoZ7dY.js";/**
2
- * @license lucide-react v0.469.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const X=E("FlaskConical",[["path",{d:"M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2",key:"18mbvz"}],["path",{d:"M6.453 15h11.094",key:"3shlmq"}],["path",{d:"M8.5 2h7",key:"csnxdl"}]]);/**
7
- * @license lucide-react v0.469.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const Y=E("Globe",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20",key:"13o1zl"}],["path",{d:"M2 12h20",key:"9i4pu4"}]]);/**
12
- * @license lucide-react v0.469.0 - ISC
13
- *
14
- * This source code is licensed under the ISC license.
15
- * See the LICENSE file in the root directory of this source tree.
16
- */const Z=E("Key",[["path",{d:"m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4",key:"g0fldk"}],["path",{d:"m21 2-9.6 9.6",key:"1j0ho8"}],["circle",{cx:"7.5",cy:"15.5",r:"5.5",key:"yqb3hr"}]]);function $(r,a){const o=(r??"").split(",").map(i=>i.trim()).filter(Boolean),h=new Set(a.map(i=>i.name)),m=new Set,f=[];for(const i of o)!h.has(i)||m.has(i)||(f.push({name:i,enabled:!0}),m.add(i));for(const i of a)m.has(i.name)||f.push({name:i.name,enabled:!1});return f}function M(r){return r.filter(a=>a.enabled).map(a=>a.name).join(",")}function me(){const{t:r}=R(["settings","common"]),a=_({reveal:!1}),o=z(),h=F(),m=U(),f=a.data?.env??{},i=o.data?.providers??[],y=o.data?.chain??[],d=C.useMemo(()=>({chain:$(f.IMHUB_WEB_SEARCH_PROVIDERS,i),keys:{},keysTouched:{}}),[f.IMHUB_WEB_SEARCH_PROVIDERS,i]),[l,u]=C.useState(d),[k,S]=C.useState("");C.useEffect(()=>{const s=JSON.stringify(d);s!==k&&(u(d),S(s))},[d,k]);const N=JSON.stringify(l.chain)!==JSON.stringify(d.chain)||Object.keys(l.keysTouched).length>0;function w(s,t){u(c=>{const n=[...c.chain],x=s+t;if(x<0||x>=n.length)return c;const v=n[s],B=n[x];return!v||!B?c:(n[s]=B,n[x]=v,{...c,chain:n})})}function K(s,t){u(c=>{const n=[...c.chain],x=n[s];return x?(n[s]={...x,enabled:t},{...c,chain:n}):c})}function p(s,t){u(c=>({...c,keys:{...c.keys,[s]:t},keysTouched:{...c.keysTouched,[s]:!0}}))}function A(s){u(t=>({...t,keys:{...t.keys,[s]:""},keysTouched:{...t.keysTouched,[s]:!0}}))}async function H(){const s={},t=M(l.chain),c=M(d.chain);t!==c&&(s.IMHUB_WEB_SEARCH_PROVIDERS=t||null);for(const[n,x]of Object.entries(l.keysTouched)){if(!x)continue;const v=l.keys[n]??"";s[n]=v.trim()===""?null:v}if(Object.keys(s).length!==0)try{await h.mutateAsync({updates:s}),o.refetch(),g.success(r("search.savedToast")),u(n=>({...n,keys:{},keysTouched:{}}))}catch(n){g.error(n?.message??String(n))}}function O(){u(d)}async function D(s){try{const t=await m.mutateAsync({provider:s,query:"agim ping"});t.ok?g.success(r("search.testOk",{provider:s,hits:t.hits,ms:t.latencyMs})):g.error(r("search.testFail",{provider:s,error:t.error??"unknown error"}))}catch(t){g.error(t?.message??String(t))}}return e.jsxs("div",{className:"mx-auto flex max-w-4xl flex-col gap-6",children:[e.jsxs("header",{className:"flex items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:r("search.title")}),e.jsxs(j,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>{a.refetch(),o.refetch()},disabled:a.isFetching||o.isFetching,"aria-label":r("actions.refresh",{ns:"common"}),children:[a.isFetching||o.isFetching?e.jsx(T,{className:"h-4 w-4 animate-spin"}):e.jsx(V,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:r("search.refresh")})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:r("search.subtitle")}),e.jsx(ee,{live:y}),a.isLoading||o.isLoading?e.jsx("div",{className:"h-64 rounded-md bg-surface-2 animate-pulse"}):e.jsx("section",{className:"flex flex-col gap-2",children:l.chain.map((s,t)=>{const c=i.find(n=>n.name===s.name);return e.jsx(se,{info:c,entry:s,idx:t,count:l.chain.length,keyValue:c?.envKey?l.keys[c.envKey]:void 0,keyTouched:c?.envKey?!!l.keysTouched[c.envKey]:!1,onMove:n=>w(t,n),onToggle:n=>K(t,n),onSetKey:n=>c?.envKey&&p(c.envKey,n),onClearKey:()=>c?.envKey&&A(c.envKey),onTest:()=>D(s.name),testing:m.isPending},s.name)})}),N&&e.jsxs("div",{className:"sticky bottom-2 flex items-center gap-2 rounded-md border border-border bg-surface px-4 py-3 shadow",children:[e.jsx(b,{variant:"info",children:r("search.unsaved")}),e.jsxs(j,{variant:"ghost",size:"sm",className:"ml-auto",onClick:O,disabled:h.isPending,children:[e.jsx(P,{className:"h-4 w-4"})," ",r("search.discard")]}),e.jsxs(j,{size:"sm",onClick:()=>void H(),disabled:h.isPending,children:[h.isPending?e.jsx(T,{className:"h-4 w-4 animate-spin"}):e.jsx(q,{className:"h-4 w-4"}),r("search.save")]})]})]})}function ee({live:r}){const{t:a}=R("settings");return e.jsxs("section",{className:"rounded-md border border-border bg-surface px-4 py-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(Y,{className:"h-4 w-4 text-text-dim"}),e.jsx("span",{className:"text-text-dim",children:a("search.chainLabel")}),r.length===0?e.jsx(b,{variant:"outline",children:a("search.chainEmpty")}):e.jsx("span",{className:"font-mono text-xs",children:r.join(" → ")})]}),e.jsx("p",{className:"mt-1 text-[11px] text-text-dim",children:a("search.chainHint")})]})}function se(r){const{t:a}=R("settings"),{info:o,entry:h,idx:m,count:f,keyValue:i,keyTouched:y,onMove:d,onToggle:l,onSetKey:u,onClearKey:k,onTest:S,testing:N}=r,w=!!o?.envKey,K=!!o?.available||y&&!!i;return e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("div",{className:"flex flex-col",children:[e.jsx("button",{type:"button",className:"h-5 w-5 rounded text-text-dim hover:bg-surface-hover disabled:opacity-30",onClick:()=>d(-1),disabled:m===0,"aria-label":a("search.moveUp"),children:e.jsx(J,{className:"h-4 w-4"})}),e.jsx("button",{type:"button",className:"h-5 w-5 rounded text-text-dim hover:bg-surface-hover disabled:opacity-30",onClick:()=>d(1),disabled:m===f-1,"aria-label":a("search.moveDown"),children:e.jsx(W,{className:"h-4 w-4"})})]}),e.jsxs("label",{className:"flex items-center gap-2 text-sm",children:[e.jsx("input",{type:"checkbox",checked:h.enabled,onChange:p=>l(p.target.checked),className:"h-4 w-4 accent-accent cursor-pointer"}),e.jsx("span",{className:"font-mono text-sm",children:h.name})]}),w?K?e.jsxs(b,{variant:"success",children:[e.jsx(G,{className:"mr-1 h-3 w-3"})," ",a("search.configured")]}):e.jsxs(b,{variant:"warning",children:[e.jsx(Q,{className:"mr-1 h-3 w-3"})," ",a("search.missingKey")]}):e.jsx(b,{variant:"outline",children:a("search.noKey")}),e.jsx("div",{className:"ml-auto flex items-center gap-1",children:e.jsxs(j,{size:"sm",variant:"ghost",onClick:S,disabled:N||!h.enabled,"aria-label":a("search.testBtn"),children:[N?e.jsx(T,{className:"h-4 w-4 animate-spin"}):e.jsx(X,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:a("search.testBtn")})]})})]}),w&&e.jsxs("div",{className:"mt-3 flex flex-col gap-1",children:[e.jsxs(I,{className:"text-xs font-medium",children:[e.jsx(Z,{className:"mr-1 inline h-3 w-3"}),o?.envKey]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(L,{type:"password",value:i??"",onChange:p=>u(p.target.value),placeholder:o?.available&&!y?a("search.placeholderConfigured"):a("search.placeholderEnter"),className:"font-mono text-xs"}),o?.available&&!y&&e.jsx(j,{size:"sm",variant:"ghost",onClick:k,"aria-label":a("search.clearKey"),children:e.jsx(P,{className:"h-4 w-4"})})]}),e.jsx("p",{className:"text-[11px] text-text-dim",children:a("search.keyHint",{envKey:o?.envKey})})]})]})}export{me as default};
17
- //# sourceMappingURL=search-B8PlbtLg.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"search-B8PlbtLg.js","sources":["../../node_modules/lucide-react/dist/esm/icons/flask-conical.js","../../node_modules/lucide-react/dist/esm/icons/globe.js","../../node_modules/lucide-react/dist/esm/icons/key.js","../../src/routes/settings/search.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.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 createLucideIcon from '../createLucideIcon.js';\n\nconst FlaskConical = createLucideIcon(\"FlaskConical\", [\n [\n \"path\",\n {\n d: \"M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2\",\n key: \"18mbvz\"\n }\n ],\n [\"path\", { d: \"M6.453 15h11.094\", key: \"3shlmq\" }],\n [\"path\", { d: \"M8.5 2h7\", key: \"csnxdl\" }]\n]);\n\nexport { FlaskConical as default };\n//# sourceMappingURL=flask-conical.js.map\n","/**\n * @license lucide-react v0.469.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 createLucideIcon from '../createLucideIcon.js';\n\nconst Globe = createLucideIcon(\"Globe\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20\", key: \"13o1zl\" }],\n [\"path\", { d: \"M2 12h20\", key: \"9i4pu4\" }]\n]);\n\nexport { Globe as default };\n//# sourceMappingURL=globe.js.map\n","/**\n * @license lucide-react v0.469.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 createLucideIcon from '../createLucideIcon.js';\n\nconst Key = createLucideIcon(\"Key\", [\n [\"path\", { d: \"m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4\", key: \"g0fldk\" }],\n [\"path\", { d: \"m21 2-9.6 9.6\", key: \"1j0ho8\" }],\n [\"circle\", { cx: \"7.5\", cy: \"15.5\", r: \"5.5\", key: \"yqb3hr\" }]\n]);\n\nexport { Key as default };\n//# sourceMappingURL=key.js.map\n","/**\n * /settings/search — web_search provider config (v1.2.126).\n *\n * One row per registered provider (Tavily / Brave / Serper / Exa /\n * DuckDuckGo / Metaso): API-key input (masked-by-default), enable\n * toggle (= \"is this name in the chain?\"), reorder via up / down,\n * one-shot test button. The chain preview at the top shows what\n * IMHUB_WEB_SEARCH_PROVIDERS resolves to right now.\n *\n * Persistence: API keys go via PUT /api/env (which masks GET +\n * refuses echoed masks on PUT); the chain order is a single CSV\n * env key — same endpoint. Save is one round-trip per dirty key.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport {\n ArrowDown, ArrowUp, CheckCircle2, FlaskConical, Globe, Key,\n Loader2, RefreshCcw, Save, X, XCircle,\n} from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n useEnv,\n useSearchProviders,\n useTestSearchProvider,\n useUpdateEnv,\n} from '@/hooks/use-settings'\nimport type { SearchProviderInfo } from '@/types/api'\n\ninterface ChainEntry {\n name: string\n enabled: boolean\n}\n\ninterface Draft {\n /** Provider chain — every known provider, with `enabled`\n * reflecting \"is name in the CSV\". Order is the row order. */\n chain: ChainEntry[]\n /** Each provider's API-key input. Keyed by envKey (e.g.\n * TAVILY_API_KEY). Holds either '' (clear) or the new plaintext\n * the operator typed. We never load values back from the server. */\n keys: Record<string, string>\n /** Tracks which key fields the operator actually touched — so\n * Save only sends the diff and untouched masked keys are left\n * alone. */\n keysTouched: Record<string, boolean>\n}\n\nfunction envChainOrder(envValue: string | undefined, providers: SearchProviderInfo[]): ChainEntry[] {\n // Parse the CSV chain; preserve operator order; tail-append any\n // provider not in the CSV as disabled so they remain renderable.\n const raw = (envValue ?? '').split(',').map((s) => s.trim()).filter(Boolean)\n const known = new Set(providers.map((p) => p.name))\n const seen = new Set<string>()\n const out: ChainEntry[] = []\n for (const name of raw) {\n if (!known.has(name) || seen.has(name)) continue\n out.push({ name, enabled: true })\n seen.add(name)\n }\n for (const p of providers) {\n if (seen.has(p.name)) continue\n out.push({ name: p.name, enabled: false })\n }\n return out\n}\n\nfunction chainToCsv(chain: ChainEntry[]): string {\n return chain.filter((c) => c.enabled).map((c) => c.name).join(',')\n}\n\nexport default function SettingsSearchRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const envQuery = useEnv({ reveal: false })\n const providersQuery = useSearchProviders()\n const updateEnv = useUpdateEnv()\n const testProvider = useTestSearchProvider()\n\n const envData = envQuery.data?.env ?? {}\n const providers = providersQuery.data?.providers ?? []\n const live = providersQuery.data?.chain ?? []\n\n const initial = useMemo<Draft>(\n () => ({\n chain: envChainOrder(envData.IMHUB_WEB_SEARCH_PROVIDERS, providers),\n keys: {},\n keysTouched: {},\n }),\n [envData.IMHUB_WEB_SEARCH_PROVIDERS, providers],\n )\n\n const [draft, setDraft] = useState<Draft>(initial)\n const [syncedHash, setSyncedHash] = useState('')\n\n useEffect(() => {\n const hash = JSON.stringify(initial)\n if (hash !== syncedHash) {\n setDraft(initial)\n setSyncedHash(hash)\n }\n }, [initial, syncedHash])\n\n const isDirty =\n JSON.stringify(draft.chain) !== JSON.stringify(initial.chain) ||\n Object.keys(draft.keysTouched).length > 0\n\n function moveRow(idx: number, delta: -1 | 1): void {\n setDraft((d) => {\n const next = [...d.chain]\n const swap = idx + delta\n if (swap < 0 || swap >= next.length) return d\n const a = next[idx]\n const b = next[swap]\n if (!a || !b) return d\n next[idx] = b\n next[swap] = a\n return { ...d, chain: next }\n })\n }\n\n function toggleRow(idx: number, enabled: boolean): void {\n setDraft((d) => {\n const next = [...d.chain]\n const row = next[idx]\n if (!row) return d\n next[idx] = { ...row, enabled }\n return { ...d, chain: next }\n })\n }\n\n function setKey(envKey: string, value: string): void {\n setDraft((d) => ({\n ...d,\n keys: { ...d.keys, [envKey]: value },\n keysTouched: { ...d.keysTouched, [envKey]: true },\n }))\n }\n\n function clearKey(envKey: string): void {\n setDraft((d) => ({\n ...d,\n keys: { ...d.keys, [envKey]: '' },\n keysTouched: { ...d.keysTouched, [envKey]: true },\n }))\n }\n\n async function onSave(): Promise<void> {\n const updates: Record<string, string | null> = {}\n const nextCsv = chainToCsv(draft.chain)\n const initialCsv = chainToCsv(initial.chain)\n if (nextCsv !== initialCsv) {\n updates.IMHUB_WEB_SEARCH_PROVIDERS = nextCsv || null\n }\n for (const [envKey, touched] of Object.entries(draft.keysTouched)) {\n if (!touched) continue\n const v = draft.keys[envKey] ?? ''\n updates[envKey] = v.trim() === '' ? null : v\n }\n if (Object.keys(updates).length === 0) return\n try {\n await updateEnv.mutateAsync({ updates })\n // Refetch both — env keys changed availability, chain order changed.\n void providersQuery.refetch()\n toast.success(t('search.savedToast'))\n setDraft((d) => ({ ...d, keys: {}, keysTouched: {} }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n function onDiscard(): void {\n setDraft(initial)\n }\n\n async function onTest(provider: string): Promise<void> {\n try {\n const result = await testProvider.mutateAsync({\n provider,\n // Short, harmless probe — the dispatcher only needs to\n // verify the upstream auth + transport.\n query: 'agim ping',\n })\n if (result.ok) {\n toast.success(\n t('search.testOk', { provider, hits: result.hits, ms: result.latencyMs }),\n )\n } else {\n toast.error(\n t('search.testFail', { provider, error: result.error ?? 'unknown error' }),\n )\n }\n } catch (err) {\n toast.error((err as Error)?.message ?? String(err))\n }\n }\n\n return (\n <div className=\"mx-auto flex max-w-4xl flex-col gap-6\">\n <header className=\"flex items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('search.title')}</h1>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => {\n void envQuery.refetch()\n void providersQuery.refetch()\n }}\n disabled={envQuery.isFetching || providersQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {envQuery.isFetching || providersQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('search.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('search.subtitle')}</p>\n\n <ChainPreview live={live} />\n\n {envQuery.isLoading || providersQuery.isLoading ? (\n <div className=\"h-64 rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <section className=\"flex flex-col gap-2\">\n {draft.chain.map((entry, idx) => {\n const info = providers.find((p) => p.name === entry.name)\n return (\n <ProviderRow\n key={entry.name}\n info={info}\n entry={entry}\n idx={idx}\n count={draft.chain.length}\n keyValue={info?.envKey ? draft.keys[info.envKey] : undefined}\n keyTouched={info?.envKey ? !!draft.keysTouched[info.envKey] : false}\n onMove={(d) => moveRow(idx, d)}\n onToggle={(v) => toggleRow(idx, v)}\n onSetKey={(v) => info?.envKey && setKey(info.envKey, v)}\n onClearKey={() => info?.envKey && clearKey(info.envKey)}\n onTest={() => onTest(entry.name)}\n testing={testProvider.isPending}\n />\n )\n })}\n </section>\n )}\n\n {isDirty && (\n <div className=\"sticky bottom-2 flex items-center gap-2 rounded-md border border-border bg-surface px-4 py-3 shadow\">\n <Badge variant=\"info\">{t('search.unsaved')}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={onDiscard}\n disabled={updateEnv.isPending}\n >\n <X className=\"h-4 w-4\" /> {t('search.discard')}\n </Button>\n <Button\n size=\"sm\"\n onClick={() => void onSave()}\n disabled={updateEnv.isPending}\n >\n {updateEnv.isPending\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <Save className=\"h-4 w-4\" />}\n {t('search.save')}\n </Button>\n </div>\n )}\n </div>\n )\n}\n\nfunction ChainPreview({ live }: { live: string[] }): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <section className=\"rounded-md border border-border bg-surface px-4 py-3\">\n <div className=\"flex items-center gap-2 text-sm\">\n <Globe className=\"h-4 w-4 text-text-dim\" />\n <span className=\"text-text-dim\">{t('search.chainLabel')}</span>\n {live.length === 0 ? (\n <Badge variant=\"outline\">{t('search.chainEmpty')}</Badge>\n ) : (\n <span className=\"font-mono text-xs\">{live.join(' → ')}</span>\n )}\n </div>\n <p className=\"mt-1 text-[11px] text-text-dim\">{t('search.chainHint')}</p>\n </section>\n )\n}\n\ninterface ProviderRowProps {\n info: SearchProviderInfo | undefined\n entry: ChainEntry\n idx: number\n count: number\n keyValue: string | undefined\n keyTouched: boolean\n onMove: (delta: -1 | 1) => void\n onToggle: (v: boolean) => void\n onSetKey: (v: string) => void\n onClearKey: () => void\n onTest: () => void\n testing: boolean\n}\n\nfunction ProviderRow(props: ProviderRowProps): JSX.Element {\n const { t } = useTranslation('settings')\n const { info, entry, idx, count, keyValue, keyTouched, onMove, onToggle,\n onSetKey, onClearKey, onTest, testing } = props\n const needsKey = !!info?.envKey\n const available = !!info?.available || (keyTouched && !!keyValue)\n return (\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"flex items-center gap-2\">\n <div className=\"flex flex-col\">\n <button\n type=\"button\"\n className=\"h-5 w-5 rounded text-text-dim hover:bg-surface-hover disabled:opacity-30\"\n onClick={() => onMove(-1)}\n disabled={idx === 0}\n aria-label={t('search.moveUp')}\n >\n <ArrowUp className=\"h-4 w-4\" />\n </button>\n <button\n type=\"button\"\n className=\"h-5 w-5 rounded text-text-dim hover:bg-surface-hover disabled:opacity-30\"\n onClick={() => onMove(1)}\n disabled={idx === count - 1}\n aria-label={t('search.moveDown')}\n >\n <ArrowDown className=\"h-4 w-4\" />\n </button>\n </div>\n\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={entry.enabled}\n onChange={(e) => onToggle(e.target.checked)}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n <span className=\"font-mono text-sm\">{entry.name}</span>\n </label>\n\n {!needsKey ? (\n <Badge variant=\"outline\">{t('search.noKey')}</Badge>\n ) : available ? (\n <Badge variant=\"success\">\n <CheckCircle2 className=\"mr-1 h-3 w-3\" /> {t('search.configured')}\n </Badge>\n ) : (\n <Badge variant=\"warning\">\n <XCircle className=\"mr-1 h-3 w-3\" /> {t('search.missingKey')}\n </Badge>\n )}\n\n <div className=\"ml-auto flex items-center gap-1\">\n <Button\n size=\"sm\" variant=\"ghost\"\n onClick={onTest}\n disabled={testing || !entry.enabled}\n aria-label={t('search.testBtn')}\n >\n {testing\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <FlaskConical className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('search.testBtn')}</span>\n </Button>\n </div>\n </div>\n\n {needsKey && (\n <div className=\"mt-3 flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">\n <Key className=\"mr-1 inline h-3 w-3\" />\n {info?.envKey}\n </Label>\n <div className=\"flex items-center gap-2\">\n <Input\n type=\"password\"\n value={keyValue ?? ''}\n onChange={(e) => onSetKey(e.target.value)}\n placeholder={\n info?.available && !keyTouched\n ? t('search.placeholderConfigured')\n : t('search.placeholderEnter')\n }\n className=\"font-mono text-xs\"\n />\n {info?.available && !keyTouched && (\n <Button\n size=\"sm\" variant=\"ghost\"\n onClick={onClearKey}\n aria-label={t('search.clearKey')}\n >\n <X className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n <p className=\"text-[11px] text-text-dim\">\n {t('search.keyHint', { envKey: info?.envKey })}\n </p>\n </div>\n )}\n </div>\n )\n}\n"],"names":["FlaskConical","createLucideIcon","Globe","Key","envChainOrder","envValue","providers","raw","s","known","p","seen","out","name","chainToCsv","chain","c","SettingsSearchRoute","t","useTranslation","envQuery","useEnv","providersQuery","useSearchProviders","updateEnv","useUpdateEnv","testProvider","useTestSearchProvider","envData","live","initial","useMemo","draft","setDraft","useState","syncedHash","setSyncedHash","useEffect","hash","isDirty","moveRow","idx","delta","d","next","swap","a","b","toggleRow","enabled","row","setKey","envKey","value","clearKey","onSave","updates","nextCsv","initialCsv","touched","toast","err","onDiscard","onTest","provider","result","jsxs","jsx","Button","Loader2","RefreshCcw","ChainPreview","entry","info","ProviderRow","v","Badge","X","Save","props","count","keyValue","keyTouched","onMove","onToggle","onSetKey","onClearKey","testing","needsKey","available","ArrowUp","ArrowDown","e","CheckCircle2","XCircle","Label","Input"],"mappings":"mgBAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,EAAeC,EAAiB,eAAgB,CACpD,CACE,OACA,CACE,EAAG,0GACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,mBAAoB,IAAK,QAAQ,CAAE,EACjD,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,CAC3C,CAAC,ECnBD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMC,EAAQD,EAAiB,QAAS,CACtC,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,KAAM,IAAK,SAAU,EACzD,CAAC,OAAQ,CAAE,EAAG,kDAAmD,IAAK,QAAQ,CAAE,EAChF,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,CAC3C,CAAC,ECbD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAME,EAAMF,EAAiB,MAAO,CAClC,CAAC,OAAQ,CAAE,EAAG,iEAAkE,IAAK,QAAQ,CAAE,EAC/F,CAAC,OAAQ,CAAE,EAAG,gBAAiB,IAAK,QAAQ,CAAE,EAC9C,CAAC,SAAU,CAAE,GAAI,MAAO,GAAI,OAAQ,EAAG,MAAO,IAAK,QAAQ,CAAE,CAC/D,CAAC,ECwCD,SAASG,EAAcC,EAA8BC,EAA+C,CAGlG,MAAMC,GAAOF,GAAY,IAAI,MAAM,GAAG,EAAE,IAAKG,GAAMA,EAAE,KAAA,CAAM,EAAE,OAAO,OAAO,EACrEC,EAAQ,IAAI,IAAIH,EAAU,IAAKI,GAAMA,EAAE,IAAI,CAAC,EAC5CC,MAAW,IACXC,EAAoB,CAAA,EAC1B,UAAWC,KAAQN,EACb,CAACE,EAAM,IAAII,CAAI,GAAKF,EAAK,IAAIE,CAAI,IACrCD,EAAI,KAAK,CAAE,KAAAC,EAAM,QAAS,GAAM,EAChCF,EAAK,IAAIE,CAAI,GAEf,UAAWH,KAAKJ,EACVK,EAAK,IAAID,EAAE,IAAI,GACnBE,EAAI,KAAK,CAAE,KAAMF,EAAE,KAAM,QAAS,GAAO,EAE3C,OAAOE,CACT,CAEA,SAASE,EAAWC,EAA6B,CAC/C,OAAOA,EAAM,OAAQC,GAAMA,EAAE,OAAO,EAAE,IAAKA,GAAMA,EAAE,IAAI,EAAE,KAAK,GAAG,CACnE,CAEA,SAAwBC,IAAmC,CACzD,KAAM,CAAE,EAAAC,CAAA,EAAMC,EAAe,CAAC,WAAY,QAAQ,CAAC,EAC7CC,EAAWC,EAAO,CAAE,OAAQ,GAAO,EACnCC,EAAiBC,EAAA,EACjBC,EAAYC,EAAA,EACZC,EAAeC,EAAA,EAEfC,EAAUR,EAAS,MAAM,KAAO,CAAA,EAChCd,EAAYgB,EAAe,MAAM,WAAa,CAAA,EAC9CO,EAAOP,EAAe,MAAM,OAAS,CAAA,EAErCQ,EAAUC,EAAAA,QACd,KAAO,CACL,MAAO3B,EAAcwB,EAAQ,2BAA4BtB,CAAS,EAClE,KAAM,CAAA,EACN,YAAa,CAAA,CAAC,GAEhB,CAACsB,EAAQ,2BAA4BtB,CAAS,CAAA,EAG1C,CAAC0B,EAAOC,CAAQ,EAAIC,EAAAA,SAAgBJ,CAAO,EAC3C,CAACK,EAAYC,CAAa,EAAIF,EAAAA,SAAS,EAAE,EAE/CG,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAO,KAAK,UAAUR,CAAO,EAC/BQ,IAASH,IACXF,EAASH,CAAO,EAChBM,EAAcE,CAAI,EAEtB,EAAG,CAACR,EAASK,CAAU,CAAC,EAExB,MAAMI,EACJ,KAAK,UAAUP,EAAM,KAAK,IAAM,KAAK,UAAUF,EAAQ,KAAK,GAC5D,OAAO,KAAKE,EAAM,WAAW,EAAE,OAAS,EAE1C,SAASQ,EAAQC,EAAaC,EAAqB,CACjDT,EAAUU,GAAM,CACd,MAAMC,EAAO,CAAC,GAAGD,EAAE,KAAK,EAClBE,EAAOJ,EAAMC,EACnB,GAAIG,EAAO,GAAKA,GAAQD,EAAK,OAAQ,OAAOD,EAC5C,MAAMG,EAAIF,EAAKH,CAAG,EACZM,EAAIH,EAAKC,CAAI,EACnB,MAAI,CAACC,GAAK,CAACC,EAAUJ,GACrBC,EAAKH,CAAG,EAAIM,EACZH,EAAKC,CAAI,EAAIC,EACN,CAAE,GAAGH,EAAG,MAAOC,CAAA,EACxB,CAAC,CACH,CAEA,SAASI,EAAUP,EAAaQ,EAAwB,CACtDhB,EAAUU,GAAM,CACd,MAAMC,EAAO,CAAC,GAAGD,EAAE,KAAK,EAClBO,EAAMN,EAAKH,CAAG,EACpB,OAAKS,GACLN,EAAKH,CAAG,EAAI,CAAE,GAAGS,EAAK,QAAAD,CAAA,EACf,CAAE,GAAGN,EAAG,MAAOC,CAAA,GAFLD,CAGnB,CAAC,CACH,CAEA,SAASQ,EAAOC,EAAgBC,EAAqB,CACnDpB,EAAUU,IAAO,CACf,GAAGA,EACH,KAAM,CAAE,GAAGA,EAAE,KAAM,CAACS,CAAM,EAAGC,CAAA,EAC7B,YAAa,CAAE,GAAGV,EAAE,YAAa,CAACS,CAAM,EAAG,EAAA,CAAK,EAChD,CACJ,CAEA,SAASE,EAASF,EAAsB,CACtCnB,EAAUU,IAAO,CACf,GAAGA,EACH,KAAM,CAAE,GAAGA,EAAE,KAAM,CAACS,CAAM,EAAG,EAAA,EAC7B,YAAa,CAAE,GAAGT,EAAE,YAAa,CAACS,CAAM,EAAG,EAAA,CAAK,EAChD,CACJ,CAEA,eAAeG,GAAwB,CACrC,MAAMC,EAAyC,CAAA,EACzCC,EAAU3C,EAAWkB,EAAM,KAAK,EAChC0B,EAAa5C,EAAWgB,EAAQ,KAAK,EACvC2B,IAAYC,IACdF,EAAQ,2BAA6BC,GAAW,MAElD,SAAW,CAACL,EAAQO,CAAO,IAAK,OAAO,QAAQ3B,EAAM,WAAW,EAAG,CACjE,GAAI,CAAC2B,EAAS,SACd,MAAM,EAAI3B,EAAM,KAAKoB,CAAM,GAAK,GAChCI,EAAQJ,CAAM,EAAI,EAAE,KAAA,IAAW,GAAK,KAAO,CAC7C,CACA,GAAI,OAAO,KAAKI,CAAO,EAAE,SAAW,EACpC,GAAI,CACF,MAAMhC,EAAU,YAAY,CAAE,QAAAgC,EAAS,EAElClC,EAAe,QAAA,EACpBsC,EAAM,QAAQ1C,EAAE,mBAAmB,CAAC,EACpCe,EAAUU,IAAO,CAAE,GAAGA,EAAG,KAAM,GAAI,YAAa,CAAA,CAAC,EAAI,CACvD,OAASkB,EAAK,CACZD,EAAM,MAAQC,GAAe,SAAW,OAAOA,CAAG,CAAE,CACtD,CACF,CAEA,SAASC,GAAkB,CACzB7B,EAASH,CAAO,CAClB,CAEA,eAAeiC,EAAOC,EAAiC,CACrD,GAAI,CACF,MAAMC,EAAS,MAAMvC,EAAa,YAAY,CAC5C,SAAAsC,EAGA,MAAO,WAAA,CACR,EACGC,EAAO,GACTL,EAAM,QACJ1C,EAAE,gBAAiB,CAAE,SAAA8C,EAAU,KAAMC,EAAO,KAAM,GAAIA,EAAO,SAAA,CAAW,CAAA,EAG1EL,EAAM,MACJ1C,EAAE,kBAAmB,CAAE,SAAA8C,EAAU,MAAOC,EAAO,OAAS,gBAAiB,CAAA,CAG/E,OAASJ,EAAK,CACZD,EAAM,MAAOC,GAAe,SAAW,OAAOA,CAAG,CAAC,CACpD,CACF,CAEA,OACEK,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,0BAChB,SAAA,CAAAC,MAAC,KAAA,CAAG,UAAU,wBAAyB,SAAAjD,EAAE,cAAc,EAAE,EACzDgD,EAAAA,KAACE,EAAA,CACC,QAAQ,QAAQ,KAAK,KAAK,UAAU,UACpC,QAAS,IAAM,CACRhD,EAAS,QAAA,EACTE,EAAe,QAAA,CACtB,EACA,SAAUF,EAAS,YAAcE,EAAe,WAChD,aAAYJ,EAAE,kBAAmB,CAAE,GAAI,SAAU,EAEhD,SAAA,CAAAE,EAAS,YAAcE,EAAe,WACnC6C,EAAAA,IAACE,EAAA,CAAQ,UAAU,sBAAA,CAAuB,EAC1CF,EAAAA,IAACG,EAAA,CAAW,UAAU,SAAA,CAAU,QACnC,OAAA,CAAK,UAAU,mBAAoB,SAAApD,EAAE,gBAAgB,CAAA,CAAE,CAAA,CAAA,CAAA,CAC1D,EACF,QACC,IAAA,CAAE,UAAU,wBAAyB,SAAAA,EAAE,iBAAiB,EAAE,EAE3DiD,MAACI,IAAa,KAAA1C,EAAY,EAEzBT,EAAS,WAAaE,EAAe,UACpC6C,EAAAA,IAAC,MAAA,CAAI,UAAU,4CAAA,CAA6C,EAE5DA,EAAAA,IAAC,UAAA,CAAQ,UAAU,sBAChB,SAAAnC,EAAM,MAAM,IAAI,CAACwC,EAAO/B,IAAQ,CAC/B,MAAMgC,EAAOnE,EAAU,KAAMI,GAAMA,EAAE,OAAS8D,EAAM,IAAI,EACxD,OACEL,EAAAA,IAACO,GAAA,CAEC,KAAAD,EACA,MAAAD,EACA,IAAA/B,EACA,MAAOT,EAAM,MAAM,OACnB,SAAUyC,GAAM,OAASzC,EAAM,KAAKyC,EAAK,MAAM,EAAI,OACnD,WAAYA,GAAM,OAAS,CAAC,CAACzC,EAAM,YAAYyC,EAAK,MAAM,EAAI,GAC9D,OAAS9B,GAAMH,EAAQC,EAAKE,CAAC,EAC7B,SAAWgC,GAAM3B,EAAUP,EAAKkC,CAAC,EACjC,SAAWA,GAAMF,GAAM,QAAUtB,EAAOsB,EAAK,OAAQE,CAAC,EACtD,WAAY,IAAMF,GAAM,QAAUnB,EAASmB,EAAK,MAAM,EACtD,OAAQ,IAAMV,EAAOS,EAAM,IAAI,EAC/B,QAAS9C,EAAa,SAAA,EAZjB8C,EAAM,IAAA,CAejB,CAAC,CAAA,CACH,EAGDjC,GACC2B,EAAAA,KAAC,MAAA,CAAI,UAAU,sGACb,SAAA,CAAAC,MAACS,EAAA,CAAM,QAAQ,OAAQ,SAAA1D,EAAE,gBAAgB,EAAE,EAC3CgD,EAAAA,KAACE,EAAA,CACC,QAAQ,QAAQ,KAAK,KAAK,UAAU,UACpC,QAASN,EACT,SAAUtC,EAAU,UAEpB,SAAA,CAAA2C,EAAAA,IAACU,EAAA,CAAE,UAAU,SAAA,CAAU,EAAE,IAAE3D,EAAE,gBAAgB,CAAA,CAAA,CAAA,EAE/CgD,EAAAA,KAACE,EAAA,CACC,KAAK,KACL,QAAS,IAAM,KAAKb,EAAA,EACpB,SAAU/B,EAAU,UAEnB,SAAA,CAAAA,EAAU,gBACN6C,EAAA,CAAQ,UAAU,uBAAuB,EAC1CF,EAAAA,IAACW,EAAA,CAAK,UAAU,SAAA,CAAU,EAC7B5D,EAAE,aAAa,CAAA,CAAA,CAAA,CAClB,CAAA,CACF,CAAA,EAEJ,CAEJ,CAEA,SAASqD,GAAa,CAAE,KAAA1C,GAAyC,CAC/D,KAAM,CAAE,EAAAX,CAAA,EAAMC,EAAe,UAAU,EACvC,OACE+C,EAAAA,KAAC,UAAA,CAAQ,UAAU,uDACjB,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,kCACb,SAAA,CAAAC,EAAAA,IAACjE,EAAA,CAAM,UAAU,uBAAA,CAAwB,QACxC,OAAA,CAAK,UAAU,gBAAiB,SAAAgB,EAAE,mBAAmB,EAAE,EACvDW,EAAK,SAAW,QACd+C,EAAA,CAAM,QAAQ,UAAW,SAAA1D,EAAE,mBAAmB,CAAA,CAAE,QAEhD,OAAA,CAAK,UAAU,oBAAqB,SAAAW,EAAK,KAAK,KAAK,CAAA,CAAE,CAAA,EAE1D,QACC,IAAA,CAAE,UAAU,iCAAkC,SAAAX,EAAE,kBAAkB,CAAA,CAAE,CAAA,EACvE,CAEJ,CAiBA,SAASwD,GAAYK,EAAsC,CACzD,KAAM,CAAE,EAAA7D,CAAA,EAAMC,EAAe,UAAU,EACjC,CAAE,KAAAsD,EAAM,MAAAD,EAAO,IAAA/B,EAAK,MAAAuC,EAAO,SAAAC,EAAU,WAAAC,EAAY,OAAAC,EAAQ,SAAAC,EAC7D,SAAAC,EAAU,WAAAC,EAAY,OAAAvB,EAAQ,QAAAwB,CAAA,EAAYR,EACtCS,EAAW,CAAC,CAACf,GAAM,OACnBgB,EAAY,CAAC,CAAChB,GAAM,WAAcS,GAAc,CAAC,CAACD,EACxD,OACEf,EAAAA,KAAC,MAAA,CAAI,UAAU,iDACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,gBACb,SAAA,CAAAC,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,UAAU,2EACV,QAAS,IAAMgB,EAAO,EAAE,EACxB,SAAU1C,IAAQ,EAClB,aAAYvB,EAAE,eAAe,EAE7B,SAAAiD,EAAAA,IAACuB,EAAA,CAAQ,UAAU,SAAA,CAAU,CAAA,CAAA,EAE/BvB,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,UAAU,2EACV,QAAS,IAAMgB,EAAO,CAAC,EACvB,SAAU1C,IAAQuC,EAAQ,EAC1B,aAAY9D,EAAE,iBAAiB,EAE/B,SAAAiD,EAAAA,IAACwB,EAAA,CAAU,UAAU,SAAA,CAAU,CAAA,CAAA,CACjC,EACF,EAEAzB,EAAAA,KAAC,QAAA,CAAM,UAAU,kCACf,SAAA,CAAAC,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,QAASK,EAAM,QACf,SAAWoB,GAAMR,EAASQ,EAAE,OAAO,OAAO,EAC1C,UAAU,sCAAA,CAAA,EAEZzB,EAAAA,IAAC,OAAA,CAAK,UAAU,oBAAqB,WAAM,IAAA,CAAK,CAAA,EAClD,EAEEqB,EAEEC,EACFvB,EAAAA,KAACU,EAAA,CAAM,QAAQ,UACb,SAAA,CAAAT,EAAAA,IAAC0B,EAAA,CAAa,UAAU,cAAA,CAAe,EAAE,IAAE3E,EAAE,mBAAmB,CAAA,CAAA,CAClE,EAEAgD,EAAAA,KAACU,EAAA,CAAM,QAAQ,UACb,SAAA,CAAAT,EAAAA,IAAC2B,EAAA,CAAQ,UAAU,cAAA,CAAe,EAAE,IAAE5E,EAAE,mBAAmB,CAAA,EAC7D,EARAiD,EAAAA,IAACS,EAAA,CAAM,QAAQ,UAAW,SAAA1D,EAAE,cAAc,CAAA,CAAE,EAW9CiD,EAAAA,IAAC,MAAA,CAAI,UAAU,kCACb,SAAAD,EAAAA,KAACE,EAAA,CACC,KAAK,KAAK,QAAQ,QAClB,QAASL,EACT,SAAUwB,GAAW,CAACf,EAAM,QAC5B,aAAYtD,EAAE,gBAAgB,EAE7B,SAAA,CAAAqE,EACGpB,EAAAA,IAACE,GAAQ,UAAU,sBAAA,CAAuB,EAC1CF,EAAAA,IAACnE,EAAA,CAAa,UAAU,SAAA,CAAU,QACrC,OAAA,CAAK,UAAU,mBAAoB,SAAAkB,EAAE,gBAAgB,CAAA,CAAE,CAAA,CAAA,CAAA,CAC1D,CACF,CAAA,EACF,EAECsE,GACCtB,EAAAA,KAAC,MAAA,CAAI,UAAU,2BACb,SAAA,CAAAA,EAAAA,KAAC6B,EAAA,CAAM,UAAU,sBACf,SAAA,CAAA5B,EAAAA,IAAChE,EAAA,CAAI,UAAU,qBAAA,CAAsB,EACpCsE,GAAM,MAAA,EACT,EACAP,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAC,EAAAA,IAAC6B,EAAA,CACC,KAAK,WACL,MAAOf,GAAY,GACnB,SAAWW,GAAMP,EAASO,EAAE,OAAO,KAAK,EACxC,YACEnB,GAAM,WAAa,CAACS,EAChBhE,EAAE,8BAA8B,EAChCA,EAAE,yBAAyB,EAEjC,UAAU,mBAAA,CAAA,EAEXuD,GAAM,WAAa,CAACS,GACnBf,EAAAA,IAACC,EAAA,CACC,KAAK,KAAK,QAAQ,QAClB,QAASkB,EACT,aAAYpE,EAAE,iBAAiB,EAE/B,SAAAiD,EAAAA,IAACU,EAAA,CAAE,UAAU,SAAA,CAAU,CAAA,CAAA,CACzB,EAEJ,EACAV,EAAAA,IAAC,IAAA,CAAE,UAAU,4BACV,SAAAjD,EAAE,iBAAkB,CAAE,OAAQuD,GAAM,MAAA,CAAQ,CAAA,CAC/C,CAAA,CAAA,CACF,CAAA,EAEJ,CAEJ","x_google_ignoreList":[0,1,2]}
@@ -1,2 +0,0 @@
1
- import{u as N,j as e,B as I,I as d,S as h,g as _,h as f,i as p,k as u,p as T,m as j,n as E,q as M,c as w,l as U}from"./index-DY2Zglku.js";import{r as v}from"./react-DlP5eolq.js";import{u as S,b as L}from"./use-settings-Co-iafXD.js";import{L as C}from"./loader-circle-D8L1w9c1.js";import{R as O}from"./refresh-ccw-7HdadG5V.js";import{S as H}from"./shield-alert-DXGk9Rak.js";import{C as R}from"./circle-check-COhM5JsK.js";function V(s){if(s==null)return!1;const a=s.toLowerCase();return a==="1"||a==="true"||a==="yes"||a==="on"}function G(){const{t:s}=N(["settings","common"]),a=S(),o=L(),[i,B]=v.useState(null),[b,y]=v.useState(!1);async function g(){y(!0);try{const t=await T.get("/api/security/diagnostics");B(t.diagnostics)}catch(t){j.error(E(t,s).message)}finally{y(!1)}}v.useEffect(()=>{g()},[]);async function r(t,l){try{await o.mutateAsync({updates:{[t]:l}}),j.success(s("security.savingToast")),await g()}catch(A){j.error(E(A,s).message)}}const n=a.data?.env??{};return e.jsxs("div",{className:"mx-auto flex max-w-4xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("security.title")}),e.jsx(I,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>{a.refetch(),g()},disabled:a.isFetching||b,"aria-label":s("actions.refresh",{ns:"common"}),children:a.isFetching||b?e.jsx(C,{className:"h-4 w-4 animate-spin"}):e.jsx(O,{className:"h-4 w-4"})})]}),e.jsx("p",{className:"text-sm text-muted",children:s("security.subtitle")})]}),e.jsxs("section",{className:"rounded-lg border border-border bg-card p-4",children:[e.jsxs("h2",{className:"mb-3 flex items-center gap-2 text-sm font-semibold",children:[e.jsx(H,{className:"h-4 w-4"}),s("security.diagnostics.title")]}),i?e.jsxs("ul",{className:"grid gap-2 text-sm sm:grid-cols-2",children:[e.jsx(x,{label:s("security.diagnostics.runningAsRoot"),ok:i.runningAsRoot===!1,text:i.runningAsRoot===!0?s("security.diagnostics.runningAsRootHelp"):"OK"}),e.jsx(x,{label:s("security.diagnostics.envFilePerms"),ok:i.envFile.exists&&!i.envFile.tooPermissive,text:i.envFile.exists?i.envFile.tooPermissive?`${i.envFile.mode} — ${s("security.diagnostics.envFilePermsLax")}`:s("security.diagnostics.envFilePermsOk"):"—"}),e.jsx(x,{label:s("security.diagnostics.bwrapAvailable"),ok:i.bwrapAvailable,text:i.bwrapAvailable?"/usr/bin/bwrap":s("security.diagnostics.bwrapMissing")}),e.jsx(x,{label:s("security.diagnostics.senderAllowlist"),ok:i.senderAllowlistConfigured,text:i.senderAllowlistConfigured?s("security.diagnostics.senderAllowlistOn"):s("security.diagnostics.senderAllowlistOff")}),e.jsx(x,{label:s("security.diagnostics.adminAllowlist"),ok:i.adminAllowlistConfigured,text:i.adminAllowlistConfigured?s("security.diagnostics.adminAllowlistOn"):s("security.diagnostics.adminAllowlistOff")}),e.jsx(x,{label:s("security.diagnosticsPlatformBlacklist"),ok:i.platformBlacklist.length===0,text:i.platformBlacklist.length===0?"—":i.platformBlacklist.join(", ")})]}):e.jsx("p",{className:"text-sm text-muted",children:"…"})]}),e.jsx(m,{title:s("security.sender.title"),description:s("security.sender.description"),envKey:"IMHUB_ALLOWED_USERS",children:e.jsx(d,{defaultValue:n.IMHUB_ALLOWED_USERS??"",placeholder:s("security.sender.placeholder"),onBlur:t=>{const l=t.target.value.trim();r("IMHUB_ALLOWED_USERS",l===""?null:l)}})}),e.jsx(m,{title:s("security.exec.title"),description:s("security.exec.description"),children:e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsx(c,{label:s("security.exec.sandbox"),children:e.jsxs(h,{value:(n.IMHUB_EXEC_SANDBOX??"").toLowerCase()==="bwrap"?"bwrap":"__none__",onValueChange:t=>void r("IMHUB_EXEC_SANDBOX",t==="__none__"?null:t),children:[e.jsx(_,{children:e.jsx(f,{})}),e.jsxs(p,{children:[e.jsx(u,{value:"__none__",children:s("security.exec.sandboxNone")}),e.jsxs(u,{value:"bwrap",disabled:!i?.bwrapAvailable,children:[s("security.exec.sandboxBwrap"),!i?.bwrapAvailable&&e.jsxs("span",{className:"ml-2 text-xs text-muted",children:["(",s("security.exec.sandboxBwrapMissing"),")"]})]})]})]})}),e.jsx(c,{label:s("security.exec.sandboxNet"),children:e.jsxs(h,{value:(n.IMHUB_EXEC_SANDBOX_NET??"").toLowerCase()==="off"?"off":"on",onValueChange:t=>void r("IMHUB_EXEC_SANDBOX_NET",t==="off"?"off":null),children:[e.jsx(_,{children:e.jsx(f,{})}),e.jsxs(p,{children:[e.jsx(u,{value:"on",children:s("security.exec.sandboxNetOn")}),e.jsx(u,{value:"off",children:s("security.exec.sandboxNetOff")})]})]})}),e.jsx(c,{label:s("security.exec.timeoutMs"),children:e.jsx(d,{type:"number",defaultValue:n.IMHUB_EXEC_TIMEOUT_MS??"",placeholder:"60000",onBlur:t=>{const l=t.target.value.trim();r("IMHUB_EXEC_TIMEOUT_MS",l===""?null:l)}})}),e.jsx(c,{label:s("security.exec.maxOutput"),children:e.jsx(d,{type:"number",defaultValue:n.IMHUB_EXEC_MAX_OUTPUT??"",placeholder:"32768",onBlur:t=>{const l=t.target.value.trim();r("IMHUB_EXEC_MAX_OUTPUT",l===""?null:l)}})})]})}),e.jsx(m,{title:s("security.web.title"),description:s("security.web.description"),children:e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsx(c,{label:s("security.web.allowPrivate"),hint:s("security.web.allowPrivateHelp"),children:e.jsxs(h,{value:V(n.IMHUB_NATIVE_WEB_ALLOW_PRIVATE)?"1":"0",onValueChange:t=>void r("IMHUB_NATIVE_WEB_ALLOW_PRIVATE",t==="1"?"1":null),children:[e.jsx(_,{children:e.jsx(f,{})}),e.jsxs(p,{children:[e.jsx(u,{value:"0",children:"OFF"}),e.jsx(u,{value:"1",children:"ON"})]})]})}),e.jsx(c,{label:s("security.web.timeoutMs"),children:e.jsx(d,{type:"number",defaultValue:n.IMHUB_NATIVE_WEB_TIMEOUT_MS??"",placeholder:"30000",onBlur:t=>{const l=t.target.value.trim();r("IMHUB_NATIVE_WEB_TIMEOUT_MS",l===""?null:l)}})}),e.jsx("div",{className:"sm:col-span-2",children:e.jsx(c,{label:s("security.web.ssrfWhitelist"),children:e.jsx(d,{defaultValue:n.IMHUB_NATIVE_WEB_SSRF_WHITELIST??"",placeholder:s("security.web.ssrfWhitelistPlaceholder"),onBlur:t=>{const l=t.target.value.trim();r("IMHUB_NATIVE_WEB_SSRF_WHITELIST",l===""?null:l)}})})})]})}),e.jsx(m,{title:s("security.fs.title"),description:s("security.fs.description"),children:e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsx(c,{label:s("security.fs.restrict"),children:e.jsxs(h,{value:(n.IMHUB_NATIVE_FS_RESTRICT??"0")==="1"?"1":"0",onValueChange:t=>void r("IMHUB_NATIVE_FS_RESTRICT",t==="1"?"1":null),children:[e.jsx(_,{children:e.jsx(f,{})}),e.jsxs(p,{children:[e.jsx(u,{value:"1",children:s("security.fs.restrictOn")}),e.jsx(u,{value:"0",children:s("security.fs.restrictOff")})]})]})}),e.jsx(c,{label:s("security.fs.timeoutMs"),children:e.jsx(d,{type:"number",defaultValue:n.IMHUB_NATIVE_FS_TIMEOUT_MS??"",placeholder:"60000",onBlur:t=>{const l=t.target.value.trim();r("IMHUB_NATIVE_FS_TIMEOUT_MS",l===""?null:l)}})})]})}),e.jsx(m,{title:s("security.delegation.title"),description:s("security.delegation.description"),envKey:"IMHUB_NATIVE_CALL_AGENT_MAX_PER_TURN",children:e.jsx(d,{type:"number",defaultValue:n.IMHUB_NATIVE_CALL_AGENT_MAX_PER_TURN??"",placeholder:"2",onBlur:t=>{const l=t.target.value.trim();r("IMHUB_NATIVE_CALL_AGENT_MAX_PER_TURN",l===""?null:l)}})}),e.jsxs(m,{title:s("security.platformBlacklist.title"),description:s("security.platformBlacklist.description"),envKey:"IMHUB_PLATFORM_BLACKLIST",children:[e.jsx(d,{defaultValue:n.IMHUB_PLATFORM_BLACKLIST??"",placeholder:s("security.platformBlacklist.placeholder"),onBlur:t=>{const l=t.target.value.trim();r("IMHUB_PLATFORM_BLACKLIST",l===""?null:l)}}),i?.platformBlacklist&&i.platformBlacklist.length>0&&e.jsxs("p",{className:"mt-2 text-[10px] text-muted",children:[s("security.platformBlacklist.currentLabel"),": ",i.platformBlacklist.join(", ")]})]})]})}function x({label:s,ok:a,text:o}){return e.jsxs("li",{className:"flex items-start gap-2",children:[a?e.jsx(R,{className:"mt-0.5 h-4 w-4 shrink-0 text-success"}):e.jsx(M,{className:"mt-0.5 h-4 w-4 shrink-0 text-warning"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"font-medium",children:s}),e.jsx("div",{className:w("text-xs",a?"text-muted":"text-warning"),children:o})]})]})}function m({title:s,description:a,envKey:o,children:i}){return e.jsxs("section",{className:"rounded-lg border border-border bg-card p-4",children:[e.jsxs("div",{className:"mb-2 flex flex-wrap items-baseline gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold",children:s}),o&&e.jsx(U,{variant:"outline",className:"font-mono text-[10px]",children:o})]}),e.jsx("p",{className:"mb-3 text-xs text-muted",children:a}),i]})}function c({label:s,hint:a,children:o}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{className:"text-xs font-medium text-muted",children:s}),o,a&&e.jsx("p",{className:"text-[10px] text-muted",children:a})]})}export{G as default};
2
- //# sourceMappingURL=security-DpOGp3nS.js.map