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,7 +1,7 @@
1
- import{o as f,b as g,d as N,u as j,f as y,j as s,l as d,B as b,L as w,I as C}from"./index-DY2Zglku.js";import{r as v}from"./react-DlP5eolq.js";import{D as k}from"./data-table-BLYG79TX.js";import{E as R}from"./empty-state-96qpPTNg.js";import{L as S}from"./loader-circle-D8L1w9c1.js";import{R as L}from"./refresh-ccw-7HdadG5V.js";import"./table-_WsrnZ_T.js";import"./arrow-up-CAiQ2jy-.js";import"./arrow-down-DxlRHrs8.js";/**
1
+ import{o as f,b as g,d as N,u as j,f as y,j as s,l as d,B as b,L as w,I as C}from"./index-DHh1LYlA.js";import{r as v}from"./react-DlP5eolq.js";import{D as k}from"./data-table-DOKUic1J.js";import{E as R}from"./empty-state-CTwOQemt.js";import{L as S}from"./loader-circle-DgdBWYl0.js";import{R as L}from"./refresh-ccw-nBMm5Xal.js";import"./table-Dx65w6V0.js";import"./arrow-up-i_dEdXkz.js";import"./arrow-down-B8DkdbEY.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
6
  */const M=f("CalendarClock",[["path",{d:"M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5",key:"1osxxc"}],["path",{d:"M16 2v4",key:"4m81vk"}],["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M3 10h5",key:"r794hk"}],["path",{d:"M17.5 17.5 16 16.3V14",key:"akvzfd"}],["circle",{cx:"16",cy:"16",r:"6",key:"qoo3c4"}]]),T={all:["schedules"],list:e=>["schedules","list",e]};function E(e){return g({queryKey:T.list(e),queryFn:()=>N.listSchedules(e)})}function O(){const{t:e}=j(["tasks","common"]),[t,i]=y(),l=t.get("agent")??"",{data:m,isLoading:o,isFetching:n,refetch:h}=E(l?{agent:l}:{}),u=m?.schedules??[];function x(a){const c=new URLSearchParams(t);a?c.set("agent",a):c.delete("agent"),i(c,{replace:!0})}const p=v.useMemo(()=>[{id:"id",header:e("schedules.col.id"),cell:a=>s.jsxs("span",{className:"tabular-nums text-text-dim",children:["#",a.id]}),headClassName:"w-16"},{id:"name",header:e("schedules.col.name"),cell:a=>s.jsx("span",{className:"font-medium",children:a.name}),asCardTitle:!0},{id:"agent",header:e("schedules.col.agent"),cell:a=>s.jsx("span",{className:"text-text-dim",children:a.agent}),headClassName:"w-32"},{id:"cron",header:e("schedules.col.cron"),cell:a=>s.jsx("code",{className:"rounded bg-surface-2 px-1.5 py-0.5 text-xs",children:a.cron}),headClassName:"w-32"},{id:"prompt",header:e("schedules.col.prompt"),cell:a=>s.jsx("span",{className:"line-clamp-2 text-text-dim",children:a.prompt}),hideOnMobile:!0},{id:"enabled",header:e("schedules.col.enabled"),cell:a=>a.enabled?s.jsx(d,{variant:"success",children:e("schedules.enabled")}):s.jsx(d,{variant:"outline",children:e("schedules.disabled")}),headClassName:"w-20"},{id:"nextRun",header:e("schedules.col.nextRun"),cell:a=>s.jsx("span",{className:"text-text-dim",children:r(a.next_run)}),headClassName:"w-40"},{id:"lastRun",header:e("schedules.col.lastRun"),cell:a=>s.jsx("span",{className:"text-text-dim",children:r(a.last_run)}),headClassName:"w-40",hideOnMobile:!0}],[e]);return s.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[s.jsxs("header",{className:"flex flex-col gap-1",children:[s.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[s.jsx("h1",{className:"text-xl font-semibold",children:e("schedules.title")}),s.jsxs(b,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>h(),disabled:n,"aria-label":e("actions.refresh",{ns:"common"}),children:[n?s.jsx(S,{className:"h-4 w-4 animate-spin"}):s.jsx(L,{className:"h-4 w-4"}),s.jsx("span",{className:"hidden sm:inline",children:e("actions.refresh",{ns:"common"})})]})]}),s.jsx("p",{className:"text-sm text-text-dim",children:e("schedules.subtitle")})]}),s.jsx("div",{className:"flex flex-wrap items-end gap-2",children:s.jsxs("div",{className:"flex flex-col gap-1",children:[s.jsx(w,{htmlFor:"agent-filter",className:"text-xs text-text-dim",children:e("schedules.filter.agent")}),s.jsx(C,{id:"agent-filter",value:l,onChange:a=>x(a.target.value),placeholder:e("schedules.filter.agentAny"),className:"w-48"})]})}),s.jsx(k,{columns:p,rows:u,getRowId:a=>String(a.id),loading:o,emptyState:s.jsx(R,{icon:s.jsx(M,{}),title:e("schedules.empty.title"),description:e("schedules.empty.description")})})]})}function r(e){if(e==null)return"—";try{const t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return e}}export{O as default};
7
- //# sourceMappingURL=schedules-BddzBrxI.js.map
7
+ //# sourceMappingURL=schedules-DzwDWykc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schedules-BddzBrxI.js","sources":["../../node_modules/lucide-react/dist/esm/icons/calendar-clock.js","../../src/hooks/use-schedules.ts","../../src/routes/tasks/schedules.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 CalendarClock = createLucideIcon(\"CalendarClock\", [\n [\"path\", { d: \"M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5\", key: \"1osxxc\" }],\n [\"path\", { d: \"M16 2v4\", key: \"4m81vk\" }],\n [\"path\", { d: \"M8 2v4\", key: \"1cmpym\" }],\n [\"path\", { d: \"M3 10h5\", key: \"r794hk\" }],\n [\"path\", { d: \"M17.5 17.5 16 16.3V14\", key: \"akvzfd\" }],\n [\"circle\", { cx: \"16\", cy: \"16\", r: \"6\", key: \"qoo3c4\" }]\n]);\n\nexport { CalendarClock as default };\n//# sourceMappingURL=calendar-clock.js.map\n","/**\n * useSchedules — react-query wrapper for /api/schedules.\n *\n * Read-only: schedule create / delete / toggle isn't exposed via\n * /api today (only via CLI). When that lands the mutations slot in\n * here next to useSchedules.\n */\n\nimport { useQueryClient, useQuery } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type { ListSchedulesQuery, ListSchedulesResponse } from '@/types/api'\n\nexport const schedulesKeys = {\n all: ['schedules'] as const,\n list: (q: ListSchedulesQuery) => ['schedules', 'list', q] as const,\n}\n\nexport function useSchedules(query: ListSchedulesQuery) {\n return useQuery<ListSchedulesResponse>({\n queryKey: schedulesKeys.list(query),\n queryFn: () => api.listSchedules(query),\n })\n}\n\nexport function useInvalidateSchedules() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: schedulesKeys.all })\n}\n","/**\n * /tasks/schedules — cron-style triggers list. Read-only; mutations\n * (create / delete / toggle) only exist via CLI today; the page\n * shows what's scheduled and when the next run lands.\n */\n\nimport { useMemo } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { CalendarClock, Loader2, RefreshCcw } from 'lucide-react'\n\nimport { DataTable, type DataTableColumn } from '@/components/common/data-table'\nimport { EmptyState } from '@/components/common/empty-state'\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 { useSchedules } from '@/hooks/use-schedules'\nimport type { Schedule } from '@/types/api'\n\nexport default function SchedulesRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const [params, setParams] = useSearchParams()\n const agent = params.get('agent') ?? ''\n\n const { data, isLoading, isFetching, refetch } = useSchedules(\n agent ? { agent } : {},\n )\n const schedules = data?.schedules ?? []\n\n function setAgentFilter(v: string): void {\n const next = new URLSearchParams(params)\n if (!v) next.delete('agent')\n else next.set('agent', v)\n setParams(next, { replace: true })\n }\n\n const columns: DataTableColumn<Schedule>[] = useMemo(\n () => [\n {\n id: 'id',\n header: t('schedules.col.id'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">#{r.id}</span>,\n headClassName: 'w-16',\n },\n {\n id: 'name',\n header: t('schedules.col.name'),\n cell: (r) => <span className=\"font-medium\">{r.name}</span>,\n asCardTitle: true,\n },\n {\n id: 'agent',\n header: t('schedules.col.agent'),\n cell: (r) => <span className=\"text-text-dim\">{r.agent}</span>,\n headClassName: 'w-32',\n },\n {\n id: 'cron',\n header: t('schedules.col.cron'),\n cell: (r) => <code className=\"rounded bg-surface-2 px-1.5 py-0.5 text-xs\">{r.cron}</code>,\n headClassName: 'w-32',\n },\n {\n id: 'prompt',\n header: t('schedules.col.prompt'),\n cell: (r) => <span className=\"line-clamp-2 text-text-dim\">{r.prompt}</span>,\n hideOnMobile: true,\n },\n {\n id: 'enabled',\n header: t('schedules.col.enabled'),\n cell: (r) =>\n r.enabled ? (\n <Badge variant=\"success\">{t('schedules.enabled')}</Badge>\n ) : (\n <Badge variant=\"outline\">{t('schedules.disabled')}</Badge>\n ),\n headClassName: 'w-20',\n },\n {\n id: 'nextRun',\n header: t('schedules.col.nextRun'),\n cell: (r) => <span className=\"text-text-dim\">{formatTime(r.next_run)}</span>,\n headClassName: 'w-40',\n },\n {\n id: 'lastRun',\n header: t('schedules.col.lastRun'),\n cell: (r) => <span className=\"text-text-dim\">{formatTime(r.last_run)}</span>,\n headClassName: 'w-40',\n hideOnMobile: true,\n },\n ],\n [t],\n )\n\n return (\n <div className=\"mx-auto flex max-w-7xl 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('schedules.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {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('schedules.subtitle')}</p>\n </header>\n\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"agent-filter\" className=\"text-xs text-text-dim\">\n {t('schedules.filter.agent')}\n </Label>\n <Input\n id=\"agent-filter\"\n value={agent}\n onChange={(e) => setAgentFilter(e.target.value)}\n placeholder={t('schedules.filter.agentAny')}\n className=\"w-48\"\n />\n </div>\n </div>\n\n <DataTable\n columns={columns}\n rows={schedules}\n getRowId={(r) => String(r.id)}\n loading={isLoading}\n emptyState={\n <EmptyState\n icon={<CalendarClock />}\n title={t('schedules.empty.title')}\n description={t('schedules.empty.description')}\n />\n }\n />\n </div>\n )\n}\n\nfunction formatTime(iso: string | undefined | null): string {\n if (iso == null) return '—'\n try {\n const d = new Date(iso)\n if (Number.isNaN(d.getTime())) return iso\n return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n } catch {\n return iso\n }\n}\n"],"names":["CalendarClock","createLucideIcon","schedulesKeys","q","useSchedules","query","useQuery","api","SchedulesRoute","t","useTranslation","params","setParams","useSearchParams","agent","data","isLoading","isFetching","refetch","schedules","setAgentFilter","v","next","columns","useMemo","r","jsxs","jsx","Badge","formatTime","Button","Loader2","RefreshCcw","Label","Input","e","DataTable","EmptyState","iso","d"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"schedules-DzwDWykc.js","sources":["../../node_modules/lucide-react/dist/esm/icons/calendar-clock.js","../../src/hooks/use-schedules.ts","../../src/routes/tasks/schedules.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 CalendarClock = createLucideIcon(\"CalendarClock\", [\n [\"path\", { d: \"M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5\", key: \"1osxxc\" }],\n [\"path\", { d: \"M16 2v4\", key: \"4m81vk\" }],\n [\"path\", { d: \"M8 2v4\", key: \"1cmpym\" }],\n [\"path\", { d: \"M3 10h5\", key: \"r794hk\" }],\n [\"path\", { d: \"M17.5 17.5 16 16.3V14\", key: \"akvzfd\" }],\n [\"circle\", { cx: \"16\", cy: \"16\", r: \"6\", key: \"qoo3c4\" }]\n]);\n\nexport { CalendarClock as default };\n//# sourceMappingURL=calendar-clock.js.map\n","/**\n * useSchedules — react-query wrapper for /api/schedules.\n *\n * Read-only: schedule create / delete / toggle isn't exposed via\n * /api today (only via CLI). When that lands the mutations slot in\n * here next to useSchedules.\n */\n\nimport { useQueryClient, useQuery } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type { ListSchedulesQuery, ListSchedulesResponse } from '@/types/api'\n\nexport const schedulesKeys = {\n all: ['schedules'] as const,\n list: (q: ListSchedulesQuery) => ['schedules', 'list', q] as const,\n}\n\nexport function useSchedules(query: ListSchedulesQuery) {\n return useQuery<ListSchedulesResponse>({\n queryKey: schedulesKeys.list(query),\n queryFn: () => api.listSchedules(query),\n })\n}\n\nexport function useInvalidateSchedules() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: schedulesKeys.all })\n}\n","/**\n * /tasks/schedules — cron-style triggers list. Read-only; mutations\n * (create / delete / toggle) only exist via CLI today; the page\n * shows what's scheduled and when the next run lands.\n */\n\nimport { useMemo } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { CalendarClock, Loader2, RefreshCcw } from 'lucide-react'\n\nimport { DataTable, type DataTableColumn } from '@/components/common/data-table'\nimport { EmptyState } from '@/components/common/empty-state'\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 { useSchedules } from '@/hooks/use-schedules'\nimport type { Schedule } from '@/types/api'\n\nexport default function SchedulesRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const [params, setParams] = useSearchParams()\n const agent = params.get('agent') ?? ''\n\n const { data, isLoading, isFetching, refetch } = useSchedules(\n agent ? { agent } : {},\n )\n const schedules = data?.schedules ?? []\n\n function setAgentFilter(v: string): void {\n const next = new URLSearchParams(params)\n if (!v) next.delete('agent')\n else next.set('agent', v)\n setParams(next, { replace: true })\n }\n\n const columns: DataTableColumn<Schedule>[] = useMemo(\n () => [\n {\n id: 'id',\n header: t('schedules.col.id'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">#{r.id}</span>,\n headClassName: 'w-16',\n },\n {\n id: 'name',\n header: t('schedules.col.name'),\n cell: (r) => <span className=\"font-medium\">{r.name}</span>,\n asCardTitle: true,\n },\n {\n id: 'agent',\n header: t('schedules.col.agent'),\n cell: (r) => <span className=\"text-text-dim\">{r.agent}</span>,\n headClassName: 'w-32',\n },\n {\n id: 'cron',\n header: t('schedules.col.cron'),\n cell: (r) => <code className=\"rounded bg-surface-2 px-1.5 py-0.5 text-xs\">{r.cron}</code>,\n headClassName: 'w-32',\n },\n {\n id: 'prompt',\n header: t('schedules.col.prompt'),\n cell: (r) => <span className=\"line-clamp-2 text-text-dim\">{r.prompt}</span>,\n hideOnMobile: true,\n },\n {\n id: 'enabled',\n header: t('schedules.col.enabled'),\n cell: (r) =>\n r.enabled ? (\n <Badge variant=\"success\">{t('schedules.enabled')}</Badge>\n ) : (\n <Badge variant=\"outline\">{t('schedules.disabled')}</Badge>\n ),\n headClassName: 'w-20',\n },\n {\n id: 'nextRun',\n header: t('schedules.col.nextRun'),\n cell: (r) => <span className=\"text-text-dim\">{formatTime(r.next_run)}</span>,\n headClassName: 'w-40',\n },\n {\n id: 'lastRun',\n header: t('schedules.col.lastRun'),\n cell: (r) => <span className=\"text-text-dim\">{formatTime(r.last_run)}</span>,\n headClassName: 'w-40',\n hideOnMobile: true,\n },\n ],\n [t],\n )\n\n return (\n <div className=\"mx-auto flex max-w-7xl 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('schedules.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {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('schedules.subtitle')}</p>\n </header>\n\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"agent-filter\" className=\"text-xs text-text-dim\">\n {t('schedules.filter.agent')}\n </Label>\n <Input\n id=\"agent-filter\"\n value={agent}\n onChange={(e) => setAgentFilter(e.target.value)}\n placeholder={t('schedules.filter.agentAny')}\n className=\"w-48\"\n />\n </div>\n </div>\n\n <DataTable\n columns={columns}\n rows={schedules}\n getRowId={(r) => String(r.id)}\n loading={isLoading}\n emptyState={\n <EmptyState\n icon={<CalendarClock />}\n title={t('schedules.empty.title')}\n description={t('schedules.empty.description')}\n />\n }\n />\n </div>\n )\n}\n\nfunction formatTime(iso: string | undefined | null): string {\n if (iso == null) return '—'\n try {\n const d = new Date(iso)\n if (Number.isNaN(d.getTime())) return iso\n return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n } catch {\n return iso\n }\n}\n"],"names":["CalendarClock","createLucideIcon","schedulesKeys","q","useSchedules","query","useQuery","api","SchedulesRoute","t","useTranslation","params","setParams","useSearchParams","agent","data","isLoading","isFetching","refetch","schedules","setAgentFilter","v","next","columns","useMemo","r","jsxs","jsx","Badge","formatTime","Button","Loader2","RefreshCcw","Label","Input","e","DataTable","EmptyState","iso","d"],"mappings":"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","x_google_ignoreList":[0]}
@@ -0,0 +1,17 @@
1
+ import{o as E,u as R,j as e,B as j,l as b,X as P,m as g,L,I as _}from"./index-DHh1LYlA.js";import{r as C}from"./react-DlP5eolq.js";import{u as H,s as z,b as F,t as V}from"./use-settings-DKbDqCEJ.js";import{L as T}from"./loader-circle-DgdBWYl0.js";import{R as G}from"./refresh-ccw-nBMm5Xal.js";import{S as q}from"./save-DbrrCFDM.js";import{A as J}from"./arrow-up-i_dEdXkz.js";import{A as U}from"./arrow-down-B8DkdbEY.js";import{C as W}from"./circle-check-DZnkaUdk.js";import{C as Q}from"./circle-x-DHK7ypFY.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=H({reveal:!1}),o=z(),h=F(),m=V(),f=a.data?.env??{},i=o.data?.providers??[],y=o.data?.chain??[],d=C.useMemo(()=>({chain:$(f.AGIM_WEB_SEARCH_PROVIDERS,i),keys:{},keysTouched:{}}),[f.AGIM_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],A=n[x];return!v||!A?c:(n[s]=A,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 O(s){u(t=>({...t,keys:{...t.keys,[s]:""},keysTouched:{...t.keysTouched,[s]:!0}}))}async function B(){const s={},t=M(l.chain),c=M(d.chain);t!==c&&(s.AGIM_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 D(){u(d)}async function I(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(G,{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&&O(c.envKey),onTest:()=>I(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:D,disabled:h.isPending,children:[e.jsx(P,{className:"h-4 w-4"})," ",r("search.discard")]}),e.jsxs(j,{size:"sm",onClick:()=>void B(),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(U,{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(W,{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(L,{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(_,{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-5q3dkINm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-5q3dkINm.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 * AGIM_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.AGIM_WEB_SEARCH_PROVIDERS, providers),\n keys: {},\n keysTouched: {},\n }),\n [envData.AGIM_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.AGIM_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":"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","x_google_ignoreList":[0,1,2]}
@@ -1,7 +1,7 @@
1
- import{o as e}from"./index-DY2Zglku.js";/**
1
+ import{o as e}from"./index-DHh1LYlA.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
6
  */const r=e("Search",[["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["path",{d:"m21 21-4.3-4.3",key:"1qie3q"}]]);export{r as S};
7
- //# sourceMappingURL=search-DxkvV-8p.js.map
7
+ //# sourceMappingURL=search-DbE4VEm9.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"search-DxkvV-8p.js","sources":["../../node_modules/lucide-react/dist/esm/icons/search.js"],"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 Search = createLucideIcon(\"Search\", [\n [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }],\n [\"path\", { d: \"m21 21-4.3-4.3\", key: \"1qie3q\" }]\n]);\n\nexport { Search as default };\n//# sourceMappingURL=search.js.map\n"],"names":["Search","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAASC,EAAiB,SAAU,CACxC,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,SAAU,EACxD,CAAC,OAAQ,CAAE,EAAG,iBAAkB,IAAK,QAAQ,CAAE,CACjD,CAAC","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"search-DbE4VEm9.js","sources":["../../node_modules/lucide-react/dist/esm/icons/search.js"],"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 Search = createLucideIcon(\"Search\", [\n [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }],\n [\"path\", { d: \"m21 21-4.3-4.3\", key: \"1qie3q\" }]\n]);\n\nexport { Search as default };\n//# sourceMappingURL=search.js.map\n"],"names":["Search","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAASC,EAAiB,SAAU,CACxC,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,SAAU,EACxD,CAAC,OAAQ,CAAE,EAAG,iBAAkB,IAAK,QAAQ,CAAE,CACjD,CAAC","x_google_ignoreList":[0]}
@@ -0,0 +1,2 @@
1
+ import{u as I,j as e,B as T,I as d,S as h,g as _,h as f,i as p,k as u,p as M,m as j,n as y,q as w,c as S,l as B}from"./index-DHh1LYlA.js";import{r as A}from"./react-DlP5eolq.js";import{u as L,b as C}from"./use-settings-DKbDqCEJ.js";import{L as O}from"./loader-circle-DgdBWYl0.js";import{R as G}from"./refresh-ccw-nBMm5Xal.js";import{S as R}from"./shield-alert-WOa69jy3.js";import{C as V}from"./circle-check-DZnkaUdk.js";function k(s){if(s==null)return!1;const a=s.toLowerCase();return a==="1"||a==="true"||a==="yes"||a==="on"}function H(){const{t:s}=I(["settings","common"]),a=L(),o=C(),[i,E]=A.useState(null),[v,b]=A.useState(!1);async function g(){b(!0);try{const t=await M.get("/api/security/diagnostics");E(t.diagnostics)}catch(t){j.error(y(t,s).message)}finally{b(!1)}}A.useEffect(()=>{g()},[]);async function r(t,l){try{await o.mutateAsync({updates:{[t]:l}}),j.success(s("security.savingToast")),await g()}catch(N){j.error(y(N,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(T,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>{a.refetch(),g()},disabled:a.isFetching||v,"aria-label":s("actions.refresh",{ns:"common"}),children:a.isFetching||v?e.jsx(O,{className:"h-4 w-4 animate-spin"}):e.jsx(G,{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(R,{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:"AGIM_ALLOWED_USERS",children:e.jsx(d,{defaultValue:n.AGIM_ALLOWED_USERS??"",placeholder:s("security.sender.placeholder"),onBlur:t=>{const l=t.target.value.trim();r("AGIM_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.AGIM_EXEC_SANDBOX??"").toLowerCase()==="bwrap"?"bwrap":"__none__",onValueChange:t=>void r("AGIM_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.AGIM_EXEC_SANDBOX_NET??"").toLowerCase()==="off"?"off":"on",onValueChange:t=>void r("AGIM_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.AGIM_EXEC_TIMEOUT_MS??"",placeholder:"60000",onBlur:t=>{const l=t.target.value.trim();r("AGIM_EXEC_TIMEOUT_MS",l===""?null:l)}})}),e.jsx(c,{label:s("security.exec.maxOutput"),children:e.jsx(d,{type:"number",defaultValue:n.AGIM_EXEC_MAX_OUTPUT??"",placeholder:"32768",onBlur:t=>{const l=t.target.value.trim();r("AGIM_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:k(n.AGIM_NATIVE_WEB_ALLOW_PRIVATE)?"1":"0",onValueChange:t=>void r("AGIM_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.AGIM_NATIVE_WEB_TIMEOUT_MS??"",placeholder:"30000",onBlur:t=>{const l=t.target.value.trim();r("AGIM_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.AGIM_NATIVE_WEB_SSRF_WHITELIST??"",placeholder:s("security.web.ssrfWhitelistPlaceholder"),onBlur:t=>{const l=t.target.value.trim();r("AGIM_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.AGIM_NATIVE_FS_RESTRICT??"0")==="1"?"1":"0",onValueChange:t=>void r("AGIM_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.AGIM_NATIVE_FS_TIMEOUT_MS??"",placeholder:"60000",onBlur:t=>{const l=t.target.value.trim();r("AGIM_NATIVE_FS_TIMEOUT_MS",l===""?null:l)}})})]})}),e.jsx(m,{title:s("security.delegation.title"),description:s("security.delegation.description"),envKey:"AGIM_NATIVE_CALL_AGENT_MAX_PER_TURN",children:e.jsx(d,{type:"number",defaultValue:n.AGIM_NATIVE_CALL_AGENT_MAX_PER_TURN??"",placeholder:"2",onBlur:t=>{const l=t.target.value.trim();r("AGIM_NATIVE_CALL_AGENT_MAX_PER_TURN",l===""?null:l)}})}),e.jsxs(m,{title:s("security.platformBlacklist.title"),description:s("security.platformBlacklist.description"),envKey:"AGIM_PLATFORM_BLACKLIST",children:[e.jsx(d,{defaultValue:n.AGIM_PLATFORM_BLACKLIST??"",placeholder:s("security.platformBlacklist.placeholder"),onBlur:t=>{const l=t.target.value.trim();r("AGIM_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(V,{className:"mt-0.5 h-4 w-4 shrink-0 text-success"}):e.jsx(w,{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:S("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(B,{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{H as default};
2
+ //# sourceMappingURL=security-BIcnUrAs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-BIcnUrAs.js","sources":["../../src/routes/settings/security.tsx"],"sourcesContent":["/**\n * /settings/security — central console for v1.2.66 security controls.\n *\n * Lays out:\n * • Diagnostics card (read-only) — uid 0? env file perms? bwrap? allowlists configured?\n * • Sender allowlist (AGIM_ALLOWED_USERS)\n * • Native exec (AGIM_EXEC_SANDBOX, AGIM_EXEC_SANDBOX_NET, AGIM_EXEC_TIMEOUT_MS, AGIM_EXEC_MAX_OUTPUT)\n * • Native web (AGIM_NATIVE_WEB_ALLOW_PRIVATE, AGIM_NATIVE_WEB_SSRF_WHITELIST, AGIM_NATIVE_WEB_TIMEOUT_MS)\n * • Native fs (AGIM_NATIVE_FS_RESTRICT, AGIM_NATIVE_FS_TIMEOUT_MS)\n * • Delegation (AGIM_NATIVE_CALL_AGENT_MAX_PER_TURN)\n *\n * All writes go through PUT /api/env (admin-gated). Most knobs are\n * hot-reloaded (read process.env per tool call); the exec sandbox +\n * sender allowlist apply at boot — service restart required.\n */\n\nimport { useEffect, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { AlertTriangle, CheckCircle2, Loader2, RefreshCcw, ShieldAlert } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport { useEnv, useUpdateEnv } from '@/hooks/use-settings'\nimport { client } from '@/lib/api/client'\nimport { describeError } from '@/lib/api/errors'\nimport { cn } from '@/lib/utils'\n\ninterface Diagnostics {\n runningAsRoot: boolean | null\n envFile: { exists: boolean; mode: string | null; tooPermissive: boolean }\n bwrapAvailable: boolean\n senderAllowlistConfigured: boolean\n adminAllowlistConfigured: boolean\n platformBlacklist: string[]\n liveEnv: Record<string, string | null>\n}\n\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 SettingsSecurityRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const envQuery = useEnv()\n const updateEnv = useUpdateEnv()\n const [diagnostics, setDiagnostics] = useState<Diagnostics | null>(null)\n const [diagLoading, setDiagLoading] = useState(false)\n\n async function loadDiagnostics(): Promise<void> {\n setDiagLoading(true)\n try {\n const res = await client.get<{ diagnostics: Diagnostics }>('/api/security/diagnostics')\n setDiagnostics(res.diagnostics)\n } catch (err) {\n toast.error(describeError(err, t).message)\n } finally {\n setDiagLoading(false)\n }\n }\n\n useEffect(() => { void loadDiagnostics() }, [])\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('security.savingToast'))\n await loadDiagnostics()\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n const env = envQuery.data?.env ?? {}\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('security.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => { void envQuery.refetch(); void loadDiagnostics() }}\n disabled={envQuery.isFetching || diagLoading}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {envQuery.isFetching || diagLoading\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />\n }\n </Button>\n </div>\n <p className=\"text-sm text-muted\">{t('security.subtitle')}</p>\n </header>\n\n {/* Diagnostics card */}\n <section className=\"rounded-lg border border-border bg-card p-4\">\n <h2 className=\"mb-3 flex items-center gap-2 text-sm font-semibold\">\n <ShieldAlert className=\"h-4 w-4\" />\n {t('security.diagnostics.title')}\n </h2>\n {diagnostics ? (\n <ul className=\"grid gap-2 text-sm sm:grid-cols-2\">\n <DiagRow\n label={t('security.diagnostics.runningAsRoot')}\n ok={diagnostics.runningAsRoot === false}\n text={diagnostics.runningAsRoot === true ? t('security.diagnostics.runningAsRootHelp') : 'OK'}\n />\n <DiagRow\n label={t('security.diagnostics.envFilePerms')}\n ok={diagnostics.envFile.exists && !diagnostics.envFile.tooPermissive}\n text={\n !diagnostics.envFile.exists\n ? '—'\n : diagnostics.envFile.tooPermissive\n ? `${diagnostics.envFile.mode} — ${t('security.diagnostics.envFilePermsLax')}`\n : t('security.diagnostics.envFilePermsOk')\n }\n />\n <DiagRow\n label={t('security.diagnostics.bwrapAvailable')}\n ok={diagnostics.bwrapAvailable}\n text={diagnostics.bwrapAvailable ? '/usr/bin/bwrap' : t('security.diagnostics.bwrapMissing')}\n />\n <DiagRow\n label={t('security.diagnostics.senderAllowlist')}\n ok={diagnostics.senderAllowlistConfigured}\n text={diagnostics.senderAllowlistConfigured\n ? t('security.diagnostics.senderAllowlistOn')\n : t('security.diagnostics.senderAllowlistOff')\n }\n />\n <DiagRow\n label={t('security.diagnostics.adminAllowlist')}\n ok={diagnostics.adminAllowlistConfigured}\n text={diagnostics.adminAllowlistConfigured\n ? t('security.diagnostics.adminAllowlistOn')\n : t('security.diagnostics.adminAllowlistOff')\n }\n />\n <DiagRow\n label={t('security.diagnosticsPlatformBlacklist')}\n ok={diagnostics.platformBlacklist.length === 0}\n text={diagnostics.platformBlacklist.length === 0\n ? '—'\n : diagnostics.platformBlacklist.join(', ')\n }\n />\n </ul>\n ) : (\n <p className=\"text-sm text-muted\">…</p>\n )}\n </section>\n\n {/* Sender allowlist */}\n <ControlCard\n title={t('security.sender.title')}\n description={t('security.sender.description')}\n envKey=\"AGIM_ALLOWED_USERS\"\n >\n <Input\n defaultValue={env.AGIM_ALLOWED_USERS ?? ''}\n placeholder={t('security.sender.placeholder')}\n onBlur={(e) => {\n const v = e.target.value.trim()\n void setValue('AGIM_ALLOWED_USERS', v === '' ? null : v)\n }}\n />\n </ControlCard>\n\n {/* Exec sandbox */}\n <ControlCard\n title={t('security.exec.title')}\n description={t('security.exec.description')}\n >\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <LabeledField label={t('security.exec.sandbox')}>\n <Select\n value={(env.AGIM_EXEC_SANDBOX ?? '').toLowerCase() === 'bwrap' ? 'bwrap' : '__none__'}\n onValueChange={(v) => void setValue('AGIM_EXEC_SANDBOX', v === '__none__' ? null : v)}\n >\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__none__\">{t('security.exec.sandboxNone')}</SelectItem>\n <SelectItem\n value=\"bwrap\"\n disabled={!diagnostics?.bwrapAvailable}\n >\n {t('security.exec.sandboxBwrap')}\n {!diagnostics?.bwrapAvailable && (\n <span className=\"ml-2 text-xs text-muted\">\n ({t('security.exec.sandboxBwrapMissing')})\n </span>\n )}\n </SelectItem>\n </SelectContent>\n </Select>\n </LabeledField>\n\n <LabeledField label={t('security.exec.sandboxNet')}>\n <Select\n value={(env.AGIM_EXEC_SANDBOX_NET ?? '').toLowerCase() === 'off' ? 'off' : 'on'}\n onValueChange={(v) => void setValue('AGIM_EXEC_SANDBOX_NET', v === 'off' ? 'off' : null)}\n >\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"on\">{t('security.exec.sandboxNetOn')}</SelectItem>\n <SelectItem value=\"off\">{t('security.exec.sandboxNetOff')}</SelectItem>\n </SelectContent>\n </Select>\n </LabeledField>\n\n <LabeledField label={t('security.exec.timeoutMs')}>\n <Input\n type=\"number\"\n defaultValue={env.AGIM_EXEC_TIMEOUT_MS ?? ''}\n placeholder=\"60000\"\n onBlur={(e) => {\n const v = e.target.value.trim()\n void setValue('AGIM_EXEC_TIMEOUT_MS', v === '' ? null : v)\n }}\n />\n </LabeledField>\n\n <LabeledField label={t('security.exec.maxOutput')}>\n <Input\n type=\"number\"\n defaultValue={env.AGIM_EXEC_MAX_OUTPUT ?? ''}\n placeholder=\"32768\"\n onBlur={(e) => {\n const v = e.target.value.trim()\n void setValue('AGIM_EXEC_MAX_OUTPUT', v === '' ? null : v)\n }}\n />\n </LabeledField>\n </div>\n </ControlCard>\n\n {/* Web SSRF */}\n <ControlCard\n title={t('security.web.title')}\n description={t('security.web.description')}\n >\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <LabeledField label={t('security.web.allowPrivate')} hint={t('security.web.allowPrivateHelp')}>\n <Select\n value={envBool(env.AGIM_NATIVE_WEB_ALLOW_PRIVATE) ? '1' : '0'}\n onValueChange={(v) => void setValue('AGIM_NATIVE_WEB_ALLOW_PRIVATE', v === '1' ? '1' : null)}\n >\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"0\">OFF</SelectItem>\n <SelectItem value=\"1\">ON</SelectItem>\n </SelectContent>\n </Select>\n </LabeledField>\n\n <LabeledField label={t('security.web.timeoutMs')}>\n <Input\n type=\"number\"\n defaultValue={env.AGIM_NATIVE_WEB_TIMEOUT_MS ?? ''}\n placeholder=\"30000\"\n onBlur={(e) => {\n const v = e.target.value.trim()\n void setValue('AGIM_NATIVE_WEB_TIMEOUT_MS', v === '' ? null : v)\n }}\n />\n </LabeledField>\n\n <div className=\"sm:col-span-2\">\n <LabeledField label={t('security.web.ssrfWhitelist')}>\n <Input\n defaultValue={env.AGIM_NATIVE_WEB_SSRF_WHITELIST ?? ''}\n placeholder={t('security.web.ssrfWhitelistPlaceholder')}\n onBlur={(e) => {\n const v = e.target.value.trim()\n void setValue('AGIM_NATIVE_WEB_SSRF_WHITELIST', v === '' ? null : v)\n }}\n />\n </LabeledField>\n </div>\n </div>\n </ControlCard>\n\n {/* FS */}\n <ControlCard\n title={t('security.fs.title')}\n description={t('security.fs.description')}\n >\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <LabeledField label={t('security.fs.restrict')}>\n <Select\n value={(env.AGIM_NATIVE_FS_RESTRICT ?? '0') === '1' ? '1' : '0'}\n onValueChange={(v) => void setValue('AGIM_NATIVE_FS_RESTRICT', v === '1' ? '1' : null)}\n >\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"1\">{t('security.fs.restrictOn')}</SelectItem>\n <SelectItem value=\"0\">{t('security.fs.restrictOff')}</SelectItem>\n </SelectContent>\n </Select>\n </LabeledField>\n\n <LabeledField label={t('security.fs.timeoutMs')}>\n <Input\n type=\"number\"\n defaultValue={env.AGIM_NATIVE_FS_TIMEOUT_MS ?? ''}\n placeholder=\"60000\"\n onBlur={(e) => {\n const v = e.target.value.trim()\n void setValue('AGIM_NATIVE_FS_TIMEOUT_MS', v === '' ? null : v)\n }}\n />\n </LabeledField>\n </div>\n </ControlCard>\n\n {/* Delegation cap */}\n <ControlCard\n title={t('security.delegation.title')}\n description={t('security.delegation.description')}\n envKey=\"AGIM_NATIVE_CALL_AGENT_MAX_PER_TURN\"\n >\n <Input\n type=\"number\"\n defaultValue={env.AGIM_NATIVE_CALL_AGENT_MAX_PER_TURN ?? ''}\n placeholder=\"2\"\n onBlur={(e) => {\n const v = e.target.value.trim()\n void setValue('AGIM_NATIVE_CALL_AGENT_MAX_PER_TURN', v === '' ? null : v)\n }}\n />\n </ControlCard>\n\n {/* IM platform blacklist */}\n <ControlCard\n title={t('security.platformBlacklist.title')}\n description={t('security.platformBlacklist.description')}\n envKey=\"AGIM_PLATFORM_BLACKLIST\"\n >\n <Input\n defaultValue={env.AGIM_PLATFORM_BLACKLIST ?? ''}\n placeholder={t('security.platformBlacklist.placeholder')}\n onBlur={(e) => {\n const v = e.target.value.trim()\n void setValue('AGIM_PLATFORM_BLACKLIST', v === '' ? null : v)\n }}\n />\n {diagnostics?.platformBlacklist && diagnostics.platformBlacklist.length > 0 && (\n <p className=\"mt-2 text-[10px] text-muted\">\n {t('security.platformBlacklist.currentLabel')}: {diagnostics.platformBlacklist.join(', ')}\n </p>\n )}\n </ControlCard>\n </div>\n )\n}\n\nfunction DiagRow({ label, ok, text }: { label: string; ok: boolean; text: string }): JSX.Element {\n return (\n <li className=\"flex items-start gap-2\">\n {ok\n ? <CheckCircle2 className=\"mt-0.5 h-4 w-4 shrink-0 text-success\" />\n : <AlertTriangle className=\"mt-0.5 h-4 w-4 shrink-0 text-warning\" />\n }\n <div className=\"flex-1\">\n <div className=\"font-medium\">{label}</div>\n <div className={cn('text-xs', ok ? 'text-muted' : 'text-warning')}>{text}</div>\n </div>\n </li>\n )\n}\n\nfunction ControlCard({\n title, description, envKey, children,\n}: { title: string; description: string; envKey?: string; children: React.ReactNode }): JSX.Element {\n return (\n <section className=\"rounded-lg border border-border bg-card p-4\">\n <div className=\"mb-2 flex flex-wrap items-baseline gap-2\">\n <h2 className=\"text-sm font-semibold\">{title}</h2>\n {envKey && <Badge variant=\"outline\" className=\"font-mono text-[10px]\">{envKey}</Badge>}\n </div>\n <p className=\"mb-3 text-xs text-muted\">{description}</p>\n {children}\n </section>\n )\n}\n\nfunction LabeledField({\n label, hint, children,\n}: { label: string; hint?: string; children: React.ReactNode }): JSX.Element {\n return (\n <div className=\"flex flex-col gap-1\">\n <label className=\"text-xs font-medium text-muted\">{label}</label>\n {children}\n {hint && <p className=\"text-[10px] text-muted\">{hint}</p>}\n </div>\n )\n}\n"],"names":["envBool","v","t","SettingsSecurityRoute","useTranslation","envQuery","useEnv","updateEnv","useUpdateEnv","diagnostics","setDiagnostics","useState","diagLoading","setDiagLoading","loadDiagnostics","res","client","err","toast","describeError","useEffect","setValue","key","value","env","jsxs","jsx","Button","Loader2","RefreshCcw","ShieldAlert","DiagRow","ControlCard","Input","e","LabeledField","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","label","ok","text","CheckCircle2","AlertTriangle","cn","title","description","envKey","children","Badge","hint"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import{o as z,u as P,j as e,B as f,l as L,R as T,c as w,m,n as v,X as U,L as _,I as O}from"./index-DY2Zglku.js";import{r as p}from"./react-DlP5eolq.js";import{C as y}from"./confirm-dialog-CgpJL9oN.js";import{j as B,k as W,l as q,m as M,a as H,c as Q}from"./use-settings-Co-iafXD.js";import{L as S}from"./loader-circle-D8L1w9c1.js";import{R as V}from"./refresh-ccw-7HdadG5V.js";import{P as X}from"./play-Di1jqulh.js";import{N as $}from"./network-BBdRdrH_.js";import{S as G}from"./save-BYFmz9gD.js";/**
1
+ import{o as z,u as P,j as e,B as f,l as L,R as T,c as w,m,n as v,X as U,L as _,I as O}from"./index-DHh1LYlA.js";import{r as p}from"./react-DlP5eolq.js";import{C as y}from"./confirm-dialog-gPKJnvEW.js";import{j as B,k as W,l as q,m as M,a as H,c as Q}from"./use-settings-DKbDqCEJ.js";import{L as S}from"./loader-circle-DgdBWYl0.js";import{R as V}from"./refresh-ccw-nBMm5Xal.js";import{P as X}from"./play-CPoE_JnS.js";import{N as $}from"./network--s113Jkm.js";import{S as G}from"./save-DbrrCFDM.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
6
  */const J=z("Square",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]]),K={systemd:"success",background:"info",foreground:"warning",none:"default"},C=3e3,k=9090;function oe(){const{t:s}=P(["settings","common"]),r=B(),t=r.data,a=t&&t.mode!=="none",i=W(),n=q(),o=M(),[u,x]=p.useState(!1),[h,g]=p.useState(!1);async function b(){try{await i.mutateAsync(),m.success(s("service.toast.started"))}catch(c){m.error(v(c,s).message)}}async function d(){try{await n.mutateAsync(),m.success(s("service.toast.stopped"))}catch(c){throw m.error(v(c,s).message),c}}async function l(){try{await o.mutateAsync(),m.success(s("service.toast.restarted"))}catch(c){throw m.error(v(c,s).message),c}}return e.jsxs("div",{className:"mx-auto flex max-w-3xl 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("service.title")}),e.jsxs(f,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>r.refetch(),disabled:r.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[r.isFetching?e.jsx(S,{className:"h-4 w-4 animate-spin"}):e.jsx(V,{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("service.subtitle")})]}),e.jsx(Y,{}),r.isLoading?e.jsx("div",{className:"h-48 rounded-md bg-surface-2 animate-pulse"}):t?e.jsxs("div",{className:"rounded-md border border-border bg-surface p-4",children:[e.jsxs("dl",{className:"grid grid-cols-[max-content_1fr] gap-x-4 gap-y-2 text-sm",children:[e.jsx("dt",{className:"text-text-dim",children:s("service.modeLabel")}),e.jsx("dd",{children:e.jsx(L,{variant:K[t.mode],children:s(`service.mode.${t.mode}`)})}),t.pid!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:s("service.pidLabel")}),e.jsx("dd",{className:"tabular-nums font-mono",children:t.pid})]}),t.uptime&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:s("service.uptimeLabel")}),e.jsx("dd",{className:"tabular-nums",children:t.uptime})]}),t.web&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:s("service.webLabel")}),e.jsxs("dd",{className:"font-mono text-xs",children:[t.web.bind,":",t.web.port]})]}),e.jsx("dt",{className:"text-text-dim",children:s("service.bootPhaseLabel")}),e.jsx("dd",{children:e.jsx("code",{className:"rounded bg-surface-2 px-1.5 py-0.5 text-xs",children:t.bootPhase})})]}),e.jsxs("div",{className:"mt-4 flex flex-wrap gap-2",children:[e.jsxs(f,{type:"button",variant:"default",size:"sm",disabled:a||i.isPending,onClick:()=>void b(),children:[i.isPending?e.jsx(S,{className:"h-4 w-4 animate-spin"}):e.jsx(X,{className:"h-4 w-4"}),s("service.actions.start")]}),e.jsxs(f,{type:"button",variant:"outline",size:"sm",disabled:!a||o.isPending,onClick:()=>g(!0),children:[e.jsx(T,{className:w("h-4 w-4",o.isPending&&"animate-spin")}),s("service.actions.restart")]}),e.jsxs(f,{type:"button",variant:"destructive",size:"sm",disabled:!a||n.isPending,onClick:()=>x(!0),children:[e.jsx(J,{className:"h-4 w-4"}),s("service.actions.stop")]})]})]}):null,e.jsx(y,{open:u,onOpenChange:x,title:s("service.actions.confirmStop"),description:s("service.actions.confirmStopDesc"),intent:"danger",confirmLabel:s("service.actions.stop"),onConfirm:d}),e.jsx(y,{open:h,onOpenChange:g,title:s("service.actions.confirmRestart"),description:s("service.actions.confirmRestartDesc"),intent:"danger",confirmLabel:s("service.actions.restart"),onConfirm:l})]})}function A(s){const r=s.trim();if(!r)return{ok:!0,value:void 0};const t=Number.parseInt(r,10);return!Number.isFinite(t)||t<1||t>65535?{ok:!1}:{ok:!0,value:t}}function Y(){const{t:s}=P(["settings","common"]),r=H(),t=Q(),a=r.data,i=a?.webPort,n=a?.acpPort,[o,u]=p.useState(""),[x,h]=p.useState(""),[g,b]=p.useState(0);p.useEffect(()=>{a&&r.dataUpdatedAt!==g&&(u(i!=null?String(i):""),h(n!=null?String(n):""),b(r.dataUpdatedAt))},[a,r.dataUpdatedAt,i,n,g]);const d=A(o),l=A(x),c=!d.ok,j=!l.ok,D=p.useMemo(()=>{if(!a)return!1;const N=d.ok?d.value:void 0,I=l.ok?l.value:void 0;return N!==i||I!==n},[a,d,l,i,n]);function F(){u(i!=null?String(i):""),h(n!=null?String(n):"")}async function E(){if(!(!a||c||j))try{await t.mutateAsync({...a,webPort:d.ok?d.value:void 0,acpPort:l.ok?l.value:void 0}),m.success(s("service.ports.toast.saved"))}catch(N){m.error(v(N,s).message)}}return r.isLoading?e.jsx("div",{className:"h-32 rounded-md bg-surface-2 animate-pulse"}):e.jsxs("section",{className:"rounded-md border border-border bg-surface",children:[e.jsxs("header",{className:"flex items-center gap-2 border-b border-border px-4 py-3",children:[e.jsx($,{className:"h-4 w-4 text-text-dim"}),e.jsx("h2",{className:"text-sm font-semibold",children:s("service.ports.title")})]}),e.jsx("p",{className:"px-4 pt-2 text-xs text-text-dim",children:s("service.ports.subtitle")}),e.jsxs("div",{className:"grid grid-cols-1 gap-3 px-4 py-3 sm:grid-cols-2",children:[e.jsx(R,{id:"web-port",label:s("service.ports.webPort"),hint:s("service.ports.webPortHint",{default:C}),value:o,onChange:u,invalid:c,placeholder:String(C)}),a?.features?.remoteAgent?e.jsx(R,{id:"acp-port",label:s("service.ports.acpPort"),hint:s("service.ports.acpPortHint",{default:k}),value:x,onChange:h,invalid:j,placeholder:String(k)}):null]}),D&&e.jsxs("div",{className:"flex items-center gap-2 border-t border-border px-4 py-3",children:[e.jsx(L,{variant:"warning",children:s("service.ports.restartRequired")}),e.jsxs(f,{variant:"ghost",size:"sm",className:"ml-auto",onClick:F,disabled:t.isPending,children:[e.jsx(U,{className:"h-4 w-4"}),s("service.ports.discard")]}),e.jsxs(f,{size:"sm",onClick:()=>void E(),disabled:t.isPending||c||j,children:[t.isPending?e.jsx(S,{className:"h-4 w-4 animate-spin"}):e.jsx(G,{className:"h-4 w-4"}),t.isPending?s("service.ports.saving"):s("service.ports.save")]})]})]})}function R({id:s,label:r,hint:t,value:a,onChange:i,invalid:n,placeholder:o}){const{t:u}=P("settings");return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(_,{htmlFor:s,className:"text-xs font-medium",children:r}),e.jsx(O,{id:s,type:"number",inputMode:"numeric",min:1,max:65535,value:a,onChange:x=>i(x.target.value),placeholder:o,"aria-invalid":n,className:w("font-mono",n&&"border-danger focus:ring-danger")}),e.jsx("p",{className:w("text-[11px]",n?"text-danger":"text-text-dim"),children:n?u("service.ports.invalidPort"):t})]})}export{oe as default};
7
- //# sourceMappingURL=service-BsY8CaNG.js.map
7
+ //# sourceMappingURL=service-CnorFHzZ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"service-BsY8CaNG.js","sources":["../../node_modules/lucide-react/dist/esm/icons/square.js","../../src/routes/settings/service.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 Square = createLucideIcon(\"Square\", [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }]\n]);\n\nexport { Square as default };\n//# sourceMappingURL=square.js.map\n","/**\n * /settings/service — operator-facing process control: see the\n * running agim daemon's mode/pid/uptime + start, stop, or restart it.\n *\n * R8 (this round) added a dedicated \"Ports\" card at the top covering\n * webPort + acpPort. They live in `~/.agim/config.json` (PUT /api/config),\n * and take effect on the next service restart — handled by the\n * Start/Restart buttons immediately below.\n *\n * Stop and restart go through ConfirmDialog because they\n * permanently interrupt every messenger adapter + in-flight job;\n * Start is one-click since it's safe to invoke even when already\n * running (backend short-circuits to alreadyRunning:true).\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport {\n Loader2, Network, Play, RefreshCcw, RotateCcw, Save, Square, X,\n} from 'lucide-react'\n\nimport { ConfirmDialog } from '@/components/common/confirm-dialog'\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 useConfig,\n useRestartService,\n useServiceStatus,\n useStartService,\n useStopService,\n useUpdateConfig,\n} from '@/hooks/use-settings'\nimport { describeError } from '@/lib/api/errors'\nimport type { ServiceMode } from '@/types/api'\nimport { cn } from '@/lib/utils'\n\nconst MODE_VARIANT: Record<ServiceMode, 'success' | 'info' | 'warning' | 'default'> = {\n systemd: 'success',\n background: 'info',\n foreground: 'warning',\n none: 'default',\n}\n\nconst DEFAULT_WEB_PORT = 3000\nconst DEFAULT_ACP_PORT = 9090\n\nexport default function SettingsServiceRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const status = useServiceStatus()\n const data = status.data\n const isRunning = data && data.mode !== 'none'\n\n const start = useStartService()\n const stop = useStopService()\n const restart = useRestartService()\n\n const [confirmStop, setConfirmStop] = useState(false)\n const [confirmRestart, setConfirmRestart] = useState(false)\n\n async function onStart(): Promise<void> {\n try {\n await start.mutateAsync()\n toast.success(t('service.toast.started'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n async function onConfirmStop(): Promise<void> {\n try {\n await stop.mutateAsync()\n toast.success(t('service.toast.stopped'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n throw err\n }\n }\n async function onConfirmRestart(): Promise<void> {\n try {\n await restart.mutateAsync()\n toast.success(t('service.toast.restarted'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n throw err\n }\n }\n\n return (\n <div className=\"mx-auto flex max-w-3xl 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('service.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => status.refetch()}\n disabled={status.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {status.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('service.subtitle')}</p>\n </header>\n\n <PortsCard />\n\n {status.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : data ? (\n <div className=\"rounded-md border border-border bg-surface p-4\">\n <dl className=\"grid grid-cols-[max-content_1fr] gap-x-4 gap-y-2 text-sm\">\n <dt className=\"text-text-dim\">{t('service.modeLabel')}</dt>\n <dd>\n <Badge variant={MODE_VARIANT[data.mode]}>\n {t(`service.mode.${data.mode}`)}\n </Badge>\n </dd>\n {data.pid != null && (\n <>\n <dt className=\"text-text-dim\">{t('service.pidLabel')}</dt>\n <dd className=\"tabular-nums font-mono\">{data.pid}</dd>\n </>\n )}\n {data.uptime && (\n <>\n <dt className=\"text-text-dim\">{t('service.uptimeLabel')}</dt>\n <dd className=\"tabular-nums\">{data.uptime}</dd>\n </>\n )}\n {data.web && (\n <>\n <dt className=\"text-text-dim\">{t('service.webLabel')}</dt>\n <dd className=\"font-mono text-xs\">{data.web.bind}:{data.web.port}</dd>\n </>\n )}\n <dt className=\"text-text-dim\">{t('service.bootPhaseLabel')}</dt>\n <dd>\n <code className=\"rounded bg-surface-2 px-1.5 py-0.5 text-xs\">{data.bootPhase}</code>\n </dd>\n </dl>\n\n {/* Action buttons */}\n <div className=\"mt-4 flex flex-wrap gap-2\">\n <Button\n type=\"button\"\n variant=\"default\"\n size=\"sm\"\n disabled={isRunning || start.isPending}\n onClick={() => void onStart()}\n >\n {start.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Play className=\"h-4 w-4\" />}\n {t('service.actions.start')}\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={!isRunning || restart.isPending}\n onClick={() => setConfirmRestart(true)}\n >\n <RotateCcw className={cn('h-4 w-4', restart.isPending && 'animate-spin')} />\n {t('service.actions.restart')}\n </Button>\n <Button\n type=\"button\"\n variant=\"destructive\"\n size=\"sm\"\n disabled={!isRunning || stop.isPending}\n onClick={() => setConfirmStop(true)}\n >\n <Square className=\"h-4 w-4\" />\n {t('service.actions.stop')}\n </Button>\n </div>\n </div>\n ) : null}\n\n <ConfirmDialog\n open={confirmStop}\n onOpenChange={setConfirmStop}\n title={t('service.actions.confirmStop')}\n description={t('service.actions.confirmStopDesc')}\n intent=\"danger\"\n confirmLabel={t('service.actions.stop')}\n onConfirm={onConfirmStop}\n />\n <ConfirmDialog\n open={confirmRestart}\n onOpenChange={setConfirmRestart}\n title={t('service.actions.confirmRestart')}\n description={t('service.actions.confirmRestartDesc')}\n intent=\"danger\"\n confirmLabel={t('service.actions.restart')}\n onConfirm={onConfirmRestart}\n />\n </div>\n )\n}\n\n/* ─────────────── Ports card (webPort + acpPort) ─────────────── */\n\n/** Validate a port string. Empty = \"use the default\", which we\n * represent on the wire as `undefined` (omitted field). Non-empty\n * must parse to 1..65535. */\nfunction parsePort(s: string): { ok: true; value: number | undefined } | { ok: false } {\n const trimmed = s.trim()\n if (!trimmed) return { ok: true, value: undefined }\n const n = Number.parseInt(trimmed, 10)\n if (!Number.isFinite(n) || n < 1 || n > 65535) return { ok: false }\n return { ok: true, value: n }\n}\n\nfunction PortsCard(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const cfgQuery = useConfig()\n const updateCfg = useUpdateConfig()\n\n const cfg = cfgQuery.data\n const currentWeb = cfg?.webPort\n const currentAcp = cfg?.acpPort\n\n const [webDraft, setWebDraft] = useState<string>('')\n const [acpDraft, setAcpDraft] = useState<string>('')\n // Tracks the cfg snapshot we last synced from, so post-save refetch\n // re-hydrates the drafts cleanly (and so local edits don't get\n // clobbered by background refetches).\n const [syncedAt, setSyncedAt] = useState<number>(0)\n\n useEffect(() => {\n if (!cfg) return\n if (cfgQuery.dataUpdatedAt === syncedAt) return\n setWebDraft(currentWeb != null ? String(currentWeb) : '')\n setAcpDraft(currentAcp != null ? String(currentAcp) : '')\n setSyncedAt(cfgQuery.dataUpdatedAt)\n }, [cfg, cfgQuery.dataUpdatedAt, currentWeb, currentAcp, syncedAt])\n\n const webParsed = parsePort(webDraft)\n const acpParsed = parsePort(acpDraft)\n const webInvalid = !webParsed.ok\n const acpInvalid = !acpParsed.ok\n\n const isDirty = useMemo(() => {\n if (!cfg) return false\n const nextWeb = webParsed.ok ? webParsed.value : undefined\n const nextAcp = acpParsed.ok ? acpParsed.value : undefined\n return nextWeb !== currentWeb || nextAcp !== currentAcp\n }, [cfg, webParsed, acpParsed, currentWeb, currentAcp])\n\n function onDiscard(): void {\n setWebDraft(currentWeb != null ? String(currentWeb) : '')\n setAcpDraft(currentAcp != null ? String(currentAcp) : '')\n }\n\n async function onSave(): Promise<void> {\n if (!cfg || webInvalid || acpInvalid) return\n try {\n await updateCfg.mutateAsync({\n ...cfg,\n webPort: webParsed.ok ? webParsed.value : undefined,\n acpPort: acpParsed.ok ? acpParsed.value : undefined,\n })\n toast.success(t('service.ports.toast.saved'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n if (cfgQuery.isLoading) {\n return <div className=\"h-32 rounded-md bg-surface-2 animate-pulse\" />\n }\n\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('service.ports.title')}</h2>\n </header>\n <p className=\"px-4 pt-2 text-xs text-text-dim\">{t('service.ports.subtitle')}</p>\n\n <div className=\"grid grid-cols-1 gap-3 px-4 py-3 sm:grid-cols-2\">\n <PortField\n id=\"web-port\"\n label={t('service.ports.webPort')}\n hint={t('service.ports.webPortHint', { default: DEFAULT_WEB_PORT })}\n value={webDraft}\n onChange={setWebDraft}\n invalid={webInvalid}\n placeholder={String(DEFAULT_WEB_PORT)}\n />\n {/* R15 — acpPort hidden when remote-agent feature is off (same\n gate as the ACP card in /settings/agents). Server already\n strips acpPort from GET /api/config and drops it from\n incoming PUT in the off state. */}\n {cfg?.features?.remoteAgent ? (\n <PortField\n id=\"acp-port\"\n label={t('service.ports.acpPort')}\n hint={t('service.ports.acpPortHint', { default: DEFAULT_ACP_PORT })}\n value={acpDraft}\n onChange={setAcpDraft}\n invalid={acpInvalid}\n placeholder={String(DEFAULT_ACP_PORT)}\n />\n ) : null}\n </div>\n\n {isDirty && (\n <div className=\"flex items-center gap-2 border-t border-border px-4 py-3\">\n <Badge variant=\"warning\">{t('service.ports.restartRequired')}</Badge>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={onDiscard}\n disabled={updateCfg.isPending}\n >\n <X className=\"h-4 w-4\" />\n {t('service.ports.discard')}\n </Button>\n <Button\n size=\"sm\"\n onClick={() => void onSave()}\n disabled={updateCfg.isPending || webInvalid || acpInvalid}\n >\n {updateCfg.isPending\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <Save className=\"h-4 w-4\" />}\n {updateCfg.isPending ? t('service.ports.saving') : t('service.ports.save')}\n </Button>\n </div>\n )}\n </section>\n )\n}\n\ninterface PortFieldProps {\n id: string\n label: string\n hint: string\n value: string\n onChange: (v: string) => void\n invalid: boolean\n placeholder: string\n}\n\nfunction PortField({\n id, label, hint, value, onChange, invalid, placeholder,\n}: PortFieldProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor={id} className=\"text-xs font-medium\">{label}</Label>\n <Input\n id={id}\n type=\"number\"\n inputMode=\"numeric\"\n min={1}\n max={65535}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n placeholder={placeholder}\n aria-invalid={invalid}\n className={cn('font-mono', invalid && 'border-danger focus:ring-danger')}\n />\n <p className={cn('text-[11px]', invalid ? 'text-danger' : 'text-text-dim')}>\n {invalid ? t('service.ports.invalidPort') : hint}\n </p>\n </div>\n )\n}\n"],"names":["Square","createLucideIcon","MODE_VARIANT","DEFAULT_WEB_PORT","DEFAULT_ACP_PORT","SettingsServiceRoute","t","useTranslation","status","useServiceStatus","data","isRunning","start","useStartService","stop","useStopService","restart","useRestartService","confirmStop","setConfirmStop","useState","confirmRestart","setConfirmRestart","onStart","toast","err","describeError","onConfirmStop","onConfirmRestart","jsxs","jsx","Button","Loader2","RefreshCcw","PortsCard","Badge","Fragment","Play","RotateCcw","cn","ConfirmDialog","parsePort","trimmed","n","cfgQuery","useConfig","updateCfg","useUpdateConfig","cfg","currentWeb","currentAcp","webDraft","setWebDraft","acpDraft","setAcpDraft","syncedAt","setSyncedAt","useEffect","webParsed","acpParsed","webInvalid","acpInvalid","isDirty","useMemo","nextWeb","nextAcp","onDiscard","onSave","Network","PortField","X","Save","id","label","hint","value","onChange","invalid","placeholder","Label","Input","e"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"service-CnorFHzZ.js","sources":["../../node_modules/lucide-react/dist/esm/icons/square.js","../../src/routes/settings/service.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 Square = createLucideIcon(\"Square\", [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }]\n]);\n\nexport { Square as default };\n//# sourceMappingURL=square.js.map\n","/**\n * /settings/service — operator-facing process control: see the\n * running agim daemon's mode/pid/uptime + start, stop, or restart it.\n *\n * R8 (this round) added a dedicated \"Ports\" card at the top covering\n * webPort + acpPort. They live in `~/.agim/config.json` (PUT /api/config),\n * and take effect on the next service restart — handled by the\n * Start/Restart buttons immediately below.\n *\n * Stop and restart go through ConfirmDialog because they\n * permanently interrupt every messenger adapter + in-flight job;\n * Start is one-click since it's safe to invoke even when already\n * running (backend short-circuits to alreadyRunning:true).\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport {\n Loader2, Network, Play, RefreshCcw, RotateCcw, Save, Square, X,\n} from 'lucide-react'\n\nimport { ConfirmDialog } from '@/components/common/confirm-dialog'\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 useConfig,\n useRestartService,\n useServiceStatus,\n useStartService,\n useStopService,\n useUpdateConfig,\n} from '@/hooks/use-settings'\nimport { describeError } from '@/lib/api/errors'\nimport type { ServiceMode } from '@/types/api'\nimport { cn } from '@/lib/utils'\n\nconst MODE_VARIANT: Record<ServiceMode, 'success' | 'info' | 'warning' | 'default'> = {\n systemd: 'success',\n background: 'info',\n foreground: 'warning',\n none: 'default',\n}\n\nconst DEFAULT_WEB_PORT = 3000\nconst DEFAULT_ACP_PORT = 9090\n\nexport default function SettingsServiceRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const status = useServiceStatus()\n const data = status.data\n const isRunning = data && data.mode !== 'none'\n\n const start = useStartService()\n const stop = useStopService()\n const restart = useRestartService()\n\n const [confirmStop, setConfirmStop] = useState(false)\n const [confirmRestart, setConfirmRestart] = useState(false)\n\n async function onStart(): Promise<void> {\n try {\n await start.mutateAsync()\n toast.success(t('service.toast.started'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n async function onConfirmStop(): Promise<void> {\n try {\n await stop.mutateAsync()\n toast.success(t('service.toast.stopped'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n throw err\n }\n }\n async function onConfirmRestart(): Promise<void> {\n try {\n await restart.mutateAsync()\n toast.success(t('service.toast.restarted'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n throw err\n }\n }\n\n return (\n <div className=\"mx-auto flex max-w-3xl 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('service.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => status.refetch()}\n disabled={status.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {status.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('service.subtitle')}</p>\n </header>\n\n <PortsCard />\n\n {status.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : data ? (\n <div className=\"rounded-md border border-border bg-surface p-4\">\n <dl className=\"grid grid-cols-[max-content_1fr] gap-x-4 gap-y-2 text-sm\">\n <dt className=\"text-text-dim\">{t('service.modeLabel')}</dt>\n <dd>\n <Badge variant={MODE_VARIANT[data.mode]}>\n {t(`service.mode.${data.mode}`)}\n </Badge>\n </dd>\n {data.pid != null && (\n <>\n <dt className=\"text-text-dim\">{t('service.pidLabel')}</dt>\n <dd className=\"tabular-nums font-mono\">{data.pid}</dd>\n </>\n )}\n {data.uptime && (\n <>\n <dt className=\"text-text-dim\">{t('service.uptimeLabel')}</dt>\n <dd className=\"tabular-nums\">{data.uptime}</dd>\n </>\n )}\n {data.web && (\n <>\n <dt className=\"text-text-dim\">{t('service.webLabel')}</dt>\n <dd className=\"font-mono text-xs\">{data.web.bind}:{data.web.port}</dd>\n </>\n )}\n <dt className=\"text-text-dim\">{t('service.bootPhaseLabel')}</dt>\n <dd>\n <code className=\"rounded bg-surface-2 px-1.5 py-0.5 text-xs\">{data.bootPhase}</code>\n </dd>\n </dl>\n\n {/* Action buttons */}\n <div className=\"mt-4 flex flex-wrap gap-2\">\n <Button\n type=\"button\"\n variant=\"default\"\n size=\"sm\"\n disabled={isRunning || start.isPending}\n onClick={() => void onStart()}\n >\n {start.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Play className=\"h-4 w-4\" />}\n {t('service.actions.start')}\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={!isRunning || restart.isPending}\n onClick={() => setConfirmRestart(true)}\n >\n <RotateCcw className={cn('h-4 w-4', restart.isPending && 'animate-spin')} />\n {t('service.actions.restart')}\n </Button>\n <Button\n type=\"button\"\n variant=\"destructive\"\n size=\"sm\"\n disabled={!isRunning || stop.isPending}\n onClick={() => setConfirmStop(true)}\n >\n <Square className=\"h-4 w-4\" />\n {t('service.actions.stop')}\n </Button>\n </div>\n </div>\n ) : null}\n\n <ConfirmDialog\n open={confirmStop}\n onOpenChange={setConfirmStop}\n title={t('service.actions.confirmStop')}\n description={t('service.actions.confirmStopDesc')}\n intent=\"danger\"\n confirmLabel={t('service.actions.stop')}\n onConfirm={onConfirmStop}\n />\n <ConfirmDialog\n open={confirmRestart}\n onOpenChange={setConfirmRestart}\n title={t('service.actions.confirmRestart')}\n description={t('service.actions.confirmRestartDesc')}\n intent=\"danger\"\n confirmLabel={t('service.actions.restart')}\n onConfirm={onConfirmRestart}\n />\n </div>\n )\n}\n\n/* ─────────────── Ports card (webPort + acpPort) ─────────────── */\n\n/** Validate a port string. Empty = \"use the default\", which we\n * represent on the wire as `undefined` (omitted field). Non-empty\n * must parse to 1..65535. */\nfunction parsePort(s: string): { ok: true; value: number | undefined } | { ok: false } {\n const trimmed = s.trim()\n if (!trimmed) return { ok: true, value: undefined }\n const n = Number.parseInt(trimmed, 10)\n if (!Number.isFinite(n) || n < 1 || n > 65535) return { ok: false }\n return { ok: true, value: n }\n}\n\nfunction PortsCard(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const cfgQuery = useConfig()\n const updateCfg = useUpdateConfig()\n\n const cfg = cfgQuery.data\n const currentWeb = cfg?.webPort\n const currentAcp = cfg?.acpPort\n\n const [webDraft, setWebDraft] = useState<string>('')\n const [acpDraft, setAcpDraft] = useState<string>('')\n // Tracks the cfg snapshot we last synced from, so post-save refetch\n // re-hydrates the drafts cleanly (and so local edits don't get\n // clobbered by background refetches).\n const [syncedAt, setSyncedAt] = useState<number>(0)\n\n useEffect(() => {\n if (!cfg) return\n if (cfgQuery.dataUpdatedAt === syncedAt) return\n setWebDraft(currentWeb != null ? String(currentWeb) : '')\n setAcpDraft(currentAcp != null ? String(currentAcp) : '')\n setSyncedAt(cfgQuery.dataUpdatedAt)\n }, [cfg, cfgQuery.dataUpdatedAt, currentWeb, currentAcp, syncedAt])\n\n const webParsed = parsePort(webDraft)\n const acpParsed = parsePort(acpDraft)\n const webInvalid = !webParsed.ok\n const acpInvalid = !acpParsed.ok\n\n const isDirty = useMemo(() => {\n if (!cfg) return false\n const nextWeb = webParsed.ok ? webParsed.value : undefined\n const nextAcp = acpParsed.ok ? acpParsed.value : undefined\n return nextWeb !== currentWeb || nextAcp !== currentAcp\n }, [cfg, webParsed, acpParsed, currentWeb, currentAcp])\n\n function onDiscard(): void {\n setWebDraft(currentWeb != null ? String(currentWeb) : '')\n setAcpDraft(currentAcp != null ? String(currentAcp) : '')\n }\n\n async function onSave(): Promise<void> {\n if (!cfg || webInvalid || acpInvalid) return\n try {\n await updateCfg.mutateAsync({\n ...cfg,\n webPort: webParsed.ok ? webParsed.value : undefined,\n acpPort: acpParsed.ok ? acpParsed.value : undefined,\n })\n toast.success(t('service.ports.toast.saved'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n if (cfgQuery.isLoading) {\n return <div className=\"h-32 rounded-md bg-surface-2 animate-pulse\" />\n }\n\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('service.ports.title')}</h2>\n </header>\n <p className=\"px-4 pt-2 text-xs text-text-dim\">{t('service.ports.subtitle')}</p>\n\n <div className=\"grid grid-cols-1 gap-3 px-4 py-3 sm:grid-cols-2\">\n <PortField\n id=\"web-port\"\n label={t('service.ports.webPort')}\n hint={t('service.ports.webPortHint', { default: DEFAULT_WEB_PORT })}\n value={webDraft}\n onChange={setWebDraft}\n invalid={webInvalid}\n placeholder={String(DEFAULT_WEB_PORT)}\n />\n {/* R15 — acpPort hidden when remote-agent feature is off (same\n gate as the ACP card in /settings/agents). Server already\n strips acpPort from GET /api/config and drops it from\n incoming PUT in the off state. */}\n {cfg?.features?.remoteAgent ? (\n <PortField\n id=\"acp-port\"\n label={t('service.ports.acpPort')}\n hint={t('service.ports.acpPortHint', { default: DEFAULT_ACP_PORT })}\n value={acpDraft}\n onChange={setAcpDraft}\n invalid={acpInvalid}\n placeholder={String(DEFAULT_ACP_PORT)}\n />\n ) : null}\n </div>\n\n {isDirty && (\n <div className=\"flex items-center gap-2 border-t border-border px-4 py-3\">\n <Badge variant=\"warning\">{t('service.ports.restartRequired')}</Badge>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={onDiscard}\n disabled={updateCfg.isPending}\n >\n <X className=\"h-4 w-4\" />\n {t('service.ports.discard')}\n </Button>\n <Button\n size=\"sm\"\n onClick={() => void onSave()}\n disabled={updateCfg.isPending || webInvalid || acpInvalid}\n >\n {updateCfg.isPending\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <Save className=\"h-4 w-4\" />}\n {updateCfg.isPending ? t('service.ports.saving') : t('service.ports.save')}\n </Button>\n </div>\n )}\n </section>\n )\n}\n\ninterface PortFieldProps {\n id: string\n label: string\n hint: string\n value: string\n onChange: (v: string) => void\n invalid: boolean\n placeholder: string\n}\n\nfunction PortField({\n id, label, hint, value, onChange, invalid, placeholder,\n}: PortFieldProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor={id} className=\"text-xs font-medium\">{label}</Label>\n <Input\n id={id}\n type=\"number\"\n inputMode=\"numeric\"\n min={1}\n max={65535}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n placeholder={placeholder}\n aria-invalid={invalid}\n className={cn('font-mono', invalid && 'border-danger focus:ring-danger')}\n />\n <p className={cn('text-[11px]', invalid ? 'text-danger' : 'text-text-dim')}>\n {invalid ? t('service.ports.invalidPort') : hint}\n </p>\n </div>\n )\n}\n"],"names":["Square","createLucideIcon","MODE_VARIANT","DEFAULT_WEB_PORT","DEFAULT_ACP_PORT","SettingsServiceRoute","t","useTranslation","status","useServiceStatus","data","isRunning","start","useStartService","stop","useStopService","restart","useRestartService","confirmStop","setConfirmStop","useState","confirmRestart","setConfirmRestart","onStart","toast","err","describeError","onConfirmStop","onConfirmRestart","jsxs","jsx","Button","Loader2","RefreshCcw","PortsCard","Badge","Fragment","Play","RotateCcw","cn","ConfirmDialog","parsePort","trimmed","n","cfgQuery","useConfig","updateCfg","useUpdateConfig","cfg","currentWeb","currentAcp","webDraft","setWebDraft","acpDraft","setAcpDraft","syncedAt","setSyncedAt","useEffect","webParsed","acpParsed","webInvalid","acpInvalid","isDirty","useMemo","nextWeb","nextAcp","onDiscard","onSave","Network","PortField","X","Save","id","label","hint","value","onChange","invalid","placeholder","Label","Input","e"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1,7 +1,7 @@
1
- import{o as e}from"./index-DY2Zglku.js";/**
1
+ import{o as e}from"./index-DHh1LYlA.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
6
  */const t=e("ShieldAlert",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"M12 8v4",key:"1got3b"}],["path",{d:"M12 16h.01",key:"1drbdi"}]]);export{t as S};
7
- //# sourceMappingURL=shield-alert-DXGk9Rak.js.map
7
+ //# sourceMappingURL=shield-alert-WOa69jy3.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shield-alert-DXGk9Rak.js","sources":["../../node_modules/lucide-react/dist/esm/icons/shield-alert.js"],"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 ShieldAlert = createLucideIcon(\"ShieldAlert\", [\n [\n \"path\",\n {\n d: \"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\",\n key: \"oel41y\"\n }\n ],\n [\"path\", { d: \"M12 8v4\", key: \"1got3b\" }],\n [\"path\", { d: \"M12 16h.01\", key: \"1drbdi\" }]\n]);\n\nexport { ShieldAlert as default };\n//# sourceMappingURL=shield-alert.js.map\n"],"names":["ShieldAlert","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAcC,EAAiB,cAAe,CAClD,CACE,OACA,CACE,EAAG,qKACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAQ,CAAE,EACxC,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,CAC7C,CAAC","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"shield-alert-WOa69jy3.js","sources":["../../node_modules/lucide-react/dist/esm/icons/shield-alert.js"],"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 ShieldAlert = createLucideIcon(\"ShieldAlert\", [\n [\n \"path\",\n {\n d: \"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\",\n key: \"oel41y\"\n }\n ],\n [\"path\", { d: \"M12 8v4\", key: \"1got3b\" }],\n [\"path\", { d: \"M12 16h.01\", key: \"1drbdi\" }]\n]);\n\nexport { ShieldAlert as default };\n//# sourceMappingURL=shield-alert.js.map\n"],"names":["ShieldAlert","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAcC,EAAiB,cAAe,CAClD,CACE,OACA,CACE,EAAG,qKACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAQ,CAAE,EACxC,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,CAC7C,CAAC","x_google_ignoreList":[0]}
@@ -1,2 +1,2 @@
1
- import{j as r,l as c}from"./index-DY2Zglku.js";const i={succeeded:"success",completed:"success",done:"success",approved:"success",allowed:"success",delivered:"success",active:"success",running:"info",in_progress:"info",pending:"info",queued:"info",scheduled:"info",open:"info",paused:"warning",awaiting:"warning",timeout:"warning",expired:"warning",failed:"danger",error:"danger",denied:"danger",rejected:"danger",cancelled:"danger",canceled:"danger",finished:"default",closed:"default",archived:"default"};function o({status:e,variant:n,children:d,...s}){const a=n??i[e.toLowerCase()]??"default";return r.jsx(c,{variant:a,...s,children:d??e})}o.displayName="StatusBadge";export{o as S};
2
- //# sourceMappingURL=status-badge-D0nbFSom.js.map
1
+ import{j as r,l as c}from"./index-DHh1LYlA.js";const i={succeeded:"success",completed:"success",done:"success",approved:"success",allowed:"success",delivered:"success",active:"success",running:"info",in_progress:"info",pending:"info",queued:"info",scheduled:"info",open:"info",paused:"warning",awaiting:"warning",timeout:"warning",expired:"warning",failed:"danger",error:"danger",denied:"danger",rejected:"danger",cancelled:"danger",canceled:"danger",finished:"default",closed:"default",archived:"default"};function o({status:e,variant:n,children:d,...s}){const a=n??i[e.toLowerCase()]??"default";return r.jsx(c,{variant:a,...s,children:d??e})}o.displayName="StatusBadge";export{o as S};
2
+ //# sourceMappingURL=status-badge-D5xhwquL.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"status-badge-D0nbFSom.js","sources":["../../src/components/common/status-badge.tsx"],"sourcesContent":["/**\n * StatusBadge — domain status string → Badge variant + label.\n *\n * Single source of truth for the color mapping across the 4 M2 pages\n * (jobs / approvals / reminders / memos) plus the M3 observability\n * page. Without this every page would invent its own (job status\n * \"running\" mapped to \"warning\" on tasks.html, \"info\" on approvals.\n * html, \"secondary\" on observability — the kind of drift the v2\n * rewrite is supposed to eliminate).\n *\n * The label slot is intentionally a child rather than a prop: callers\n * pass i18n'd strings via `<StatusBadge status=\"running\">{t('jobs.\n * status.running')}</StatusBadge>` so the badge stays language-aware\n * without needing useTranslation here.\n *\n * Unknown status falls back to `default` variant (neutral gray pill)\n * so a backend that introduces a new state doesn't crash the page.\n */\n\nimport * as React from 'react'\nimport { Badge, type BadgeProps } from '@/components/ui/badge'\n\n/**\n * Status palette shared across domain entities. The mapping is\n * deliberately broad — both \"succeeded\" and \"completed\" land on\n * success; both \"running\" and \"in_progress\" land on info, etc. —\n * because the backend hasn't been canonicalised yet (memory.ts uses\n * one set, jobs.ts another).\n */\nconst STATUS_VARIANT: Record<string, BadgeProps['variant']> = {\n // Success-family\n succeeded: 'success',\n completed: 'success',\n done: 'success',\n approved: 'success',\n allowed: 'success',\n delivered: 'success',\n active: 'success',\n\n // In-flight\n running: 'info',\n in_progress:'info',\n pending: 'info',\n queued: 'info',\n scheduled: 'info',\n open: 'info',\n\n // Warnings (operator may need to look)\n paused: 'warning',\n awaiting: 'warning',\n timeout: 'warning',\n expired: 'warning',\n\n // Failed / errored\n failed: 'danger',\n error: 'danger',\n denied: 'danger',\n rejected: 'danger',\n cancelled: 'danger',\n canceled: 'danger',\n\n // Terminal-neutral\n finished: 'default',\n closed: 'default',\n archived: 'default',\n}\n\nexport interface StatusBadgeProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'children'> {\n status: string\n children?: React.ReactNode\n /** Force-override the auto-mapped variant. */\n variant?: BadgeProps['variant']\n}\n\nfunction StatusBadge({\n status,\n variant,\n children,\n ...rest\n}: StatusBadgeProps): JSX.Element {\n const resolved = variant ?? STATUS_VARIANT[status.toLowerCase()] ?? 'default'\n return (\n <Badge variant={resolved} {...rest}>\n {children ?? status}\n </Badge>\n )\n}\nStatusBadge.displayName = 'StatusBadge'\n\nexport { StatusBadge, STATUS_VARIANT }\n"],"names":["STATUS_VARIANT","StatusBadge","status","variant","children","rest","resolved","Badge"],"mappings":"+CA6BA,MAAMA,EAAwD,CAE5D,UAAY,UACZ,UAAY,UACZ,KAAY,UACZ,SAAY,UACZ,QAAY,UACZ,UAAY,UACZ,OAAY,UAGZ,QAAY,OACZ,YAAY,OACZ,QAAY,OACZ,OAAY,OACZ,UAAY,OACZ,KAAY,OAGZ,OAAY,UACZ,SAAY,UACZ,QAAY,UACZ,QAAY,UAGZ,OAAY,SACZ,MAAY,SACZ,OAAY,SACZ,SAAY,SACZ,UAAY,SACZ,SAAY,SAGZ,SAAY,UACZ,OAAY,UACZ,SAAY,SACd,EASA,SAASC,EAAY,CACnB,OAAAC,EACA,QAAAC,EACA,SAAAC,EACA,GAAGC,CACL,EAAkC,CAChC,MAAMC,EAAWH,GAAWH,EAAeE,EAAO,YAAA,CAAa,GAAK,UACpE,aACGK,EAAA,CAAM,QAASD,EAAW,GAAGD,EAC3B,YAAYH,EACf,CAEJ,CACAD,EAAY,YAAc"}
1
+ {"version":3,"file":"status-badge-D5xhwquL.js","sources":["../../src/components/common/status-badge.tsx"],"sourcesContent":["/**\n * StatusBadge — domain status string → Badge variant + label.\n *\n * Single source of truth for the color mapping across the 4 M2 pages\n * (jobs / approvals / reminders / memos) plus the M3 observability\n * page. Without this every page would invent its own (job status\n * \"running\" mapped to \"warning\" on tasks.html, \"info\" on approvals.\n * html, \"secondary\" on observability — the kind of drift the v2\n * rewrite is supposed to eliminate).\n *\n * The label slot is intentionally a child rather than a prop: callers\n * pass i18n'd strings via `<StatusBadge status=\"running\">{t('jobs.\n * status.running')}</StatusBadge>` so the badge stays language-aware\n * without needing useTranslation here.\n *\n * Unknown status falls back to `default` variant (neutral gray pill)\n * so a backend that introduces a new state doesn't crash the page.\n */\n\nimport * as React from 'react'\nimport { Badge, type BadgeProps } from '@/components/ui/badge'\n\n/**\n * Status palette shared across domain entities. The mapping is\n * deliberately broad — both \"succeeded\" and \"completed\" land on\n * success; both \"running\" and \"in_progress\" land on info, etc. —\n * because the backend hasn't been canonicalised yet (memory.ts uses\n * one set, jobs.ts another).\n */\nconst STATUS_VARIANT: Record<string, BadgeProps['variant']> = {\n // Success-family\n succeeded: 'success',\n completed: 'success',\n done: 'success',\n approved: 'success',\n allowed: 'success',\n delivered: 'success',\n active: 'success',\n\n // In-flight\n running: 'info',\n in_progress:'info',\n pending: 'info',\n queued: 'info',\n scheduled: 'info',\n open: 'info',\n\n // Warnings (operator may need to look)\n paused: 'warning',\n awaiting: 'warning',\n timeout: 'warning',\n expired: 'warning',\n\n // Failed / errored\n failed: 'danger',\n error: 'danger',\n denied: 'danger',\n rejected: 'danger',\n cancelled: 'danger',\n canceled: 'danger',\n\n // Terminal-neutral\n finished: 'default',\n closed: 'default',\n archived: 'default',\n}\n\nexport interface StatusBadgeProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'children'> {\n status: string\n children?: React.ReactNode\n /** Force-override the auto-mapped variant. */\n variant?: BadgeProps['variant']\n}\n\nfunction StatusBadge({\n status,\n variant,\n children,\n ...rest\n}: StatusBadgeProps): JSX.Element {\n const resolved = variant ?? STATUS_VARIANT[status.toLowerCase()] ?? 'default'\n return (\n <Badge variant={resolved} {...rest}>\n {children ?? status}\n </Badge>\n )\n}\nStatusBadge.displayName = 'StatusBadge'\n\nexport { StatusBadge, STATUS_VARIANT }\n"],"names":["STATUS_VARIANT","StatusBadge","status","variant","children","rest","resolved","Badge"],"mappings":"+CA6BA,MAAMA,EAAwD,CAE5D,UAAY,UACZ,UAAY,UACZ,KAAY,UACZ,SAAY,UACZ,QAAY,UACZ,UAAY,UACZ,OAAY,UAGZ,QAAY,OACZ,YAAY,OACZ,QAAY,OACZ,OAAY,OACZ,UAAY,OACZ,KAAY,OAGZ,OAAY,UACZ,SAAY,UACZ,QAAY,UACZ,QAAY,UAGZ,OAAY,SACZ,MAAY,SACZ,OAAY,SACZ,SAAY,SACZ,UAAY,SACZ,SAAY,SAGZ,SAAY,UACZ,OAAY,UACZ,SAAY,SACd,EASA,SAASC,EAAY,CACnB,OAAAC,EACA,QAAAC,EACA,SAAAC,EACA,GAAGC,CACL,EAAkC,CAChC,MAAMC,EAAWH,GAAWH,EAAeE,EAAO,YAAA,CAAa,GAAK,UACpE,aACGK,EAAA,CAAM,QAASD,EAAW,GAAGD,EAC3B,YAAYH,EACf,CAEJ,CACAD,EAAY,YAAc"}
@@ -1,7 +1,7 @@
1
- import{o as g,a as b,b as j,d as k,u as N,f as y,j as s,c as w,B as S,L as v,I as C}from"./index-DY2Zglku.js";import{r as L}from"./react-DlP5eolq.js";import{D as T}from"./data-table-BLYG79TX.js";import{E as I}from"./empty-state-96qpPTNg.js";import{S as A}from"./status-badge-D0nbFSom.js";import{u as D}from"./use-event-stream-I1lMFEfh.js";import{L as M}from"./loader-circle-D8L1w9c1.js";import{R as E}from"./refresh-ccw-7HdadG5V.js";import"./table-_WsrnZ_T.js";import"./arrow-up-CAiQ2jy-.js";import"./arrow-down-DxlRHrs8.js";/**
1
+ import{o as g,a as b,b as j,d as k,u as N,f as y,j as s,c as w,B as S,L as v,I as C}from"./index-DHh1LYlA.js";import{r as L}from"./react-DlP5eolq.js";import{D as T}from"./data-table-DOKUic1J.js";import{E as I}from"./empty-state-CTwOQemt.js";import{S as A}from"./status-badge-D5xhwquL.js";import{u as D}from"./use-event-stream-I1lMFEfh.js";import{L as M}from"./loader-circle-DgdBWYl0.js";import{R as E}from"./refresh-ccw-nBMm5Xal.js";import"./table-Dx65w6V0.js";import"./arrow-up-i_dEdXkz.js";import"./arrow-down-B8DkdbEY.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
6
  */const R=g("ListTree",[["path",{d:"M21 12h-8",key:"1bmf0i"}],["path",{d:"M21 6H8",key:"1pqkrb"}],["path",{d:"M21 18h-8",key:"1tm79t"}],["path",{d:"M3 6v4c0 1.1.9 2 2 2h3",key:"1ywdgy"}],["path",{d:"M3 10v6c0 1.1.9 2 2 2h3",key:"2wc746"}]]),d={all:["subtasks"],list:e=>["subtasks","list",e]};function q(e){return j({queryKey:d.list(e),queryFn:()=>k.listSubtasks(e)})}function F(){const e=b();return()=>e.invalidateQueries({queryKey:d.all})}const $={connected:"text-success",connecting:"text-text-dim",reconnecting:"text-warning",closed:"text-text-muted"};function W(){const{t:e}=N(["tasks","common"]),[a,n]=y(),r=F(),i=a.get("agent")??"",{data:m,isLoading:u,isFetching:c,refetch:x}=q(i?{agent:i}:{}),p=m?.subtasks??[],o=D({job:()=>r()});function h(t){const l=new URLSearchParams(a);t?l.set("agent",t):l.delete("agent"),n(l,{replace:!0})}const f=L.useMemo(()=>[{id:"id",header:e("subtasks.col.id"),cell:t=>s.jsxs("span",{className:"tabular-nums text-text-dim",children:["#",t.id]}),headClassName:"w-16"},{id:"agent",header:e("subtasks.col.agent"),cell:t=>s.jsx("span",{className:"font-medium",children:t.agent}),headClassName:"w-32"},{id:"prompt",header:e("subtasks.col.prompt"),cell:t=>s.jsx("span",{className:"line-clamp-2 text-text-dim",children:t.prompt}),asCardTitle:!0},{id:"status",header:e("subtasks.col.status"),cell:t=>s.jsx(A,{status:t.status,children:e(`subtasks.status.${t.status}`,{defaultValue:t.status})}),headClassName:"w-32"},{id:"parent",header:e("subtasks.col.parent"),cell:t=>s.jsxs("span",{className:"text-text-dim",children:[s.jsx("span",{className:"font-medium text-text",children:t.parentAgent}),s.jsx("span",{className:"text-text-muted",children:" / "}),s.jsx("span",{title:t.parentSessionId,children:t.parentSessionId.slice(0,8)})]}),headClassName:"w-40"},{id:"platform",header:e("subtasks.col.platform"),cell:t=>s.jsx("span",{className:"text-text-dim",children:t.platform}),headClassName:"w-28",hideOnMobile:!0},{id:"createdAt",header:e("subtasks.col.createdAt"),cell:t=>s.jsx("span",{className:"text-text-dim",children:B(t.createdAt)}),headClassName:"w-40",hideOnMobile:!0}],[e]);return s.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[s.jsxs("header",{className:"flex flex-col gap-1",children:[s.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[s.jsx("h1",{className:"text-xl font-semibold",children:e("subtasks.title")}),s.jsx("span",{className:w("text-xs font-medium tabular-nums",$[o]),children:e(`jobs.live.${o}`)}),s.jsxs(S,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>x(),disabled:c,"aria-label":e("actions.refresh",{ns:"common"}),children:[c?s.jsx(M,{className:"h-4 w-4 animate-spin"}):s.jsx(E,{className:"h-4 w-4"}),s.jsx("span",{className:"hidden sm:inline",children:e("actions.refresh",{ns:"common"})})]})]}),s.jsx("p",{className:"text-sm text-text-dim",children:e("subtasks.subtitle")})]}),s.jsx("div",{className:"flex flex-wrap items-end gap-2",children:s.jsxs("div",{className:"flex flex-col gap-1",children:[s.jsx(v,{htmlFor:"agent-filter",className:"text-xs text-text-dim",children:e("subtasks.filter.agent")}),s.jsx(C,{id:"agent-filter",value:i,onChange:t=>h(t.target.value),placeholder:e("subtasks.filter.agentAny"),className:"w-48"})]})}),s.jsx(T,{columns:f,rows:p,getRowId:t=>`${t.parentSessionId}:${t.id}`,loading:u,emptyState:s.jsx(I,{icon:s.jsx(R,{}),title:e("subtasks.empty.title"),description:e("subtasks.empty.description")})})]})}function B(e){try{const a=new Date(e);if(Number.isNaN(a.getTime()))return e;const n=new Date;return a.toDateString()===n.toDateString()?a.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit"}):a.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return e}}export{W as default};
7
- //# sourceMappingURL=subtasks-DFiAXvDp.js.map
7
+ //# sourceMappingURL=subtasks-DMRyk6YS.js.map