agim-cli 1.4.9 → 1.5.1

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 (659) hide show
  1. package/CHANGELOG.md +437 -402
  2. package/README.md +43 -7
  3. package/README.zh-CN.md +42 -7
  4. package/bin/agim_rpc.py +12 -12
  5. package/dist/cli-ui/cmd-handlers.d.ts +25 -4
  6. package/dist/cli-ui/cmd-handlers.d.ts.map +1 -1
  7. package/dist/cli-ui/cmd-handlers.js +315 -59
  8. package/dist/cli-ui/cmd-handlers.js.map +1 -1
  9. package/dist/cli-ui/config-wizard.d.ts +13 -1
  10. package/dist/cli-ui/config-wizard.d.ts.map +1 -1
  11. package/dist/cli-ui/config-wizard.js +120 -48
  12. package/dist/cli-ui/config-wizard.js.map +1 -1
  13. package/dist/cli-ui/doctor.d.ts +15 -0
  14. package/dist/cli-ui/doctor.d.ts.map +1 -0
  15. package/dist/cli-ui/doctor.js +151 -0
  16. package/dist/cli-ui/doctor.js.map +1 -0
  17. package/dist/cli-ui/entry-menu.d.ts +6 -0
  18. package/dist/cli-ui/entry-menu.d.ts.map +1 -1
  19. package/dist/cli-ui/entry-menu.js +67 -30
  20. package/dist/cli-ui/entry-menu.js.map +1 -1
  21. package/dist/cli-ui/env-file.d.ts +4 -4
  22. package/dist/cli-ui/env-file.js +13 -13
  23. package/dist/cli-ui/env-file.js.map +1 -1
  24. package/dist/cli-ui/i18n.d.ts +17 -8
  25. package/dist/cli-ui/i18n.d.ts.map +1 -1
  26. package/dist/cli-ui/i18n.js +39 -21
  27. package/dist/cli-ui/i18n.js.map +1 -1
  28. package/dist/cli-ui/lang-picker.js +1 -1
  29. package/dist/cli-ui/lang-picker.js.map +1 -1
  30. package/dist/cli-ui/paths.d.ts.map +1 -1
  31. package/dist/cli-ui/paths.js +2 -4
  32. package/dist/cli-ui/paths.js.map +1 -1
  33. package/dist/cli-ui/quickstart.d.ts +3 -0
  34. package/dist/cli-ui/quickstart.d.ts.map +1 -0
  35. package/dist/cli-ui/quickstart.js +108 -0
  36. package/dist/cli-ui/quickstart.js.map +1 -0
  37. package/dist/cli-ui/readiness.d.ts +10 -0
  38. package/dist/cli-ui/readiness.d.ts.map +1 -0
  39. package/dist/cli-ui/readiness.js +75 -0
  40. package/dist/cli-ui/readiness.js.map +1 -0
  41. package/dist/cli-ui/service.d.ts +30 -7
  42. package/dist/cli-ui/service.d.ts.map +1 -1
  43. package/dist/cli-ui/service.js +171 -77
  44. package/dist/cli-ui/service.js.map +1 -1
  45. package/dist/cli-ui/tui/app.js +2 -2
  46. package/dist/cli-ui/tui/app.js.map +1 -1
  47. package/dist/cli-ui/tui/index.js +6 -6
  48. package/dist/cli-ui/tui/index.js.map +1 -1
  49. package/dist/cli-ui/tui/mouse-stdin.js +1 -1
  50. package/dist/cli-ui/tui/mouse-stdin.js.map +1 -1
  51. package/dist/cli-ui/tui/stream-reveal.d.ts +2 -2
  52. package/dist/cli-ui/tui/stream-reveal.d.ts.map +1 -1
  53. package/dist/cli-ui/tui/stream-reveal.js +4 -4
  54. package/dist/cli-ui/tui/stream-reveal.js.map +1 -1
  55. package/dist/cli.js +118 -436
  56. package/dist/cli.js.map +1 -1
  57. package/dist/core/a2a-notify.js +5 -5
  58. package/dist/core/a2a-notify.js.map +1 -1
  59. package/dist/core/a2a.d.ts +2 -2
  60. package/dist/core/a2a.d.ts.map +1 -1
  61. package/dist/core/a2a.js +12 -12
  62. package/dist/core/a2a.js.map +1 -1
  63. package/dist/core/access-token.d.ts +1 -1
  64. package/dist/core/access-token.js +7 -7
  65. package/dist/core/access-token.js.map +1 -1
  66. package/dist/core/acp-server.d.ts.map +1 -1
  67. package/dist/core/acp-server.js +21 -7
  68. package/dist/core/acp-server.js.map +1 -1
  69. package/dist/core/admin-allowlist.js +5 -5
  70. package/dist/core/admin-allowlist.js.map +1 -1
  71. package/dist/core/agent-base.d.ts +1 -1
  72. package/dist/core/agent-base.js +3 -3
  73. package/dist/core/agent-base.js.map +1 -1
  74. package/dist/core/agent-cwd.d.ts +13 -6
  75. package/dist/core/agent-cwd.d.ts.map +1 -1
  76. package/dist/core/agent-cwd.js +72 -23
  77. package/dist/core/agent-cwd.js.map +1 -1
  78. package/dist/core/agim-paths.d.ts +1 -4
  79. package/dist/core/agim-paths.d.ts.map +1 -1
  80. package/dist/core/agim-paths.js +18 -35
  81. package/dist/core/agim-paths.js.map +1 -1
  82. package/dist/core/approval-bus.d.ts +4 -4
  83. package/dist/core/approval-bus.d.ts.map +1 -1
  84. package/dist/core/approval-bus.js +14 -14
  85. package/dist/core/approval-bus.js.map +1 -1
  86. package/dist/core/approval-router.js +2 -2
  87. package/dist/core/artifacts.js +3 -3
  88. package/dist/core/artifacts.js.map +1 -1
  89. package/dist/core/ask-user-rpc.js +1 -1
  90. package/dist/core/ask-user-rpc.js.map +1 -1
  91. package/dist/core/audit-log.js +2 -2
  92. package/dist/core/audit-log.js.map +1 -1
  93. package/dist/core/bgjob-reader.d.ts +1 -1
  94. package/dist/core/bgjob-reader.js +4 -4
  95. package/dist/core/bgjob-reader.js.map +1 -1
  96. package/dist/core/commands/approval.js +2 -2
  97. package/dist/core/commands/approval.js.map +1 -1
  98. package/dist/core/commands/builtin.d.ts.map +1 -1
  99. package/dist/core/commands/builtin.js +12 -2
  100. package/dist/core/commands/builtin.js.map +1 -1
  101. package/dist/core/commands/heartbeat.js +2 -2
  102. package/dist/core/commands/heartbeat.js.map +1 -1
  103. package/dist/core/commands/memo.js +1 -1
  104. package/dist/core/commands/memo.js.map +1 -1
  105. package/dist/core/commands/model.d.ts.map +1 -1
  106. package/dist/core/commands/model.js +32 -3
  107. package/dist/core/commands/model.js.map +1 -1
  108. package/dist/core/commands/plan.js +3 -3
  109. package/dist/core/commands/plan.js.map +1 -1
  110. package/dist/core/commands/router-compare.js +3 -3
  111. package/dist/core/commands/router-compare.js.map +1 -1
  112. package/dist/core/commands/service.d.ts.map +1 -1
  113. package/dist/core/commands/service.js +1 -3
  114. package/dist/core/commands/service.js.map +1 -1
  115. package/dist/core/commands/sessions.js +4 -4
  116. package/dist/core/commands/sessions.js.map +1 -1
  117. package/dist/core/commands/skill.js +1 -1
  118. package/dist/core/commands/skill.js.map +1 -1
  119. package/dist/core/commands/stats.js +1 -1
  120. package/dist/core/commands/stats.js.map +1 -1
  121. package/dist/core/commands/web.js +5 -5
  122. package/dist/core/commands/web.js.map +1 -1
  123. package/dist/core/config-schema.js +1 -1
  124. package/dist/core/coord-systems.d.ts +1 -1
  125. package/dist/core/coord-systems.js +4 -4
  126. package/dist/core/coord-systems.js.map +1 -1
  127. package/dist/core/event-bus.d.ts +5 -5
  128. package/dist/core/event-bus.d.ts.map +1 -1
  129. package/dist/core/event-bus.js +3 -3
  130. package/dist/core/event-bus.js.map +1 -1
  131. package/dist/core/feature-flags.d.ts +2 -2
  132. package/dist/core/feature-flags.js +4 -4
  133. package/dist/core/feature-flags.js.map +1 -1
  134. package/dist/core/goal-rpc.js +2 -2
  135. package/dist/core/goal-rpc.js.map +1 -1
  136. package/dist/core/goals.d.ts +1 -1
  137. package/dist/core/goals.js +3 -3
  138. package/dist/core/goals.js.map +1 -1
  139. package/dist/core/heartbeat-store.d.ts +1 -1
  140. package/dist/core/heartbeat-store.d.ts.map +1 -1
  141. package/dist/core/heartbeat-store.js +3 -3
  142. package/dist/core/heartbeat-store.js.map +1 -1
  143. package/dist/core/heartbeat.js +4 -4
  144. package/dist/core/heartbeat.js.map +1 -1
  145. package/dist/core/intent-llm.d.ts +2 -2
  146. package/dist/core/intent-llm.js +5 -5
  147. package/dist/core/intent-llm.js.map +1 -1
  148. package/dist/core/job-board.d.ts +5 -5
  149. package/dist/core/job-board.d.ts.map +1 -1
  150. package/dist/core/job-board.js +17 -17
  151. package/dist/core/job-board.js.map +1 -1
  152. package/dist/core/llm/agent-loop.d.ts +3 -3
  153. package/dist/core/llm/agent-loop.js +14 -14
  154. package/dist/core/llm/agent-loop.js.map +1 -1
  155. package/dist/core/llm/{imhub-dispatcher.d.ts → agim-dispatcher.d.ts} +4 -4
  156. package/dist/core/llm/agim-dispatcher.d.ts.map +1 -0
  157. package/dist/core/llm/{imhub-dispatcher.js → agim-dispatcher.js} +43 -43
  158. package/dist/core/llm/agim-dispatcher.js.map +1 -0
  159. package/dist/core/llm/agim-rpc-server.js +17 -17
  160. package/dist/core/llm/agim-rpc-server.js.map +1 -1
  161. package/dist/core/llm/anthropic-provider.js +2 -1
  162. package/dist/core/llm/anthropic-provider.js.map +1 -1
  163. package/dist/core/llm/auto-compact.d.ts +3 -3
  164. package/dist/core/llm/auto-compact.d.ts.map +1 -1
  165. package/dist/core/llm/auto-compact.js +5 -5
  166. package/dist/core/llm/auto-compact.js.map +1 -1
  167. package/dist/core/llm/builtin-dispatcher.js +3 -3
  168. package/dist/core/llm/builtin-dispatcher.js.map +1 -1
  169. package/dist/core/llm/exec-dispatcher.d.ts +2 -2
  170. package/dist/core/llm/exec-dispatcher.d.ts.map +1 -1
  171. package/dist/core/llm/exec-dispatcher.js +20 -22
  172. package/dist/core/llm/exec-dispatcher.js.map +1 -1
  173. package/dist/core/llm/fs-dispatcher.js +8 -8
  174. package/dist/core/llm/fs-dispatcher.js.map +1 -1
  175. package/dist/core/llm/goal-critic.js +4 -4
  176. package/dist/core/llm/goal-critic.js.map +1 -1
  177. package/dist/core/llm/hallucination-detector.js +2 -2
  178. package/dist/core/llm/hallucination-detector.js.map +1 -1
  179. package/dist/core/llm/mcp-client.d.ts +1 -1
  180. package/dist/core/llm/mcp-client.js +3 -3
  181. package/dist/core/llm/mcp-client.js.map +1 -1
  182. package/dist/core/llm/mcp-registry.js +3 -3
  183. package/dist/core/llm/mcp-registry.js.map +1 -1
  184. package/dist/core/llm/openai-compat-provider.d.ts +1 -1
  185. package/dist/core/llm/openai-compat-provider.js +5 -4
  186. package/dist/core/llm/openai-compat-provider.js.map +1 -1
  187. package/dist/core/llm/provider-base.d.ts +5 -5
  188. package/dist/core/llm/provider-base.d.ts.map +1 -1
  189. package/dist/core/llm/provider-base.js +1 -1
  190. package/dist/core/llm/provider-base.js.map +1 -1
  191. package/dist/core/llm/secrets.d.ts +2 -2
  192. package/dist/core/llm/secrets.d.ts.map +1 -1
  193. package/dist/core/llm/tool-dispatcher.d.ts +1 -1
  194. package/dist/core/llm/web-dispatcher.d.ts +1 -1
  195. package/dist/core/llm/web-dispatcher.js +15 -15
  196. package/dist/core/llm/web-dispatcher.js.map +1 -1
  197. package/dist/core/logger.d.ts +1 -1
  198. package/dist/core/logger.js +3 -3
  199. package/dist/core/logger.js.map +1 -1
  200. package/dist/core/memo-rpc.js +3 -3
  201. package/dist/core/memo-rpc.js.map +1 -1
  202. package/dist/core/memory-consolidate.js +4 -4
  203. package/dist/core/memory-consolidate.js.map +1 -1
  204. package/dist/core/memory-distill.js +4 -4
  205. package/dist/core/memory-distill.js.map +1 -1
  206. package/dist/core/memory-distiller.js +9 -9
  207. package/dist/core/memory-distiller.js.map +1 -1
  208. package/dist/core/memory-vector.js +9 -9
  209. package/dist/core/memory-vector.js.map +1 -1
  210. package/dist/core/memory.js +2 -2
  211. package/dist/core/memory.js.map +1 -1
  212. package/dist/core/memos.js +6 -6
  213. package/dist/core/memos.js.map +1 -1
  214. package/dist/core/message-sink.js +13 -13
  215. package/dist/core/message-sink.js.map +1 -1
  216. package/dist/core/notification-evaluator.d.ts +2 -2
  217. package/dist/core/notification-evaluator.js +4 -4
  218. package/dist/core/notification-evaluator.js.map +1 -1
  219. package/dist/core/onboarding.js +3 -3
  220. package/dist/core/onboarding.js.map +1 -1
  221. package/dist/core/outbox.js +2 -2
  222. package/dist/core/outbox.js.map +1 -1
  223. package/dist/core/persona.d.ts +1 -1
  224. package/dist/core/persona.d.ts.map +1 -1
  225. package/dist/core/persona.js +2 -2
  226. package/dist/core/persona.js.map +1 -1
  227. package/dist/core/plan-history.js +1 -1
  228. package/dist/core/plan-history.js.map +1 -1
  229. package/dist/core/plan-intent.js +5 -5
  230. package/dist/core/plan-intent.js.map +1 -1
  231. package/dist/core/plan-mode-state.d.ts +1 -1
  232. package/dist/core/plan-mode-state.js +4 -4
  233. package/dist/core/plan-mode-state.js.map +1 -1
  234. package/dist/core/push-rpc.d.ts +1 -1
  235. package/dist/core/push-rpc.js +6 -6
  236. package/dist/core/push-rpc.js.map +1 -1
  237. package/dist/core/registry.d.ts +4 -4
  238. package/dist/core/registry.js +10 -10
  239. package/dist/core/registry.js.map +1 -1
  240. package/dist/core/reminders.js +1 -1
  241. package/dist/core/reminders.js.map +1 -1
  242. package/dist/core/restart-flow.d.ts.map +1 -1
  243. package/dist/core/restart-flow.js +5 -7
  244. package/dist/core/restart-flow.js.map +1 -1
  245. package/dist/core/router.d.ts +1 -1
  246. package/dist/core/router.js +5 -5
  247. package/dist/core/router.js.map +1 -1
  248. package/dist/core/schedule.d.ts +2 -2
  249. package/dist/core/schedule.js +4 -4
  250. package/dist/core/schedule.js.map +1 -1
  251. package/dist/core/self-protect.js +3 -3
  252. package/dist/core/self-protect.js.map +1 -1
  253. package/dist/core/sender-allowlist.js +7 -7
  254. package/dist/core/sender-allowlist.js.map +1 -1
  255. package/dist/core/sensitive-paths.d.ts.map +1 -1
  256. package/dist/core/sensitive-paths.js +1 -2
  257. package/dist/core/sensitive-paths.js.map +1 -1
  258. package/dist/core/session.js +2 -2
  259. package/dist/core/session.js.map +1 -1
  260. package/dist/core/skills/builtin/ECC_NOTICE.md +1 -1
  261. package/dist/core/skills/builtin/agim-memory/SKILL.md +1 -1
  262. package/dist/core/skills/builtin/agim-reminders/SKILL.md +2 -2
  263. package/dist/core/skills/builtin/agim-self/SKILL.md +9 -9
  264. package/dist/core/skills/builtin/agim-skill-discovery/SKILL.md +5 -5
  265. package/dist/core/skills/builtin/image-generation/SKILL.md +2 -2
  266. package/dist/core/skills/builtin/long-goal/SKILL.md +7 -7
  267. package/dist/core/skills/builtin/my/SKILL.md +2 -2
  268. package/dist/core/skills/builtin/skill-creator/SKILL.md +2 -2
  269. package/dist/core/skills/loader.d.ts +4 -4
  270. package/dist/core/skills/loader.js +22 -22
  271. package/dist/core/skills/loader.js.map +1 -1
  272. package/dist/core/skills-rpc.js +1 -1
  273. package/dist/core/skills-rpc.js.map +1 -1
  274. package/dist/core/transcribe.js +13 -13
  275. package/dist/core/transcribe.js.map +1 -1
  276. package/dist/core/tunnel.js +1 -1
  277. package/dist/core/tunnel.js.map +1 -1
  278. package/dist/core/types.d.ts +2 -2
  279. package/dist/core/types.d.ts.map +1 -1
  280. package/dist/core/user-coord-prefs.js +1 -1
  281. package/dist/core/user-coord-prefs.js.map +1 -1
  282. package/dist/core/viewer-config.d.ts +8 -8
  283. package/dist/core/viewer-config.js +17 -17
  284. package/dist/core/viewer-config.js.map +1 -1
  285. package/dist/core/viewer-local.js +4 -4
  286. package/dist/core/viewer-local.js.map +1 -1
  287. package/dist/core/viewer-remote.js +1 -1
  288. package/dist/core/viewer-remote.js.map +1 -1
  289. package/dist/plugins/agents/acp/url-guard.d.ts +1 -1
  290. package/dist/plugins/agents/acp/url-guard.js +2 -2
  291. package/dist/plugins/agents/acp/url-guard.js.map +1 -1
  292. package/dist/plugins/agents/antigravity/ensure-mcp-config.d.ts +6 -6
  293. package/dist/plugins/agents/antigravity/ensure-mcp-config.d.ts.map +1 -1
  294. package/dist/plugins/agents/antigravity/ensure-mcp-config.js +12 -12
  295. package/dist/plugins/agents/antigravity/ensure-mcp-config.js.map +1 -1
  296. package/dist/plugins/agents/antigravity/index.js +10 -10
  297. package/dist/plugins/agents/antigravity/index.js.map +1 -1
  298. package/dist/plugins/agents/claude-code/index.d.ts +2 -2
  299. package/dist/plugins/agents/claude-code/index.js +16 -16
  300. package/dist/plugins/agents/claude-code/index.js.map +1 -1
  301. package/dist/plugins/agents/claude-code/mcp-approval-server.js +13 -13
  302. package/dist/plugins/agents/claude-code/mcp-approval-server.js.map +1 -1
  303. package/dist/plugins/agents/codex/build-mcp-cli-args.d.ts +4 -4
  304. package/dist/plugins/agents/codex/build-mcp-cli-args.js +14 -14
  305. package/dist/plugins/agents/codex/build-mcp-cli-args.js.map +1 -1
  306. package/dist/plugins/agents/codex/index.d.ts +3 -3
  307. package/dist/plugins/agents/codex/index.js +14 -14
  308. package/dist/plugins/agents/codex/index.js.map +1 -1
  309. package/dist/plugins/agents/cursor/ensure-mcp-config.d.ts +5 -5
  310. package/dist/plugins/agents/cursor/ensure-mcp-config.d.ts.map +1 -1
  311. package/dist/plugins/agents/cursor/ensure-mcp-config.js +11 -11
  312. package/dist/plugins/agents/cursor/ensure-mcp-config.js.map +1 -1
  313. package/dist/plugins/agents/cursor/index.d.ts +1 -1
  314. package/dist/plugins/agents/cursor/index.js +12 -12
  315. package/dist/plugins/agents/cursor/index.js.map +1 -1
  316. package/dist/plugins/agents/native/index.d.ts +1 -0
  317. package/dist/plugins/agents/native/index.d.ts.map +1 -1
  318. package/dist/plugins/agents/native/index.js +28 -14
  319. package/dist/plugins/agents/native/index.js.map +1 -1
  320. package/dist/plugins/agents/native/tool-registry.d.ts +3 -3
  321. package/dist/plugins/agents/native/tool-registry.d.ts.map +1 -1
  322. package/dist/plugins/agents/native/tool-registry.js +5 -5
  323. package/dist/plugins/agents/native/tool-registry.js.map +1 -1
  324. package/dist/plugins/agents/opencode/ensure-mcp-config.d.ts +1 -1
  325. package/dist/plugins/agents/opencode/ensure-mcp-config.js +9 -9
  326. package/dist/plugins/agents/opencode/ensure-mcp-config.js.map +1 -1
  327. package/dist/plugins/agents/opencode/index.js +3 -3
  328. package/dist/plugins/agents/opencode/index.js.map +1 -1
  329. package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts +4 -0
  330. package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts.map +1 -1
  331. package/dist/plugins/agents/opencode/opencode-http-adapter.js +16 -12
  332. package/dist/plugins/agents/opencode/opencode-http-adapter.js.map +1 -1
  333. package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts +2 -2
  334. package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts.map +1 -1
  335. package/dist/plugins/agents/opencode/opencode-stdio-adapter.js +7 -5
  336. package/dist/plugins/agents/opencode/opencode-stdio-adapter.js.map +1 -1
  337. package/dist/plugins/agents/opencode/serve-manager.d.ts +1 -1
  338. package/dist/plugins/agents/opencode/serve-manager.d.ts.map +1 -1
  339. package/dist/plugins/agents/opencode/serve-manager.js +10 -10
  340. package/dist/plugins/agents/opencode/serve-manager.js.map +1 -1
  341. package/dist/plugins/agents/pi-native/factory.d.ts.map +1 -1
  342. package/dist/plugins/agents/pi-native/factory.js +29 -13
  343. package/dist/plugins/agents/pi-native/factory.js.map +1 -1
  344. package/dist/plugins/agents/pi-native/index.d.ts +14 -3
  345. package/dist/plugins/agents/pi-native/index.d.ts.map +1 -1
  346. package/dist/plugins/agents/pi-native/index.js +58 -4
  347. package/dist/plugins/agents/pi-native/index.js.map +1 -1
  348. package/dist/plugins/agents/pi-native/provider-resolver.d.ts +2 -0
  349. package/dist/plugins/agents/pi-native/provider-resolver.d.ts.map +1 -1
  350. package/dist/plugins/agents/pi-native/provider-resolver.js +9 -1
  351. package/dist/plugins/agents/pi-native/provider-resolver.js.map +1 -1
  352. package/dist/plugins/agents/pi-native/tool-bridge.js +1 -1
  353. package/dist/plugins/agents/pi-native/tool-bridge.js.map +1 -1
  354. package/dist/plugins/agents/pi-native/tools.js +4 -4
  355. package/dist/plugins/agents/pi-native/tools.js.map +1 -1
  356. package/dist/plugins/messengers/dingtalk/dingtalk-adapter.d.ts +1 -1
  357. package/dist/plugins/messengers/dingtalk/dingtalk-adapter.js +2 -2
  358. package/dist/plugins/messengers/dingtalk/dingtalk-adapter.js.map +1 -1
  359. package/dist/plugins/messengers/email/email-adapter.js +15 -15
  360. package/dist/plugins/messengers/email/email-adapter.js.map +1 -1
  361. package/dist/plugins/messengers/telegram/media-download.d.ts +1 -1
  362. package/dist/plugins/messengers/telegram/media-download.js +4 -4
  363. package/dist/plugins/messengers/telegram/media-download.js.map +1 -1
  364. package/dist/plugins/messengers/telegram/telegram-adapter.d.ts +1 -1
  365. package/dist/plugins/messengers/telegram/telegram-adapter.js +3 -3
  366. package/dist/plugins/messengers/telegram/telegram-adapter.js.map +1 -1
  367. package/dist/plugins/messengers/wechat/context-store.js +1 -1
  368. package/dist/plugins/messengers/wechat/context-store.js.map +1 -1
  369. package/dist/plugins/messengers/wechat/ilink-adapter.js +1 -1
  370. package/dist/plugins/messengers/wechat/ilink-adapter.js.map +1 -1
  371. package/dist/plugins/messengers/wechat/ilink-client.js +1 -1
  372. package/dist/plugins/messengers/wechat/ilink-client.js.map +1 -1
  373. package/dist/plugins/messengers/wechat/media-download.js +1 -1
  374. package/dist/plugins/messengers/wechat/media-download.js.map +1 -1
  375. package/dist/scripts/migrate-gcj02-to-wgs84.js +1 -1
  376. package/dist/scripts/migrate-gcj02-to-wgs84.js.map +1 -1
  377. package/dist/web/public/assets/a2a-CTsDMefo.js +7 -0
  378. package/dist/web/public/assets/a2a-CTsDMefo.js.map +1 -0
  379. package/dist/web/public/assets/{activity-BnlFGipw.js → activity-ul8Os7Pz.js} +2 -2
  380. package/dist/web/public/assets/{activity-BnlFGipw.js.map → activity-ul8Os7Pz.js.map} +1 -1
  381. package/dist/web/public/assets/{admins-CH84Rw1d.js → admins-ByMAuquy.js} +3 -3
  382. package/dist/web/public/assets/{admins-CH84Rw1d.js.map → admins-ByMAuquy.js.map} +1 -1
  383. package/dist/web/public/assets/agents-Ds1zyxBj.js +2 -0
  384. package/dist/web/public/assets/agents-Ds1zyxBj.js.map +1 -0
  385. package/dist/web/public/assets/{approvals-DnzjbDR6.js → approvals-DOWlWI7Z.js} +3 -3
  386. package/dist/web/public/assets/{approvals-DnzjbDR6.js.map → approvals-DOWlWI7Z.js.map} +1 -1
  387. package/dist/web/public/assets/{arrow-down-DxlRHrs8.js → arrow-down-7i0xwCI2.js} +2 -2
  388. package/dist/web/public/assets/{arrow-down-DxlRHrs8.js.map → arrow-down-7i0xwCI2.js.map} +1 -1
  389. package/dist/web/public/assets/arrow-right-A889Wof8.js +7 -0
  390. package/dist/web/public/assets/arrow-right-A889Wof8.js.map +1 -0
  391. package/dist/web/public/assets/{arrow-up-CAiQ2jy-.js → arrow-up-Dm0U4-6U.js} +2 -2
  392. package/dist/web/public/assets/{arrow-up-CAiQ2jy-.js.map → arrow-up-Dm0U4-6U.js.map} +1 -1
  393. package/dist/web/public/assets/{asks-DyUQopay.js → asks-DGuBsrJ7.js} +3 -3
  394. package/dist/web/public/assets/{asks-DyUQopay.js.map → asks-DGuBsrJ7.js.map} +1 -1
  395. package/dist/web/public/assets/{audit-BVHTMS82.js → audit-BRXsplJ2.js} +2 -2
  396. package/dist/web/public/assets/{audit-BVHTMS82.js.map → audit-BRXsplJ2.js.map} +1 -1
  397. package/dist/web/public/assets/{bell-D7iS7ctN.js → bell-B-UdeJsp.js} +2 -2
  398. package/dist/web/public/assets/{bell-D7iS7ctN.js.map → bell-B-UdeJsp.js.map} +1 -1
  399. package/dist/web/public/assets/bgjobs-CcRiffyJ.js +2 -0
  400. package/dist/web/public/assets/bgjobs-CcRiffyJ.js.map +1 -0
  401. package/dist/web/public/assets/book-open-CSCq5cjL.js +7 -0
  402. package/dist/web/public/assets/book-open-CSCq5cjL.js.map +1 -0
  403. package/dist/web/public/assets/{brain-CCF25Egu.js → brain-Dl4DF5kX.js} +2 -2
  404. package/dist/web/public/assets/{brain-CCF25Egu.js.map → brain-Dl4DF5kX.js.map} +1 -1
  405. package/dist/web/public/assets/{briefcase-BMLMD8nM.js → briefcase-CeKUkFSq.js} +2 -2
  406. package/dist/web/public/assets/{briefcase-BMLMD8nM.js.map → briefcase-CeKUkFSq.js.map} +1 -1
  407. package/dist/web/public/assets/chat-rLJMdJBk.js +12 -0
  408. package/dist/web/public/assets/chat-rLJMdJBk.js.map +1 -0
  409. package/dist/web/public/assets/{chevron-left-BDO3vw8G.js → chevron-left-01fAFVpo.js} +2 -2
  410. package/dist/web/public/assets/{chevron-left-BDO3vw8G.js.map → chevron-left-01fAFVpo.js.map} +1 -1
  411. package/dist/web/public/assets/{chevron-right-5ZUC2opg.js → chevron-right-CFRb-SM_.js} +3 -3
  412. package/dist/web/public/assets/{chevron-right-5ZUC2opg.js.map → chevron-right-CFRb-SM_.js.map} +1 -1
  413. package/dist/web/public/assets/{circle-check-big-DHAHqUlS.js → circle-check-big-DBg2BD6o.js} +2 -2
  414. package/dist/web/public/assets/{circle-check-big-DHAHqUlS.js.map → circle-check-big-DBg2BD6o.js.map} +1 -1
  415. package/dist/web/public/assets/{circle-x-7VaoZ7dY.js → circle-x-CqFMzO-x.js} +2 -2
  416. package/dist/web/public/assets/{circle-x-7VaoZ7dY.js.map → circle-x-CqFMzO-x.js.map} +1 -1
  417. package/dist/web/public/assets/clipboard-list-lnqdk2_J.js +7 -0
  418. package/dist/web/public/assets/clipboard-list-lnqdk2_J.js.map +1 -0
  419. package/dist/web/public/assets/{clock-ZPVXnd6V.js → clock-4hd1joQe.js} +3 -3
  420. package/dist/web/public/assets/{clock-ZPVXnd6V.js.map → clock-4hd1joQe.js.map} +1 -1
  421. package/dist/web/public/assets/confirm-dialog-BDb0NLny.js +2 -0
  422. package/dist/web/public/assets/{confirm-dialog-CgpJL9oN.js.map → confirm-dialog-BDb0NLny.js.map} +1 -1
  423. package/dist/web/public/assets/{copy-BaZl52tH.js → copy-CD4A7VD8.js} +3 -3
  424. package/dist/web/public/assets/{copy-BaZl52tH.js.map → copy-CD4A7VD8.js.map} +1 -1
  425. package/dist/web/public/assets/dashboard-CG3WiG7h.js +2 -0
  426. package/dist/web/public/assets/dashboard-CG3WiG7h.js.map +1 -0
  427. package/dist/web/public/assets/{data-table-BLYG79TX.js → data-table-BkUshOZz.js} +2 -2
  428. package/dist/web/public/assets/{data-table-BLYG79TX.js.map → data-table-BkUshOZz.js.map} +1 -1
  429. package/dist/web/public/assets/database-lQzk64rV.js +7 -0
  430. package/dist/web/public/assets/database-lQzk64rV.js.map +1 -0
  431. package/dist/web/public/assets/distill-CPurVW3v.js +7 -0
  432. package/dist/web/public/assets/distill-CPurVW3v.js.map +1 -0
  433. package/dist/web/public/assets/{download-bzCepctg.js → download-CVZnHcwj.js} +2 -2
  434. package/dist/web/public/assets/{download-bzCepctg.js.map → download-CVZnHcwj.js.map} +1 -1
  435. package/dist/web/public/assets/dropdown-menu-BNH5SrVb.js +7 -0
  436. package/dist/web/public/assets/dropdown-menu-BNH5SrVb.js.map +1 -0
  437. package/dist/web/public/assets/email-YlI4MWLp.js +7 -0
  438. package/dist/web/public/assets/email-YlI4MWLp.js.map +1 -0
  439. package/dist/web/public/assets/{empty-state-96qpPTNg.js → empty-state-CuiqdZiB.js} +2 -2
  440. package/dist/web/public/assets/{empty-state-96qpPTNg.js.map → empty-state-CuiqdZiB.js.map} +1 -1
  441. package/dist/web/public/assets/{external-link-J4nIlCem.js → external-link-1WPpVvdu.js} +2 -2
  442. package/dist/web/public/assets/{external-link-J4nIlCem.js.map → external-link-1WPpVvdu.js.map} +1 -1
  443. package/dist/web/public/assets/{eye-BvsBLK42.js → eye-BfPyNFzk.js} +2 -2
  444. package/dist/web/public/assets/{eye-BvsBLK42.js.map → eye-BfPyNFzk.js.map} +1 -1
  445. package/dist/web/public/assets/{facts-DMucDXYd.js → facts-xT_24pH8.js} +2 -2
  446. package/dist/web/public/assets/{facts-DMucDXYd.js.map → facts-xT_24pH8.js.map} +1 -1
  447. package/dist/web/public/assets/file-text-BxfdLM0-.js +7 -0
  448. package/dist/web/public/assets/file-text-BxfdLM0-.js.map +1 -0
  449. package/dist/web/public/assets/{goals-B9ETHgL0.js → goals-C8ZQfbhj.js} +3 -3
  450. package/dist/web/public/assets/{goals-B9ETHgL0.js.map → goals-C8ZQfbhj.js.map} +1 -1
  451. package/dist/web/public/assets/health-A2StNEfn.js +2 -0
  452. package/dist/web/public/assets/{health-DLzZ7KHc.js.map → health-A2StNEfn.js.map} +1 -1
  453. package/dist/web/public/assets/{heart-pulse-CVEeD2sz.js → heart-pulse-DXlE9oic.js} +2 -2
  454. package/dist/web/public/assets/{heart-pulse-CVEeD2sz.js.map → heart-pulse-DXlE9oic.js.map} +1 -1
  455. package/dist/web/public/assets/{heartbeat-B1BEBHge.js → heartbeat-ClO5gJrj.js} +3 -3
  456. package/dist/web/public/assets/{heartbeat-B1BEBHge.js.map → heartbeat-ClO5gJrj.js.map} +1 -1
  457. package/dist/web/public/assets/hot-bfTA-V_z.js +7 -0
  458. package/dist/web/public/assets/{hot-Yc7iad0D.js.map → hot-bfTA-V_z.js.map} +1 -1
  459. package/dist/web/public/assets/index-Bi2qWb-u.css +1 -0
  460. package/dist/web/public/assets/index-DCfdN5R7.js +244 -0
  461. package/dist/web/public/assets/index-DCfdN5R7.js.map +1 -0
  462. package/dist/web/public/assets/{injection-Ca-9gbo0.js → injection-omvCR6-p.js} +2 -2
  463. package/dist/web/public/assets/{injection-Ca-9gbo0.js.map → injection-omvCR6-p.js.map} +1 -1
  464. package/dist/web/public/assets/{installed-Zz34apdi.js → installed-DL6r3ktm.js} +4 -9
  465. package/dist/web/public/assets/installed-DL6r3ktm.js.map +1 -0
  466. package/dist/web/public/assets/jobs-Biy5lYd4.js +2 -0
  467. package/dist/web/public/assets/jobs-Biy5lYd4.js.map +1 -0
  468. package/dist/web/public/assets/layout-BLm6NJ3V.js +2 -0
  469. package/dist/web/public/assets/layout-BLm6NJ3V.js.map +1 -0
  470. package/dist/web/public/assets/layout-BTKafRVZ.js +2 -0
  471. package/dist/web/public/assets/layout-BTKafRVZ.js.map +1 -0
  472. package/dist/web/public/assets/layout-Bm-2s2fp.js +2 -0
  473. package/dist/web/public/assets/layout-Bm-2s2fp.js.map +1 -0
  474. package/dist/web/public/assets/layout-DsZ8eR4i.js +2 -0
  475. package/dist/web/public/assets/layout-DsZ8eR4i.js.map +1 -0
  476. package/dist/web/public/assets/{layout-CtDc2i7w.js → layout-sxvovjEH.js} +2 -2
  477. package/dist/web/public/assets/{layout-CtDc2i7w.js.map → layout-sxvovjEH.js.map} +1 -1
  478. package/dist/web/public/assets/llm-JjZDbBvJ.js +37 -0
  479. package/dist/web/public/assets/llm-JjZDbBvJ.js.map +1 -0
  480. package/dist/web/public/assets/loader-circle-DDdmcH0k.js +7 -0
  481. package/dist/web/public/assets/{loader-circle-D8L1w9c1.js.map → loader-circle-DDdmcH0k.js.map} +1 -1
  482. package/dist/web/public/assets/{map-pin--GMunU9n.js → map-pin-C_jAxukI.js} +2 -2
  483. package/dist/web/public/assets/{map-pin--GMunU9n.js.map → map-pin-C_jAxukI.js.map} +1 -1
  484. package/dist/web/public/assets/{mcp-DhnXhO9B.js → mcp-vKajK1F8.js} +3 -3
  485. package/dist/web/public/assets/{mcp-DhnXhO9B.js.map → mcp-vKajK1F8.js.map} +1 -1
  486. package/dist/web/public/assets/memos-DAt4k3DO.js +7 -0
  487. package/dist/web/public/assets/memos-DAt4k3DO.js.map +1 -0
  488. package/dist/web/public/assets/messengers-GYVTFlAj.js +2 -0
  489. package/dist/web/public/assets/messengers-GYVTFlAj.js.map +1 -0
  490. package/dist/web/public/assets/{mobile-CUZ359rQ.js → mobile-VUyTo40E.js} +3 -3
  491. package/dist/web/public/assets/{mobile-CUZ359rQ.js.map → mobile-VUyTo40E.js.map} +1 -1
  492. package/dist/web/public/assets/{network-BBdRdrH_.js → network-BUeWK3bs.js} +2 -2
  493. package/dist/web/public/assets/{network-BBdRdrH_.js.map → network-BUeWK3bs.js.map} +1 -1
  494. package/dist/web/public/assets/outbox-CEE0rwN3.js +2 -0
  495. package/dist/web/public/assets/outbox-CEE0rwN3.js.map +1 -0
  496. package/dist/web/public/assets/overview-BSOZ5gTD.js +12 -0
  497. package/dist/web/public/assets/overview-BSOZ5gTD.js.map +1 -0
  498. package/dist/web/public/assets/overview-COop5K2Y.js +12 -0
  499. package/dist/web/public/assets/overview-COop5K2Y.js.map +1 -0
  500. package/dist/web/public/assets/overview-DeH5ud6d.js +2 -0
  501. package/dist/web/public/assets/overview-DeH5ud6d.js.map +1 -0
  502. package/dist/web/public/assets/{pagination-DcsgDXXM.js → pagination-BBicLzXP.js} +3 -3
  503. package/dist/web/public/assets/{pagination-DcsgDXXM.js.map → pagination-BBicLzXP.js.map} +1 -1
  504. package/dist/web/public/assets/persona-CElXQZ4p.js +2 -0
  505. package/dist/web/public/assets/{persona-ig2ac4mY.js.map → persona-CElXQZ4p.js.map} +1 -1
  506. package/dist/web/public/assets/{plans-Bzbk8eUr.js → plans-Bo5LlLeH.js} +3 -8
  507. package/dist/web/public/assets/plans-Bo5LlLeH.js.map +1 -0
  508. package/dist/web/public/assets/{play-Di1jqulh.js → play-DX5wp4WH.js} +2 -2
  509. package/dist/web/public/assets/{play-Di1jqulh.js.map → play-DX5wp4WH.js.map} +1 -1
  510. package/dist/web/public/assets/{plus-C2zyJ1mF.js → plus-DH4J_YhN.js} +2 -2
  511. package/dist/web/public/assets/{plus-C2zyJ1mF.js.map → plus-DH4J_YhN.js.map} +1 -1
  512. package/dist/web/public/assets/policy-BrgOuDt_.js +2 -0
  513. package/dist/web/public/assets/policy-BrgOuDt_.js.map +1 -0
  514. package/dist/web/public/assets/{qr-code-C-ACsKv_.js → qr-code-YrEuhMPC.js} +2 -2
  515. package/dist/web/public/assets/{qr-code-C-ACsKv_.js.map → qr-code-YrEuhMPC.js.map} +1 -1
  516. package/dist/web/public/assets/{refresh-ccw-7HdadG5V.js → refresh-ccw-DlAd-eTQ.js} +2 -2
  517. package/dist/web/public/assets/{refresh-ccw-7HdadG5V.js.map → refresh-ccw-DlAd-eTQ.js.map} +1 -1
  518. package/dist/web/public/assets/{reminders-BDeiVYTC.js → reminders-DBEE0zXG.js} +3 -3
  519. package/dist/web/public/assets/{reminders-BDeiVYTC.js.map → reminders-DBEE0zXG.js.map} +1 -1
  520. package/dist/web/public/assets/{save-BYFmz9gD.js → save-BDOtZrfp.js} +2 -2
  521. package/dist/web/public/assets/{save-BYFmz9gD.js.map → save-BDOtZrfp.js.map} +1 -1
  522. package/dist/web/public/assets/schedules-DAyhVI8-.js +2 -0
  523. package/dist/web/public/assets/schedules-DAyhVI8-.js.map +1 -0
  524. package/dist/web/public/assets/search-55mtgHrB.js +17 -0
  525. package/dist/web/public/assets/search-55mtgHrB.js.map +1 -0
  526. package/dist/web/public/assets/{search-DxkvV-8p.js → search-CAICU3aU.js} +2 -2
  527. package/dist/web/public/assets/{search-DxkvV-8p.js.map → search-CAICU3aU.js.map} +1 -1
  528. package/dist/web/public/assets/security-CbP4QgVp.js +2 -0
  529. package/dist/web/public/assets/security-CbP4QgVp.js.map +1 -0
  530. package/dist/web/public/assets/server-Dg4e8pvm.js +7 -0
  531. package/dist/web/public/assets/server-Dg4e8pvm.js.map +1 -0
  532. package/dist/web/public/assets/service-gWZa3sup.js +7 -0
  533. package/dist/web/public/assets/service-gWZa3sup.js.map +1 -0
  534. package/dist/web/public/assets/{shield-alert-DXGk9Rak.js → shield-alert-DOKK9EnJ.js} +2 -2
  535. package/dist/web/public/assets/{shield-alert-DXGk9Rak.js.map → shield-alert-DOKK9EnJ.js.map} +1 -1
  536. package/dist/web/public/assets/sparkles-G0QIs9nP.js +7 -0
  537. package/dist/web/public/assets/sparkles-G0QIs9nP.js.map +1 -0
  538. package/dist/web/public/assets/start-D-abhl3q.js +2 -0
  539. package/dist/web/public/assets/start-D-abhl3q.js.map +1 -0
  540. package/dist/web/public/assets/{status-badge-D0nbFSom.js → status-badge-CyLdpsXq.js} +2 -2
  541. package/dist/web/public/assets/{status-badge-D0nbFSom.js.map → status-badge-CyLdpsXq.js.map} +1 -1
  542. package/dist/web/public/assets/{subtasks-DFiAXvDp.js → subtasks-BnEjSGUR.js} +3 -3
  543. package/dist/web/public/assets/{subtasks-DFiAXvDp.js.map → subtasks-BnEjSGUR.js.map} +1 -1
  544. package/dist/web/public/assets/{table-_WsrnZ_T.js → table-sCMZBe_Z.js} +2 -2
  545. package/dist/web/public/assets/{table-_WsrnZ_T.js.map → table-sCMZBe_Z.js.map} +1 -1
  546. package/dist/web/public/assets/terminal-_pXeEjXG.js +7 -0
  547. package/dist/web/public/assets/terminal-_pXeEjXG.js.map +1 -0
  548. package/dist/web/public/assets/{topn-C2PHE4tX.js → topn-D1B-gS1M.js} +3 -3
  549. package/dist/web/public/assets/{topn-C2PHE4tX.js.map → topn-D1B-gS1M.js.map} +1 -1
  550. package/dist/web/public/assets/{trash-2-1Km439fW.js → trash-2-D2x2UPuZ.js} +2 -2
  551. package/dist/web/public/assets/{trash-2-1Km439fW.js.map → trash-2-D2x2UPuZ.js.map} +1 -1
  552. package/dist/web/public/assets/use-a2a-C98e2Via.js +2 -0
  553. package/dist/web/public/assets/use-a2a-C98e2Via.js.map +1 -0
  554. package/dist/web/public/assets/{use-agim-skills-COSqZrdH.js → use-agim-skills-BbuJP3NT.js} +2 -2
  555. package/dist/web/public/assets/{use-agim-skills-COSqZrdH.js.map → use-agim-skills-BbuJP3NT.js.map} +1 -1
  556. package/dist/web/public/assets/use-background-tasks-CwFmOokw.js +2 -0
  557. package/dist/web/public/assets/{use-background-tasks-wCL7jn68.js.map → use-background-tasks-CwFmOokw.js.map} +1 -1
  558. package/dist/web/public/assets/use-jobs-BJjeJ5lh.js +2 -0
  559. package/dist/web/public/assets/use-jobs-BJjeJ5lh.js.map +1 -0
  560. package/dist/web/public/assets/use-memory-CXDwKCco.js +2 -0
  561. package/dist/web/public/assets/{use-memory-B9oRyQC8.js.map → use-memory-CXDwKCco.js.map} +1 -1
  562. package/dist/web/public/assets/use-observability-CY5ZUPrC.js +2 -0
  563. package/dist/web/public/assets/{use-observability-DGkN80qa.js.map → use-observability-CY5ZUPrC.js.map} +1 -1
  564. package/dist/web/public/assets/use-outbox-DT_XWB_7.js +7 -0
  565. package/dist/web/public/assets/use-outbox-DT_XWB_7.js.map +1 -0
  566. package/dist/web/public/assets/use-schedules-D4W8fMwo.js +7 -0
  567. package/dist/web/public/assets/use-schedules-D4W8fMwo.js.map +1 -0
  568. package/dist/web/public/assets/use-settings-DGIjmUX0.js +2 -0
  569. package/dist/web/public/assets/use-settings-DGIjmUX0.js.map +1 -0
  570. package/dist/web/public/assets/use-skills-D2bMM580.js +7 -0
  571. package/dist/web/public/assets/use-skills-D2bMM580.js.map +1 -0
  572. package/dist/web/public/assets/use-vector-BYOFwjU0.js +2 -0
  573. package/dist/web/public/assets/use-vector-BYOFwjU0.js.map +1 -0
  574. package/dist/web/public/assets/use-workspace-CuytyHwb.js +2 -0
  575. package/dist/web/public/assets/{use-workspace-BDXP5XO1.js.map → use-workspace-CuytyHwb.js.map} +1 -1
  576. package/dist/web/public/assets/vector-CL8ezpSR.js +2 -0
  577. package/dist/web/public/assets/vector-CL8ezpSR.js.map +1 -0
  578. package/dist/web/public/assets/viewer-CD0iEfPU.js +7 -0
  579. package/dist/web/public/assets/viewer-CD0iEfPU.js.map +1 -0
  580. package/dist/web/public/assets/workspace-BA1_hso3.js +17 -0
  581. package/dist/web/public/assets/workspace-BA1_hso3.js.map +1 -0
  582. package/dist/web/public/assets/workspaces-DyGLJUgB.js +7 -0
  583. package/dist/web/public/assets/workspaces-DyGLJUgB.js.map +1 -0
  584. package/dist/web/public/index.html +2 -2
  585. package/dist/web/public/loc.html +1 -1
  586. package/dist/web/public/login.html +2 -2
  587. package/dist/web/server.d.ts +2 -5
  588. package/dist/web/server.d.ts.map +1 -1
  589. package/dist/web/server.js +256 -122
  590. package/dist/web/server.js.map +1 -1
  591. package/package.json +2 -3
  592. package/dist/core/llm/imhub-dispatcher.d.ts.map +0 -1
  593. package/dist/core/llm/imhub-dispatcher.js.map +0 -1
  594. package/dist/web/public/assets/a2a-CZxwvgvh.js +0 -7
  595. package/dist/web/public/assets/a2a-CZxwvgvh.js.map +0 -1
  596. package/dist/web/public/assets/agents-CFB4Uj6b.js +0 -7
  597. package/dist/web/public/assets/agents-CFB4Uj6b.js.map +0 -1
  598. package/dist/web/public/assets/bgjobs-BYCQhd_1.js +0 -7
  599. package/dist/web/public/assets/bgjobs-BYCQhd_1.js.map +0 -1
  600. package/dist/web/public/assets/chat-DPkKy5y_.js +0 -17
  601. package/dist/web/public/assets/chat-DPkKy5y_.js.map +0 -1
  602. package/dist/web/public/assets/circle-check-COhM5JsK.js +0 -7
  603. package/dist/web/public/assets/circle-check-COhM5JsK.js.map +0 -1
  604. package/dist/web/public/assets/confirm-dialog-CgpJL9oN.js +0 -2
  605. package/dist/web/public/assets/distill-D9p8O8Jf.js +0 -7
  606. package/dist/web/public/assets/distill-D9p8O8Jf.js.map +0 -1
  607. package/dist/web/public/assets/email-Douv-rZ5.js +0 -7
  608. package/dist/web/public/assets/email-Douv-rZ5.js.map +0 -1
  609. package/dist/web/public/assets/health-DLzZ7KHc.js +0 -2
  610. package/dist/web/public/assets/hot-Yc7iad0D.js +0 -12
  611. package/dist/web/public/assets/index-DY2Zglku.js +0 -209
  612. package/dist/web/public/assets/index-DY2Zglku.js.map +0 -1
  613. package/dist/web/public/assets/index-DknVjPYB.css +0 -1
  614. package/dist/web/public/assets/installed-Zz34apdi.js.map +0 -1
  615. package/dist/web/public/assets/jobs-CtVRpl0r.js +0 -2
  616. package/dist/web/public/assets/jobs-CtVRpl0r.js.map +0 -1
  617. package/dist/web/public/assets/layout-BTCLgkgN.js +0 -2
  618. package/dist/web/public/assets/layout-BTCLgkgN.js.map +0 -1
  619. package/dist/web/public/assets/layout-Cxch59sI.js +0 -2
  620. package/dist/web/public/assets/layout-Cxch59sI.js.map +0 -1
  621. package/dist/web/public/assets/layout-DnANw2Q2.js +0 -2
  622. package/dist/web/public/assets/layout-DnANw2Q2.js.map +0 -1
  623. package/dist/web/public/assets/layout-yIZG87fq.js +0 -2
  624. package/dist/web/public/assets/layout-yIZG87fq.js.map +0 -1
  625. package/dist/web/public/assets/llm-CMMa85Ig.js +0 -27
  626. package/dist/web/public/assets/llm-CMMa85Ig.js.map +0 -1
  627. package/dist/web/public/assets/loader-circle-D8L1w9c1.js +0 -7
  628. package/dist/web/public/assets/memos-DQZc7llR.js +0 -12
  629. package/dist/web/public/assets/memos-DQZc7llR.js.map +0 -1
  630. package/dist/web/public/assets/messengers-DwSmauLs.js +0 -2
  631. package/dist/web/public/assets/messengers-DwSmauLs.js.map +0 -1
  632. package/dist/web/public/assets/outbox-CmN0U35l.js +0 -7
  633. package/dist/web/public/assets/outbox-CmN0U35l.js.map +0 -1
  634. package/dist/web/public/assets/persona-ig2ac4mY.js +0 -2
  635. package/dist/web/public/assets/plans-Bzbk8eUr.js.map +0 -1
  636. package/dist/web/public/assets/policy-yD1c2Pcn.js +0 -2
  637. package/dist/web/public/assets/policy-yD1c2Pcn.js.map +0 -1
  638. package/dist/web/public/assets/schedules-BddzBrxI.js +0 -7
  639. package/dist/web/public/assets/schedules-BddzBrxI.js.map +0 -1
  640. package/dist/web/public/assets/search-B8PlbtLg.js +0 -17
  641. package/dist/web/public/assets/search-B8PlbtLg.js.map +0 -1
  642. package/dist/web/public/assets/security-DpOGp3nS.js +0 -2
  643. package/dist/web/public/assets/security-DpOGp3nS.js.map +0 -1
  644. package/dist/web/public/assets/service-BsY8CaNG.js +0 -7
  645. package/dist/web/public/assets/service-BsY8CaNG.js.map +0 -1
  646. package/dist/web/public/assets/use-background-tasks-wCL7jn68.js +0 -2
  647. package/dist/web/public/assets/use-memory-B9oRyQC8.js +0 -2
  648. package/dist/web/public/assets/use-observability-DGkN80qa.js +0 -2
  649. package/dist/web/public/assets/use-settings-Co-iafXD.js +0 -2
  650. package/dist/web/public/assets/use-settings-Co-iafXD.js.map +0 -1
  651. package/dist/web/public/assets/use-workspace-BDXP5XO1.js +0 -2
  652. package/dist/web/public/assets/vector-BfIEx8xX.js +0 -2
  653. package/dist/web/public/assets/vector-BfIEx8xX.js.map +0 -1
  654. package/dist/web/public/assets/viewer-BPMZkT05.js +0 -12
  655. package/dist/web/public/assets/viewer-BPMZkT05.js.map +0 -1
  656. package/dist/web/public/assets/workspace-BbCchiHE.js +0 -17
  657. package/dist/web/public/assets/workspace-BbCchiHE.js.map +0 -1
  658. package/dist/web/public/assets/workspaces-5HE7pjdA.js +0 -7
  659. package/dist/web/public/assets/workspaces-5HE7pjdA.js.map +0 -1
@@ -0,0 +1,7 @@
1
+ import{h as e}from"./index-DCfdN5R7.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 t=e("FileText",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M10 9H8",key:"b1mrlr"}],["path",{d:"M16 13H8",key:"t4e002"}],["path",{d:"M16 17H8",key:"z1uh3a"}]]);export{t as F};
7
+ //# sourceMappingURL=file-text-BxfdLM0-.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-text-BxfdLM0-.js","sources":["../../node_modules/lucide-react/dist/esm/icons/file-text.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 FileText = createLucideIcon(\"FileText\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"path\", { d: \"M10 9H8\", key: \"b1mrlr\" }],\n [\"path\", { d: \"M16 13H8\", key: \"t4e002\" }],\n [\"path\", { d: \"M16 17H8\", key: \"z1uh3a\" }]\n]);\n\nexport { FileText as default };\n//# sourceMappingURL=file-text.js.map\n"],"names":["FileText","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAWC,EAAiB,WAAY,CAC5C,CAAC,OAAQ,CAAE,EAAG,6DAA8D,IAAK,QAAQ,CAAE,EAC3F,CAAC,OAAQ,CAAE,EAAG,0BAA2B,IAAK,QAAQ,CAAE,EACxD,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAQ,CAAE,EACxC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,CAC3C,CAAC","x_google_ignoreList":[0]}
@@ -1,4 +1,4 @@
1
- import{o as h,u as g,j as e,l as p,B as d,m as j}from"./index-DY2Zglku.js";import{r as u}from"./react-DlP5eolq.js";import{T as b,a as N,b as m,c as i,d as v,e as l}from"./table-_WsrnZ_T.js";import{b as k,c as w}from"./use-background-tasks-wCL7jn68.js";import{L as C}from"./loader-circle-D8L1w9c1.js";import{R as T}from"./refresh-ccw-7HdadG5V.js";import{C as L}from"./circle-check-COhM5JsK.js";import{C as M}from"./circle-x-7VaoZ7dY.js";/**
1
+ import{h,u as g,j as e,d as p,e as d,C as b,p as j}from"./index-DCfdN5R7.js";import{r as u}from"./react-DlP5eolq.js";import{T as N,a as v,b as m,c as i,d as k,e as l}from"./table-sCMZBe_Z.js";import{a as w,d as C}from"./use-background-tasks-CwFmOokw.js";import{L as T}from"./loader-circle-DDdmcH0k.js";import{R as L}from"./refresh-ccw-DlAd-eTQ.js";import{C as M}from"./circle-x-CqFMzO-x.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -13,5 +13,5 @@ import{o as h,u as g,j as e,l as p,B as d,m as j}from"./index-DY2Zglku.js";impor
13
13
  *
14
14
  * This source code is licensed under the ISC license.
15
15
  * See the LICENSE file in the root directory of this source tree.
16
- */const B=h("Target",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["circle",{cx:"12",cy:"12",r:"6",key:"1vlfrh"}],["circle",{cx:"12",cy:"12",r:"2",key:"1c9p78"}]]);function D(){const{t:s}=g(["tasks","common"]),r=k(),o=w(),[y,f]=u.useState(null);async function n(a,c){try{await o.mutateAsync({id:a.id,status:c}),j.success(s("goals.statusUpdated",{status:s(`goals.status.${c}`,{defaultValue:c})}))}catch(t){j.error(t?.message??String(t))}}const x=r.data?.goals??[];return e.jsxs("div",{className:"mx-auto flex max-w-6xl flex-col gap-4 p-4",children:[e.jsxs("header",{className:"flex items-center gap-3",children:[e.jsx(B,{className:"h-5 w-5 text-text-dim"}),e.jsx("h1",{className:"text-xl font-semibold",children:s("goals.title")}),e.jsx(p,{variant:"info",children:x.length}),e.jsxs(d,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>void r.refetch(),disabled:r.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[r.isFetching?e.jsx(C,{className:"h-4 w-4 animate-spin"}):e.jsx(T,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("goals.refresh")})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("goals.subtitle")}),r.isLoading?e.jsx("div",{className:"h-48 rounded-md bg-surface-2 animate-pulse"}):x.length===0?e.jsx(P,{}):e.jsx("section",{className:"rounded-md border border-border bg-surface",children:e.jsxs(b,{children:[e.jsx(N,{children:e.jsxs(m,{children:[e.jsx(i,{className:"w-12",children:s("goals.col.id")}),e.jsx(i,{children:s("goals.col.thread")}),e.jsx(i,{children:s("goals.col.title")}),e.jsx(i,{children:s("goals.col.progress")}),e.jsx(i,{children:s("goals.col.updated")}),e.jsx(i,{children:s("goals.col.actions")})]})}),e.jsx(v,{children:x.map(a=>{const c=y===a.id;return e.jsxs(u.Fragment,{children:[e.jsxs(m,{children:[e.jsx(l,{className:"font-mono text-xs",children:a.id}),e.jsxs(l,{className:"font-mono text-[11px]",children:[a.platform,":",a.threadId]}),e.jsx(l,{children:e.jsx(d,{variant:"ghost",size:"sm",className:"-ml-2 text-left",onClick:()=>f(c?null:a.id),title:s(c?"goals.hideBody":"goals.showBody"),children:a.title})}),e.jsx(l,{children:e.jsx(p,{variant:"outline",children:a.progressCount})}),e.jsx(l,{className:"text-[11px] text-text-dim",children:a.updatedAt}),e.jsxs(l,{className:"flex flex-wrap gap-1",children:[e.jsx(d,{variant:"ghost",size:"sm",title:s("goals.pause"),onClick:()=>void n(a,"paused"),disabled:o.isPending,children:e.jsx(z,{className:"h-4 w-4"})}),e.jsx(d,{variant:"ghost",size:"sm",title:s("goals.complete"),onClick:()=>void n(a,"completed"),disabled:o.isPending,children:e.jsx(L,{className:"h-4 w-4 text-success"})}),e.jsx(d,{variant:"ghost",size:"sm",title:s("goals.cancel"),onClick:()=>void n(a,"cancelled"),disabled:o.isPending,className:"text-danger hover:text-danger",children:e.jsx(M,{className:"h-4 w-4"})})]})]}),c&&e.jsxs(m,{children:[e.jsx(l,{}),e.jsx(l,{colSpan:5,children:e.jsxs("div",{className:"space-y-2 rounded bg-surface-2 p-3 text-xs",children:[a.body&&e.jsxs("div",{children:[e.jsx("div",{className:"text-text-dim",children:s("goals.body")}),e.jsx("pre",{className:"mt-1 whitespace-pre-wrap break-words",children:a.body})]}),a.progressLog.length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"text-text-dim",children:s("goals.recentProgress",{count:a.progressLog.length})}),e.jsx("ul",{className:"mt-1 space-y-1",children:a.progressLog.slice().reverse().map(t=>e.jsxs("li",{className:"font-mono text-[11px]",children:[e.jsxs("span",{className:"text-text-dim",children:[t.ts.slice(0,19)," (",t.by,")"]})," ",t.text]},`${t.ts}-${t.by}-${t.text}`))})]}),e.jsxs("div",{className:"text-[11px] text-text-dim",children:[s("goals.created",{at:a.createdAt}),a.closedAt?` · ${s("goals.closed",{at:a.closedAt})}`:""]})]})})]})]},a.id)})})]})})]})}function P(){const{t:s}=g("tasks");return e.jsxs("section",{className:"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim",children:[s("goals.empty"),e.jsx("div",{className:"mt-2",children:e.jsx(S,{className:"mx-auto h-8 w-8 opacity-30"})})]})}export{D as default};
17
- //# sourceMappingURL=goals-B9ETHgL0.js.map
16
+ */const P=h("Target",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["circle",{cx:"12",cy:"12",r:"6",key:"1vlfrh"}],["circle",{cx:"12",cy:"12",r:"2",key:"1c9p78"}]]);function G(){const{t:s}=g(["tasks","common"]),r=w(),o=C(),[y,f]=u.useState(null);async function n(a,c){try{await o.mutateAsync({id:a.id,status:c}),j.success(s("goals.statusUpdated",{status:s(`goals.status.${c}`,{defaultValue:c})}))}catch(t){j.error(t?.message??String(t))}}const x=r.data?.goals??[];return e.jsxs("div",{className:"mx-auto flex max-w-6xl flex-col gap-4 p-4",children:[e.jsxs("header",{className:"flex items-center gap-3",children:[e.jsx(P,{className:"h-5 w-5 text-text-dim"}),e.jsx("h1",{className:"text-xl font-semibold",children:s("goals.title")}),e.jsx(p,{variant:"info",children:x.length}),e.jsxs(d,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>void r.refetch(),disabled:r.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[r.isFetching?e.jsx(T,{className:"h-4 w-4 animate-spin"}):e.jsx(L,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("goals.refresh")})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("goals.subtitle")}),r.isLoading?e.jsx("div",{className:"h-48 rounded-md bg-surface-2 animate-pulse"}):x.length===0?e.jsx(A,{}):e.jsx("section",{className:"rounded-md border border-border bg-surface",children:e.jsxs(N,{children:[e.jsx(v,{children:e.jsxs(m,{children:[e.jsx(i,{className:"w-12",children:s("goals.col.id")}),e.jsx(i,{children:s("goals.col.thread")}),e.jsx(i,{children:s("goals.col.title")}),e.jsx(i,{children:s("goals.col.progress")}),e.jsx(i,{children:s("goals.col.updated")}),e.jsx(i,{children:s("goals.col.actions")})]})}),e.jsx(k,{children:x.map(a=>{const c=y===a.id;return e.jsxs(u.Fragment,{children:[e.jsxs(m,{children:[e.jsx(l,{className:"font-mono text-xs",children:a.id}),e.jsxs(l,{className:"font-mono text-[11px]",children:[a.platform,":",a.threadId]}),e.jsx(l,{children:e.jsx(d,{variant:"ghost",size:"sm",className:"-ml-2 text-left",onClick:()=>f(c?null:a.id),title:s(c?"goals.hideBody":"goals.showBody"),children:a.title})}),e.jsx(l,{children:e.jsx(p,{variant:"outline",children:a.progressCount})}),e.jsx(l,{className:"text-[11px] text-text-dim",children:a.updatedAt}),e.jsxs(l,{className:"flex flex-wrap gap-1",children:[e.jsx(d,{variant:"ghost",size:"sm",title:s("goals.pause"),onClick:()=>void n(a,"paused"),disabled:o.isPending,children:e.jsx(z,{className:"h-4 w-4"})}),e.jsx(d,{variant:"ghost",size:"sm",title:s("goals.complete"),onClick:()=>void n(a,"completed"),disabled:o.isPending,children:e.jsx(b,{className:"h-4 w-4 text-success"})}),e.jsx(d,{variant:"ghost",size:"sm",title:s("goals.cancel"),onClick:()=>void n(a,"cancelled"),disabled:o.isPending,className:"text-danger hover:text-danger",children:e.jsx(M,{className:"h-4 w-4"})})]})]}),c&&e.jsxs(m,{children:[e.jsx(l,{}),e.jsx(l,{colSpan:5,children:e.jsxs("div",{className:"space-y-2 rounded bg-surface-2 p-3 text-xs",children:[a.body&&e.jsxs("div",{children:[e.jsx("div",{className:"text-text-dim",children:s("goals.body")}),e.jsx("pre",{className:"mt-1 whitespace-pre-wrap break-words",children:a.body})]}),a.progressLog.length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"text-text-dim",children:s("goals.recentProgress",{count:a.progressLog.length})}),e.jsx("ul",{className:"mt-1 space-y-1",children:a.progressLog.slice().reverse().map(t=>e.jsxs("li",{className:"font-mono text-[11px]",children:[e.jsxs("span",{className:"text-text-dim",children:[t.ts.slice(0,19)," (",t.by,")"]})," ",t.text]},`${t.ts}-${t.by}-${t.text}`))})]}),e.jsxs("div",{className:"text-[11px] text-text-dim",children:[s("goals.created",{at:a.createdAt}),a.closedAt?` · ${s("goals.closed",{at:a.closedAt})}`:""]})]})})]})]},a.id)})})]})})]})}function A(){const{t:s}=g("tasks");return e.jsxs("section",{className:"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim",children:[s("goals.empty"),e.jsx("div",{className:"mt-2",children:e.jsx(S,{className:"mx-auto h-8 w-8 opacity-30"})})]})}export{G as default};
17
+ //# sourceMappingURL=goals-C8ZQfbhj.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"goals-B9ETHgL0.js","sources":["../../node_modules/lucide-react/dist/esm/icons/circle-dashed.js","../../node_modules/lucide-react/dist/esm/icons/circle-pause.js","../../node_modules/lucide-react/dist/esm/icons/target.js","../../src/routes/tasks/goals.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 CircleDashed = createLucideIcon(\"CircleDashed\", [\n [\"path\", { d: \"M10.1 2.182a10 10 0 0 1 3.8 0\", key: \"5ilxe3\" }],\n [\"path\", { d: \"M13.9 21.818a10 10 0 0 1-3.8 0\", key: \"11zvb9\" }],\n [\"path\", { d: \"M17.609 3.721a10 10 0 0 1 2.69 2.7\", key: \"1iw5b2\" }],\n [\"path\", { d: \"M2.182 13.9a10 10 0 0 1 0-3.8\", key: \"c0bmvh\" }],\n [\"path\", { d: \"M20.279 17.609a10 10 0 0 1-2.7 2.69\", key: \"1ruxm7\" }],\n [\"path\", { d: \"M21.818 10.1a10 10 0 0 1 0 3.8\", key: \"qkgqxc\" }],\n [\"path\", { d: \"M3.721 6.391a10 10 0 0 1 2.7-2.69\", key: \"1mcia2\" }],\n [\"path\", { d: \"M6.391 20.279a10 10 0 0 1-2.69-2.7\", key: \"1fvljs\" }]\n]);\n\nexport { CircleDashed as default };\n//# sourceMappingURL=circle-dashed.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 CirclePause = createLucideIcon(\"CirclePause\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"10\", x2: \"10\", y1: \"15\", y2: \"9\", key: \"c1nkhi\" }],\n [\"line\", { x1: \"14\", x2: \"14\", y1: \"15\", y2: \"9\", key: \"h65svq\" }]\n]);\n\nexport { CirclePause as default };\n//# sourceMappingURL=circle-pause.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 Target = createLucideIcon(\"Target\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"6\", key: \"1vlfrh\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"2\", key: \"1c9p78\" }]\n]);\n\nexport { Target as default };\n//# sourceMappingURL=target.js.map\n","/**\n * /tasks/goals — admin overview of every ACTIVE goal (P1).\n */\n\nimport { Fragment, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { CheckCircle2, CircleDashed, Loader2, PauseCircle, RefreshCcw, Target, XCircle } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useGoalsList, useGoalUpdateStatus, type GoalRow,\n} from '@/hooks/use-background-tasks'\n\nexport default function TasksGoalsRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const listQuery = useGoalsList()\n const updateStatus = useGoalUpdateStatus()\n const [expandedId, setExpandedId] = useState<number | null>(null)\n\n async function onChangeStatus(g: GoalRow, status: GoalRow['status']): Promise<void> {\n try {\n await updateStatus.mutateAsync({ id: g.id, status })\n toast.success(t('goals.statusUpdated', {\n status: t(`goals.status.${status}`, { defaultValue: status }),\n }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n const rows = listQuery.data?.goals ?? []\n return (\n <div className=\"mx-auto flex max-w-6xl flex-col gap-4 p-4\">\n <header className=\"flex items-center gap-3\">\n <Target className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('goals.title')}</h1>\n <Badge variant=\"info\">{rows.length}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('goals.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('goals.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : rows.length === 0 ? (\n <EmptySection />\n ) : (\n <section className=\"rounded-md border border-border bg-surface\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-12\">{t('goals.col.id')}</TableHead>\n <TableHead>{t('goals.col.thread')}</TableHead>\n <TableHead>{t('goals.col.title')}</TableHead>\n <TableHead>{t('goals.col.progress')}</TableHead>\n <TableHead>{t('goals.col.updated')}</TableHead>\n <TableHead>{t('goals.col.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((g) => {\n const isExpanded = expandedId === g.id\n return (\n <Fragment key={g.id}>\n <TableRow>\n <TableCell className=\"font-mono text-xs\">{g.id}</TableCell>\n <TableCell className=\"font-mono text-[11px]\">{g.platform}:{g.threadId}</TableCell>\n <TableCell>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"-ml-2 text-left\"\n onClick={() => setExpandedId(isExpanded ? null : g.id)}\n title={isExpanded ? t('goals.hideBody') : t('goals.showBody')}\n >\n {g.title}\n </Button>\n </TableCell>\n <TableCell><Badge variant=\"outline\">{g.progressCount}</Badge></TableCell>\n <TableCell className=\"text-[11px] text-text-dim\">{g.updatedAt}</TableCell>\n <TableCell className=\"flex flex-wrap gap-1\">\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.pause')}\n onClick={() => void onChangeStatus(g, 'paused')}\n disabled={updateStatus.isPending}\n >\n <PauseCircle className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.complete')}\n onClick={() => void onChangeStatus(g, 'completed')}\n disabled={updateStatus.isPending}\n >\n <CheckCircle2 className=\"h-4 w-4 text-success\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.cancel')}\n onClick={() => void onChangeStatus(g, 'cancelled')}\n disabled={updateStatus.isPending}\n className=\"text-danger hover:text-danger\"\n >\n <XCircle className=\"h-4 w-4\" />\n </Button>\n </TableCell>\n </TableRow>\n {isExpanded && (\n <TableRow>\n <TableCell />\n <TableCell colSpan={5}>\n <div className=\"space-y-2 rounded bg-surface-2 p-3 text-xs\">\n {g.body && (\n <div>\n <div className=\"text-text-dim\">{t('goals.body')}</div>\n <pre className=\"mt-1 whitespace-pre-wrap break-words\">{g.body}</pre>\n </div>\n )}\n {g.progressLog.length > 0 && (\n <div>\n <div className=\"text-text-dim\">\n {t('goals.recentProgress', { count: g.progressLog.length })}\n </div>\n <ul className=\"mt-1 space-y-1\">\n {g.progressLog.slice().reverse().map((n) => (\n <li key={`${n.ts}-${n.by}-${n.text}`} className=\"font-mono text-[11px]\">\n <span className=\"text-text-dim\">{n.ts.slice(0, 19)} ({n.by})</span> {n.text}\n </li>\n ))}\n </ul>\n </div>\n )}\n <div className=\"text-[11px] text-text-dim\">\n {t('goals.created', { at: g.createdAt })}\n {g.closedAt ? ` · ${t('goals.closed', { at: g.closedAt })}` : ''}\n </div>\n </div>\n </TableCell>\n </TableRow>\n )}\n </Fragment>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )}\n </div>\n )\n}\n\nfunction EmptySection(): JSX.Element {\n const { t } = useTranslation('tasks')\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('goals.empty')}\n <div className=\"mt-2\">\n <CircleDashed className=\"mx-auto h-8 w-8 opacity-30\" />\n </div>\n </section>\n )\n}\n"],"names":["CircleDashed","createLucideIcon","CirclePause","Target","TasksGoalsRoute","t","useTranslation","listQuery","useGoalsList","updateStatus","useGoalUpdateStatus","expandedId","setExpandedId","useState","onChangeStatus","g","status","toast","err","rows","jsxs","jsx","Badge","Button","Loader2","RefreshCcw","EmptySection","Table","TableHeader","TableRow","TableHead","TableBody","isExpanded","Fragment","TableCell","PauseCircle","CheckCircle2","XCircle","n"],"mappings":"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","x_google_ignoreList":[0,1,2]}
1
+ {"version":3,"file":"goals-C8ZQfbhj.js","sources":["../../node_modules/lucide-react/dist/esm/icons/circle-dashed.js","../../node_modules/lucide-react/dist/esm/icons/circle-pause.js","../../node_modules/lucide-react/dist/esm/icons/target.js","../../src/routes/tasks/goals.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 CircleDashed = createLucideIcon(\"CircleDashed\", [\n [\"path\", { d: \"M10.1 2.182a10 10 0 0 1 3.8 0\", key: \"5ilxe3\" }],\n [\"path\", { d: \"M13.9 21.818a10 10 0 0 1-3.8 0\", key: \"11zvb9\" }],\n [\"path\", { d: \"M17.609 3.721a10 10 0 0 1 2.69 2.7\", key: \"1iw5b2\" }],\n [\"path\", { d: \"M2.182 13.9a10 10 0 0 1 0-3.8\", key: \"c0bmvh\" }],\n [\"path\", { d: \"M20.279 17.609a10 10 0 0 1-2.7 2.69\", key: \"1ruxm7\" }],\n [\"path\", { d: \"M21.818 10.1a10 10 0 0 1 0 3.8\", key: \"qkgqxc\" }],\n [\"path\", { d: \"M3.721 6.391a10 10 0 0 1 2.7-2.69\", key: \"1mcia2\" }],\n [\"path\", { d: \"M6.391 20.279a10 10 0 0 1-2.69-2.7\", key: \"1fvljs\" }]\n]);\n\nexport { CircleDashed as default };\n//# sourceMappingURL=circle-dashed.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 CirclePause = createLucideIcon(\"CirclePause\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"10\", x2: \"10\", y1: \"15\", y2: \"9\", key: \"c1nkhi\" }],\n [\"line\", { x1: \"14\", x2: \"14\", y1: \"15\", y2: \"9\", key: \"h65svq\" }]\n]);\n\nexport { CirclePause as default };\n//# sourceMappingURL=circle-pause.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 Target = createLucideIcon(\"Target\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"6\", key: \"1vlfrh\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"2\", key: \"1c9p78\" }]\n]);\n\nexport { Target as default };\n//# sourceMappingURL=target.js.map\n","/**\n * /tasks/goals — admin overview of every ACTIVE goal (P1).\n */\n\nimport { Fragment, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { CheckCircle2, CircleDashed, Loader2, PauseCircle, RefreshCcw, Target, XCircle } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useGoalsList, useGoalUpdateStatus, type GoalRow,\n} from '@/hooks/use-background-tasks'\n\nexport default function TasksGoalsRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const listQuery = useGoalsList()\n const updateStatus = useGoalUpdateStatus()\n const [expandedId, setExpandedId] = useState<number | null>(null)\n\n async function onChangeStatus(g: GoalRow, status: GoalRow['status']): Promise<void> {\n try {\n await updateStatus.mutateAsync({ id: g.id, status })\n toast.success(t('goals.statusUpdated', {\n status: t(`goals.status.${status}`, { defaultValue: status }),\n }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n const rows = listQuery.data?.goals ?? []\n return (\n <div className=\"mx-auto flex max-w-6xl flex-col gap-4 p-4\">\n <header className=\"flex items-center gap-3\">\n <Target className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('goals.title')}</h1>\n <Badge variant=\"info\">{rows.length}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('goals.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('goals.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : rows.length === 0 ? (\n <EmptySection />\n ) : (\n <section className=\"rounded-md border border-border bg-surface\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-12\">{t('goals.col.id')}</TableHead>\n <TableHead>{t('goals.col.thread')}</TableHead>\n <TableHead>{t('goals.col.title')}</TableHead>\n <TableHead>{t('goals.col.progress')}</TableHead>\n <TableHead>{t('goals.col.updated')}</TableHead>\n <TableHead>{t('goals.col.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((g) => {\n const isExpanded = expandedId === g.id\n return (\n <Fragment key={g.id}>\n <TableRow>\n <TableCell className=\"font-mono text-xs\">{g.id}</TableCell>\n <TableCell className=\"font-mono text-[11px]\">{g.platform}:{g.threadId}</TableCell>\n <TableCell>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"-ml-2 text-left\"\n onClick={() => setExpandedId(isExpanded ? null : g.id)}\n title={isExpanded ? t('goals.hideBody') : t('goals.showBody')}\n >\n {g.title}\n </Button>\n </TableCell>\n <TableCell><Badge variant=\"outline\">{g.progressCount}</Badge></TableCell>\n <TableCell className=\"text-[11px] text-text-dim\">{g.updatedAt}</TableCell>\n <TableCell className=\"flex flex-wrap gap-1\">\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.pause')}\n onClick={() => void onChangeStatus(g, 'paused')}\n disabled={updateStatus.isPending}\n >\n <PauseCircle className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.complete')}\n onClick={() => void onChangeStatus(g, 'completed')}\n disabled={updateStatus.isPending}\n >\n <CheckCircle2 className=\"h-4 w-4 text-success\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.cancel')}\n onClick={() => void onChangeStatus(g, 'cancelled')}\n disabled={updateStatus.isPending}\n className=\"text-danger hover:text-danger\"\n >\n <XCircle className=\"h-4 w-4\" />\n </Button>\n </TableCell>\n </TableRow>\n {isExpanded && (\n <TableRow>\n <TableCell />\n <TableCell colSpan={5}>\n <div className=\"space-y-2 rounded bg-surface-2 p-3 text-xs\">\n {g.body && (\n <div>\n <div className=\"text-text-dim\">{t('goals.body')}</div>\n <pre className=\"mt-1 whitespace-pre-wrap break-words\">{g.body}</pre>\n </div>\n )}\n {g.progressLog.length > 0 && (\n <div>\n <div className=\"text-text-dim\">\n {t('goals.recentProgress', { count: g.progressLog.length })}\n </div>\n <ul className=\"mt-1 space-y-1\">\n {g.progressLog.slice().reverse().map((n) => (\n <li key={`${n.ts}-${n.by}-${n.text}`} className=\"font-mono text-[11px]\">\n <span className=\"text-text-dim\">{n.ts.slice(0, 19)} ({n.by})</span> {n.text}\n </li>\n ))}\n </ul>\n </div>\n )}\n <div className=\"text-[11px] text-text-dim\">\n {t('goals.created', { at: g.createdAt })}\n {g.closedAt ? ` · ${t('goals.closed', { at: g.closedAt })}` : ''}\n </div>\n </div>\n </TableCell>\n </TableRow>\n )}\n </Fragment>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )}\n </div>\n )\n}\n\nfunction EmptySection(): JSX.Element {\n const { t } = useTranslation('tasks')\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('goals.empty')}\n <div className=\"mt-2\">\n <CircleDashed className=\"mx-auto h-8 w-8 opacity-30\" />\n </div>\n </section>\n )\n}\n"],"names":["CircleDashed","createLucideIcon","CirclePause","Target","TasksGoalsRoute","t","useTranslation","listQuery","useGoalsList","updateStatus","useGoalUpdateStatus","expandedId","setExpandedId","useState","onChangeStatus","g","status","toast","err","rows","jsxs","jsx","Badge","Button","Loader2","RefreshCcw","EmptySection","Table","TableHeader","TableRow","TableHead","TableBody","isExpanded","Fragment","TableCell","PauseCircle","CheckCircle2","XCircle","n"],"mappings":"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","x_google_ignoreList":[0,1,2]}
@@ -0,0 +1,2 @@
1
+ import{u as p,i as f,j as e,e as g,f as y}from"./index-DCfdN5R7.js";import{r as N}from"./react-DlP5eolq.js";import{E as v}from"./empty-state-CuiqdZiB.js";import{T as w,a as C,b as h,c as i,d as M,e as o}from"./table-sCMZBe_Z.js";import{u as L}from"./use-observability-CY5ZUPrC.js";import{L as T}from"./loader-circle-DDdmcH0k.js";import{R as k}from"./refresh-ccw-DlAd-eTQ.js";import{A as D}from"./activity-ul8Os7Pz.js";function K(){const{t:s}=p(["observability","common"]),[l]=f(),n=Math.max(1,Number(l.get("days"))||7),{data:c,isLoading:u,isFetching:m,refetch:j}=L(n),a=c?.totals,d=c?.byDay??[],b=N.useMemo(()=>d.reduce((t,x)=>x.calls>t?x.calls:t,0),[d]);return e.jsxs("div",{className:"mx-auto flex max-w-7xl 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("health.title")}),e.jsxs(g,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>j(),disabled:m,"aria-label":s("actions.refresh",{ns:"common"}),children:[m?e.jsx(T,{className:"h-4 w-4 animate-spin"}):e.jsx(k,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]}),c&&e.jsxs("p",{className:"text-xs text-text-dim tabular-nums",children:[c.since," → ",c.until]})]}),u?e.jsx("div",{className:"h-48 w-full rounded-md bg-surface-2 animate-pulse"}):!a||a.calls===0&&d.length===0?e.jsx(v,{icon:e.jsx(D,{}),title:s("health.empty.title"),description:s("health.empty.description")}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6",children:[e.jsx(r,{label:s("health.kpi.calls"),value:String(a.calls),tone:"info"}),e.jsx(r,{label:s("health.kpi.cost"),value:`$${a.cost.toFixed(4)}`,tone:"info"}),e.jsx(r,{label:s("health.kpi.errors"),value:String(a.errors),tone:a.errors>0?"danger":"success"}),e.jsx(r,{label:s("health.kpi.errorRate"),value:`${(a.errorRate*100).toFixed(1)}%`,tone:a.errorRate>.05?"warning":"success"}),e.jsx(r,{label:s("health.kpi.avgLatencyMs"),value:`${Math.round(a.avgLatencyMs)}ms`,tone:"info"}),e.jsx(r,{label:s("health.kpi.p95LatencyMs"),value:`${Math.round(a.p95LatencyMs)}ms`,tone:"info"})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"mb-2 text-sm font-medium uppercase tracking-wide text-text-dim",children:s("health.byDay")}),e.jsxs(w,{children:[e.jsx(C,{children:e.jsxs(h,{children:[e.jsx(i,{className:"w-28",children:s("health.byDayCol.date")}),e.jsx(i,{children:s("health.byDayCol.calls")}),e.jsx(i,{className:"w-24",children:s("health.byDayCol.cost")}),e.jsx(i,{className:"w-24",children:s("health.byDayCol.errors")}),e.jsx(i,{className:"w-32",children:s("health.byDayCol.avgLatencyMs")})]})}),e.jsx(M,{children:d.map(t=>e.jsxs(h,{children:[e.jsx(o,{className:"font-mono text-xs",children:t.date}),e.jsx(o,{children:e.jsx(S,{value:t.calls,max:b})}),e.jsxs(o,{className:"tabular-nums",children:["$",t.cost.toFixed(4)]}),e.jsx(o,{className:"tabular-nums",children:e.jsx("span",{className:t.errors>0?"text-danger":"text-text-dim",children:t.errors})}),e.jsxs(o,{className:"tabular-nums",children:[Math.round(t.avgLatencyMs),"ms"]})]},t.date))})]})]})]})]})}const R={info:"border-info/30 text-info",success:"border-success/30 text-success",warning:"border-warning/30 text-warning",danger:"border-danger/30 text-danger"};function r({label:s,value:l,tone:n}){return e.jsxs("div",{className:y("rounded-md border bg-surface px-3 py-2",R[n]),children:[e.jsx("div",{className:"text-xs uppercase tracking-wide text-text-dim",children:s}),e.jsx("div",{className:"text-xl font-semibold tabular-nums",children:l})]})}function S({value:s,max:l}){const n=l>0?s/l*100:0;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"relative h-3 w-full max-w-xs overflow-hidden rounded bg-surface-2",children:e.jsx("div",{className:"absolute inset-y-0 left-0 bg-accent/60",style:{width:`${n}%`}})}),e.jsx("span",{className:"tabular-nums text-sm text-text-dim",children:s})]})}export{K as default};
2
+ //# sourceMappingURL=health-A2StNEfn.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"health-DLzZ7KHc.js","sources":["../../src/routes/observability/health.tsx"],"sourcesContent":["/**\n * /observability/health — invocation totals + per-day breakdown.\n *\n * No chart library yet (would push bundle past budget). Instead we\n * render a CSS bar chart inline: each byDay row gets a horizontal\n * bar proportional to the max calls across the window. Cheap,\n * readable, no JS dependency.\n */\n\nimport { useMemo } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { Activity, Loader2, RefreshCcw } from 'lucide-react'\n\nimport { EmptyState } from '@/components/common/empty-state'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table'\nimport { Button } from '@/components/ui/button'\nimport { useHealthSummary } from '@/hooks/use-observability'\nimport { cn } from '@/lib/utils'\n\nexport default function ObservabilityHealthRoute(): JSX.Element {\n const { t } = useTranslation(['observability', 'common'])\n const [params] = useSearchParams()\n const days = Math.max(1, Number(params.get('days')) || 7)\n\n const { data, isLoading, isFetching, refetch } = useHealthSummary(days)\n const totals = data?.totals\n const byDay = data?.byDay ?? []\n\n const maxCalls = useMemo(\n () => byDay.reduce((m, r) => (r.calls > m ? r.calls : m), 0),\n [byDay],\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('health.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 {data && (\n <p className=\"text-xs text-text-dim tabular-nums\">{data.since} → {data.until}</p>\n )}\n </header>\n\n {isLoading ? (\n <div className=\"h-48 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : !totals || (totals.calls === 0 && byDay.length === 0) ? (\n <EmptyState\n icon={<Activity />}\n title={t('health.empty.title')}\n description={t('health.empty.description')}\n />\n ) : (\n <>\n {/* KPI strip */}\n <div className=\"grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6\">\n <Kpi label={t('health.kpi.calls')} value={String(totals.calls)} tone=\"info\" />\n <Kpi label={t('health.kpi.cost')} value={`$${totals.cost.toFixed(4)}`} tone=\"info\" />\n <Kpi label={t('health.kpi.errors')} value={String(totals.errors)} tone={totals.errors > 0 ? 'danger' : 'success'} />\n <Kpi label={t('health.kpi.errorRate')} value={`${(totals.errorRate * 100).toFixed(1)}%`} tone={totals.errorRate > 0.05 ? 'warning' : 'success'} />\n <Kpi label={t('health.kpi.avgLatencyMs')} value={`${Math.round(totals.avgLatencyMs)}ms`} tone=\"info\" />\n <Kpi label={t('health.kpi.p95LatencyMs')} value={`${Math.round(totals.p95LatencyMs)}ms`} tone=\"info\" />\n </div>\n\n {/* By-day table with inline CSS bars */}\n <div>\n <h2 className=\"mb-2 text-sm font-medium uppercase tracking-wide text-text-dim\">\n {t('health.byDay')}\n </h2>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-28\">{t('health.byDayCol.date')}</TableHead>\n <TableHead>{t('health.byDayCol.calls')}</TableHead>\n <TableHead className=\"w-24\">{t('health.byDayCol.cost')}</TableHead>\n <TableHead className=\"w-24\">{t('health.byDayCol.errors')}</TableHead>\n <TableHead className=\"w-32\">{t('health.byDayCol.avgLatencyMs')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {byDay.map((r) => (\n <TableRow key={r.date}>\n <TableCell className=\"font-mono text-xs\">{r.date}</TableCell>\n <TableCell>\n <CallsBar value={r.calls} max={maxCalls} />\n </TableCell>\n <TableCell className=\"tabular-nums\">${r.cost.toFixed(4)}</TableCell>\n <TableCell className=\"tabular-nums\">\n <span className={r.errors > 0 ? 'text-danger' : 'text-text-dim'}>{r.errors}</span>\n </TableCell>\n <TableCell className=\"tabular-nums\">{Math.round(r.avgLatencyMs)}ms</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n </>\n )}\n </div>\n )\n}\n\ninterface KpiProps {\n label: string\n value: string\n tone: 'info' | 'success' | 'warning' | 'danger'\n}\n\nconst TONE_STYLES: Record<KpiProps['tone'], string> = {\n info: 'border-info/30 text-info',\n success: 'border-success/30 text-success',\n warning: 'border-warning/30 text-warning',\n danger: 'border-danger/30 text-danger',\n}\n\nfunction Kpi({ label, value, tone }: KpiProps): JSX.Element {\n return (\n <div className={cn('rounded-md border bg-surface px-3 py-2', TONE_STYLES[tone])}>\n <div className=\"text-xs uppercase tracking-wide text-text-dim\">{label}</div>\n <div className=\"text-xl font-semibold tabular-nums\">{value}</div>\n </div>\n )\n}\n\ninterface CallsBarProps {\n value: number\n max: number\n}\n\n/** Inline CSS bar — width proportional to max across the window. */\nfunction CallsBar({ value, max }: CallsBarProps): JSX.Element {\n const pct = max > 0 ? (value / max) * 100 : 0\n return (\n <div className=\"flex items-center gap-2\">\n <div className=\"relative h-3 w-full max-w-xs overflow-hidden rounded bg-surface-2\">\n <div\n className=\"absolute inset-y-0 left-0 bg-accent/60\"\n style={{ width: `${pct}%` }}\n />\n </div>\n <span className=\"tabular-nums text-sm text-text-dim\">{value}</span>\n </div>\n )\n}\n"],"names":["ObservabilityHealthRoute","t","useTranslation","params","useSearchParams","days","data","isLoading","isFetching","refetch","useHealthSummary","totals","byDay","maxCalls","useMemo","m","r","jsxs","jsx","Button","Loader2","RefreshCcw","EmptyState","Activity","Fragment","Kpi","Table","TableHeader","TableRow","TableHead","TableBody","TableCell","CallsBar","TONE_STYLES","label","value","tone","cn","max","pct"],"mappings":"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"}
1
+ {"version":3,"file":"health-A2StNEfn.js","sources":["../../src/routes/observability/health.tsx"],"sourcesContent":["/**\n * /observability/health — invocation totals + per-day breakdown.\n *\n * No chart library yet (would push bundle past budget). Instead we\n * render a CSS bar chart inline: each byDay row gets a horizontal\n * bar proportional to the max calls across the window. Cheap,\n * readable, no JS dependency.\n */\n\nimport { useMemo } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { Activity, Loader2, RefreshCcw } from 'lucide-react'\n\nimport { EmptyState } from '@/components/common/empty-state'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table'\nimport { Button } from '@/components/ui/button'\nimport { useHealthSummary } from '@/hooks/use-observability'\nimport { cn } from '@/lib/utils'\n\nexport default function ObservabilityHealthRoute(): JSX.Element {\n const { t } = useTranslation(['observability', 'common'])\n const [params] = useSearchParams()\n const days = Math.max(1, Number(params.get('days')) || 7)\n\n const { data, isLoading, isFetching, refetch } = useHealthSummary(days)\n const totals = data?.totals\n const byDay = data?.byDay ?? []\n\n const maxCalls = useMemo(\n () => byDay.reduce((m, r) => (r.calls > m ? r.calls : m), 0),\n [byDay],\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('health.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 {data && (\n <p className=\"text-xs text-text-dim tabular-nums\">{data.since} → {data.until}</p>\n )}\n </header>\n\n {isLoading ? (\n <div className=\"h-48 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : !totals || (totals.calls === 0 && byDay.length === 0) ? (\n <EmptyState\n icon={<Activity />}\n title={t('health.empty.title')}\n description={t('health.empty.description')}\n />\n ) : (\n <>\n {/* KPI strip */}\n <div className=\"grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6\">\n <Kpi label={t('health.kpi.calls')} value={String(totals.calls)} tone=\"info\" />\n <Kpi label={t('health.kpi.cost')} value={`$${totals.cost.toFixed(4)}`} tone=\"info\" />\n <Kpi label={t('health.kpi.errors')} value={String(totals.errors)} tone={totals.errors > 0 ? 'danger' : 'success'} />\n <Kpi label={t('health.kpi.errorRate')} value={`${(totals.errorRate * 100).toFixed(1)}%`} tone={totals.errorRate > 0.05 ? 'warning' : 'success'} />\n <Kpi label={t('health.kpi.avgLatencyMs')} value={`${Math.round(totals.avgLatencyMs)}ms`} tone=\"info\" />\n <Kpi label={t('health.kpi.p95LatencyMs')} value={`${Math.round(totals.p95LatencyMs)}ms`} tone=\"info\" />\n </div>\n\n {/* By-day table with inline CSS bars */}\n <div>\n <h2 className=\"mb-2 text-sm font-medium uppercase tracking-wide text-text-dim\">\n {t('health.byDay')}\n </h2>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-28\">{t('health.byDayCol.date')}</TableHead>\n <TableHead>{t('health.byDayCol.calls')}</TableHead>\n <TableHead className=\"w-24\">{t('health.byDayCol.cost')}</TableHead>\n <TableHead className=\"w-24\">{t('health.byDayCol.errors')}</TableHead>\n <TableHead className=\"w-32\">{t('health.byDayCol.avgLatencyMs')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {byDay.map((r) => (\n <TableRow key={r.date}>\n <TableCell className=\"font-mono text-xs\">{r.date}</TableCell>\n <TableCell>\n <CallsBar value={r.calls} max={maxCalls} />\n </TableCell>\n <TableCell className=\"tabular-nums\">${r.cost.toFixed(4)}</TableCell>\n <TableCell className=\"tabular-nums\">\n <span className={r.errors > 0 ? 'text-danger' : 'text-text-dim'}>{r.errors}</span>\n </TableCell>\n <TableCell className=\"tabular-nums\">{Math.round(r.avgLatencyMs)}ms</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n </>\n )}\n </div>\n )\n}\n\ninterface KpiProps {\n label: string\n value: string\n tone: 'info' | 'success' | 'warning' | 'danger'\n}\n\nconst TONE_STYLES: Record<KpiProps['tone'], string> = {\n info: 'border-info/30 text-info',\n success: 'border-success/30 text-success',\n warning: 'border-warning/30 text-warning',\n danger: 'border-danger/30 text-danger',\n}\n\nfunction Kpi({ label, value, tone }: KpiProps): JSX.Element {\n return (\n <div className={cn('rounded-md border bg-surface px-3 py-2', TONE_STYLES[tone])}>\n <div className=\"text-xs uppercase tracking-wide text-text-dim\">{label}</div>\n <div className=\"text-xl font-semibold tabular-nums\">{value}</div>\n </div>\n )\n}\n\ninterface CallsBarProps {\n value: number\n max: number\n}\n\n/** Inline CSS bar — width proportional to max across the window. */\nfunction CallsBar({ value, max }: CallsBarProps): JSX.Element {\n const pct = max > 0 ? (value / max) * 100 : 0\n return (\n <div className=\"flex items-center gap-2\">\n <div className=\"relative h-3 w-full max-w-xs overflow-hidden rounded bg-surface-2\">\n <div\n className=\"absolute inset-y-0 left-0 bg-accent/60\"\n style={{ width: `${pct}%` }}\n />\n </div>\n <span className=\"tabular-nums text-sm text-text-dim\">{value}</span>\n </div>\n )\n}\n"],"names":["ObservabilityHealthRoute","t","useTranslation","params","useSearchParams","days","data","isLoading","isFetching","refetch","useHealthSummary","totals","byDay","maxCalls","useMemo","m","r","jsxs","jsx","Button","Loader2","RefreshCcw","EmptyState","Activity","Fragment","Kpi","Table","TableHeader","TableRow","TableHead","TableBody","TableCell","CallsBar","TONE_STYLES","label","value","tone","cn","max","pct"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import{o as e}from"./index-DY2Zglku.js";/**
1
+ import{h as e}from"./index-DCfdN5R7.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("HeartPulse",[["path",{d:"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z",key:"c3ymky"}],["path",{d:"M3.22 12H9.5l.5-1 2 4.5 2-7 1.5 3.5h5.27",key:"1uw2ng"}]]);export{t as H};
7
- //# sourceMappingURL=heart-pulse-CVEeD2sz.js.map
7
+ //# sourceMappingURL=heart-pulse-DXlE9oic.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"heart-pulse-CVEeD2sz.js","sources":["../../node_modules/lucide-react/dist/esm/icons/heart-pulse.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 HeartPulse = createLucideIcon(\"HeartPulse\", [\n [\n \"path\",\n {\n d: \"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z\",\n key: \"c3ymky\"\n }\n ],\n [\"path\", { d: \"M3.22 12H9.5l.5-1 2 4.5 2-7 1.5 3.5h5.27\", key: \"1uw2ng\" }]\n]);\n\nexport { HeartPulse as default };\n//# sourceMappingURL=heart-pulse.js.map\n"],"names":["HeartPulse","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAaC,EAAiB,aAAc,CAChD,CACE,OACA,CACE,EAAG,2IACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,2CAA4C,IAAK,QAAQ,CAAE,CAC3E,CAAC","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"heart-pulse-DXlE9oic.js","sources":["../../node_modules/lucide-react/dist/esm/icons/heart-pulse.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 HeartPulse = createLucideIcon(\"HeartPulse\", [\n [\n \"path\",\n {\n d: \"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z\",\n key: \"c3ymky\"\n }\n ],\n [\"path\", { d: \"M3.22 12H9.5l.5-1 2 4.5 2-7 1.5 3.5h5.27\", key: \"1uw2ng\" }]\n]);\n\nexport { HeartPulse as default };\n//# sourceMappingURL=heart-pulse.js.map\n"],"names":["HeartPulse","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAaC,EAAiB,aAAc,CAChD,CACE,OACA,CACE,EAAG,2IACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,2CAA4C,IAAK,QAAQ,CAAE,CAC3E,CAAC","x_google_ignoreList":[0]}
@@ -1,7 +1,7 @@
1
- import{o as w,u as b,j as e,l as o,B as h,m}from"./index-DY2Zglku.js";import{r as N}from"./react-DlP5eolq.js";import{T as v,a as T,b as u,c as l,d as y,e as c}from"./table-_WsrnZ_T.js";import{u as k,a as A}from"./use-background-tasks-wCL7jn68.js";import{H}from"./heart-pulse-CVEeD2sz.js";import{L as R}from"./loader-circle-D8L1w9c1.js";import{R as S}from"./refresh-ccw-7HdadG5V.js";import{P as C}from"./play-Di1jqulh.js";/**
1
+ import{h as w,u as b,j as e,d as o,e as h,p as m}from"./index-DCfdN5R7.js";import{r as N}from"./react-DlP5eolq.js";import{T as v,a as T,b as u,c as l,d as y,e as c}from"./table-sCMZBe_Z.js";import{u as k,c as A}from"./use-background-tasks-CwFmOokw.js";import{H}from"./heart-pulse-DXlE9oic.js";import{L as R}from"./loader-circle-DDdmcH0k.js";import{R as S}from"./refresh-ccw-DlAd-eTQ.js";import{P as C}from"./play-DX5wp4WH.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
- */const P=w("Pause",[["rect",{x:"14",y:"4",width:"4",height:"16",rx:"1",key:"zuxfzm"}],["rect",{x:"6",y:"4",width:"4",height:"16",rx:"1",key:"1okwgv"}]]);function K(){const{t}=b(["tasks","common"]),s=k(),r=A(),[j,f]=N.useState(null);async function g(a,n){try{await r.mutateAsync({row:a,op:n}),m.success(t(n==="enable"?"heartbeat.enabledToast":"heartbeat.disabledToast"))}catch(i){m.error(i?.message??String(i))}}const d=s.data?.bindings??[];return e.jsxs("div",{className:"mx-auto flex max-w-6xl flex-col gap-4 p-4",children:[e.jsxs("header",{className:"flex items-center gap-3",children:[e.jsx(H,{className:"h-5 w-5 text-text-dim"}),e.jsx("h1",{className:"text-xl font-semibold",children:t("heartbeat.title")}),e.jsx(o,{variant:"info",children:d.length}),e.jsxs(h,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>void s.refetch(),disabled:s.isFetching,"aria-label":t("actions.refresh",{ns:"common"}),children:[s.isFetching?e.jsx(R,{className:"h-4 w-4 animate-spin"}):e.jsx(S,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:t("heartbeat.refresh")})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:t("heartbeat.subtitle")}),s.isLoading?e.jsx("div",{className:"h-48 rounded-md bg-surface-2 animate-pulse"}):d.length===0?e.jsx(z,{}):e.jsx("section",{className:"rounded-md border border-border bg-surface",children:e.jsxs(v,{children:[e.jsx(T,{children:e.jsxs(u,{children:[e.jsx(l,{children:t("heartbeat.col.thread")}),e.jsx(l,{children:t("heartbeat.col.owner")}),e.jsx(l,{children:t("heartbeat.col.interval")}),e.jsx(l,{children:t("heartbeat.col.lastTick")}),e.jsx(l,{children:t("heartbeat.col.enabled")}),e.jsx(l,{children:t("heartbeat.col.body")})]})}),e.jsx(y,{children:d.map(a=>{const n=`${a.platform}:${a.channelId}:${a.threadId}`,i=j===n,p=a.lastTickAt?a.lastStatus==="delivered"?e.jsx(o,{variant:"success",children:x(a.lastTickAt,t)}):a.lastStatus==="error"?e.jsxs(o,{variant:"danger",title:a.lastReason,children:[a.lastStatus," · ",x(a.lastTickAt,t)]}):e.jsxs(o,{variant:"outline",title:a.lastReason,children:[a.lastStatus," · ",x(a.lastTickAt,t)]}):e.jsx(o,{variant:"outline",children:t("heartbeat.never")});return e.jsxs(u,{children:[e.jsxs(c,{className:"font-mono text-[11px]",children:[a.platform,":",a.threadId]}),e.jsx(c,{className:"font-mono text-[11px]",children:a.userId||"—"}),e.jsx(c,{className:"text-xs",children:t("heartbeat.intervalMin",{count:a.intervalMinutes})}),e.jsx(c,{children:p}),e.jsx(c,{children:e.jsx(h,{variant:"ghost",size:"sm",onClick:()=>void g(a,a.enabled?"disable":"enable"),disabled:r.isPending,children:a.enabled?e.jsxs(e.Fragment,{children:[e.jsx(P,{className:"h-4 w-4"}),e.jsx("span",{children:t("heartbeat.pause")})]}):e.jsxs(e.Fragment,{children:[e.jsx(C,{className:"h-4 w-4"}),e.jsx("span",{children:t("heartbeat.enable")})]})})}),e.jsxs(c,{className:"max-w-md",children:[e.jsx(h,{variant:"ghost",size:"sm",onClick:()=>f(i?null:n),className:"-ml-2",children:t(i?"heartbeat.hide":"heartbeat.show")}),i&&e.jsx("pre",{className:"mt-2 whitespace-pre-wrap break-words rounded bg-surface-2 p-2 text-[11px] text-text-dim",children:a.body})]})]},n)})})]})})]})}function z(){const{t}=b("tasks");return e.jsx("section",{className:"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim",children:t("heartbeat.empty")})}function x(t,s){if(!t)return s("heartbeat.never");const r=Date.now()-new Date(t).getTime();return!Number.isFinite(r)||r<0||r<6e4?s("heartbeat.justNow"):r<36e5?s("heartbeat.minutesAgo",{count:Math.floor(r/6e4)}):r<864e5?s("heartbeat.hoursAgo",{count:Math.floor(r/36e5)}):s("heartbeat.daysAgo",{count:Math.floor(r/864e5)})}export{K as default};
7
- //# sourceMappingURL=heartbeat-B1BEBHge.js.map
6
+ */const P=w("Pause",[["rect",{x:"14",y:"4",width:"4",height:"16",rx:"1",key:"zuxfzm"}],["rect",{x:"6",y:"4",width:"4",height:"16",rx:"1",key:"1okwgv"}]]);function K(){const{t}=b(["tasks","common"]),s=k(),r=A(),[j,f]=N.useState(null);async function p(a,n){try{await r.mutateAsync({row:a,op:n}),m.success(t(n==="enable"?"heartbeat.enabledToast":"heartbeat.disabledToast"))}catch(i){m.error(i?.message??String(i))}}const d=s.data?.bindings??[];return e.jsxs("div",{className:"mx-auto flex max-w-6xl flex-col gap-4 p-4",children:[e.jsxs("header",{className:"flex items-center gap-3",children:[e.jsx(H,{className:"h-5 w-5 text-text-dim"}),e.jsx("h1",{className:"text-xl font-semibold",children:t("heartbeat.title")}),e.jsx(o,{variant:"info",children:d.length}),e.jsxs(h,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>void s.refetch(),disabled:s.isFetching,"aria-label":t("actions.refresh",{ns:"common"}),children:[s.isFetching?e.jsx(R,{className:"h-4 w-4 animate-spin"}):e.jsx(S,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:t("heartbeat.refresh")})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:t("heartbeat.subtitle")}),s.isLoading?e.jsx("div",{className:"h-48 rounded-md bg-surface-2 animate-pulse"}):d.length===0?e.jsx(z,{}):e.jsx("section",{className:"rounded-md border border-border bg-surface",children:e.jsxs(v,{children:[e.jsx(T,{children:e.jsxs(u,{children:[e.jsx(l,{children:t("heartbeat.col.thread")}),e.jsx(l,{children:t("heartbeat.col.owner")}),e.jsx(l,{children:t("heartbeat.col.interval")}),e.jsx(l,{children:t("heartbeat.col.lastTick")}),e.jsx(l,{children:t("heartbeat.col.enabled")}),e.jsx(l,{children:t("heartbeat.col.body")})]})}),e.jsx(y,{children:d.map(a=>{const n=`${a.platform}:${a.channelId}:${a.threadId}`,i=j===n,g=a.lastTickAt?a.lastStatus==="delivered"?e.jsx(o,{variant:"success",children:x(a.lastTickAt,t)}):a.lastStatus==="error"?e.jsxs(o,{variant:"danger",title:a.lastReason,children:[a.lastStatus," · ",x(a.lastTickAt,t)]}):e.jsxs(o,{variant:"outline",title:a.lastReason,children:[a.lastStatus," · ",x(a.lastTickAt,t)]}):e.jsx(o,{variant:"outline",children:t("heartbeat.never")});return e.jsxs(u,{children:[e.jsxs(c,{className:"font-mono text-[11px]",children:[a.platform,":",a.threadId]}),e.jsx(c,{className:"font-mono text-[11px]",children:a.userId||"—"}),e.jsx(c,{className:"text-xs",children:t("heartbeat.intervalMin",{count:a.intervalMinutes})}),e.jsx(c,{children:g}),e.jsx(c,{children:e.jsx(h,{variant:"ghost",size:"sm",onClick:()=>void p(a,a.enabled?"disable":"enable"),disabled:r.isPending,children:a.enabled?e.jsxs(e.Fragment,{children:[e.jsx(P,{className:"h-4 w-4"}),e.jsx("span",{children:t("heartbeat.pause")})]}):e.jsxs(e.Fragment,{children:[e.jsx(C,{className:"h-4 w-4"}),e.jsx("span",{children:t("heartbeat.enable")})]})})}),e.jsxs(c,{className:"max-w-md",children:[e.jsx(h,{variant:"ghost",size:"sm",onClick:()=>f(i?null:n),className:"-ml-2",children:t(i?"heartbeat.hide":"heartbeat.show")}),i&&e.jsx("pre",{className:"mt-2 whitespace-pre-wrap break-words rounded bg-surface-2 p-2 text-[11px] text-text-dim",children:a.body})]})]},n)})})]})})]})}function z(){const{t}=b("tasks");return e.jsx("section",{className:"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim",children:t("heartbeat.empty")})}function x(t,s){if(!t)return s("heartbeat.never");const r=Date.now()-new Date(t).getTime();return!Number.isFinite(r)||r<0||r<6e4?s("heartbeat.justNow"):r<36e5?s("heartbeat.minutesAgo",{count:Math.floor(r/6e4)}):r<864e5?s("heartbeat.hoursAgo",{count:Math.floor(r/36e5)}):s("heartbeat.daysAgo",{count:Math.floor(r/864e5)})}export{K as default};
7
+ //# sourceMappingURL=heartbeat-ClO5gJrj.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"heartbeat-B1BEBHge.js","sources":["../../node_modules/lucide-react/dist/esm/icons/pause.js","../../src/routes/tasks/heartbeat.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 Pause = createLucideIcon(\"Pause\", [\n [\"rect\", { x: \"14\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"zuxfzm\" }],\n [\"rect\", { x: \"6\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"1okwgv\" }]\n]);\n\nexport { Pause as default };\n//# sourceMappingURL=pause.js.map\n","/**\n * /tasks/heartbeat — admin overview of every heartbeat binding (P1).\n */\n\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { HeartPulse, Loader2, Pause, Play, RefreshCcw } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useHeartbeatList, useHeartbeatToggle, type HeartbeatRow,\n} from '@/hooks/use-background-tasks'\n\nexport default function TasksHeartbeatRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const listQuery = useHeartbeatList()\n const toggle = useHeartbeatToggle()\n const [expandedKey, setExpandedKey] = useState<string | null>(null)\n\n async function onToggle(row: HeartbeatRow, op: 'enable' | 'disable'): Promise<void> {\n try {\n await toggle.mutateAsync({ row, op })\n toast.success(op === 'enable' ? t('heartbeat.enabledToast') : t('heartbeat.disabledToast'))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n const rows = listQuery.data?.bindings ?? []\n return (\n <div className=\"mx-auto flex max-w-6xl flex-col gap-4 p-4\">\n <header className=\"flex items-center gap-3\">\n <HeartPulse className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('heartbeat.title')}</h1>\n <Badge variant=\"info\">{rows.length}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('heartbeat.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('heartbeat.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : rows.length === 0 ? (\n <EmptySection />\n ) : (\n <section className=\"rounded-md border border-border bg-surface\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('heartbeat.col.thread')}</TableHead>\n <TableHead>{t('heartbeat.col.owner')}</TableHead>\n <TableHead>{t('heartbeat.col.interval')}</TableHead>\n <TableHead>{t('heartbeat.col.lastTick')}</TableHead>\n <TableHead>{t('heartbeat.col.enabled')}</TableHead>\n <TableHead>{t('heartbeat.col.body')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((r) => {\n const key = `${r.platform}:${r.channelId}:${r.threadId}`\n const isExpanded = expandedKey === key\n const tickBadge = !r.lastTickAt\n ? <Badge variant=\"outline\">{t('heartbeat.never')}</Badge>\n : r.lastStatus === 'delivered'\n ? <Badge variant=\"success\">{shortAge(r.lastTickAt, t)}</Badge>\n : r.lastStatus === 'error'\n ? <Badge variant=\"danger\" title={r.lastReason}>{r.lastStatus} · {shortAge(r.lastTickAt, t)}</Badge>\n : <Badge variant=\"outline\" title={r.lastReason}>{r.lastStatus} · {shortAge(r.lastTickAt, t)}</Badge>\n return (\n <TableRow key={key}>\n <TableCell className=\"font-mono text-[11px]\">{r.platform}:{r.threadId}</TableCell>\n <TableCell className=\"font-mono text-[11px]\">{r.userId || '—'}</TableCell>\n <TableCell className=\"text-xs\">{t('heartbeat.intervalMin', { count: r.intervalMinutes })}</TableCell>\n <TableCell>{tickBadge}</TableCell>\n <TableCell>\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onToggle(r, r.enabled ? 'disable' : 'enable')}\n disabled={toggle.isPending}\n >\n {r.enabled\n ? <><Pause className=\"h-4 w-4\" /><span>{t('heartbeat.pause')}</span></>\n : <><Play className=\"h-4 w-4\" /><span>{t('heartbeat.enable')}</span></>}\n </Button>\n </TableCell>\n <TableCell className=\"max-w-md\">\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => setExpandedKey(isExpanded ? null : key)}\n className=\"-ml-2\"\n >\n {isExpanded ? t('heartbeat.hide') : t('heartbeat.show')}\n </Button>\n {isExpanded && (\n <pre className=\"mt-2 whitespace-pre-wrap break-words rounded bg-surface-2 p-2 text-[11px] text-text-dim\">\n {r.body}\n </pre>\n )}\n </TableCell>\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )}\n </div>\n )\n}\n\nfunction EmptySection(): JSX.Element {\n const { t } = useTranslation('tasks')\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('heartbeat.empty')}\n </section>\n )\n}\n\nfunction shortAge(iso: string | null, t: (key: string, opts?: Record<string, unknown>) => string): string {\n if (!iso) return t('heartbeat.never')\n const ms = Date.now() - new Date(iso).getTime()\n if (!Number.isFinite(ms) || ms < 0) return t('heartbeat.justNow')\n if (ms < 60_000) return t('heartbeat.justNow')\n if (ms < 3_600_000) return t('heartbeat.minutesAgo', { count: Math.floor(ms / 60_000) })\n if (ms < 86_400_000) return t('heartbeat.hoursAgo', { count: Math.floor(ms / 3_600_000) })\n return t('heartbeat.daysAgo', { count: Math.floor(ms / 86_400_000) })\n}\n"],"names":["Pause","createLucideIcon","TasksHeartbeatRoute","useTranslation","listQuery","useHeartbeatList","toggle","useHeartbeatToggle","expandedKey","setExpandedKey","useState","onToggle","row","op","toast","err","rows","jsxs","jsx","HeartPulse","Badge","Button","Loader2","RefreshCcw","EmptySection","Table","TableHeader","TableRow","TableHead","TableBody","r","key","isExpanded","tickBadge","shortAge","TableCell","Fragment","Play","iso","t","ms"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"heartbeat-ClO5gJrj.js","sources":["../../node_modules/lucide-react/dist/esm/icons/pause.js","../../src/routes/tasks/heartbeat.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 Pause = createLucideIcon(\"Pause\", [\n [\"rect\", { x: \"14\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"zuxfzm\" }],\n [\"rect\", { x: \"6\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"1okwgv\" }]\n]);\n\nexport { Pause as default };\n//# sourceMappingURL=pause.js.map\n","/**\n * /tasks/heartbeat — admin overview of every heartbeat binding (P1).\n */\n\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { HeartPulse, Loader2, Pause, Play, RefreshCcw } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useHeartbeatList, useHeartbeatToggle, type HeartbeatRow,\n} from '@/hooks/use-background-tasks'\n\nexport default function TasksHeartbeatRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const listQuery = useHeartbeatList()\n const toggle = useHeartbeatToggle()\n const [expandedKey, setExpandedKey] = useState<string | null>(null)\n\n async function onToggle(row: HeartbeatRow, op: 'enable' | 'disable'): Promise<void> {\n try {\n await toggle.mutateAsync({ row, op })\n toast.success(op === 'enable' ? t('heartbeat.enabledToast') : t('heartbeat.disabledToast'))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n const rows = listQuery.data?.bindings ?? []\n return (\n <div className=\"mx-auto flex max-w-6xl flex-col gap-4 p-4\">\n <header className=\"flex items-center gap-3\">\n <HeartPulse className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('heartbeat.title')}</h1>\n <Badge variant=\"info\">{rows.length}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('heartbeat.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('heartbeat.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : rows.length === 0 ? (\n <EmptySection />\n ) : (\n <section className=\"rounded-md border border-border bg-surface\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('heartbeat.col.thread')}</TableHead>\n <TableHead>{t('heartbeat.col.owner')}</TableHead>\n <TableHead>{t('heartbeat.col.interval')}</TableHead>\n <TableHead>{t('heartbeat.col.lastTick')}</TableHead>\n <TableHead>{t('heartbeat.col.enabled')}</TableHead>\n <TableHead>{t('heartbeat.col.body')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((r) => {\n const key = `${r.platform}:${r.channelId}:${r.threadId}`\n const isExpanded = expandedKey === key\n const tickBadge = !r.lastTickAt\n ? <Badge variant=\"outline\">{t('heartbeat.never')}</Badge>\n : r.lastStatus === 'delivered'\n ? <Badge variant=\"success\">{shortAge(r.lastTickAt, t)}</Badge>\n : r.lastStatus === 'error'\n ? <Badge variant=\"danger\" title={r.lastReason}>{r.lastStatus} · {shortAge(r.lastTickAt, t)}</Badge>\n : <Badge variant=\"outline\" title={r.lastReason}>{r.lastStatus} · {shortAge(r.lastTickAt, t)}</Badge>\n return (\n <TableRow key={key}>\n <TableCell className=\"font-mono text-[11px]\">{r.platform}:{r.threadId}</TableCell>\n <TableCell className=\"font-mono text-[11px]\">{r.userId || '—'}</TableCell>\n <TableCell className=\"text-xs\">{t('heartbeat.intervalMin', { count: r.intervalMinutes })}</TableCell>\n <TableCell>{tickBadge}</TableCell>\n <TableCell>\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onToggle(r, r.enabled ? 'disable' : 'enable')}\n disabled={toggle.isPending}\n >\n {r.enabled\n ? <><Pause className=\"h-4 w-4\" /><span>{t('heartbeat.pause')}</span></>\n : <><Play className=\"h-4 w-4\" /><span>{t('heartbeat.enable')}</span></>}\n </Button>\n </TableCell>\n <TableCell className=\"max-w-md\">\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => setExpandedKey(isExpanded ? null : key)}\n className=\"-ml-2\"\n >\n {isExpanded ? t('heartbeat.hide') : t('heartbeat.show')}\n </Button>\n {isExpanded && (\n <pre className=\"mt-2 whitespace-pre-wrap break-words rounded bg-surface-2 p-2 text-[11px] text-text-dim\">\n {r.body}\n </pre>\n )}\n </TableCell>\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )}\n </div>\n )\n}\n\nfunction EmptySection(): JSX.Element {\n const { t } = useTranslation('tasks')\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('heartbeat.empty')}\n </section>\n )\n}\n\nfunction shortAge(iso: string | null, t: (key: string, opts?: Record<string, unknown>) => string): string {\n if (!iso) return t('heartbeat.never')\n const ms = Date.now() - new Date(iso).getTime()\n if (!Number.isFinite(ms) || ms < 0) return t('heartbeat.justNow')\n if (ms < 60_000) return t('heartbeat.justNow')\n if (ms < 3_600_000) return t('heartbeat.minutesAgo', { count: Math.floor(ms / 60_000) })\n if (ms < 86_400_000) return t('heartbeat.hoursAgo', { count: Math.floor(ms / 3_600_000) })\n return t('heartbeat.daysAgo', { count: Math.floor(ms / 86_400_000) })\n}\n"],"names":["Pause","createLucideIcon","TasksHeartbeatRoute","useTranslation","listQuery","useHeartbeatList","toggle","useHeartbeatToggle","expandedKey","setExpandedKey","useState","onToggle","row","op","toast","err","rows","jsxs","jsx","HeartPulse","Badge","Button","Loader2","RefreshCcw","EmptySection","Table","TableHeader","TableRow","TableHead","TableBody","r","key","isExpanded","tickBadge","shortAge","TableCell","Fragment","Play","iso","t","ms"],"mappings":"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","x_google_ignoreList":[0]}
@@ -0,0 +1,7 @@
1
+ import{h as v,u as x,j as e,e as u,I as y,d as m,f as C,D as S,E as L,F as k,G as D,H as F,p as j}from"./index-DCfdN5R7.js";import{r as o}from"./react-DlP5eolq.js";import{E}from"./empty-state-CuiqdZiB.js";import{u as R,F as N}from"./use-skills-D2bMM580.js";import{E as z}from"./external-link-1WPpVvdu.js";import{L as H}from"./loader-circle-DDdmcH0k.js";import{R as I}from"./refresh-ccw-DlAd-eTQ.js";import{S as M}from"./search-CAICU3aU.js";import{D as T}from"./download-CVZnHcwj.js";import{C as $}from"./copy-CD4A7VD8.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 A=v("Star",[["path",{d:"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z",key:"r04s7s"}]]);function Y(){const{t:s}=x(["skills","common"]),{data:n,isLoading:l,isFetching:r,refetch:i}=R(),a=n?.skills??[],[h,w]=o.useState(""),[p,g]=o.useState(null),f=o.useMemo(()=>{const t=h.trim().toLowerCase();return t?a.filter(d=>d.slug.toLowerCase().includes(t)||(d.name||"").toLowerCase().includes(t)||(d.description||"").toLowerCase().includes(t)||(d.category||"").toLowerCase().includes(t)):a},[a,h]),b=p?a.find(t=>t.slug===p)??null:null;return e.jsxs("div",{className:"mx-auto flex max-w-5xl 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.jsxs("h1",{className:"text-xl font-semibold inline-flex items-center gap-2",children:[e.jsx(N,{className:"h-5 w-5 text-warning"}),s("hot.title")]}),e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[e.jsx(u,{asChild:!0,variant:"ghost",size:"sm",children:e.jsxs("a",{href:"https://skillhub.cn",target:"_blank",rel:"noopener noreferrer",children:[e.jsx(z,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("hot.openHub")})]})}),e.jsxs(u,{variant:"ghost",size:"sm",onClick:()=>i(),disabled:r,"aria-label":s("actions.refresh",{ns:"common"}),children:[r?e.jsx(H,{className:"h-4 w-4 animate-spin"}):e.jsx(I,{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("hot.subtitle")}),n&&e.jsx(B,{cached:!!n.cached,stale:!!n.stale,fetchedAt:n.fetchedAt})]}),a.length>0&&e.jsxs("div",{className:"flex flex-wrap items-end gap-2",children:[e.jsxs("div",{className:"relative flex-1 min-w-[180px] max-w-md",children:[e.jsx(M,{className:"pointer-events-none absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-text-muted"}),e.jsx(y,{value:h,onChange:t=>w(t.target.value),placeholder:s("actions.search",{ns:"common"}),className:"pl-7"})]}),e.jsxs(m,{variant:"secondary",className:"ml-auto",children:[f.length," / ",a.length]})]}),l?e.jsx("div",{className:"h-48 w-full rounded-md bg-surface-2 animate-pulse"}):a.length===0?e.jsx(E,{icon:e.jsx(N,{}),title:s("hot.empty")}):e.jsx("ul",{className:"flex flex-col gap-2",children:f.map(t=>e.jsx("li",{children:e.jsxs("button",{type:"button",onClick:()=>g(t.slug),className:C("flex w-full flex-col gap-1 rounded-md border border-border bg-surface px-3 py-2 text-left","transition-colors hover:border-border-strong hover:bg-surface-hover"),children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:t.name||t.slug}),t.version&&e.jsxs("span",{className:"text-text-muted text-xs font-mono",children:["v",t.version]}),t.category&&e.jsx(m,{variant:"outline",children:t.category}),e.jsxs("div",{className:"ml-auto flex items-center gap-3 text-xs text-text-dim tabular-nums",children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(A,{className:"h-3 w-3"}),c(t.stars)]}),e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(T,{className:"h-3 w-3"}),c(t.installs)]})]})]}),e.jsx("code",{className:"text-text-muted text-xs font-mono",children:t.slug}),t.description&&e.jsx("p",{className:"line-clamp-2 text-sm text-text-dim",children:t.description})]})},t.slug))}),e.jsx(O,{skill:b,onOpenChange:t=>{t||g(null)}})]})}function B({cached:s,stale:n,fetchedAt:l}){const{t:r}=x("skills"),i=o.useMemo(()=>{try{const a=new Date(l);return Number.isNaN(a.getTime())?"":a.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return""}},[l]);return e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs text-text-muted",children:[e.jsx("span",{children:r("hot.updatedAt",{at:i})}),s&&e.jsx(m,{variant:"outline",children:r("hot.cached")}),n&&e.jsx(m,{variant:"warning",children:r("hot.stale")})]})}function O({skill:s,onOpenChange:n}){const{t:l,i18n:r}=x("skills"),i=o.useMemo(()=>s?[{key:"cliInstall",cmd:`skillhub install ${s.slug}`},{key:"cliSearch",cmd:`skillhub search ${s.slug}`},{key:"imAsk",cmd:r.language.startsWith("zh")?`请用 skillhub 安装 ${s.slug} 技能`:`Please install ${s.slug} via skillhub`}]:[],[r.language,s]);return e.jsx(S,{open:s!=null,onOpenChange:n,children:e.jsxs(L,{className:"sm:max-w-2xl",children:[e.jsxs(k,{children:[e.jsx(D,{children:s?.name||s?.slug||""}),s?.description&&e.jsx(F,{children:s.description})]}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("dl",{className:"grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-xs",children:[e.jsx("dt",{className:"text-text-dim",children:l("hot.detail.slug")}),e.jsx("dd",{className:"font-mono",children:s.slug}),s.version&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:l("hot.detail.version")}),e.jsxs("dd",{className:"font-mono",children:["v",s.version]})]}),s.category&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:l("hot.detail.category")}),e.jsx("dd",{children:s.category})]}),e.jsx("dt",{className:"text-text-dim",children:l("hot.detail.stars")}),e.jsx("dd",{className:"tabular-nums",children:c(s.stars)}),e.jsx("dt",{className:"text-text-dim",children:l("hot.detail.installs")}),e.jsx("dd",{className:"tabular-nums",children:c(s.installs)}),s.downloads!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:l("hot.detail.downloads")}),e.jsx("dd",{className:"tabular-nums",children:c(s.downloads)})]})]}),e.jsxs("div",{className:"mt-4 border-t border-border pt-3",children:[e.jsx("h3",{className:"text-sm font-medium",children:l("hot.detail.howInstall")}),e.jsx("ul",{className:"mt-2 flex flex-col gap-2",children:i.map(a=>e.jsxs("li",{className:"flex flex-col gap-1 sm:flex-row sm:items-center sm:gap-2",children:[e.jsx("span",{className:"text-xs text-text-dim sm:w-40 sm:shrink-0",children:l(`hot.detail.label.${a.key}`)}),e.jsx("code",{className:"flex-1 rounded bg-surface-2 px-2 py-1 font-mono text-xs break-all",children:a.cmd}),e.jsx(_,{text:a.cmd})]},a.key))}),e.jsx("p",{className:"mt-3 text-[11px] text-text-muted",children:l("hot.detail.hint")})]})]})]})})}function _({text:s}){const{t:n}=x("skills"),[l,r]=o.useState(!1);async function i(){try{await navigator.clipboard.writeText(s),r(!0),j.success(n("hot.detail.copied")),setTimeout(()=>r(!1),1500)}catch(a){j.error(String(a?.message??a))}}return e.jsxs(u,{type:"button",variant:"secondary",size:"sm",onClick:()=>void i(),className:"shrink-0",children:[e.jsx($,{className:"h-3 w-3"}),n(l?"hot.detail.copied":"hot.detail.copy")]})}function c(s){return s==null||!Number.isFinite(s)?"—":s.toLocaleString()}export{Y as default};
7
+ //# sourceMappingURL=hot-bfTA-V_z.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hot-Yc7iad0D.js","sources":["../../node_modules/lucide-react/dist/esm/icons/flame.js","../../node_modules/lucide-react/dist/esm/icons/star.js","../../src/hooks/use-skills.ts","../../src/routes/settings/agim-skills/hot.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 Flame = createLucideIcon(\"Flame\", [\n [\n \"path\",\n {\n d: \"M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z\",\n key: \"96xj49\"\n }\n ]\n]);\n\nexport { Flame as default };\n//# sourceMappingURL=flame.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 Star = createLucideIcon(\"Star\", [\n [\n \"path\",\n {\n d: \"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\",\n key: \"r04s7s\"\n }\n ]\n]);\n\nexport { Star as default };\n//# sourceMappingURL=star.js.map\n","/**\n * useSkills — read-only browse of the agent skills.\n *\n * useSkills() — list of every skill on disk\n * useSkillDetail(slug) — markdown body, fetched on demand\n * when the modal opens\n *\n * No mutations: installs happen via the skillhub CLI on the host,\n * agim is strictly read-only here.\n */\n\nimport { useQuery } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type {\n ListSkillsResponse,\n RemoteHotSkillsResponse,\n SkillDetail,\n} from '@/types/api'\n\nexport const skillsKeys = {\n all: ['skills'] as const,\n list: ['skills', 'list'] as const,\n detail: (slug: string) => ['skills', 'detail', slug] as const,\n remoteHot: ['skills', 'remote', 'hot'] as const,\n}\n\nexport function useSkills() {\n return useQuery<ListSkillsResponse>({\n queryKey: skillsKeys.list,\n queryFn: () => api.listSkills(),\n })\n}\n\nexport function useSkillDetail(slug: string | null) {\n return useQuery<SkillDetail>({\n queryKey: skillsKeys.detail(slug ?? ''),\n queryFn: () => api.getSkillDetail(slug as string),\n enabled: Boolean(slug),\n })\n}\n\n/** skillhub.cn hot list. The proxy on the server caches for 5 min and\n * serves stale-while-error, so we don't need an aggressive client-side\n * refresh — the operator hits the refresh button when they want fresh\n * data. staleTime keeps tab-switch round-trips cheap. */\nexport function useSkillsRemoteHot() {\n return useQuery<RemoteHotSkillsResponse>({\n queryKey: skillsKeys.remoteHot,\n queryFn: () => api.getSkillsRemoteHot(),\n staleTime: 60_000,\n })\n}\n","/**\n * /skills/hot — read-only browse of skillhub.cn's hot list.\n *\n * Backed by /api/skills/remote/hot (server proxies upstream with a\n * 5-min cache + stale-while-error). agim never auto-runs an install:\n * the detail dialog surfaces three copy-pasteable commands and the\n * operator decides where to execute.\n *\n * Restored from v1's tasks.html in 2026-05; the v2 SPA had the\n * installed-skills view but had dropped the hot list during the\n * memory-tab port.\n */\n\nimport { useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport {\n Copy,\n Download,\n ExternalLink,\n Flame,\n Loader2,\n RefreshCcw,\n Search,\n Star,\n} from 'lucide-react'\n\nimport { EmptyState } from '@/components/common/empty-state'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '@/components/ui/dialog'\nimport { Input } from '@/components/ui/input'\nimport { useSkillsRemoteHot } from '@/hooks/use-skills'\nimport type { RemoteSkill } from '@/types/api'\nimport { cn } from '@/lib/utils'\n\nexport default function SkillsHotRoute(): JSX.Element {\n const { t } = useTranslation(['skills', 'common'])\n const { data, isLoading, isFetching, refetch } = useSkillsRemoteHot()\n\n const skills: RemoteSkill[] = data?.skills ?? []\n const [q, setQ] = useState('')\n const [openSlug, setOpenSlug] = useState<string | null>(null)\n\n const filtered = useMemo(() => {\n const needle = q.trim().toLowerCase()\n if (!needle) return skills\n return skills.filter((s) =>\n s.slug.toLowerCase().includes(needle)\n || (s.name || '').toLowerCase().includes(needle)\n || (s.description || '').toLowerCase().includes(needle)\n || (s.category || '').toLowerCase().includes(needle)\n )\n }, [skills, q])\n\n const openSkill = openSlug ? skills.find((s) => s.slug === openSlug) ?? null : null\n\n return (\n <div className=\"mx-auto flex max-w-5xl 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 inline-flex items-center gap-2\">\n <Flame className=\"h-5 w-5 text-warning\" />\n {t('hot.title')}\n </h1>\n <div className=\"ml-auto flex items-center gap-2\">\n <Button\n asChild\n variant=\"ghost\"\n size=\"sm\"\n >\n <a\n href=\"https://skillhub.cn\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <ExternalLink className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">{t('hot.openHub')}</span>\n </a>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\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 </div>\n <p className=\"text-sm text-text-dim\">{t('hot.subtitle')}</p>\n {data && (\n <CacheMeta\n cached={!!data.cached}\n stale={!!data.stale}\n fetchedAt={data.fetchedAt}\n />\n )}\n </header>\n\n {skills.length > 0 && (\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"relative flex-1 min-w-[180px] max-w-md\">\n <Search className=\"pointer-events-none absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-text-muted\" />\n <Input\n value={q}\n onChange={(e) => setQ(e.target.value)}\n placeholder={t('actions.search', { ns: 'common' })}\n className=\"pl-7\"\n />\n </div>\n <Badge variant=\"secondary\" className=\"ml-auto\">\n {filtered.length} / {skills.length}\n </Badge>\n </div>\n )}\n\n {isLoading ? (\n <div className=\"h-48 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : skills.length === 0 ? (\n <EmptyState icon={<Flame />} title={t('hot.empty')} />\n ) : (\n <ul className=\"flex flex-col gap-2\">\n {filtered.map((s) => (\n <li key={s.slug}>\n <button\n type=\"button\"\n onClick={() => setOpenSlug(s.slug)}\n className={cn(\n 'flex w-full flex-col gap-1 rounded-md border border-border bg-surface px-3 py-2 text-left',\n 'transition-colors hover:border-border-strong hover:bg-surface-hover',\n )}\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium text-text\">{s.name || s.slug}</span>\n {s.version && (\n <span className=\"text-text-muted text-xs font-mono\">v{s.version}</span>\n )}\n {s.category && (\n <Badge variant=\"outline\">{s.category}</Badge>\n )}\n <div className=\"ml-auto flex items-center gap-3 text-xs text-text-dim tabular-nums\">\n <span className=\"inline-flex items-center gap-1\">\n <Star className=\"h-3 w-3\" />\n {formatNum(s.stars)}\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <Download className=\"h-3 w-3\" />\n {formatNum(s.installs)}\n </span>\n </div>\n </div>\n <code className=\"text-text-muted text-xs font-mono\">{s.slug}</code>\n {s.description && (\n <p className=\"line-clamp-2 text-sm text-text-dim\">{s.description}</p>\n )}\n </button>\n </li>\n ))}\n </ul>\n )}\n\n <RemoteSkillDialog\n skill={openSkill}\n onOpenChange={(open) => { if (!open) setOpenSlug(null) }}\n />\n </div>\n )\n}\n\nfunction CacheMeta({\n cached,\n stale,\n fetchedAt,\n}: {\n cached: boolean\n stale: boolean\n fetchedAt: number\n}): JSX.Element | null {\n const { t } = useTranslation('skills')\n const when = useMemo(() => {\n try {\n const d = new Date(fetchedAt)\n if (Number.isNaN(d.getTime())) return ''\n return d.toLocaleString(undefined, {\n month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit',\n })\n } catch {\n return ''\n }\n }, [fetchedAt])\n return (\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-text-muted\">\n <span>{t('hot.updatedAt', { at: when })}</span>\n {cached && <Badge variant=\"outline\">{t('hot.cached')}</Badge>}\n {stale && <Badge variant=\"warning\">{t('hot.stale')}</Badge>}\n </div>\n )\n}\n\ninterface RemoteSkillDialogProps {\n skill: RemoteSkill | null\n onOpenChange: (open: boolean) => void\n}\n\nfunction RemoteSkillDialog({ skill, onOpenChange }: RemoteSkillDialogProps): JSX.Element {\n const { t, i18n } = useTranslation('skills')\n\n // Three copy-pasteable install paths. agim never executes them itself\n // — the operator chooses CLI or IM.\n const commands = useMemo(() => {\n if (!skill) return []\n return [\n { key: 'cliInstall', cmd: `skillhub install ${skill.slug}` },\n { key: 'cliSearch', cmd: `skillhub search ${skill.slug}` },\n {\n key: 'imAsk',\n cmd: i18n.language.startsWith('zh')\n ? `请用 skillhub 安装 ${skill.slug} 技能`\n : `Please install ${skill.slug} via skillhub`,\n },\n ]\n }, [i18n.language, skill])\n\n return (\n <Dialog open={skill != null} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-2xl\">\n <DialogHeader>\n <DialogTitle>{skill?.name || skill?.slug || ''}</DialogTitle>\n {skill?.description && (\n <DialogDescription>{skill.description}</DialogDescription>\n )}\n </DialogHeader>\n\n {skill && (\n <>\n <dl className=\"grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-xs\">\n <dt className=\"text-text-dim\">{t('hot.detail.slug')}</dt>\n <dd className=\"font-mono\">{skill.slug}</dd>\n {skill.version && (\n <>\n <dt className=\"text-text-dim\">{t('hot.detail.version')}</dt>\n <dd className=\"font-mono\">v{skill.version}</dd>\n </>\n )}\n {skill.category && (\n <>\n <dt className=\"text-text-dim\">{t('hot.detail.category')}</dt>\n <dd>{skill.category}</dd>\n </>\n )}\n <dt className=\"text-text-dim\">{t('hot.detail.stars')}</dt>\n <dd className=\"tabular-nums\">{formatNum(skill.stars)}</dd>\n <dt className=\"text-text-dim\">{t('hot.detail.installs')}</dt>\n <dd className=\"tabular-nums\">{formatNum(skill.installs)}</dd>\n {skill.downloads != null && (\n <>\n <dt className=\"text-text-dim\">{t('hot.detail.downloads')}</dt>\n <dd className=\"tabular-nums\">{formatNum(skill.downloads)}</dd>\n </>\n )}\n </dl>\n\n <div className=\"mt-4 border-t border-border pt-3\">\n <h3 className=\"text-sm font-medium\">{t('hot.detail.howInstall')}</h3>\n <ul className=\"mt-2 flex flex-col gap-2\">\n {commands.map((c) => (\n <li key={c.key} className=\"flex flex-col gap-1 sm:flex-row sm:items-center sm:gap-2\">\n <span className=\"text-xs text-text-dim sm:w-40 sm:shrink-0\">\n {t(`hot.detail.label.${c.key}`)}\n </span>\n <code className=\"flex-1 rounded bg-surface-2 px-2 py-1 font-mono text-xs break-all\">\n {c.cmd}\n </code>\n <CopyButton text={c.cmd} />\n </li>\n ))}\n </ul>\n <p className=\"mt-3 text-[11px] text-text-muted\">{t('hot.detail.hint')}</p>\n </div>\n </>\n )}\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction CopyButton({ text }: { text: string }): JSX.Element {\n const { t } = useTranslation('skills')\n const [copied, setCopied] = useState(false)\n async function onClick(): Promise<void> {\n try {\n await navigator.clipboard.writeText(text)\n setCopied(true)\n toast.success(t('hot.detail.copied'))\n setTimeout(() => setCopied(false), 1500)\n } catch (err) {\n toast.error(String((err as Error)?.message ?? err))\n }\n }\n return (\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => void onClick()}\n className=\"shrink-0\"\n >\n <Copy className=\"h-3 w-3\" />\n {copied ? t('hot.detail.copied') : t('hot.detail.copy')}\n </Button>\n )\n}\n\nfunction formatNum(n: number | undefined): string {\n if (n == null || !Number.isFinite(n)) return '—'\n return n.toLocaleString()\n}\n"],"names":["Flame","createLucideIcon","Star","skillsKeys","useSkillsRemoteHot","useQuery","api","SkillsHotRoute","t","useTranslation","data","isLoading","isFetching","refetch","skills","q","setQ","useState","openSlug","setOpenSlug","filtered","useMemo","needle","s","openSkill","jsxs","jsx","Button","ExternalLink","Loader2","RefreshCcw","CacheMeta","Search","Input","e","Badge","EmptyState","cn","formatNum","Download","RemoteSkillDialog","open","cached","stale","fetchedAt","when","d","skill","onOpenChange","i18n","commands","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","Fragment","c","CopyButton","text","copied","setCopied","onClick","toast","err","Copy","n"],"mappings":"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","x_google_ignoreList":[0,1]}
1
+ {"version":3,"file":"hot-bfTA-V_z.js","sources":["../../node_modules/lucide-react/dist/esm/icons/star.js","../../src/routes/settings/agim-skills/hot.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 Star = createLucideIcon(\"Star\", [\n [\n \"path\",\n {\n d: \"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\",\n key: \"r04s7s\"\n }\n ]\n]);\n\nexport { Star as default };\n//# sourceMappingURL=star.js.map\n","/**\n * /skills/hot — read-only browse of skillhub.cn's hot list.\n *\n * Backed by /api/skills/remote/hot (server proxies upstream with a\n * 5-min cache + stale-while-error). agim never auto-runs an install:\n * the detail dialog surfaces three copy-pasteable commands and the\n * operator decides where to execute.\n *\n * Restored from v1's tasks.html in 2026-05; the v2 SPA had the\n * installed-skills view but had dropped the hot list during the\n * memory-tab port.\n */\n\nimport { useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport {\n Copy,\n Download,\n ExternalLink,\n Flame,\n Loader2,\n RefreshCcw,\n Search,\n Star,\n} from 'lucide-react'\n\nimport { EmptyState } from '@/components/common/empty-state'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '@/components/ui/dialog'\nimport { Input } from '@/components/ui/input'\nimport { useSkillsRemoteHot } from '@/hooks/use-skills'\nimport type { RemoteSkill } from '@/types/api'\nimport { cn } from '@/lib/utils'\n\nexport default function SkillsHotRoute(): JSX.Element {\n const { t } = useTranslation(['skills', 'common'])\n const { data, isLoading, isFetching, refetch } = useSkillsRemoteHot()\n\n const skills: RemoteSkill[] = data?.skills ?? []\n const [q, setQ] = useState('')\n const [openSlug, setOpenSlug] = useState<string | null>(null)\n\n const filtered = useMemo(() => {\n const needle = q.trim().toLowerCase()\n if (!needle) return skills\n return skills.filter((s) =>\n s.slug.toLowerCase().includes(needle)\n || (s.name || '').toLowerCase().includes(needle)\n || (s.description || '').toLowerCase().includes(needle)\n || (s.category || '').toLowerCase().includes(needle)\n )\n }, [skills, q])\n\n const openSkill = openSlug ? skills.find((s) => s.slug === openSlug) ?? null : null\n\n return (\n <div className=\"mx-auto flex max-w-5xl 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 inline-flex items-center gap-2\">\n <Flame className=\"h-5 w-5 text-warning\" />\n {t('hot.title')}\n </h1>\n <div className=\"ml-auto flex items-center gap-2\">\n <Button\n asChild\n variant=\"ghost\"\n size=\"sm\"\n >\n <a\n href=\"https://skillhub.cn\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <ExternalLink className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">{t('hot.openHub')}</span>\n </a>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\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 </div>\n <p className=\"text-sm text-text-dim\">{t('hot.subtitle')}</p>\n {data && (\n <CacheMeta\n cached={!!data.cached}\n stale={!!data.stale}\n fetchedAt={data.fetchedAt}\n />\n )}\n </header>\n\n {skills.length > 0 && (\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"relative flex-1 min-w-[180px] max-w-md\">\n <Search className=\"pointer-events-none absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-text-muted\" />\n <Input\n value={q}\n onChange={(e) => setQ(e.target.value)}\n placeholder={t('actions.search', { ns: 'common' })}\n className=\"pl-7\"\n />\n </div>\n <Badge variant=\"secondary\" className=\"ml-auto\">\n {filtered.length} / {skills.length}\n </Badge>\n </div>\n )}\n\n {isLoading ? (\n <div className=\"h-48 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : skills.length === 0 ? (\n <EmptyState icon={<Flame />} title={t('hot.empty')} />\n ) : (\n <ul className=\"flex flex-col gap-2\">\n {filtered.map((s) => (\n <li key={s.slug}>\n <button\n type=\"button\"\n onClick={() => setOpenSlug(s.slug)}\n className={cn(\n 'flex w-full flex-col gap-1 rounded-md border border-border bg-surface px-3 py-2 text-left',\n 'transition-colors hover:border-border-strong hover:bg-surface-hover',\n )}\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium text-text\">{s.name || s.slug}</span>\n {s.version && (\n <span className=\"text-text-muted text-xs font-mono\">v{s.version}</span>\n )}\n {s.category && (\n <Badge variant=\"outline\">{s.category}</Badge>\n )}\n <div className=\"ml-auto flex items-center gap-3 text-xs text-text-dim tabular-nums\">\n <span className=\"inline-flex items-center gap-1\">\n <Star className=\"h-3 w-3\" />\n {formatNum(s.stars)}\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <Download className=\"h-3 w-3\" />\n {formatNum(s.installs)}\n </span>\n </div>\n </div>\n <code className=\"text-text-muted text-xs font-mono\">{s.slug}</code>\n {s.description && (\n <p className=\"line-clamp-2 text-sm text-text-dim\">{s.description}</p>\n )}\n </button>\n </li>\n ))}\n </ul>\n )}\n\n <RemoteSkillDialog\n skill={openSkill}\n onOpenChange={(open) => { if (!open) setOpenSlug(null) }}\n />\n </div>\n )\n}\n\nfunction CacheMeta({\n cached,\n stale,\n fetchedAt,\n}: {\n cached: boolean\n stale: boolean\n fetchedAt: number\n}): JSX.Element | null {\n const { t } = useTranslation('skills')\n const when = useMemo(() => {\n try {\n const d = new Date(fetchedAt)\n if (Number.isNaN(d.getTime())) return ''\n return d.toLocaleString(undefined, {\n month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit',\n })\n } catch {\n return ''\n }\n }, [fetchedAt])\n return (\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-text-muted\">\n <span>{t('hot.updatedAt', { at: when })}</span>\n {cached && <Badge variant=\"outline\">{t('hot.cached')}</Badge>}\n {stale && <Badge variant=\"warning\">{t('hot.stale')}</Badge>}\n </div>\n )\n}\n\ninterface RemoteSkillDialogProps {\n skill: RemoteSkill | null\n onOpenChange: (open: boolean) => void\n}\n\nfunction RemoteSkillDialog({ skill, onOpenChange }: RemoteSkillDialogProps): JSX.Element {\n const { t, i18n } = useTranslation('skills')\n\n // Three copy-pasteable install paths. agim never executes them itself\n // — the operator chooses CLI or IM.\n const commands = useMemo(() => {\n if (!skill) return []\n return [\n { key: 'cliInstall', cmd: `skillhub install ${skill.slug}` },\n { key: 'cliSearch', cmd: `skillhub search ${skill.slug}` },\n {\n key: 'imAsk',\n cmd: i18n.language.startsWith('zh')\n ? `请用 skillhub 安装 ${skill.slug} 技能`\n : `Please install ${skill.slug} via skillhub`,\n },\n ]\n }, [i18n.language, skill])\n\n return (\n <Dialog open={skill != null} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-2xl\">\n <DialogHeader>\n <DialogTitle>{skill?.name || skill?.slug || ''}</DialogTitle>\n {skill?.description && (\n <DialogDescription>{skill.description}</DialogDescription>\n )}\n </DialogHeader>\n\n {skill && (\n <>\n <dl className=\"grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-xs\">\n <dt className=\"text-text-dim\">{t('hot.detail.slug')}</dt>\n <dd className=\"font-mono\">{skill.slug}</dd>\n {skill.version && (\n <>\n <dt className=\"text-text-dim\">{t('hot.detail.version')}</dt>\n <dd className=\"font-mono\">v{skill.version}</dd>\n </>\n )}\n {skill.category && (\n <>\n <dt className=\"text-text-dim\">{t('hot.detail.category')}</dt>\n <dd>{skill.category}</dd>\n </>\n )}\n <dt className=\"text-text-dim\">{t('hot.detail.stars')}</dt>\n <dd className=\"tabular-nums\">{formatNum(skill.stars)}</dd>\n <dt className=\"text-text-dim\">{t('hot.detail.installs')}</dt>\n <dd className=\"tabular-nums\">{formatNum(skill.installs)}</dd>\n {skill.downloads != null && (\n <>\n <dt className=\"text-text-dim\">{t('hot.detail.downloads')}</dt>\n <dd className=\"tabular-nums\">{formatNum(skill.downloads)}</dd>\n </>\n )}\n </dl>\n\n <div className=\"mt-4 border-t border-border pt-3\">\n <h3 className=\"text-sm font-medium\">{t('hot.detail.howInstall')}</h3>\n <ul className=\"mt-2 flex flex-col gap-2\">\n {commands.map((c) => (\n <li key={c.key} className=\"flex flex-col gap-1 sm:flex-row sm:items-center sm:gap-2\">\n <span className=\"text-xs text-text-dim sm:w-40 sm:shrink-0\">\n {t(`hot.detail.label.${c.key}`)}\n </span>\n <code className=\"flex-1 rounded bg-surface-2 px-2 py-1 font-mono text-xs break-all\">\n {c.cmd}\n </code>\n <CopyButton text={c.cmd} />\n </li>\n ))}\n </ul>\n <p className=\"mt-3 text-[11px] text-text-muted\">{t('hot.detail.hint')}</p>\n </div>\n </>\n )}\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction CopyButton({ text }: { text: string }): JSX.Element {\n const { t } = useTranslation('skills')\n const [copied, setCopied] = useState(false)\n async function onClick(): Promise<void> {\n try {\n await navigator.clipboard.writeText(text)\n setCopied(true)\n toast.success(t('hot.detail.copied'))\n setTimeout(() => setCopied(false), 1500)\n } catch (err) {\n toast.error(String((err as Error)?.message ?? err))\n }\n }\n return (\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => void onClick()}\n className=\"shrink-0\"\n >\n <Copy className=\"h-3 w-3\" />\n {copied ? t('hot.detail.copied') : t('hot.detail.copy')}\n </Button>\n )\n}\n\nfunction formatNum(n: number | undefined): string {\n if (n == null || !Number.isFinite(n)) return '—'\n return n.toLocaleString()\n}\n"],"names":["Star","createLucideIcon","SkillsHotRoute","t","useTranslation","data","isLoading","isFetching","refetch","useSkillsRemoteHot","skills","q","setQ","useState","openSlug","setOpenSlug","filtered","useMemo","needle","s","openSkill","jsxs","jsx","Flame","Button","ExternalLink","Loader2","RefreshCcw","CacheMeta","Search","Input","e","Badge","EmptyState","cn","formatNum","Download","RemoteSkillDialog","open","cached","stale","fetchedAt","when","d","skill","onOpenChange","i18n","commands","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","Fragment","c","CopyButton","text","copied","setCopied","onClick","toast","err","Copy","n"],"mappings":"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","x_google_ignoreList":[0]}