agim-cli 1.5.0 → 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 (344) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +39 -3
  3. package/README.zh-CN.md +42 -7
  4. package/dist/cli-ui/cmd-handlers.d.ts +22 -1
  5. package/dist/cli-ui/cmd-handlers.d.ts.map +1 -1
  6. package/dist/cli-ui/cmd-handlers.js +304 -40
  7. package/dist/cli-ui/cmd-handlers.js.map +1 -1
  8. package/dist/cli-ui/config-wizard.d.ts +13 -1
  9. package/dist/cli-ui/config-wizard.d.ts.map +1 -1
  10. package/dist/cli-ui/config-wizard.js +93 -21
  11. package/dist/cli-ui/config-wizard.js.map +1 -1
  12. package/dist/cli-ui/doctor.d.ts +15 -0
  13. package/dist/cli-ui/doctor.d.ts.map +1 -0
  14. package/dist/cli-ui/doctor.js +151 -0
  15. package/dist/cli-ui/doctor.js.map +1 -0
  16. package/dist/cli-ui/entry-menu.d.ts +6 -0
  17. package/dist/cli-ui/entry-menu.d.ts.map +1 -1
  18. package/dist/cli-ui/entry-menu.js +67 -30
  19. package/dist/cli-ui/entry-menu.js.map +1 -1
  20. package/dist/cli-ui/i18n.d.ts +15 -6
  21. package/dist/cli-ui/i18n.d.ts.map +1 -1
  22. package/dist/cli-ui/i18n.js +30 -12
  23. package/dist/cli-ui/i18n.js.map +1 -1
  24. package/dist/cli-ui/quickstart.d.ts +3 -0
  25. package/dist/cli-ui/quickstart.d.ts.map +1 -0
  26. package/dist/cli-ui/quickstart.js +108 -0
  27. package/dist/cli-ui/quickstart.js.map +1 -0
  28. package/dist/cli-ui/readiness.d.ts +10 -0
  29. package/dist/cli-ui/readiness.d.ts.map +1 -0
  30. package/dist/cli-ui/readiness.js +75 -0
  31. package/dist/cli-ui/readiness.js.map +1 -0
  32. package/dist/cli-ui/service.d.ts +23 -0
  33. package/dist/cli-ui/service.d.ts.map +1 -1
  34. package/dist/cli-ui/service.js +114 -5
  35. package/dist/cli-ui/service.js.map +1 -1
  36. package/dist/cli.js +99 -396
  37. package/dist/cli.js.map +1 -1
  38. package/dist/core/acp-server.d.ts.map +1 -1
  39. package/dist/core/acp-server.js +16 -2
  40. package/dist/core/acp-server.js.map +1 -1
  41. package/dist/core/agent-cwd.d.ts +8 -0
  42. package/dist/core/agent-cwd.d.ts.map +1 -1
  43. package/dist/core/agent-cwd.js +57 -7
  44. package/dist/core/agent-cwd.js.map +1 -1
  45. package/dist/core/commands/builtin.d.ts.map +1 -1
  46. package/dist/core/commands/builtin.js +12 -2
  47. package/dist/core/commands/builtin.js.map +1 -1
  48. package/dist/core/commands/model.d.ts.map +1 -1
  49. package/dist/core/commands/model.js +31 -2
  50. package/dist/core/commands/model.js.map +1 -1
  51. package/dist/core/llm/anthropic-provider.js +2 -1
  52. package/dist/core/llm/anthropic-provider.js.map +1 -1
  53. package/dist/core/llm/openai-compat-provider.js +3 -2
  54. package/dist/core/llm/openai-compat-provider.js.map +1 -1
  55. package/dist/core/llm/provider-base.d.ts +4 -4
  56. package/dist/core/llm/provider-base.d.ts.map +1 -1
  57. package/dist/core/llm/provider-base.js +1 -1
  58. package/dist/core/llm/provider-base.js.map +1 -1
  59. package/dist/plugins/agents/native/index.d.ts +1 -0
  60. package/dist/plugins/agents/native/index.d.ts.map +1 -1
  61. package/dist/plugins/agents/native/index.js +14 -0
  62. package/dist/plugins/agents/native/index.js.map +1 -1
  63. package/dist/plugins/agents/pi-native/factory.d.ts.map +1 -1
  64. package/dist/plugins/agents/pi-native/factory.js +19 -3
  65. package/dist/plugins/agents/pi-native/factory.js.map +1 -1
  66. package/dist/plugins/agents/pi-native/index.d.ts +11 -0
  67. package/dist/plugins/agents/pi-native/index.d.ts.map +1 -1
  68. package/dist/plugins/agents/pi-native/index.js +56 -2
  69. package/dist/plugins/agents/pi-native/index.js.map +1 -1
  70. package/dist/plugins/agents/pi-native/provider-resolver.d.ts +2 -0
  71. package/dist/plugins/agents/pi-native/provider-resolver.d.ts.map +1 -1
  72. package/dist/plugins/agents/pi-native/provider-resolver.js +9 -1
  73. package/dist/plugins/agents/pi-native/provider-resolver.js.map +1 -1
  74. package/dist/web/public/assets/a2a-CTsDMefo.js +7 -0
  75. package/dist/web/public/assets/a2a-CTsDMefo.js.map +1 -0
  76. package/dist/web/public/assets/{activity-BAgb2WZC.js → activity-ul8Os7Pz.js} +2 -2
  77. package/dist/web/public/assets/{activity-BAgb2WZC.js.map → activity-ul8Os7Pz.js.map} +1 -1
  78. package/dist/web/public/assets/{admins-CZYANmhn.js → admins-ByMAuquy.js} +3 -3
  79. package/dist/web/public/assets/{admins-CZYANmhn.js.map → admins-ByMAuquy.js.map} +1 -1
  80. package/dist/web/public/assets/agents-Ds1zyxBj.js +2 -0
  81. package/dist/web/public/assets/{agents-BXThDW6f.js.map → agents-Ds1zyxBj.js.map} +1 -1
  82. package/dist/web/public/assets/{approvals-ByPXIYVl.js → approvals-DOWlWI7Z.js} +3 -3
  83. package/dist/web/public/assets/{approvals-ByPXIYVl.js.map → approvals-DOWlWI7Z.js.map} +1 -1
  84. package/dist/web/public/assets/{arrow-down-B8DkdbEY.js → arrow-down-7i0xwCI2.js} +2 -2
  85. package/dist/web/public/assets/{arrow-down-B8DkdbEY.js.map → arrow-down-7i0xwCI2.js.map} +1 -1
  86. package/dist/web/public/assets/arrow-right-A889Wof8.js +7 -0
  87. package/dist/web/public/assets/arrow-right-A889Wof8.js.map +1 -0
  88. package/dist/web/public/assets/{arrow-up-i_dEdXkz.js → arrow-up-Dm0U4-6U.js} +2 -2
  89. package/dist/web/public/assets/{arrow-up-i_dEdXkz.js.map → arrow-up-Dm0U4-6U.js.map} +1 -1
  90. package/dist/web/public/assets/{asks-yD_inOnM.js → asks-DGuBsrJ7.js} +3 -3
  91. package/dist/web/public/assets/{asks-yD_inOnM.js.map → asks-DGuBsrJ7.js.map} +1 -1
  92. package/dist/web/public/assets/{audit-teCIRtgN.js → audit-BRXsplJ2.js} +2 -2
  93. package/dist/web/public/assets/{audit-teCIRtgN.js.map → audit-BRXsplJ2.js.map} +1 -1
  94. package/dist/web/public/assets/{bell-CeWDMs8_.js → bell-B-UdeJsp.js} +2 -2
  95. package/dist/web/public/assets/{bell-CeWDMs8_.js.map → bell-B-UdeJsp.js.map} +1 -1
  96. package/dist/web/public/assets/bgjobs-CcRiffyJ.js +2 -0
  97. package/dist/web/public/assets/bgjobs-CcRiffyJ.js.map +1 -0
  98. package/dist/web/public/assets/book-open-CSCq5cjL.js +7 -0
  99. package/dist/web/public/assets/book-open-CSCq5cjL.js.map +1 -0
  100. package/dist/web/public/assets/{brain-BQqv0Zhc.js → brain-Dl4DF5kX.js} +2 -2
  101. package/dist/web/public/assets/{brain-BQqv0Zhc.js.map → brain-Dl4DF5kX.js.map} +1 -1
  102. package/dist/web/public/assets/{briefcase-DUXbR4xs.js → briefcase-CeKUkFSq.js} +2 -2
  103. package/dist/web/public/assets/{briefcase-DUXbR4xs.js.map → briefcase-CeKUkFSq.js.map} +1 -1
  104. package/dist/web/public/assets/chat-rLJMdJBk.js +12 -0
  105. package/dist/web/public/assets/chat-rLJMdJBk.js.map +1 -0
  106. package/dist/web/public/assets/{chevron-left-RC6mMSiX.js → chevron-left-01fAFVpo.js} +2 -2
  107. package/dist/web/public/assets/{chevron-left-RC6mMSiX.js.map → chevron-left-01fAFVpo.js.map} +1 -1
  108. package/dist/web/public/assets/{chevron-right-DrkYVi19.js → chevron-right-CFRb-SM_.js} +3 -3
  109. package/dist/web/public/assets/{chevron-right-DrkYVi19.js.map → chevron-right-CFRb-SM_.js.map} +1 -1
  110. package/dist/web/public/assets/{circle-check-big-BC8ntMsz.js → circle-check-big-DBg2BD6o.js} +2 -2
  111. package/dist/web/public/assets/{circle-check-big-BC8ntMsz.js.map → circle-check-big-DBg2BD6o.js.map} +1 -1
  112. package/dist/web/public/assets/{circle-x-DHK7ypFY.js → circle-x-CqFMzO-x.js} +2 -2
  113. package/dist/web/public/assets/{circle-x-DHK7ypFY.js.map → circle-x-CqFMzO-x.js.map} +1 -1
  114. package/dist/web/public/assets/clipboard-list-lnqdk2_J.js +7 -0
  115. package/dist/web/public/assets/clipboard-list-lnqdk2_J.js.map +1 -0
  116. package/dist/web/public/assets/{clock-DXHhWqJH.js → clock-4hd1joQe.js} +3 -3
  117. package/dist/web/public/assets/{clock-DXHhWqJH.js.map → clock-4hd1joQe.js.map} +1 -1
  118. package/dist/web/public/assets/confirm-dialog-BDb0NLny.js +2 -0
  119. package/dist/web/public/assets/{confirm-dialog-gPKJnvEW.js.map → confirm-dialog-BDb0NLny.js.map} +1 -1
  120. package/dist/web/public/assets/{copy-DtQxgcR0.js → copy-CD4A7VD8.js} +3 -3
  121. package/dist/web/public/assets/{copy-DtQxgcR0.js.map → copy-CD4A7VD8.js.map} +1 -1
  122. package/dist/web/public/assets/dashboard-CG3WiG7h.js +2 -0
  123. package/dist/web/public/assets/dashboard-CG3WiG7h.js.map +1 -0
  124. package/dist/web/public/assets/{data-table-DOKUic1J.js → data-table-BkUshOZz.js} +2 -2
  125. package/dist/web/public/assets/{data-table-DOKUic1J.js.map → data-table-BkUshOZz.js.map} +1 -1
  126. package/dist/web/public/assets/database-lQzk64rV.js +7 -0
  127. package/dist/web/public/assets/database-lQzk64rV.js.map +1 -0
  128. package/dist/web/public/assets/{distill-p6P7-1UR.js → distill-CPurVW3v.js} +3 -3
  129. package/dist/web/public/assets/{distill-p6P7-1UR.js.map → distill-CPurVW3v.js.map} +1 -1
  130. package/dist/web/public/assets/{download-CqNiIHa8.js → download-CVZnHcwj.js} +2 -2
  131. package/dist/web/public/assets/{download-CqNiIHa8.js.map → download-CVZnHcwj.js.map} +1 -1
  132. package/dist/web/public/assets/dropdown-menu-BNH5SrVb.js +7 -0
  133. package/dist/web/public/assets/dropdown-menu-BNH5SrVb.js.map +1 -0
  134. package/dist/web/public/assets/{email-DwbfTUlV.js → email-YlI4MWLp.js} +3 -3
  135. package/dist/web/public/assets/{email-DwbfTUlV.js.map → email-YlI4MWLp.js.map} +1 -1
  136. package/dist/web/public/assets/{empty-state-CTwOQemt.js → empty-state-CuiqdZiB.js} +2 -2
  137. package/dist/web/public/assets/{empty-state-CTwOQemt.js.map → empty-state-CuiqdZiB.js.map} +1 -1
  138. package/dist/web/public/assets/{external-link-BY7Ye8yi.js → external-link-1WPpVvdu.js} +2 -2
  139. package/dist/web/public/assets/{external-link-BY7Ye8yi.js.map → external-link-1WPpVvdu.js.map} +1 -1
  140. package/dist/web/public/assets/{eye-6RUADoDS.js → eye-BfPyNFzk.js} +2 -2
  141. package/dist/web/public/assets/{eye-6RUADoDS.js.map → eye-BfPyNFzk.js.map} +1 -1
  142. package/dist/web/public/assets/{facts-DXE0aJmb.js → facts-xT_24pH8.js} +2 -2
  143. package/dist/web/public/assets/{facts-DXE0aJmb.js.map → facts-xT_24pH8.js.map} +1 -1
  144. package/dist/web/public/assets/file-text-BxfdLM0-.js +7 -0
  145. package/dist/web/public/assets/file-text-BxfdLM0-.js.map +1 -0
  146. package/dist/web/public/assets/{goals-C1LCm3qL.js → goals-C8ZQfbhj.js} +3 -3
  147. package/dist/web/public/assets/{goals-C1LCm3qL.js.map → goals-C8ZQfbhj.js.map} +1 -1
  148. package/dist/web/public/assets/health-A2StNEfn.js +2 -0
  149. package/dist/web/public/assets/{health-wqCp-K_o.js.map → health-A2StNEfn.js.map} +1 -1
  150. package/dist/web/public/assets/{heart-pulse-DfqI4GF7.js → heart-pulse-DXlE9oic.js} +2 -2
  151. package/dist/web/public/assets/{heart-pulse-DfqI4GF7.js.map → heart-pulse-DXlE9oic.js.map} +1 -1
  152. package/dist/web/public/assets/{heartbeat-Bumv4XtQ.js → heartbeat-ClO5gJrj.js} +3 -3
  153. package/dist/web/public/assets/{heartbeat-Bumv4XtQ.js.map → heartbeat-ClO5gJrj.js.map} +1 -1
  154. package/dist/web/public/assets/hot-bfTA-V_z.js +7 -0
  155. package/dist/web/public/assets/{hot-B-CMjQIr.js.map → hot-bfTA-V_z.js.map} +1 -1
  156. package/dist/web/public/assets/index-Bi2qWb-u.css +1 -0
  157. package/dist/web/public/assets/index-DCfdN5R7.js +244 -0
  158. package/dist/web/public/assets/index-DCfdN5R7.js.map +1 -0
  159. package/dist/web/public/assets/{injection-Dn_XqgLG.js → injection-omvCR6-p.js} +2 -2
  160. package/dist/web/public/assets/{injection-Dn_XqgLG.js.map → injection-omvCR6-p.js.map} +1 -1
  161. package/dist/web/public/assets/{installed-Cet-1M2Q.js → installed-DL6r3ktm.js} +4 -9
  162. package/dist/web/public/assets/installed-DL6r3ktm.js.map +1 -0
  163. package/dist/web/public/assets/jobs-Biy5lYd4.js +2 -0
  164. package/dist/web/public/assets/jobs-Biy5lYd4.js.map +1 -0
  165. package/dist/web/public/assets/layout-BLm6NJ3V.js +2 -0
  166. package/dist/web/public/assets/layout-BLm6NJ3V.js.map +1 -0
  167. package/dist/web/public/assets/layout-BTKafRVZ.js +2 -0
  168. package/dist/web/public/assets/layout-BTKafRVZ.js.map +1 -0
  169. package/dist/web/public/assets/layout-Bm-2s2fp.js +2 -0
  170. package/dist/web/public/assets/layout-Bm-2s2fp.js.map +1 -0
  171. package/dist/web/public/assets/layout-DsZ8eR4i.js +2 -0
  172. package/dist/web/public/assets/layout-DsZ8eR4i.js.map +1 -0
  173. package/dist/web/public/assets/{layout-D_3ZcVG7.js → layout-sxvovjEH.js} +2 -2
  174. package/dist/web/public/assets/{layout-D_3ZcVG7.js.map → layout-sxvovjEH.js.map} +1 -1
  175. package/dist/web/public/assets/llm-JjZDbBvJ.js +37 -0
  176. package/dist/web/public/assets/llm-JjZDbBvJ.js.map +1 -0
  177. package/dist/web/public/assets/loader-circle-DDdmcH0k.js +7 -0
  178. package/dist/web/public/assets/{loader-circle-DgdBWYl0.js.map → loader-circle-DDdmcH0k.js.map} +1 -1
  179. package/dist/web/public/assets/{map-pin-3QS1A0-I.js → map-pin-C_jAxukI.js} +2 -2
  180. package/dist/web/public/assets/{map-pin-3QS1A0-I.js.map → map-pin-C_jAxukI.js.map} +1 -1
  181. package/dist/web/public/assets/{mcp-DwKZULET.js → mcp-vKajK1F8.js} +3 -3
  182. package/dist/web/public/assets/{mcp-DwKZULET.js.map → mcp-vKajK1F8.js.map} +1 -1
  183. package/dist/web/public/assets/memos-DAt4k3DO.js +7 -0
  184. package/dist/web/public/assets/memos-DAt4k3DO.js.map +1 -0
  185. package/dist/web/public/assets/messengers-GYVTFlAj.js +2 -0
  186. package/dist/web/public/assets/messengers-GYVTFlAj.js.map +1 -0
  187. package/dist/web/public/assets/{mobile-Bq0FH9JV.js → mobile-VUyTo40E.js} +3 -3
  188. package/dist/web/public/assets/{mobile-Bq0FH9JV.js.map → mobile-VUyTo40E.js.map} +1 -1
  189. package/dist/web/public/assets/{network--s113Jkm.js → network-BUeWK3bs.js} +2 -2
  190. package/dist/web/public/assets/{network--s113Jkm.js.map → network-BUeWK3bs.js.map} +1 -1
  191. package/dist/web/public/assets/outbox-CEE0rwN3.js +2 -0
  192. package/dist/web/public/assets/outbox-CEE0rwN3.js.map +1 -0
  193. package/dist/web/public/assets/overview-BSOZ5gTD.js +12 -0
  194. package/dist/web/public/assets/overview-BSOZ5gTD.js.map +1 -0
  195. package/dist/web/public/assets/overview-COop5K2Y.js +12 -0
  196. package/dist/web/public/assets/overview-COop5K2Y.js.map +1 -0
  197. package/dist/web/public/assets/overview-DeH5ud6d.js +2 -0
  198. package/dist/web/public/assets/overview-DeH5ud6d.js.map +1 -0
  199. package/dist/web/public/assets/{pagination-DkdCTctJ.js → pagination-BBicLzXP.js} +3 -3
  200. package/dist/web/public/assets/{pagination-DkdCTctJ.js.map → pagination-BBicLzXP.js.map} +1 -1
  201. package/dist/web/public/assets/persona-CElXQZ4p.js +2 -0
  202. package/dist/web/public/assets/{persona-BvtcZh6G.js.map → persona-CElXQZ4p.js.map} +1 -1
  203. package/dist/web/public/assets/{plans-i3a6lrqF.js → plans-Bo5LlLeH.js} +3 -8
  204. package/dist/web/public/assets/plans-Bo5LlLeH.js.map +1 -0
  205. package/dist/web/public/assets/{play-CPoE_JnS.js → play-DX5wp4WH.js} +2 -2
  206. package/dist/web/public/assets/{play-CPoE_JnS.js.map → play-DX5wp4WH.js.map} +1 -1
  207. package/dist/web/public/assets/{plus-CfzKV_0u.js → plus-DH4J_YhN.js} +2 -2
  208. package/dist/web/public/assets/{plus-CfzKV_0u.js.map → plus-DH4J_YhN.js.map} +1 -1
  209. package/dist/web/public/assets/policy-BrgOuDt_.js +2 -0
  210. package/dist/web/public/assets/{policy-Cm88P8LO.js.map → policy-BrgOuDt_.js.map} +1 -1
  211. package/dist/web/public/assets/{qr-code-DMkV8nv2.js → qr-code-YrEuhMPC.js} +2 -2
  212. package/dist/web/public/assets/{qr-code-DMkV8nv2.js.map → qr-code-YrEuhMPC.js.map} +1 -1
  213. package/dist/web/public/assets/{refresh-ccw-nBMm5Xal.js → refresh-ccw-DlAd-eTQ.js} +2 -2
  214. package/dist/web/public/assets/{refresh-ccw-nBMm5Xal.js.map → refresh-ccw-DlAd-eTQ.js.map} +1 -1
  215. package/dist/web/public/assets/{reminders-DjEujanC.js → reminders-DBEE0zXG.js} +3 -3
  216. package/dist/web/public/assets/{reminders-DjEujanC.js.map → reminders-DBEE0zXG.js.map} +1 -1
  217. package/dist/web/public/assets/{save-DbrrCFDM.js → save-BDOtZrfp.js} +2 -2
  218. package/dist/web/public/assets/{save-DbrrCFDM.js.map → save-BDOtZrfp.js.map} +1 -1
  219. package/dist/web/public/assets/schedules-DAyhVI8-.js +2 -0
  220. package/dist/web/public/assets/schedules-DAyhVI8-.js.map +1 -0
  221. package/dist/web/public/assets/{search-5q3dkINm.js → search-55mtgHrB.js} +3 -3
  222. package/dist/web/public/assets/{search-5q3dkINm.js.map → search-55mtgHrB.js.map} +1 -1
  223. package/dist/web/public/assets/{search-DbE4VEm9.js → search-CAICU3aU.js} +2 -2
  224. package/dist/web/public/assets/{search-DbE4VEm9.js.map → search-CAICU3aU.js.map} +1 -1
  225. package/dist/web/public/assets/security-CbP4QgVp.js +2 -0
  226. package/dist/web/public/assets/security-CbP4QgVp.js.map +1 -0
  227. package/dist/web/public/assets/server-Dg4e8pvm.js +7 -0
  228. package/dist/web/public/assets/server-Dg4e8pvm.js.map +1 -0
  229. package/dist/web/public/assets/service-gWZa3sup.js +7 -0
  230. package/dist/web/public/assets/service-gWZa3sup.js.map +1 -0
  231. package/dist/web/public/assets/{shield-alert-WOa69jy3.js → shield-alert-DOKK9EnJ.js} +2 -2
  232. package/dist/web/public/assets/{shield-alert-WOa69jy3.js.map → shield-alert-DOKK9EnJ.js.map} +1 -1
  233. package/dist/web/public/assets/sparkles-G0QIs9nP.js +7 -0
  234. package/dist/web/public/assets/sparkles-G0QIs9nP.js.map +1 -0
  235. package/dist/web/public/assets/start-D-abhl3q.js +2 -0
  236. package/dist/web/public/assets/start-D-abhl3q.js.map +1 -0
  237. package/dist/web/public/assets/{status-badge-D5xhwquL.js → status-badge-CyLdpsXq.js} +2 -2
  238. package/dist/web/public/assets/{status-badge-D5xhwquL.js.map → status-badge-CyLdpsXq.js.map} +1 -1
  239. package/dist/web/public/assets/{subtasks-DMRyk6YS.js → subtasks-BnEjSGUR.js} +3 -3
  240. package/dist/web/public/assets/{subtasks-DMRyk6YS.js.map → subtasks-BnEjSGUR.js.map} +1 -1
  241. package/dist/web/public/assets/{table-Dx65w6V0.js → table-sCMZBe_Z.js} +2 -2
  242. package/dist/web/public/assets/{table-Dx65w6V0.js.map → table-sCMZBe_Z.js.map} +1 -1
  243. package/dist/web/public/assets/terminal-_pXeEjXG.js +7 -0
  244. package/dist/web/public/assets/terminal-_pXeEjXG.js.map +1 -0
  245. package/dist/web/public/assets/{topn-L7Juczp3.js → topn-D1B-gS1M.js} +3 -3
  246. package/dist/web/public/assets/{topn-L7Juczp3.js.map → topn-D1B-gS1M.js.map} +1 -1
  247. package/dist/web/public/assets/{trash-2-7xrfqd-v.js → trash-2-D2x2UPuZ.js} +2 -2
  248. package/dist/web/public/assets/{trash-2-7xrfqd-v.js.map → trash-2-D2x2UPuZ.js.map} +1 -1
  249. package/dist/web/public/assets/use-a2a-C98e2Via.js +2 -0
  250. package/dist/web/public/assets/use-a2a-C98e2Via.js.map +1 -0
  251. package/dist/web/public/assets/{use-agim-skills-pFjfgqMF.js → use-agim-skills-BbuJP3NT.js} +2 -2
  252. package/dist/web/public/assets/{use-agim-skills-pFjfgqMF.js.map → use-agim-skills-BbuJP3NT.js.map} +1 -1
  253. package/dist/web/public/assets/use-background-tasks-CwFmOokw.js +2 -0
  254. package/dist/web/public/assets/{use-background-tasks-D1--hHjp.js.map → use-background-tasks-CwFmOokw.js.map} +1 -1
  255. package/dist/web/public/assets/use-jobs-BJjeJ5lh.js +2 -0
  256. package/dist/web/public/assets/use-jobs-BJjeJ5lh.js.map +1 -0
  257. package/dist/web/public/assets/use-memory-CXDwKCco.js +2 -0
  258. package/dist/web/public/assets/{use-memory-Bz1Zao7g.js.map → use-memory-CXDwKCco.js.map} +1 -1
  259. package/dist/web/public/assets/use-observability-CY5ZUPrC.js +2 -0
  260. package/dist/web/public/assets/{use-observability-DtqSWVjM.js.map → use-observability-CY5ZUPrC.js.map} +1 -1
  261. package/dist/web/public/assets/use-outbox-DT_XWB_7.js +7 -0
  262. package/dist/web/public/assets/use-outbox-DT_XWB_7.js.map +1 -0
  263. package/dist/web/public/assets/use-schedules-D4W8fMwo.js +7 -0
  264. package/dist/web/public/assets/use-schedules-D4W8fMwo.js.map +1 -0
  265. package/dist/web/public/assets/use-settings-DGIjmUX0.js +2 -0
  266. package/dist/web/public/assets/use-settings-DGIjmUX0.js.map +1 -0
  267. package/dist/web/public/assets/use-skills-D2bMM580.js +7 -0
  268. package/dist/web/public/assets/use-skills-D2bMM580.js.map +1 -0
  269. package/dist/web/public/assets/use-vector-BYOFwjU0.js +2 -0
  270. package/dist/web/public/assets/use-vector-BYOFwjU0.js.map +1 -0
  271. package/dist/web/public/assets/use-workspace-CuytyHwb.js +2 -0
  272. package/dist/web/public/assets/{use-workspace-CConjEx0.js.map → use-workspace-CuytyHwb.js.map} +1 -1
  273. package/dist/web/public/assets/vector-CL8ezpSR.js +2 -0
  274. package/dist/web/public/assets/vector-CL8ezpSR.js.map +1 -0
  275. package/dist/web/public/assets/viewer-CD0iEfPU.js +7 -0
  276. package/dist/web/public/assets/viewer-CD0iEfPU.js.map +1 -0
  277. package/dist/web/public/assets/workspace-BA1_hso3.js +17 -0
  278. package/dist/web/public/assets/workspace-BA1_hso3.js.map +1 -0
  279. package/dist/web/public/assets/workspaces-DyGLJUgB.js +7 -0
  280. package/dist/web/public/assets/workspaces-DyGLJUgB.js.map +1 -0
  281. package/dist/web/public/index.html +2 -2
  282. package/dist/web/server.d.ts +0 -3
  283. package/dist/web/server.d.ts.map +1 -1
  284. package/dist/web/server.js +138 -3
  285. package/dist/web/server.js.map +1 -1
  286. package/package.json +1 -1
  287. package/dist/web/public/assets/a2a-D7MoJ1iT.js +0 -7
  288. package/dist/web/public/assets/a2a-D7MoJ1iT.js.map +0 -1
  289. package/dist/web/public/assets/agents-BXThDW6f.js +0 -7
  290. package/dist/web/public/assets/bgjobs-Rc05aEy9.js +0 -7
  291. package/dist/web/public/assets/bgjobs-Rc05aEy9.js.map +0 -1
  292. package/dist/web/public/assets/chat-DQpQLW9j.js +0 -17
  293. package/dist/web/public/assets/chat-DQpQLW9j.js.map +0 -1
  294. package/dist/web/public/assets/circle-check-DZnkaUdk.js +0 -7
  295. package/dist/web/public/assets/circle-check-DZnkaUdk.js.map +0 -1
  296. package/dist/web/public/assets/confirm-dialog-gPKJnvEW.js +0 -2
  297. package/dist/web/public/assets/health-wqCp-K_o.js +0 -2
  298. package/dist/web/public/assets/hot-B-CMjQIr.js +0 -12
  299. package/dist/web/public/assets/index-DHh1LYlA.js +0 -209
  300. package/dist/web/public/assets/index-DHh1LYlA.js.map +0 -1
  301. package/dist/web/public/assets/index-DknVjPYB.css +0 -1
  302. package/dist/web/public/assets/installed-Cet-1M2Q.js.map +0 -1
  303. package/dist/web/public/assets/jobs-CfEzOOAC.js +0 -2
  304. package/dist/web/public/assets/jobs-CfEzOOAC.js.map +0 -1
  305. package/dist/web/public/assets/layout-BX43KyXM.js +0 -2
  306. package/dist/web/public/assets/layout-BX43KyXM.js.map +0 -1
  307. package/dist/web/public/assets/layout-BcYZlaqf.js +0 -2
  308. package/dist/web/public/assets/layout-BcYZlaqf.js.map +0 -1
  309. package/dist/web/public/assets/layout-Cb7looUv.js +0 -2
  310. package/dist/web/public/assets/layout-Cb7looUv.js.map +0 -1
  311. package/dist/web/public/assets/layout-D7xH78OU.js +0 -2
  312. package/dist/web/public/assets/layout-D7xH78OU.js.map +0 -1
  313. package/dist/web/public/assets/llm-BZ9qqp-D.js +0 -27
  314. package/dist/web/public/assets/llm-BZ9qqp-D.js.map +0 -1
  315. package/dist/web/public/assets/loader-circle-DgdBWYl0.js +0 -7
  316. package/dist/web/public/assets/memos-BBtqFcoH.js +0 -12
  317. package/dist/web/public/assets/memos-BBtqFcoH.js.map +0 -1
  318. package/dist/web/public/assets/messengers-i7WvNT3o.js +0 -2
  319. package/dist/web/public/assets/messengers-i7WvNT3o.js.map +0 -1
  320. package/dist/web/public/assets/outbox-BbfC5kuG.js +0 -7
  321. package/dist/web/public/assets/outbox-BbfC5kuG.js.map +0 -1
  322. package/dist/web/public/assets/persona-BvtcZh6G.js +0 -2
  323. package/dist/web/public/assets/plans-i3a6lrqF.js.map +0 -1
  324. package/dist/web/public/assets/policy-Cm88P8LO.js +0 -2
  325. package/dist/web/public/assets/schedules-DzwDWykc.js +0 -7
  326. package/dist/web/public/assets/schedules-DzwDWykc.js.map +0 -1
  327. package/dist/web/public/assets/security-BIcnUrAs.js +0 -2
  328. package/dist/web/public/assets/security-BIcnUrAs.js.map +0 -1
  329. package/dist/web/public/assets/service-CnorFHzZ.js +0 -7
  330. package/dist/web/public/assets/service-CnorFHzZ.js.map +0 -1
  331. package/dist/web/public/assets/use-background-tasks-D1--hHjp.js +0 -2
  332. package/dist/web/public/assets/use-memory-Bz1Zao7g.js +0 -2
  333. package/dist/web/public/assets/use-observability-DtqSWVjM.js +0 -2
  334. package/dist/web/public/assets/use-settings-DKbDqCEJ.js +0 -2
  335. package/dist/web/public/assets/use-settings-DKbDqCEJ.js.map +0 -1
  336. package/dist/web/public/assets/use-workspace-CConjEx0.js +0 -2
  337. package/dist/web/public/assets/vector-D8sEa2W-.js +0 -2
  338. package/dist/web/public/assets/vector-D8sEa2W-.js.map +0 -1
  339. package/dist/web/public/assets/viewer-aSIjAKVA.js +0 -12
  340. package/dist/web/public/assets/viewer-aSIjAKVA.js.map +0 -1
  341. package/dist/web/public/assets/workspace-BqwWoinI.js +0 -17
  342. package/dist/web/public/assets/workspace-BqwWoinI.js.map +0 -1
  343. package/dist/web/public/assets/workspaces-ChsJcrav.js +0 -7
  344. package/dist/web/public/assets/workspaces-ChsJcrav.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start-D-abhl3q.js","sources":["../../src/routes/settings/start.tsx"],"sourcesContent":["/**\n * /settings/start — low-friction setup runway.\n *\n * This page does not replace the detailed settings pages. It gives new\n * operators a small number of visible next steps, each linking to the\n * existing page that owns the actual configuration.\n */\n\nimport { Link } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport {\n AlertCircle,\n ArrowRight,\n Bot,\n CheckCircle2,\n Loader2,\n MessageSquare,\n Plug,\n RefreshCcw,\n Server,\n} from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { useLlmList } from '@/hooks/use-llm-admin'\nimport { useConfig, useServiceStatus } from '@/hooks/use-settings'\nimport { useAgentsStatus } from '@/hooks/use-workspace'\nimport { agentDisplayName } from '@/lib/agent-label'\nimport { cn } from '@/lib/utils'\n\ntype StepState = 'done' | 'todo' | 'warn' | 'loading'\n\ninterface SetupStep {\n id: string\n state: StepState\n icon: JSX.Element\n title: string\n detail: string\n action: string\n to: string\n}\n\nconst STATE_BADGE: Record<StepState, 'success' | 'warning' | 'info' | 'outline'> = {\n done: 'success',\n todo: 'outline',\n warn: 'warning',\n loading: 'info',\n}\n\nexport default function SettingsStartRoute(): JSX.Element {\n const { t } = useTranslation('settings')\n const cfgQuery = useConfig()\n const serviceQuery = useServiceStatus()\n const agentsQuery = useAgentsStatus()\n const llmQuery = useLlmList()\n\n const cfg = cfgQuery.data\n const defaultAgent = cfg?.defaultAgent || cfg?.agents?.[0] || ''\n const agentName = defaultAgent ? agentDisplayName(defaultAgent) : t('start.unknown')\n const agentStatus = defaultAgent ? agentsQuery.data?.[defaultAgent] : undefined\n const agentLoading = cfgQuery.isLoading || agentsQuery.isLoading\n const service = serviceQuery.data\n const serviceRunning = Boolean(service && service.mode !== 'none')\n const usableBackends = (llmQuery.data?.backends ?? []).filter((b) => b.secret.source !== 'none')\n const llmReady = usableBackends.length > 0\n const messengers = cfg?.messengers ?? []\n const imReady = messengers.length > 0\n\n const webState: StepState = serviceQuery.isLoading ? 'loading' : serviceRunning ? 'done' : 'warn'\n const agentState: StepState = agentLoading\n ? 'loading'\n : agentStatus === true\n ? 'done'\n : agentStatus === false\n ? 'warn'\n : defaultAgent\n ? 'todo'\n : 'warn'\n const llmState: StepState = llmQuery.isLoading ? 'loading' : llmReady ? 'done' : 'todo'\n const imState: StepState = cfgQuery.isLoading ? 'loading' : imReady ? 'done' : 'todo'\n\n const doneCount = [webState, agentState, imState, llmState].filter((s) => s === 'done').length\n const steps: SetupStep[] = [\n {\n id: 'web',\n state: webState,\n icon: <MessageSquare />,\n title: t('start.steps.web.title'),\n detail: serviceRunning\n ? t('start.steps.web.ready', { mode: service?.mode ?? '' })\n : t('start.steps.web.needsStart'),\n action: t('start.steps.web.action'),\n to: '/?welcome=1',\n },\n {\n id: 'agent',\n state: agentState,\n icon: <Bot />,\n title: t('start.steps.agent.title'),\n detail: agentStatus === true\n ? t('start.steps.agent.ready', { agent: agentName })\n : agentStatus === false\n ? t('start.steps.agent.offline', { agent: agentName })\n : defaultAgent\n ? t('start.steps.agent.selected', { agent: agentName })\n : t('start.steps.agent.empty'),\n action: t('start.steps.agent.action'),\n to: '/settings/agents',\n },\n {\n id: 'llm',\n state: llmState,\n icon: <Bot />,\n title: t('start.steps.llm.title'),\n detail: llmReady\n ? t('start.steps.llm.ready', { count: usableBackends.length })\n : t('start.steps.llm.empty'),\n action: t('start.steps.llm.action'),\n to: '/settings/llm',\n },\n {\n id: 'im',\n state: imState,\n icon: <Plug />,\n title: t('start.steps.im.title'),\n detail: imReady\n ? t('start.steps.im.ready', { platforms: messengers.map((m) => platformLabel(m, t)).join(', ') })\n : t('start.steps.im.empty'),\n action: t('start.steps.im.action'),\n to: '/settings/messengers',\n },\n ]\n\n return (\n <div className=\"mx-auto flex max-w-5xl flex-col gap-4\">\n <header className=\"flex flex-col gap-3 border-b border-border pb-4 sm:flex-row sm:items-end\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h1 className=\"text-xl font-semibold\">{t('start.title')}</h1>\n <Badge variant={doneCount >= 3 ? 'success' : 'info'}>{doneCount}/4</Badge>\n </div>\n <p className=\"mt-1 max-w-2xl text-sm text-text-dim\">{t('start.subtitle')}</p>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <Button asChild size=\"sm\">\n <Link to=\"/?welcome=1\">\n <MessageSquare className=\"h-4 w-4\" />\n <span>{t('start.actions.chat')}</span>\n </Link>\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={cfgQuery.isFetching || serviceQuery.isFetching || agentsQuery.isFetching || llmQuery.isFetching}\n onClick={() => {\n void cfgQuery.refetch()\n void serviceQuery.refetch()\n void agentsQuery.refetch()\n void llmQuery.refetch()\n }}\n >\n <RefreshCcw\n className={cn(\n 'h-4 w-4',\n (cfgQuery.isFetching || serviceQuery.isFetching || agentsQuery.isFetching || llmQuery.isFetching)\n && 'animate-spin',\n )}\n />\n <span>{t('start.actions.refresh')}</span>\n </Button>\n </div>\n </header>\n\n <section className=\"grid gap-3 sm:grid-cols-2\">\n {steps.map((step) => (\n <SetupStepCard key={step.id} step={step} />\n ))}\n </section>\n\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center\">\n <span className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-surface-2 text-text-dim\">\n <Server className=\"h-4 w-4\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <h2 className=\"text-sm font-semibold\">{t('start.deploy.title')}</h2>\n <p className=\"mt-1 text-sm text-text-dim\">{t('start.deploy.detail')}</p>\n </div>\n <Button asChild variant=\"secondary\" size=\"sm\">\n <Link to=\"/settings/service\">\n <span>{t('start.deploy.action')}</span>\n <ArrowRight className=\"h-4 w-4\" />\n </Link>\n </Button>\n </div>\n </section>\n </div>\n )\n}\n\nfunction SetupStepCard({ step }: { step: SetupStep }): JSX.Element {\n const { t } = useTranslation('settings')\n const done = step.state === 'done'\n return (\n <article className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex items-start gap-3\">\n <span\n className={cn(\n 'flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-surface-2',\n step.state === 'done' && 'text-success',\n step.state === 'warn' && 'text-warning',\n step.state === 'todo' && 'text-text-dim',\n step.state === 'loading' && 'text-info',\n '[&_svg]:h-4 [&_svg]:w-4',\n )}\n aria-hidden=\"true\"\n >\n {step.state === 'done'\n ? <CheckCircle2 />\n : step.state === 'warn'\n ? <AlertCircle />\n : step.state === 'loading'\n ? <Loader2 className=\"animate-spin\" />\n : step.icon}\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h2 className=\"text-sm font-semibold\">{step.title}</h2>\n <Badge variant={STATE_BADGE[step.state]}>{t(`start.state.${step.state}`)}</Badge>\n </div>\n <p className=\"mt-1 text-sm text-text-dim\">{step.detail}</p>\n <Button asChild variant={done ? 'ghost' : 'secondary'} size=\"sm\" className=\"mt-3\">\n <Link to={step.to}>\n <span>{step.action}</span>\n <ArrowRight className=\"h-4 w-4\" />\n </Link>\n </Button>\n </div>\n </div>\n </article>\n )\n}\n\nfunction platformLabel(id: string, t: ReturnType<typeof useTranslation>['t']): string {\n const labels: Record<string, string> = {\n 'wechat-ilink': t('messengers.platform.wechat'),\n telegram: t('messengers.platform.telegram'),\n feishu: t('messengers.platform.feishu'),\n dingtalk: t('messengers.platform.dingtalk'),\n discord: t('messengers.platform.discord'),\n email: t('tabs.email'),\n }\n return labels[id] ?? id\n}\n"],"names":["STATE_BADGE","SettingsStartRoute","t","useTranslation","cfgQuery","useConfig","serviceQuery","useServiceStatus","agentsQuery","useAgentsStatus","llmQuery","useLlmList","cfg","defaultAgent","agentName","agentDisplayName","agentStatus","agentLoading","service","serviceRunning","usableBackends","b","llmReady","messengers","imReady","webState","agentState","llmState","imState","doneCount","s","steps","MessageSquare","Bot","Plug","m","platformLabel","jsxs","jsx","Badge","Button","Link","RefreshCcw","cn","step","SetupStepCard","Server","ArrowRight","done","CheckCircle2","AlertCircle","Loader2","id"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{j as r,l as c}from"./index-DHh1LYlA.js";const i={succeeded:"success",completed:"success",done:"success",approved:"success",allowed:"success",delivered:"success",active:"success",running:"info",in_progress:"info",pending:"info",queued:"info",scheduled:"info",open:"info",paused:"warning",awaiting:"warning",timeout:"warning",expired:"warning",failed:"danger",error:"danger",denied:"danger",rejected:"danger",cancelled:"danger",canceled:"danger",finished:"default",closed:"default",archived:"default"};function o({status:e,variant:n,children:d,...s}){const a=n??i[e.toLowerCase()]??"default";return r.jsx(c,{variant:a,...s,children:d??e})}o.displayName="StatusBadge";export{o as S};
2
- //# sourceMappingURL=status-badge-D5xhwquL.js.map
1
+ import{j as r,d as c}from"./index-DCfdN5R7.js";const i={succeeded:"success",completed:"success",done:"success",approved:"success",allowed:"success",delivered:"success",active:"success",running:"info",in_progress:"info",pending:"info",queued:"info",scheduled:"info",open:"info",paused:"warning",awaiting:"warning",timeout:"warning",expired:"warning",failed:"danger",error:"danger",denied:"danger",rejected:"danger",cancelled:"danger",canceled:"danger",finished:"default",closed:"default",archived:"default"};function o({status:e,variant:n,children:d,...s}){const a=n??i[e.toLowerCase()]??"default";return r.jsx(c,{variant:a,...s,children:d??e})}o.displayName="StatusBadge";export{o as S};
2
+ //# sourceMappingURL=status-badge-CyLdpsXq.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"status-badge-D5xhwquL.js","sources":["../../src/components/common/status-badge.tsx"],"sourcesContent":["/**\n * StatusBadge — domain status string → Badge variant + label.\n *\n * Single source of truth for the color mapping across the 4 M2 pages\n * (jobs / approvals / reminders / memos) plus the M3 observability\n * page. Without this every page would invent its own (job status\n * \"running\" mapped to \"warning\" on tasks.html, \"info\" on approvals.\n * html, \"secondary\" on observability — the kind of drift the v2\n * rewrite is supposed to eliminate).\n *\n * The label slot is intentionally a child rather than a prop: callers\n * pass i18n'd strings via `<StatusBadge status=\"running\">{t('jobs.\n * status.running')}</StatusBadge>` so the badge stays language-aware\n * without needing useTranslation here.\n *\n * Unknown status falls back to `default` variant (neutral gray pill)\n * so a backend that introduces a new state doesn't crash the page.\n */\n\nimport * as React from 'react'\nimport { Badge, type BadgeProps } from '@/components/ui/badge'\n\n/**\n * Status palette shared across domain entities. The mapping is\n * deliberately broad — both \"succeeded\" and \"completed\" land on\n * success; both \"running\" and \"in_progress\" land on info, etc. —\n * because the backend hasn't been canonicalised yet (memory.ts uses\n * one set, jobs.ts another).\n */\nconst STATUS_VARIANT: Record<string, BadgeProps['variant']> = {\n // Success-family\n succeeded: 'success',\n completed: 'success',\n done: 'success',\n approved: 'success',\n allowed: 'success',\n delivered: 'success',\n active: 'success',\n\n // In-flight\n running: 'info',\n in_progress:'info',\n pending: 'info',\n queued: 'info',\n scheduled: 'info',\n open: 'info',\n\n // Warnings (operator may need to look)\n paused: 'warning',\n awaiting: 'warning',\n timeout: 'warning',\n expired: 'warning',\n\n // Failed / errored\n failed: 'danger',\n error: 'danger',\n denied: 'danger',\n rejected: 'danger',\n cancelled: 'danger',\n canceled: 'danger',\n\n // Terminal-neutral\n finished: 'default',\n closed: 'default',\n archived: 'default',\n}\n\nexport interface StatusBadgeProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'children'> {\n status: string\n children?: React.ReactNode\n /** Force-override the auto-mapped variant. */\n variant?: BadgeProps['variant']\n}\n\nfunction StatusBadge({\n status,\n variant,\n children,\n ...rest\n}: StatusBadgeProps): JSX.Element {\n const resolved = variant ?? STATUS_VARIANT[status.toLowerCase()] ?? 'default'\n return (\n <Badge variant={resolved} {...rest}>\n {children ?? status}\n </Badge>\n )\n}\nStatusBadge.displayName = 'StatusBadge'\n\nexport { StatusBadge, STATUS_VARIANT }\n"],"names":["STATUS_VARIANT","StatusBadge","status","variant","children","rest","resolved","Badge"],"mappings":"+CA6BA,MAAMA,EAAwD,CAE5D,UAAY,UACZ,UAAY,UACZ,KAAY,UACZ,SAAY,UACZ,QAAY,UACZ,UAAY,UACZ,OAAY,UAGZ,QAAY,OACZ,YAAY,OACZ,QAAY,OACZ,OAAY,OACZ,UAAY,OACZ,KAAY,OAGZ,OAAY,UACZ,SAAY,UACZ,QAAY,UACZ,QAAY,UAGZ,OAAY,SACZ,MAAY,SACZ,OAAY,SACZ,SAAY,SACZ,UAAY,SACZ,SAAY,SAGZ,SAAY,UACZ,OAAY,UACZ,SAAY,SACd,EASA,SAASC,EAAY,CACnB,OAAAC,EACA,QAAAC,EACA,SAAAC,EACA,GAAGC,CACL,EAAkC,CAChC,MAAMC,EAAWH,GAAWH,EAAeE,EAAO,YAAA,CAAa,GAAK,UACpE,aACGK,EAAA,CAAM,QAASD,EAAW,GAAGD,EAC3B,YAAYH,EACf,CAEJ,CACAD,EAAY,YAAc"}
1
+ {"version":3,"file":"status-badge-CyLdpsXq.js","sources":["../../src/components/common/status-badge.tsx"],"sourcesContent":["/**\n * StatusBadge — domain status string → Badge variant + label.\n *\n * Single source of truth for the color mapping across the 4 M2 pages\n * (jobs / approvals / reminders / memos) plus the M3 observability\n * page. Without this every page would invent its own (job status\n * \"running\" mapped to \"warning\" on tasks.html, \"info\" on approvals.\n * html, \"secondary\" on observability — the kind of drift the v2\n * rewrite is supposed to eliminate).\n *\n * The label slot is intentionally a child rather than a prop: callers\n * pass i18n'd strings via `<StatusBadge status=\"running\">{t('jobs.\n * status.running')}</StatusBadge>` so the badge stays language-aware\n * without needing useTranslation here.\n *\n * Unknown status falls back to `default` variant (neutral gray pill)\n * so a backend that introduces a new state doesn't crash the page.\n */\n\nimport * as React from 'react'\nimport { Badge, type BadgeProps } from '@/components/ui/badge'\n\n/**\n * Status palette shared across domain entities. The mapping is\n * deliberately broad — both \"succeeded\" and \"completed\" land on\n * success; both \"running\" and \"in_progress\" land on info, etc. —\n * because the backend hasn't been canonicalised yet (memory.ts uses\n * one set, jobs.ts another).\n */\nconst STATUS_VARIANT: Record<string, BadgeProps['variant']> = {\n // Success-family\n succeeded: 'success',\n completed: 'success',\n done: 'success',\n approved: 'success',\n allowed: 'success',\n delivered: 'success',\n active: 'success',\n\n // In-flight\n running: 'info',\n in_progress:'info',\n pending: 'info',\n queued: 'info',\n scheduled: 'info',\n open: 'info',\n\n // Warnings (operator may need to look)\n paused: 'warning',\n awaiting: 'warning',\n timeout: 'warning',\n expired: 'warning',\n\n // Failed / errored\n failed: 'danger',\n error: 'danger',\n denied: 'danger',\n rejected: 'danger',\n cancelled: 'danger',\n canceled: 'danger',\n\n // Terminal-neutral\n finished: 'default',\n closed: 'default',\n archived: 'default',\n}\n\nexport interface StatusBadgeProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'children'> {\n status: string\n children?: React.ReactNode\n /** Force-override the auto-mapped variant. */\n variant?: BadgeProps['variant']\n}\n\nfunction StatusBadge({\n status,\n variant,\n children,\n ...rest\n}: StatusBadgeProps): JSX.Element {\n const resolved = variant ?? STATUS_VARIANT[status.toLowerCase()] ?? 'default'\n return (\n <Badge variant={resolved} {...rest}>\n {children ?? status}\n </Badge>\n )\n}\nStatusBadge.displayName = 'StatusBadge'\n\nexport { StatusBadge, STATUS_VARIANT }\n"],"names":["STATUS_VARIANT","StatusBadge","status","variant","children","rest","resolved","Badge"],"mappings":"+CA6BA,MAAMA,EAAwD,CAE5D,UAAY,UACZ,UAAY,UACZ,KAAY,UACZ,SAAY,UACZ,QAAY,UACZ,UAAY,UACZ,OAAY,UAGZ,QAAY,OACZ,YAAY,OACZ,QAAY,OACZ,OAAY,OACZ,UAAY,OACZ,KAAY,OAGZ,OAAY,UACZ,SAAY,UACZ,QAAY,UACZ,QAAY,UAGZ,OAAY,SACZ,MAAY,SACZ,OAAY,SACZ,SAAY,SACZ,UAAY,SACZ,SAAY,SAGZ,SAAY,UACZ,OAAY,UACZ,SAAY,SACd,EASA,SAASC,EAAY,CACnB,OAAAC,EACA,QAAAC,EACA,SAAAC,EACA,GAAGC,CACL,EAAkC,CAChC,MAAMC,EAAWH,GAAWH,EAAeE,EAAO,YAAA,CAAa,GAAK,UACpE,aACGK,EAAA,CAAM,QAASD,EAAW,GAAGD,EAC3B,YAAYH,EACf,CAEJ,CACAD,EAAY,YAAc"}
@@ -1,7 +1,7 @@
1
- import{o as g,a as b,b as j,d as k,u as N,f as y,j as s,c as w,B as S,L as v,I as C}from"./index-DHh1LYlA.js";import{r as L}from"./react-DlP5eolq.js";import{D as T}from"./data-table-DOKUic1J.js";import{E as I}from"./empty-state-CTwOQemt.js";import{S as A}from"./status-badge-D5xhwquL.js";import{u as D}from"./use-event-stream-I1lMFEfh.js";import{L as M}from"./loader-circle-DgdBWYl0.js";import{R as E}from"./refresh-ccw-nBMm5Xal.js";import"./table-Dx65w6V0.js";import"./arrow-up-i_dEdXkz.js";import"./arrow-down-B8DkdbEY.js";/**
1
+ import{h as g,t as b,r as j,s as k,u as N,i as w,j as s,f as y,e as S,w as v,I as C}from"./index-DCfdN5R7.js";import{r as L}from"./react-DlP5eolq.js";import{D as T}from"./data-table-BkUshOZz.js";import{E as I}from"./empty-state-CuiqdZiB.js";import{S as A}from"./status-badge-CyLdpsXq.js";import{u as D}from"./use-event-stream-I1lMFEfh.js";import{L as M}from"./loader-circle-DDdmcH0k.js";import{R as E}from"./refresh-ccw-DlAd-eTQ.js";import"./table-sCMZBe_Z.js";import"./arrow-up-Dm0U4-6U.js";import"./arrow-down-7i0xwCI2.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 R=g("ListTree",[["path",{d:"M21 12h-8",key:"1bmf0i"}],["path",{d:"M21 6H8",key:"1pqkrb"}],["path",{d:"M21 18h-8",key:"1tm79t"}],["path",{d:"M3 6v4c0 1.1.9 2 2 2h3",key:"1ywdgy"}],["path",{d:"M3 10v6c0 1.1.9 2 2 2h3",key:"2wc746"}]]),d={all:["subtasks"],list:e=>["subtasks","list",e]};function q(e){return j({queryKey:d.list(e),queryFn:()=>k.listSubtasks(e)})}function F(){const e=b();return()=>e.invalidateQueries({queryKey:d.all})}const $={connected:"text-success",connecting:"text-text-dim",reconnecting:"text-warning",closed:"text-text-muted"};function W(){const{t:e}=N(["tasks","common"]),[a,n]=y(),r=F(),i=a.get("agent")??"",{data:m,isLoading:u,isFetching:c,refetch:x}=q(i?{agent:i}:{}),p=m?.subtasks??[],o=D({job:()=>r()});function h(t){const l=new URLSearchParams(a);t?l.set("agent",t):l.delete("agent"),n(l,{replace:!0})}const f=L.useMemo(()=>[{id:"id",header:e("subtasks.col.id"),cell:t=>s.jsxs("span",{className:"tabular-nums text-text-dim",children:["#",t.id]}),headClassName:"w-16"},{id:"agent",header:e("subtasks.col.agent"),cell:t=>s.jsx("span",{className:"font-medium",children:t.agent}),headClassName:"w-32"},{id:"prompt",header:e("subtasks.col.prompt"),cell:t=>s.jsx("span",{className:"line-clamp-2 text-text-dim",children:t.prompt}),asCardTitle:!0},{id:"status",header:e("subtasks.col.status"),cell:t=>s.jsx(A,{status:t.status,children:e(`subtasks.status.${t.status}`,{defaultValue:t.status})}),headClassName:"w-32"},{id:"parent",header:e("subtasks.col.parent"),cell:t=>s.jsxs("span",{className:"text-text-dim",children:[s.jsx("span",{className:"font-medium text-text",children:t.parentAgent}),s.jsx("span",{className:"text-text-muted",children:" / "}),s.jsx("span",{title:t.parentSessionId,children:t.parentSessionId.slice(0,8)})]}),headClassName:"w-40"},{id:"platform",header:e("subtasks.col.platform"),cell:t=>s.jsx("span",{className:"text-text-dim",children:t.platform}),headClassName:"w-28",hideOnMobile:!0},{id:"createdAt",header:e("subtasks.col.createdAt"),cell:t=>s.jsx("span",{className:"text-text-dim",children:B(t.createdAt)}),headClassName:"w-40",hideOnMobile:!0}],[e]);return s.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[s.jsxs("header",{className:"flex flex-col gap-1",children:[s.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[s.jsx("h1",{className:"text-xl font-semibold",children:e("subtasks.title")}),s.jsx("span",{className:w("text-xs font-medium tabular-nums",$[o]),children:e(`jobs.live.${o}`)}),s.jsxs(S,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>x(),disabled:c,"aria-label":e("actions.refresh",{ns:"common"}),children:[c?s.jsx(M,{className:"h-4 w-4 animate-spin"}):s.jsx(E,{className:"h-4 w-4"}),s.jsx("span",{className:"hidden sm:inline",children:e("actions.refresh",{ns:"common"})})]})]}),s.jsx("p",{className:"text-sm text-text-dim",children:e("subtasks.subtitle")})]}),s.jsx("div",{className:"flex flex-wrap items-end gap-2",children:s.jsxs("div",{className:"flex flex-col gap-1",children:[s.jsx(v,{htmlFor:"agent-filter",className:"text-xs text-text-dim",children:e("subtasks.filter.agent")}),s.jsx(C,{id:"agent-filter",value:i,onChange:t=>h(t.target.value),placeholder:e("subtasks.filter.agentAny"),className:"w-48"})]})}),s.jsx(T,{columns:f,rows:p,getRowId:t=>`${t.parentSessionId}:${t.id}`,loading:u,emptyState:s.jsx(I,{icon:s.jsx(R,{}),title:e("subtasks.empty.title"),description:e("subtasks.empty.description")})})]})}function B(e){try{const a=new Date(e);if(Number.isNaN(a.getTime()))return e;const n=new Date;return a.toDateString()===n.toDateString()?a.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit"}):a.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return e}}export{W as default};
7
- //# sourceMappingURL=subtasks-DMRyk6YS.js.map
6
+ */const R=g("ListTree",[["path",{d:"M21 12h-8",key:"1bmf0i"}],["path",{d:"M21 6H8",key:"1pqkrb"}],["path",{d:"M21 18h-8",key:"1tm79t"}],["path",{d:"M3 6v4c0 1.1.9 2 2 2h3",key:"1ywdgy"}],["path",{d:"M3 10v6c0 1.1.9 2 2 2h3",key:"2wc746"}]]),m={all:["subtasks"],list:e=>["subtasks","list",e]};function q(e){return j({queryKey:m.list(e),queryFn:()=>k.listSubtasks(e)})}function F(){const e=b();return()=>e.invalidateQueries({queryKey:m.all})}const $={connected:"text-success",connecting:"text-text-dim",reconnecting:"text-warning",closed:"text-text-muted"};function W(){const{t:e}=N(["tasks","common"]),[a,n]=w(),r=F(),i=a.get("agent")??"",{data:d,isLoading:u,isFetching:c,refetch:x}=q(i?{agent:i}:{}),h=d?.subtasks??[],o=D({job:()=>r()});function p(t){const l=new URLSearchParams(a);t?l.set("agent",t):l.delete("agent"),n(l,{replace:!0})}const f=L.useMemo(()=>[{id:"id",header:e("subtasks.col.id"),cell:t=>s.jsxs("span",{className:"tabular-nums text-text-dim",children:["#",t.id]}),headClassName:"w-16"},{id:"agent",header:e("subtasks.col.agent"),cell:t=>s.jsx("span",{className:"font-medium",children:t.agent}),headClassName:"w-32"},{id:"prompt",header:e("subtasks.col.prompt"),cell:t=>s.jsx("span",{className:"line-clamp-2 text-text-dim",children:t.prompt}),asCardTitle:!0},{id:"status",header:e("subtasks.col.status"),cell:t=>s.jsx(A,{status:t.status,children:e(`subtasks.status.${t.status}`,{defaultValue:t.status})}),headClassName:"w-32"},{id:"parent",header:e("subtasks.col.parent"),cell:t=>s.jsxs("span",{className:"text-text-dim",children:[s.jsx("span",{className:"font-medium text-text",children:t.parentAgent}),s.jsx("span",{className:"text-text-muted",children:" / "}),s.jsx("span",{title:t.parentSessionId,children:t.parentSessionId.slice(0,8)})]}),headClassName:"w-40"},{id:"platform",header:e("subtasks.col.platform"),cell:t=>s.jsx("span",{className:"text-text-dim",children:t.platform}),headClassName:"w-28",hideOnMobile:!0},{id:"createdAt",header:e("subtasks.col.createdAt"),cell:t=>s.jsx("span",{className:"text-text-dim",children:K(t.createdAt)}),headClassName:"w-40",hideOnMobile:!0}],[e]);return s.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[s.jsxs("header",{className:"flex flex-col gap-1",children:[s.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[s.jsx("h1",{className:"text-xl font-semibold",children:e("subtasks.title")}),s.jsx("span",{className:y("text-xs font-medium tabular-nums",$[o]),children:e(`jobs.live.${o}`)}),s.jsxs(S,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>x(),disabled:c,"aria-label":e("actions.refresh",{ns:"common"}),children:[c?s.jsx(M,{className:"h-4 w-4 animate-spin"}):s.jsx(E,{className:"h-4 w-4"}),s.jsx("span",{className:"hidden sm:inline",children:e("actions.refresh",{ns:"common"})})]})]}),s.jsx("p",{className:"text-sm text-text-dim",children:e("subtasks.subtitle")})]}),s.jsx("div",{className:"flex flex-wrap items-end gap-2",children:s.jsxs("div",{className:"flex flex-col gap-1",children:[s.jsx(v,{htmlFor:"agent-filter",className:"text-xs text-text-dim",children:e("subtasks.filter.agent")}),s.jsx(C,{id:"agent-filter",value:i,onChange:t=>p(t.target.value),placeholder:e("subtasks.filter.agentAny"),className:"w-48"})]})}),s.jsx(T,{columns:f,rows:h,getRowId:t=>`${t.parentSessionId}:${t.id}`,loading:u,emptyState:s.jsx(I,{icon:s.jsx(R,{}),title:e("subtasks.empty.title"),description:e("subtasks.empty.description")})})]})}function K(e){try{const a=new Date(e);if(Number.isNaN(a.getTime()))return e;const n=new Date;return a.toDateString()===n.toDateString()?a.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit"}):a.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return e}}export{W as default};
7
+ //# sourceMappingURL=subtasks-BnEjSGUR.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"subtasks-DMRyk6YS.js","sources":["../../node_modules/lucide-react/dist/esm/icons/list-tree.js","../../src/hooks/use-subtasks.ts","../../src/routes/tasks/subtasks.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 ListTree = createLucideIcon(\"ListTree\", [\n [\"path\", { d: \"M21 12h-8\", key: \"1bmf0i\" }],\n [\"path\", { d: \"M21 6H8\", key: \"1pqkrb\" }],\n [\"path\", { d: \"M21 18h-8\", key: \"1tm79t\" }],\n [\"path\", { d: \"M3 6v4c0 1.1.9 2 2 2h3\", key: \"1ywdgy\" }],\n [\"path\", { d: \"M3 10v6c0 1.1.9 2 2 2h3\", key: \"2wc746\" }]\n]);\n\nexport { ListTree as default };\n//# sourceMappingURL=list-tree.js.map\n","/**\n * useSubtasks — react-query wrapper for /api/subtasks.\n *\n * Subtasks are a flattened view of session.subtasks across every\n * conversation file in ~/.agim/sessions/. The endpoint is read-only\n * — no cancel / re-run mutation surface (yet). Live refresh rides on\n * the same SSE 'job' event (subtask state changes piggy-back on the\n * parent job's lifecycle).\n */\n\nimport { useQueryClient, useQuery } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type { ListSubtasksQuery, ListSubtasksResponse } from '@/types/api'\n\nexport const subtasksKeys = {\n all: ['subtasks'] as const,\n list: (q: ListSubtasksQuery) => ['subtasks', 'list', q] as const,\n}\n\nexport function useSubtasks(query: ListSubtasksQuery) {\n return useQuery<ListSubtasksResponse>({\n queryKey: subtasksKeys.list(query),\n queryFn: () => api.listSubtasks(query),\n })\n}\n\nexport function useInvalidateSubtasks() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: subtasksKeys.all })\n}\n","/**\n * /tasks/subtasks — flattened view of per-conversation child tasks\n * spawned by parent agents.\n *\n * Read-only: the backend doesn't expose cancel / re-run for subtasks\n * separately from the parent session. The page mirrors the columns\n * of /tasks/jobs but adds parent context (agent + platform) and\n * drops the duration / cost columns (which session.subtasks doesn't\n * track per-subtask).\n *\n * SSE: subscribes to the same `job` event as /tasks/jobs — subtask\n * status changes piggy-back on the parent job lifecycle in the\n * backend's event-bus.\n */\n\nimport { useMemo } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { Loader2, ListTree, RefreshCcw } from 'lucide-react'\n\nimport { DataTable, type DataTableColumn } from '@/components/common/data-table'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { StatusBadge } from '@/components/common/status-badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport { useSubtasks, useInvalidateSubtasks } from '@/hooks/use-subtasks'\nimport { useEventStream, type SseStatus } from '@/hooks/use-event-stream'\nimport type { Subtask } from '@/types/api'\nimport { cn } from '@/lib/utils'\n\nconst LIVE_STATUS_CLASS: Record<SseStatus, string> = {\n connected: 'text-success',\n connecting: 'text-text-dim',\n reconnecting: 'text-warning',\n closed: 'text-text-muted',\n}\n\nexport default function SubtasksRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const [params, setParams] = useSearchParams()\n const invalidate = useInvalidateSubtasks()\n const agent = params.get('agent') ?? ''\n\n const { data, isLoading, isFetching, refetch } = useSubtasks(\n agent ? { agent } : {},\n )\n const subtasks = data?.subtasks ?? []\n\n const live = useEventStream({\n job: () => invalidate(),\n })\n\n function setAgentFilter(v: string): void {\n const next = new URLSearchParams(params)\n if (!v) next.delete('agent')\n else next.set('agent', v)\n setParams(next, { replace: true })\n }\n\n const columns: DataTableColumn<Subtask>[] = useMemo(\n () => [\n {\n id: 'id',\n header: t('subtasks.col.id'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">#{r.id}</span>,\n headClassName: 'w-16',\n },\n {\n id: 'agent',\n header: t('subtasks.col.agent'),\n cell: (r) => <span className=\"font-medium\">{r.agent}</span>,\n headClassName: 'w-32',\n },\n {\n id: 'prompt',\n header: t('subtasks.col.prompt'),\n cell: (r) => <span className=\"line-clamp-2 text-text-dim\">{r.prompt}</span>,\n asCardTitle: true,\n },\n {\n id: 'status',\n header: t('subtasks.col.status'),\n cell: (r) => (\n <StatusBadge status={r.status}>\n {t(`subtasks.status.${r.status}`, { defaultValue: r.status })}\n </StatusBadge>\n ),\n headClassName: 'w-32',\n },\n {\n id: 'parent',\n header: t('subtasks.col.parent'),\n cell: (r) => (\n <span className=\"text-text-dim\">\n <span className=\"font-medium text-text\">{r.parentAgent}</span>\n <span className=\"text-text-muted\"> / </span>\n <span title={r.parentSessionId}>{r.parentSessionId.slice(0, 8)}</span>\n </span>\n ),\n headClassName: 'w-40',\n },\n {\n id: 'platform',\n header: t('subtasks.col.platform'),\n cell: (r) => <span className=\"text-text-dim\">{r.platform}</span>,\n headClassName: 'w-28',\n hideOnMobile: true,\n },\n {\n id: 'createdAt',\n header: t('subtasks.col.createdAt'),\n cell: (r) => <span className=\"text-text-dim\">{formatTime(r.createdAt)}</span>,\n headClassName: 'w-40',\n hideOnMobile: true,\n },\n ],\n [t],\n )\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('subtasks.title')}</h1>\n <span className={cn('text-xs font-medium tabular-nums', LIVE_STATUS_CLASS[live])}>\n {t(`jobs.live.${live}`)}\n </span>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('subtasks.subtitle')}</p>\n </header>\n\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"agent-filter\" className=\"text-xs text-text-dim\">\n {t('subtasks.filter.agent')}\n </Label>\n <Input\n id=\"agent-filter\"\n value={agent}\n onChange={(e) => setAgentFilter(e.target.value)}\n placeholder={t('subtasks.filter.agentAny')}\n className=\"w-48\"\n />\n </div>\n </div>\n\n <DataTable\n columns={columns}\n rows={subtasks}\n getRowId={(r) => `${r.parentSessionId}:${r.id}`}\n loading={isLoading}\n emptyState={\n <EmptyState\n icon={<ListTree />}\n title={t('subtasks.empty.title')}\n description={t('subtasks.empty.description')}\n />\n }\n />\n </div>\n )\n}\n\nfunction formatTime(iso: string): string {\n try {\n const d = new Date(iso)\n if (Number.isNaN(d.getTime())) return iso\n const now = new Date()\n const sameDay = d.toDateString() === now.toDateString()\n if (sameDay) {\n return d.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit' })\n }\n return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n } catch {\n return iso\n }\n}\n"],"names":["ListTree","createLucideIcon","subtasksKeys","q","useSubtasks","query","useQuery","api","useInvalidateSubtasks","qc","useQueryClient","LIVE_STATUS_CLASS","SubtasksRoute","t","useTranslation","params","setParams","useSearchParams","invalidate","agent","data","isLoading","isFetching","refetch","subtasks","live","useEventStream","setAgentFilter","v","next","columns","useMemo","r","jsxs","jsx","StatusBadge","formatTime","cn","Button","Loader2","RefreshCcw","Label","Input","e","DataTable","EmptyState","iso","d","now"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"subtasks-BnEjSGUR.js","sources":["../../node_modules/lucide-react/dist/esm/icons/list-tree.js","../../src/hooks/use-subtasks.ts","../../src/routes/tasks/subtasks.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 ListTree = createLucideIcon(\"ListTree\", [\n [\"path\", { d: \"M21 12h-8\", key: \"1bmf0i\" }],\n [\"path\", { d: \"M21 6H8\", key: \"1pqkrb\" }],\n [\"path\", { d: \"M21 18h-8\", key: \"1tm79t\" }],\n [\"path\", { d: \"M3 6v4c0 1.1.9 2 2 2h3\", key: \"1ywdgy\" }],\n [\"path\", { d: \"M3 10v6c0 1.1.9 2 2 2h3\", key: \"2wc746\" }]\n]);\n\nexport { ListTree as default };\n//# sourceMappingURL=list-tree.js.map\n","/**\n * useSubtasks — react-query wrapper for /api/subtasks.\n *\n * Subtasks are a flattened view of session.subtasks across every\n * conversation file in ~/.agim/sessions/. The endpoint is read-only\n * — no cancel / re-run mutation surface (yet). Live refresh rides on\n * the same SSE 'job' event (subtask state changes piggy-back on the\n * parent job's lifecycle).\n */\n\nimport { useQueryClient, useQuery } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type { ListSubtasksQuery, ListSubtasksResponse } from '@/types/api'\n\nexport const subtasksKeys = {\n all: ['subtasks'] as const,\n list: (q: ListSubtasksQuery) => ['subtasks', 'list', q] as const,\n}\n\nexport function useSubtasks(query: ListSubtasksQuery) {\n return useQuery<ListSubtasksResponse>({\n queryKey: subtasksKeys.list(query),\n queryFn: () => api.listSubtasks(query),\n })\n}\n\nexport function useInvalidateSubtasks() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: subtasksKeys.all })\n}\n","/**\n * /tasks/subtasks — flattened view of per-conversation child tasks\n * spawned by parent agents.\n *\n * Read-only: the backend doesn't expose cancel / re-run for subtasks\n * separately from the parent session. The page mirrors the columns\n * of /tasks/jobs but adds parent context (agent + platform) and\n * drops the duration / cost columns (which session.subtasks doesn't\n * track per-subtask).\n *\n * SSE: subscribes to the same `job` event as /tasks/jobs — subtask\n * status changes piggy-back on the parent job lifecycle in the\n * backend's event-bus.\n */\n\nimport { useMemo } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { Loader2, ListTree, RefreshCcw } from 'lucide-react'\n\nimport { DataTable, type DataTableColumn } from '@/components/common/data-table'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { StatusBadge } from '@/components/common/status-badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport { useSubtasks, useInvalidateSubtasks } from '@/hooks/use-subtasks'\nimport { useEventStream, type SseStatus } from '@/hooks/use-event-stream'\nimport type { Subtask } from '@/types/api'\nimport { cn } from '@/lib/utils'\n\nconst LIVE_STATUS_CLASS: Record<SseStatus, string> = {\n connected: 'text-success',\n connecting: 'text-text-dim',\n reconnecting: 'text-warning',\n closed: 'text-text-muted',\n}\n\nexport default function SubtasksRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const [params, setParams] = useSearchParams()\n const invalidate = useInvalidateSubtasks()\n const agent = params.get('agent') ?? ''\n\n const { data, isLoading, isFetching, refetch } = useSubtasks(\n agent ? { agent } : {},\n )\n const subtasks = data?.subtasks ?? []\n\n const live = useEventStream({\n job: () => invalidate(),\n })\n\n function setAgentFilter(v: string): void {\n const next = new URLSearchParams(params)\n if (!v) next.delete('agent')\n else next.set('agent', v)\n setParams(next, { replace: true })\n }\n\n const columns: DataTableColumn<Subtask>[] = useMemo(\n () => [\n {\n id: 'id',\n header: t('subtasks.col.id'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">#{r.id}</span>,\n headClassName: 'w-16',\n },\n {\n id: 'agent',\n header: t('subtasks.col.agent'),\n cell: (r) => <span className=\"font-medium\">{r.agent}</span>,\n headClassName: 'w-32',\n },\n {\n id: 'prompt',\n header: t('subtasks.col.prompt'),\n cell: (r) => <span className=\"line-clamp-2 text-text-dim\">{r.prompt}</span>,\n asCardTitle: true,\n },\n {\n id: 'status',\n header: t('subtasks.col.status'),\n cell: (r) => (\n <StatusBadge status={r.status}>\n {t(`subtasks.status.${r.status}`, { defaultValue: r.status })}\n </StatusBadge>\n ),\n headClassName: 'w-32',\n },\n {\n id: 'parent',\n header: t('subtasks.col.parent'),\n cell: (r) => (\n <span className=\"text-text-dim\">\n <span className=\"font-medium text-text\">{r.parentAgent}</span>\n <span className=\"text-text-muted\"> / </span>\n <span title={r.parentSessionId}>{r.parentSessionId.slice(0, 8)}</span>\n </span>\n ),\n headClassName: 'w-40',\n },\n {\n id: 'platform',\n header: t('subtasks.col.platform'),\n cell: (r) => <span className=\"text-text-dim\">{r.platform}</span>,\n headClassName: 'w-28',\n hideOnMobile: true,\n },\n {\n id: 'createdAt',\n header: t('subtasks.col.createdAt'),\n cell: (r) => <span className=\"text-text-dim\">{formatTime(r.createdAt)}</span>,\n headClassName: 'w-40',\n hideOnMobile: true,\n },\n ],\n [t],\n )\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('subtasks.title')}</h1>\n <span className={cn('text-xs font-medium tabular-nums', LIVE_STATUS_CLASS[live])}>\n {t(`jobs.live.${live}`)}\n </span>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('subtasks.subtitle')}</p>\n </header>\n\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"agent-filter\" className=\"text-xs text-text-dim\">\n {t('subtasks.filter.agent')}\n </Label>\n <Input\n id=\"agent-filter\"\n value={agent}\n onChange={(e) => setAgentFilter(e.target.value)}\n placeholder={t('subtasks.filter.agentAny')}\n className=\"w-48\"\n />\n </div>\n </div>\n\n <DataTable\n columns={columns}\n rows={subtasks}\n getRowId={(r) => `${r.parentSessionId}:${r.id}`}\n loading={isLoading}\n emptyState={\n <EmptyState\n icon={<ListTree />}\n title={t('subtasks.empty.title')}\n description={t('subtasks.empty.description')}\n />\n }\n />\n </div>\n )\n}\n\nfunction formatTime(iso: string): string {\n try {\n const d = new Date(iso)\n if (Number.isNaN(d.getTime())) return iso\n const now = new Date()\n const sameDay = d.toDateString() === now.toDateString()\n if (sameDay) {\n return d.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit' })\n }\n return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n } catch {\n return iso\n }\n}\n"],"names":["ListTree","createLucideIcon","subtasksKeys","q","useSubtasks","query","useQuery","api","useInvalidateSubtasks","qc","useQueryClient","LIVE_STATUS_CLASS","SubtasksRoute","t","useTranslation","params","setParams","useSearchParams","invalidate","agent","data","isLoading","isFetching","refetch","subtasks","live","useEventStream","setAgentFilter","v","next","columns","useMemo","r","jsxs","jsx","StatusBadge","formatTime","cn","Button","Loader2","RefreshCcw","Label","Input","e","DataTable","EmptyState","iso","d","now"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1,2 +1,2 @@
1
- import{j as s,c as t}from"./index-DHh1LYlA.js";import{r as o}from"./react-DlP5eolq.js";const l=o.forwardRef(({className:e,...a},r)=>s.jsx("div",{className:"w-full overflow-x-auto",children:s.jsx("table",{ref:r,className:t("w-full caption-bottom text-sm",e),...a})}));l.displayName="Table";const d=o.forwardRef(({className:e,...a},r)=>s.jsx("thead",{ref:r,className:t("[&_tr]:border-b [&_tr]:border-border bg-surface-2",e),...a}));d.displayName="TableHeader";const b=o.forwardRef(({className:e,...a},r)=>s.jsx("tbody",{ref:r,className:t("[&_tr:last-child]:border-0",e),...a}));b.displayName="TableBody";const c=o.forwardRef(({className:e,...a},r)=>s.jsx("tfoot",{ref:r,className:t("border-t border-border bg-surface-2 font-medium [&>tr]:last:border-b-0",e),...a}));c.displayName="TableFooter";const m=o.forwardRef(({className:e,...a},r)=>s.jsx("tr",{ref:r,className:t("border-b border-border transition-colors","hover:bg-surface-hover data-[state=selected]:bg-accent-bg",e),...a}));m.displayName="TableRow";const i=o.forwardRef(({className:e,...a},r)=>s.jsx("th",{ref:r,className:t("h-10 px-4 text-left align-middle","text-xs font-semibold uppercase tracking-wide text-text-dim","[&:has([role=checkbox])]:pr-0",e),...a}));i.displayName="TableHead";const f=o.forwardRef(({className:e,...a},r)=>s.jsx("td",{ref:r,className:t("p-3 align-middle [&:has([role=checkbox])]:pr-0",e),...a}));f.displayName="TableCell";const x=o.forwardRef(({className:e,...a},r)=>s.jsx("caption",{ref:r,className:t("mt-4 text-sm text-text-dim",e),...a}));x.displayName="TableCaption";export{l as T,d as a,m as b,i as c,b as d,f as e};
2
- //# sourceMappingURL=table-Dx65w6V0.js.map
1
+ import{j as s,f as t}from"./index-DCfdN5R7.js";import{r as o}from"./react-DlP5eolq.js";const l=o.forwardRef(({className:e,...a},r)=>s.jsx("div",{className:"w-full overflow-x-auto",children:s.jsx("table",{ref:r,className:t("w-full caption-bottom text-sm",e),...a})}));l.displayName="Table";const d=o.forwardRef(({className:e,...a},r)=>s.jsx("thead",{ref:r,className:t("[&_tr]:border-b [&_tr]:border-border bg-surface-2",e),...a}));d.displayName="TableHeader";const b=o.forwardRef(({className:e,...a},r)=>s.jsx("tbody",{ref:r,className:t("[&_tr:last-child]:border-0",e),...a}));b.displayName="TableBody";const c=o.forwardRef(({className:e,...a},r)=>s.jsx("tfoot",{ref:r,className:t("border-t border-border bg-surface-2 font-medium [&>tr]:last:border-b-0",e),...a}));c.displayName="TableFooter";const m=o.forwardRef(({className:e,...a},r)=>s.jsx("tr",{ref:r,className:t("border-b border-border transition-colors","hover:bg-surface-hover data-[state=selected]:bg-accent-bg",e),...a}));m.displayName="TableRow";const i=o.forwardRef(({className:e,...a},r)=>s.jsx("th",{ref:r,className:t("h-10 px-4 text-left align-middle","text-xs font-semibold uppercase tracking-wide text-text-dim","[&:has([role=checkbox])]:pr-0",e),...a}));i.displayName="TableHead";const f=o.forwardRef(({className:e,...a},r)=>s.jsx("td",{ref:r,className:t("p-3 align-middle [&:has([role=checkbox])]:pr-0",e),...a}));f.displayName="TableCell";const x=o.forwardRef(({className:e,...a},r)=>s.jsx("caption",{ref:r,className:t("mt-4 text-sm text-text-dim",e),...a}));x.displayName="TableCaption";export{l as T,d as a,m as b,i as c,b as d,f as e};
2
+ //# sourceMappingURL=table-sCMZBe_Z.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"table-Dx65w6V0.js","sources":["../../src/components/ui/table.tsx"],"sourcesContent":["/**\n * Table — accessible HTML table primitives. No 3rd-party dep; the\n * sortable / paginated / virtualised DataTable that wraps this lives\n * at components/common/data-table.tsx (PR-8).\n *\n * Mobile fallback strategy: the DataTable wrapper detects `< md` and\n * renders cards instead of rows. The primitives here keep a `min-w`\n * + overflow-x-auto wrapper as the fallback fallback (degrade to\n * horizontal scroll) so even raw `<Table>` usage is usable on phone.\n */\n\nimport * as React from 'react'\nimport { cn } from '@/lib/utils'\n\nconst Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(\n ({ className, ...props }, ref) => (\n <div className=\"w-full overflow-x-auto\">\n <table\n ref={ref}\n className={cn('w-full caption-bottom text-sm', className)}\n {...props}\n />\n </div>\n ),\n)\nTable.displayName = 'Table'\n\nconst TableHeader = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(\n ({ className, ...props }, ref) => (\n <thead ref={ref} className={cn('[&_tr]:border-b [&_tr]:border-border bg-surface-2', className)} {...props} />\n ),\n)\nTableHeader.displayName = 'TableHeader'\n\nconst TableBody = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(\n ({ className, ...props }, ref) => (\n <tbody ref={ref} className={cn('[&_tr:last-child]:border-0', className)} {...props} />\n ),\n)\nTableBody.displayName = 'TableBody'\n\nconst TableFooter = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(\n ({ className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n 'border-t border-border bg-surface-2 font-medium [&>tr]:last:border-b-0',\n className,\n )}\n {...props}\n />\n ),\n)\nTableFooter.displayName = 'TableFooter'\n\nconst TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTMLTableRowElement>>(\n ({ className, ...props }, ref) => (\n <tr\n ref={ref}\n className={cn(\n 'border-b border-border transition-colors',\n 'hover:bg-surface-hover data-[state=selected]:bg-accent-bg',\n className,\n )}\n {...props}\n />\n ),\n)\nTableRow.displayName = 'TableRow'\n\nconst TableHead = React.forwardRef<HTMLTableCellElement, React.ThHTMLAttributes<HTMLTableCellElement>>(\n ({ className, ...props }, ref) => (\n <th\n ref={ref}\n className={cn(\n 'h-10 px-4 text-left align-middle',\n 'text-xs font-semibold uppercase tracking-wide text-text-dim',\n '[&:has([role=checkbox])]:pr-0',\n className,\n )}\n {...props}\n />\n ),\n)\nTableHead.displayName = 'TableHead'\n\nconst TableCell = React.forwardRef<HTMLTableCellElement, React.TdHTMLAttributes<HTMLTableCellElement>>(\n ({ className, ...props }, ref) => (\n <td\n ref={ref}\n className={cn('p-3 align-middle [&:has([role=checkbox])]:pr-0', className)}\n {...props}\n />\n ),\n)\nTableCell.displayName = 'TableCell'\n\nconst TableCaption = React.forwardRef<HTMLTableCaptionElement, React.HTMLAttributes<HTMLTableCaptionElement>>(\n ({ className, ...props }, ref) => (\n <caption ref={ref} className={cn('mt-4 text-sm text-text-dim', className)} {...props} />\n ),\n)\nTableCaption.displayName = 'TableCaption'\n\nexport { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption }\n"],"names":["Table","React.forwardRef","className","props","ref","jsx","cn","TableHeader","TableBody","TableFooter","TableRow","TableHead","TableCell","TableCaption"],"mappings":"uFAcA,MAAMA,EAAQC,EAAAA,WACZ,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,MAAC,MAAA,CAAI,UAAU,yBACb,SAAAA,EAAAA,IAAC,QAAA,CACC,IAAAD,EACA,UAAWE,EAAG,gCAAiCJ,CAAS,EACvD,GAAGC,CAAA,CAAA,CACN,CACF,CAEJ,EACAH,EAAM,YAAc,QAEpB,MAAMO,EAAcN,EAAAA,WAClB,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,EAAAA,IAAC,QAAA,CAAM,IAAAD,EAAU,UAAWE,EAAG,oDAAqDJ,CAAS,EAAI,GAAGC,CAAA,CAAO,CAE/G,EACAI,EAAY,YAAc,cAE1B,MAAMC,EAAYP,EAAAA,WAChB,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,EAAAA,IAAC,QAAA,CAAM,IAAAD,EAAU,UAAWE,EAAG,6BAA8BJ,CAAS,EAAI,GAAGC,CAAA,CAAO,CAExF,EACAK,EAAU,YAAc,YAExB,MAAMC,EAAcR,EAAAA,WAClB,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,EAAAA,IAAC,QAAA,CACC,IAAAD,EACA,UAAWE,EACT,yEACAJ,CAAA,EAED,GAAGC,CAAA,CAAA,CAGV,EACAM,EAAY,YAAc,cAE1B,MAAMC,EAAWT,EAAAA,WACf,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,EAAAA,IAAC,KAAA,CACC,IAAAD,EACA,UAAWE,EACT,2CACA,4DACAJ,CAAA,EAED,GAAGC,CAAA,CAAA,CAGV,EACAO,EAAS,YAAc,WAEvB,MAAMC,EAAYV,EAAAA,WAChB,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,EAAAA,IAAC,KAAA,CACC,IAAAD,EACA,UAAWE,EACT,mCACA,8DACA,gCACAJ,CAAA,EAED,GAAGC,CAAA,CAAA,CAGV,EACAQ,EAAU,YAAc,YAExB,MAAMC,EAAYX,EAAAA,WAChB,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,EAAAA,IAAC,KAAA,CACC,IAAAD,EACA,UAAWE,EAAG,iDAAkDJ,CAAS,EACxE,GAAGC,CAAA,CAAA,CAGV,EACAS,EAAU,YAAc,YAExB,MAAMC,EAAeZ,EAAAA,WACnB,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,EAAAA,IAAC,UAAA,CAAQ,IAAAD,EAAU,UAAWE,EAAG,6BAA8BJ,CAAS,EAAI,GAAGC,CAAA,CAAO,CAE1F,EACAU,EAAa,YAAc"}
1
+ {"version":3,"file":"table-sCMZBe_Z.js","sources":["../../src/components/ui/table.tsx"],"sourcesContent":["/**\n * Table — accessible HTML table primitives. No 3rd-party dep; the\n * sortable / paginated / virtualised DataTable that wraps this lives\n * at components/common/data-table.tsx (PR-8).\n *\n * Mobile fallback strategy: the DataTable wrapper detects `< md` and\n * renders cards instead of rows. The primitives here keep a `min-w`\n * + overflow-x-auto wrapper as the fallback fallback (degrade to\n * horizontal scroll) so even raw `<Table>` usage is usable on phone.\n */\n\nimport * as React from 'react'\nimport { cn } from '@/lib/utils'\n\nconst Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(\n ({ className, ...props }, ref) => (\n <div className=\"w-full overflow-x-auto\">\n <table\n ref={ref}\n className={cn('w-full caption-bottom text-sm', className)}\n {...props}\n />\n </div>\n ),\n)\nTable.displayName = 'Table'\n\nconst TableHeader = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(\n ({ className, ...props }, ref) => (\n <thead ref={ref} className={cn('[&_tr]:border-b [&_tr]:border-border bg-surface-2', className)} {...props} />\n ),\n)\nTableHeader.displayName = 'TableHeader'\n\nconst TableBody = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(\n ({ className, ...props }, ref) => (\n <tbody ref={ref} className={cn('[&_tr:last-child]:border-0', className)} {...props} />\n ),\n)\nTableBody.displayName = 'TableBody'\n\nconst TableFooter = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(\n ({ className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n 'border-t border-border bg-surface-2 font-medium [&>tr]:last:border-b-0',\n className,\n )}\n {...props}\n />\n ),\n)\nTableFooter.displayName = 'TableFooter'\n\nconst TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTMLTableRowElement>>(\n ({ className, ...props }, ref) => (\n <tr\n ref={ref}\n className={cn(\n 'border-b border-border transition-colors',\n 'hover:bg-surface-hover data-[state=selected]:bg-accent-bg',\n className,\n )}\n {...props}\n />\n ),\n)\nTableRow.displayName = 'TableRow'\n\nconst TableHead = React.forwardRef<HTMLTableCellElement, React.ThHTMLAttributes<HTMLTableCellElement>>(\n ({ className, ...props }, ref) => (\n <th\n ref={ref}\n className={cn(\n 'h-10 px-4 text-left align-middle',\n 'text-xs font-semibold uppercase tracking-wide text-text-dim',\n '[&:has([role=checkbox])]:pr-0',\n className,\n )}\n {...props}\n />\n ),\n)\nTableHead.displayName = 'TableHead'\n\nconst TableCell = React.forwardRef<HTMLTableCellElement, React.TdHTMLAttributes<HTMLTableCellElement>>(\n ({ className, ...props }, ref) => (\n <td\n ref={ref}\n className={cn('p-3 align-middle [&:has([role=checkbox])]:pr-0', className)}\n {...props}\n />\n ),\n)\nTableCell.displayName = 'TableCell'\n\nconst TableCaption = React.forwardRef<HTMLTableCaptionElement, React.HTMLAttributes<HTMLTableCaptionElement>>(\n ({ className, ...props }, ref) => (\n <caption ref={ref} className={cn('mt-4 text-sm text-text-dim', className)} {...props} />\n ),\n)\nTableCaption.displayName = 'TableCaption'\n\nexport { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption }\n"],"names":["Table","React.forwardRef","className","props","ref","jsx","cn","TableHeader","TableBody","TableFooter","TableRow","TableHead","TableCell","TableCaption"],"mappings":"uFAcA,MAAMA,EAAQC,EAAAA,WACZ,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,MAAC,MAAA,CAAI,UAAU,yBACb,SAAAA,EAAAA,IAAC,QAAA,CACC,IAAAD,EACA,UAAWE,EAAG,gCAAiCJ,CAAS,EACvD,GAAGC,CAAA,CAAA,CACN,CACF,CAEJ,EACAH,EAAM,YAAc,QAEpB,MAAMO,EAAcN,EAAAA,WAClB,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,EAAAA,IAAC,QAAA,CAAM,IAAAD,EAAU,UAAWE,EAAG,oDAAqDJ,CAAS,EAAI,GAAGC,CAAA,CAAO,CAE/G,EACAI,EAAY,YAAc,cAE1B,MAAMC,EAAYP,EAAAA,WAChB,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,EAAAA,IAAC,QAAA,CAAM,IAAAD,EAAU,UAAWE,EAAG,6BAA8BJ,CAAS,EAAI,GAAGC,CAAA,CAAO,CAExF,EACAK,EAAU,YAAc,YAExB,MAAMC,EAAcR,EAAAA,WAClB,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,EAAAA,IAAC,QAAA,CACC,IAAAD,EACA,UAAWE,EACT,yEACAJ,CAAA,EAED,GAAGC,CAAA,CAAA,CAGV,EACAM,EAAY,YAAc,cAE1B,MAAMC,EAAWT,EAAAA,WACf,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,EAAAA,IAAC,KAAA,CACC,IAAAD,EACA,UAAWE,EACT,2CACA,4DACAJ,CAAA,EAED,GAAGC,CAAA,CAAA,CAGV,EACAO,EAAS,YAAc,WAEvB,MAAMC,EAAYV,EAAAA,WAChB,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,EAAAA,IAAC,KAAA,CACC,IAAAD,EACA,UAAWE,EACT,mCACA,8DACA,gCACAJ,CAAA,EAED,GAAGC,CAAA,CAAA,CAGV,EACAQ,EAAU,YAAc,YAExB,MAAMC,EAAYX,EAAAA,WAChB,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,EAAAA,IAAC,KAAA,CACC,IAAAD,EACA,UAAWE,EAAG,iDAAkDJ,CAAS,EACxE,GAAGC,CAAA,CAAA,CAGV,EACAS,EAAU,YAAc,YAExB,MAAMC,EAAeZ,EAAAA,WACnB,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IACxBC,EAAAA,IAAC,UAAA,CAAQ,IAAAD,EAAU,UAAWE,EAAG,6BAA8BJ,CAAS,EAAI,GAAGC,CAAA,CAAO,CAE1F,EACAU,EAAa,YAAc"}
@@ -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 i=e("Terminal",[["polyline",{points:"4 17 10 11 4 5",key:"akl6gq"}],["line",{x1:"12",x2:"20",y1:"19",y2:"19",key:"q2wloq"}]]);export{i as T};
7
+ //# sourceMappingURL=terminal-_pXeEjXG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-_pXeEjXG.js","sources":["../../node_modules/lucide-react/dist/esm/icons/terminal.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 Terminal = createLucideIcon(\"Terminal\", [\n [\"polyline\", { points: \"4 17 10 11 4 5\", key: \"akl6gq\" }],\n [\"line\", { x1: \"12\", x2: \"20\", y1: \"19\", y2: \"19\", key: \"q2wloq\" }]\n]);\n\nexport { Terminal as default };\n//# sourceMappingURL=terminal.js.map\n"],"names":["Terminal","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAWC,EAAiB,WAAY,CAC5C,CAAC,WAAY,CAAE,OAAQ,iBAAkB,IAAK,QAAQ,CAAE,EACxD,CAAC,OAAQ,CAAE,GAAI,KAAM,GAAI,KAAM,GAAI,KAAM,GAAI,KAAM,IAAK,QAAQ,CAAE,CACpE,CAAC","x_google_ignoreList":[0]}
@@ -1,7 +1,7 @@
1
- import{o as S,u as w,f as M,j as e,B as L,L as p,S as j,g as u,h as f,i as N,k as b}from"./index-DHh1LYlA.js";import{E as R}from"./empty-state-CTwOQemt.js";import{T as V,a as $,b as g,c as t,d as E,e as c}from"./table-Dx65w6V0.js";import{a as F}from"./use-observability-DtqSWVjM.js";import{L as I}from"./loader-circle-DgdBWYl0.js";import{R as P}from"./refresh-ccw-nBMm5Xal.js";import"./react-DlP5eolq.js";/**
1
+ import{h as w,u as M,i as S,j as e,e as L,w as p,k as j,l as u,m as f,n as N,o as b}from"./index-DCfdN5R7.js";import{E as R}from"./empty-state-CuiqdZiB.js";import{T as V,a as $,b as g,c as t,d as E,e as c}from"./table-sCMZBe_Z.js";import{a as F}from"./use-observability-CY5ZUPrC.js";import{L as I}from"./loader-circle-DDdmcH0k.js";import{R as P}from"./refresh-ccw-DlAd-eTQ.js";import"./react-DlP5eolq.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 B=S("ChartColumn",[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"M18 17V9",key:"2bz60n"}],["path",{d:"M13 17V5",key:"1frdt8"}],["path",{d:"M8 17v-3",key:"17ska0"}]]),z=["user","agent","platform","intent"],H=["cost","calls","errors","avg_latency"];function J(){const{t:a}=w(["observability","common"]),[n,y]=M(),v=Math.max(1,Number(n.get("days"))||7),i=n.get("dim")??"agent",r=n.get("by")??"cost";function m(s){const l=new URLSearchParams(n);for(const[x,h]of Object.entries(s))h==null?l.delete(x):l.set(x,h);y(l,{replace:!0})}const{data:k,isLoading:C,isFetching:o,refetch:T}=F({dim:i,by:r,days:v,limit:20}),d=k?.items??[];return e.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[e.jsx("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:a("topn.title")}),e.jsxs(L,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>T(),disabled:o,"aria-label":a("actions.refresh",{ns:"common"}),children:[o?e.jsx(I,{className:"h-4 w-4 animate-spin"}):e.jsx(P,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:a("actions.refresh",{ns:"common"})})]})]})}),e.jsxs("div",{className:"flex flex-wrap items-end gap-2",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(p,{htmlFor:"dim",className:"text-xs text-text-dim",children:a("topn.filter.dim")}),e.jsxs(j,{value:i,onValueChange:s=>m({dim:s==="agent"?null:s}),children:[e.jsx(u,{id:"dim",className:"w-32",children:e.jsx(f,{})}),e.jsx(N,{children:z.map(s=>e.jsx(b,{value:s,children:a(`topn.dim.${s}`)},s))})]})]}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(p,{htmlFor:"by",className:"text-xs text-text-dim",children:a("topn.filter.metric")}),e.jsxs(j,{value:r,onValueChange:s=>m({by:s==="cost"?null:s}),children:[e.jsx(u,{id:"by",className:"w-36",children:e.jsx(f,{})}),e.jsx(N,{children:H.map(s=>e.jsx(b,{value:s,children:a(`topn.metric.${s}`)},s))})]})]})]}),C?e.jsx("div",{className:"h-48 w-full rounded-md bg-surface-2 animate-pulse"}):d.length===0?e.jsx(R,{icon:e.jsx(B,{}),title:a("topn.empty.title"),description:a("topn.empty.description")}):e.jsxs(V,{children:[e.jsx($,{children:e.jsxs(g,{children:[e.jsx(t,{className:"w-12",children:a("topn.col.rank")}),e.jsx(t,{children:a("topn.col.key")}),e.jsx(t,{className:"w-24",children:a("topn.col.calls")}),e.jsx(t,{className:"w-24",children:a("topn.col.cost")}),e.jsx(t,{className:"w-24",children:a("topn.col.errors")}),e.jsx(t,{className:"w-32",children:a("topn.col.avgLatencyMs")})]})}),e.jsx(E,{children:d.map((s,l)=>e.jsxs(g,{children:[e.jsx(c,{className:"tabular-nums text-text-dim",children:l+1}),e.jsx(c,{className:"font-medium",children:s.key}),e.jsx(c,{className:"tabular-nums",children:s.calls}),e.jsxs(c,{className:"tabular-nums",children:["$",s.cost.toFixed(4)]}),e.jsx(c,{className:"tabular-nums",children:e.jsx("span",{className:s.errors>0?"text-danger":"text-text-dim",children:s.errors})}),e.jsxs(c,{className:"tabular-nums",children:[Math.round(s.avgLatencyMs),"ms"]})]},`${s.key}-${l}`))})]})]})}export{J as default};
7
- //# sourceMappingURL=topn-L7Juczp3.js.map
6
+ */const z=w("ChartColumn",[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"M18 17V9",key:"2bz60n"}],["path",{d:"M13 17V5",key:"1frdt8"}],["path",{d:"M8 17v-3",key:"17ska0"}]]),B=["user","agent","platform","intent"],H=["cost","calls","errors","avg_latency"];function J(){const{t:a}=M(["observability","common"]),[n,y]=S(),v=Math.max(1,Number(n.get("days"))||7),i=n.get("dim")??"agent",r=n.get("by")??"cost";function m(s){const l=new URLSearchParams(n);for(const[x,h]of Object.entries(s))h==null?l.delete(x):l.set(x,h);y(l,{replace:!0})}const{data:k,isLoading:C,isFetching:o,refetch:T}=F({dim:i,by:r,days:v,limit:20}),d=k?.items??[];return e.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[e.jsx("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:a("topn.title")}),e.jsxs(L,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>T(),disabled:o,"aria-label":a("actions.refresh",{ns:"common"}),children:[o?e.jsx(I,{className:"h-4 w-4 animate-spin"}):e.jsx(P,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:a("actions.refresh",{ns:"common"})})]})]})}),e.jsxs("div",{className:"flex flex-wrap items-end gap-2",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(p,{htmlFor:"dim",className:"text-xs text-text-dim",children:a("topn.filter.dim")}),e.jsxs(j,{value:i,onValueChange:s=>m({dim:s==="agent"?null:s}),children:[e.jsx(u,{id:"dim",className:"w-32",children:e.jsx(f,{})}),e.jsx(N,{children:B.map(s=>e.jsx(b,{value:s,children:a(`topn.dim.${s}`)},s))})]})]}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(p,{htmlFor:"by",className:"text-xs text-text-dim",children:a("topn.filter.metric")}),e.jsxs(j,{value:r,onValueChange:s=>m({by:s==="cost"?null:s}),children:[e.jsx(u,{id:"by",className:"w-36",children:e.jsx(f,{})}),e.jsx(N,{children:H.map(s=>e.jsx(b,{value:s,children:a(`topn.metric.${s}`)},s))})]})]})]}),C?e.jsx("div",{className:"h-48 w-full rounded-md bg-surface-2 animate-pulse"}):d.length===0?e.jsx(R,{icon:e.jsx(z,{}),title:a("topn.empty.title"),description:a("topn.empty.description")}):e.jsxs(V,{children:[e.jsx($,{children:e.jsxs(g,{children:[e.jsx(t,{className:"w-12",children:a("topn.col.rank")}),e.jsx(t,{children:a("topn.col.key")}),e.jsx(t,{className:"w-24",children:a("topn.col.calls")}),e.jsx(t,{className:"w-24",children:a("topn.col.cost")}),e.jsx(t,{className:"w-24",children:a("topn.col.errors")}),e.jsx(t,{className:"w-32",children:a("topn.col.avgLatencyMs")})]})}),e.jsx(E,{children:d.map((s,l)=>e.jsxs(g,{children:[e.jsx(c,{className:"tabular-nums text-text-dim",children:l+1}),e.jsx(c,{className:"font-medium",children:s.key}),e.jsx(c,{className:"tabular-nums",children:s.calls}),e.jsxs(c,{className:"tabular-nums",children:["$",s.cost.toFixed(4)]}),e.jsx(c,{className:"tabular-nums",children:e.jsx("span",{className:s.errors>0?"text-danger":"text-text-dim",children:s.errors})}),e.jsxs(c,{className:"tabular-nums",children:[Math.round(s.avgLatencyMs),"ms"]})]},`${s.key}-${l}`))})]})]})}export{J as default};
7
+ //# sourceMappingURL=topn-D1B-gS1M.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"topn-L7Juczp3.js","sources":["../../node_modules/lucide-react/dist/esm/icons/chart-column.js","../../src/routes/observability/topn.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 ChartColumn = createLucideIcon(\"ChartColumn\", [\n [\"path\", { d: \"M3 3v16a2 2 0 0 0 2 2h16\", key: \"c24i48\" }],\n [\"path\", { d: \"M18 17V9\", key: \"2bz60n\" }],\n [\"path\", { d: \"M13 17V5\", key: \"1frdt8\" }],\n [\"path\", { d: \"M8 17v-3\", key: \"17ska0\" }]\n]);\n\nexport { ChartColumn as default };\n//# sourceMappingURL=chart-column.js.map\n","/**\n * /observability/topn — leaderboard grouped by a dimension, sorted\n * by a metric. Dim + metric live in URL state alongside the\n * layout's ?days= so the URL fully describes the view.\n */\n\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { BarChart3, 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 { Label } from '@/components/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport { useTopN } from '@/hooks/use-observability'\nimport type { TopNDim, TopNMetric } from '@/types/api'\n\nconst DIMS: TopNDim[] = ['user', 'agent', 'platform', 'intent']\nconst METRICS: TopNMetric[] = ['cost', 'calls', 'errors', 'avg_latency']\n\nexport default function ObservabilityTopNRoute(): JSX.Element {\n const { t } = useTranslation(['observability', 'common'])\n const [params, setParams] = useSearchParams()\n const days = Math.max(1, Number(params.get('days')) || 7)\n const dim = (params.get('dim') as TopNDim | null) ?? 'agent'\n const by = (params.get('by') as TopNMetric | null) ?? 'cost'\n\n function patchParams(patch: Record<string, string | null>): void {\n const next = new URLSearchParams(params)\n for (const [k, v] of Object.entries(patch)) {\n if (v == null) next.delete(k)\n else next.set(k, v)\n }\n setParams(next, { replace: true })\n }\n\n const { data, isLoading, isFetching, refetch } = useTopN({ dim, by, days, limit: 20 })\n const items = data?.items ?? []\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('topn.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 </header>\n\n {/* Filter row */}\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"dim\" className=\"text-xs text-text-dim\">{t('topn.filter.dim')}</Label>\n <Select value={dim} onValueChange={(v) => patchParams({ dim: v === 'agent' ? null : v })}>\n <SelectTrigger id=\"dim\" className=\"w-32\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {DIMS.map((d) => (\n <SelectItem key={d} value={d}>{t(`topn.dim.${d}`)}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"by\" className=\"text-xs text-text-dim\">{t('topn.filter.metric')}</Label>\n <Select value={by} onValueChange={(v) => patchParams({ by: v === 'cost' ? null : v })}>\n <SelectTrigger id=\"by\" className=\"w-36\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {METRICS.map((m) => (\n <SelectItem key={m} value={m}>{t(`topn.metric.${m}`)}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {isLoading ? (\n <div className=\"h-48 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<BarChart3 />}\n title={t('topn.empty.title')}\n description={t('topn.empty.description')}\n />\n ) : (\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-12\">{t('topn.col.rank')}</TableHead>\n <TableHead>{t('topn.col.key')}</TableHead>\n <TableHead className=\"w-24\">{t('topn.col.calls')}</TableHead>\n <TableHead className=\"w-24\">{t('topn.col.cost')}</TableHead>\n <TableHead className=\"w-24\">{t('topn.col.errors')}</TableHead>\n <TableHead className=\"w-32\">{t('topn.col.avgLatencyMs')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {items.map((row, i) => (\n <TableRow key={`${row.key}-${i}`}>\n <TableCell className=\"tabular-nums text-text-dim\">{i + 1}</TableCell>\n <TableCell className=\"font-medium\">{row.key}</TableCell>\n <TableCell className=\"tabular-nums\">{row.calls}</TableCell>\n <TableCell className=\"tabular-nums\">${row.cost.toFixed(4)}</TableCell>\n <TableCell className=\"tabular-nums\">\n <span className={row.errors > 0 ? 'text-danger' : 'text-text-dim'}>{row.errors}</span>\n </TableCell>\n <TableCell className=\"tabular-nums\">{Math.round(row.avgLatencyMs)}ms</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n )}\n </div>\n )\n}\n"],"names":["ChartColumn","createLucideIcon","DIMS","METRICS","ObservabilityTopNRoute","t","useTranslation","params","setParams","useSearchParams","days","dim","by","patchParams","patch","next","k","v","data","isLoading","isFetching","refetch","useTopN","items","jsxs","jsx","Button","Loader2","RefreshCcw","Label","Select","SelectTrigger","SelectValue","SelectContent","d","SelectItem","m","EmptyState","BarChart3","Table","TableHeader","TableRow","TableHead","TableBody","row","i","TableCell"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"topn-D1B-gS1M.js","sources":["../../node_modules/lucide-react/dist/esm/icons/chart-column.js","../../src/routes/observability/topn.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 ChartColumn = createLucideIcon(\"ChartColumn\", [\n [\"path\", { d: \"M3 3v16a2 2 0 0 0 2 2h16\", key: \"c24i48\" }],\n [\"path\", { d: \"M18 17V9\", key: \"2bz60n\" }],\n [\"path\", { d: \"M13 17V5\", key: \"1frdt8\" }],\n [\"path\", { d: \"M8 17v-3\", key: \"17ska0\" }]\n]);\n\nexport { ChartColumn as default };\n//# sourceMappingURL=chart-column.js.map\n","/**\n * /observability/topn — leaderboard grouped by a dimension, sorted\n * by a metric. Dim + metric live in URL state alongside the\n * layout's ?days= so the URL fully describes the view.\n */\n\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { BarChart3, 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 { Label } from '@/components/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport { useTopN } from '@/hooks/use-observability'\nimport type { TopNDim, TopNMetric } from '@/types/api'\n\nconst DIMS: TopNDim[] = ['user', 'agent', 'platform', 'intent']\nconst METRICS: TopNMetric[] = ['cost', 'calls', 'errors', 'avg_latency']\n\nexport default function ObservabilityTopNRoute(): JSX.Element {\n const { t } = useTranslation(['observability', 'common'])\n const [params, setParams] = useSearchParams()\n const days = Math.max(1, Number(params.get('days')) || 7)\n const dim = (params.get('dim') as TopNDim | null) ?? 'agent'\n const by = (params.get('by') as TopNMetric | null) ?? 'cost'\n\n function patchParams(patch: Record<string, string | null>): void {\n const next = new URLSearchParams(params)\n for (const [k, v] of Object.entries(patch)) {\n if (v == null) next.delete(k)\n else next.set(k, v)\n }\n setParams(next, { replace: true })\n }\n\n const { data, isLoading, isFetching, refetch } = useTopN({ dim, by, days, limit: 20 })\n const items = data?.items ?? []\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('topn.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 </header>\n\n {/* Filter row */}\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"dim\" className=\"text-xs text-text-dim\">{t('topn.filter.dim')}</Label>\n <Select value={dim} onValueChange={(v) => patchParams({ dim: v === 'agent' ? null : v })}>\n <SelectTrigger id=\"dim\" className=\"w-32\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {DIMS.map((d) => (\n <SelectItem key={d} value={d}>{t(`topn.dim.${d}`)}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"by\" className=\"text-xs text-text-dim\">{t('topn.filter.metric')}</Label>\n <Select value={by} onValueChange={(v) => patchParams({ by: v === 'cost' ? null : v })}>\n <SelectTrigger id=\"by\" className=\"w-36\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {METRICS.map((m) => (\n <SelectItem key={m} value={m}>{t(`topn.metric.${m}`)}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {isLoading ? (\n <div className=\"h-48 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<BarChart3 />}\n title={t('topn.empty.title')}\n description={t('topn.empty.description')}\n />\n ) : (\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-12\">{t('topn.col.rank')}</TableHead>\n <TableHead>{t('topn.col.key')}</TableHead>\n <TableHead className=\"w-24\">{t('topn.col.calls')}</TableHead>\n <TableHead className=\"w-24\">{t('topn.col.cost')}</TableHead>\n <TableHead className=\"w-24\">{t('topn.col.errors')}</TableHead>\n <TableHead className=\"w-32\">{t('topn.col.avgLatencyMs')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {items.map((row, i) => (\n <TableRow key={`${row.key}-${i}`}>\n <TableCell className=\"tabular-nums text-text-dim\">{i + 1}</TableCell>\n <TableCell className=\"font-medium\">{row.key}</TableCell>\n <TableCell className=\"tabular-nums\">{row.calls}</TableCell>\n <TableCell className=\"tabular-nums\">${row.cost.toFixed(4)}</TableCell>\n <TableCell className=\"tabular-nums\">\n <span className={row.errors > 0 ? 'text-danger' : 'text-text-dim'}>{row.errors}</span>\n </TableCell>\n <TableCell className=\"tabular-nums\">{Math.round(row.avgLatencyMs)}ms</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n )}\n </div>\n )\n}\n"],"names":["ChartColumn","createLucideIcon","DIMS","METRICS","ObservabilityTopNRoute","t","useTranslation","params","setParams","useSearchParams","days","dim","by","patchParams","patch","next","k","v","data","isLoading","isFetching","refetch","useTopN","items","jsxs","jsx","Button","Loader2","RefreshCcw","Label","Select","SelectTrigger","SelectValue","SelectContent","d","SelectItem","m","EmptyState","BarChart3","Table","TableHeader","TableRow","TableHead","TableBody","row","i","TableCell"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1,7 +1,7 @@
1
- import{o as e}from"./index-DHh1LYlA.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("Trash2",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}],["line",{x1:"10",x2:"10",y1:"11",y2:"17",key:"1uufr5"}],["line",{x1:"14",x2:"14",y1:"11",y2:"17",key:"xtxkd"}]]);export{t as T};
7
- //# sourceMappingURL=trash-2-7xrfqd-v.js.map
7
+ //# sourceMappingURL=trash-2-D2x2UPuZ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"trash-2-7xrfqd-v.js","sources":["../../node_modules/lucide-react/dist/esm/icons/trash-2.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 Trash2 = createLucideIcon(\"Trash2\", [\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\", key: \"4alrt4\" }],\n [\"path\", { d: \"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\", key: \"v07s0e\" }],\n [\"line\", { x1: \"10\", x2: \"10\", y1: \"11\", y2: \"17\", key: \"1uufr5\" }],\n [\"line\", { x1: \"14\", x2: \"14\", y1: \"11\", y2: \"17\", key: \"xtxkd\" }]\n]);\n\nexport { Trash2 as default };\n//# sourceMappingURL=trash-2.js.map\n"],"names":["Trash2","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAASC,EAAiB,SAAU,CACxC,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAQ,CAAE,EACxC,CAAC,OAAQ,CAAE,EAAG,wCAAyC,IAAK,QAAQ,CAAE,EACtE,CAAC,OAAQ,CAAE,EAAG,qCAAsC,IAAK,QAAQ,CAAE,EACnE,CAAC,OAAQ,CAAE,GAAI,KAAM,GAAI,KAAM,GAAI,KAAM,GAAI,KAAM,IAAK,QAAQ,CAAE,EAClE,CAAC,OAAQ,CAAE,GAAI,KAAM,GAAI,KAAM,GAAI,KAAM,GAAI,KAAM,IAAK,OAAO,CAAE,CACnE,CAAC","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"trash-2-D2x2UPuZ.js","sources":["../../node_modules/lucide-react/dist/esm/icons/trash-2.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 Trash2 = createLucideIcon(\"Trash2\", [\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\", key: \"4alrt4\" }],\n [\"path\", { d: \"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\", key: \"v07s0e\" }],\n [\"line\", { x1: \"10\", x2: \"10\", y1: \"11\", y2: \"17\", key: \"1uufr5\" }],\n [\"line\", { x1: \"14\", x2: \"14\", y1: \"11\", y2: \"17\", key: \"xtxkd\" }]\n]);\n\nexport { Trash2 as default };\n//# sourceMappingURL=trash-2.js.map\n"],"names":["Trash2","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAASC,EAAiB,SAAU,CACxC,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAQ,CAAE,EACxC,CAAC,OAAQ,CAAE,EAAG,wCAAyC,IAAK,QAAQ,CAAE,EACtE,CAAC,OAAQ,CAAE,EAAG,qCAAsC,IAAK,QAAQ,CAAE,EACnE,CAAC,OAAQ,CAAE,GAAI,KAAM,GAAI,KAAM,GAAI,KAAM,GAAI,KAAM,IAAK,QAAQ,CAAE,EAClE,CAAC,OAAQ,CAAE,GAAI,KAAM,GAAI,KAAM,GAAI,KAAM,GAAI,KAAM,IAAK,OAAO,CAAE,CACnE,CAAC","x_google_ignoreList":[0]}
@@ -0,0 +1,2 @@
1
+ import{r as a,s,t as n}from"./index-DCfdN5R7.js";const t={all:["a2a"],stats:["a2a","stats"],recent:e=>["a2a","recent",e]};function u(){return a({queryKey:t.stats,queryFn:()=>s.getA2AStats()})}function c(e){return a({queryKey:t.recent(e),queryFn:()=>s.getA2ARecent(e)})}function i(){const e=n();return()=>e.invalidateQueries({queryKey:t.all})}export{i as a,c as b,u};
2
+ //# sourceMappingURL=use-a2a-C98e2Via.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-a2a-C98e2Via.js","sources":["../../src/hooks/use-a2a.ts"],"sourcesContent":["/**\n * useA2A* — react-query wrappers for the Agent-to-Agent inline-job\n * view. Read-only; data lives in jobs.db and is exposed via:\n *\n * GET /api/a2a/stats → totals, recent24h, maxDepth, byStatus/byAgent\n * GET /api/a2a/recent → recent rows (truncated prompt + result)\n *\n * SSE: subscribes to the `job` event so a freshly-completed inline\n * sub-invocation shows up without manual refresh.\n */\n\nimport { useQueryClient, useQuery } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type { A2AStats, ListA2ARecentQuery, ListA2ARecentResponse } from '@/types/api'\n\nexport const a2aKeys = {\n all: ['a2a'] as const,\n stats: ['a2a', 'stats'] as const,\n recent: (q: ListA2ARecentQuery) => ['a2a', 'recent', q] as const,\n}\n\nexport function useA2AStats() {\n return useQuery<A2AStats>({\n queryKey: a2aKeys.stats,\n queryFn: () => api.getA2AStats(),\n })\n}\n\nexport function useA2ARecent(query: ListA2ARecentQuery) {\n return useQuery<ListA2ARecentResponse>({\n queryKey: a2aKeys.recent(query),\n queryFn: () => api.getA2ARecent(query),\n })\n}\n\nexport function useInvalidateA2A() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: a2aKeys.all })\n}\n"],"names":["a2aKeys","q","useA2AStats","useQuery","api","useA2ARecent","query","useInvalidateA2A","qc","useQueryClient"],"mappings":"iDAeO,MAAMA,EAAU,CACrB,IAAQ,CAAC,KAAK,EACd,MAAQ,CAAC,MAAO,OAAO,EACvB,OAASC,GAA0B,CAAC,MAAO,SAAUA,CAAC,CACxD,EAEO,SAASC,GAAc,CAC5B,OAAOC,EAAmB,CACxB,SAAUH,EAAQ,MAClB,QAAS,IAAMI,EAAI,YAAA,CAAY,CAChC,CACH,CAEO,SAASC,EAAaC,EAA2B,CACtD,OAAOH,EAAgC,CACrC,SAAUH,EAAQ,OAAOM,CAAK,EAC9B,QAAS,IAAMF,EAAI,aAAaE,CAAK,CAAA,CACtC,CACH,CAEO,SAASC,GAAmB,CACjC,MAAMC,EAAKC,EAAA,EACX,MAAO,IAAMD,EAAG,kBAAkB,CAAE,SAAUR,EAAQ,IAAK,CAC7D"}
@@ -1,2 +1,2 @@
1
- import{b as u,p as i,a as s,e as t}from"./index-DHh1LYlA.js";const l={all:["agim-skills"],list:["agim-skills","list"],one:e=>["agim-skills","one",e]};function r(){return u({queryKey:l.list,queryFn:()=>i.get("/api/agim-skills")})}function m(e){return u({queryKey:e?l.one(e):["agim-skills","one","__none__"],queryFn:()=>i.get(`/api/agim-skills/${encodeURIComponent(e)}`),enabled:!!e})}function y(){const e=s();return t({mutationFn:n=>i.post("/api/agim-skills",{body:n}),onSuccess:()=>e.invalidateQueries({queryKey:l.all})})}function g(){const e=s();return t({mutationFn:({name:n,body:o})=>i.put(`/api/agim-skills/${encodeURIComponent(n)}`,{body:{body:o}}),onSuccess:()=>e.invalidateQueries({queryKey:l.all})})}function k(){const e=s();return t({mutationFn:n=>i.delete(`/api/agim-skills/${encodeURIComponent(n)}`),onSuccess:()=>e.invalidateQueries({queryKey:l.all})})}function p(){const e=s();return t({mutationFn:()=>i.post("/api/agim-skills/refresh"),onSuccess:()=>e.invalidateQueries({queryKey:l.all})})}const a=["agim-skills","injection"];function q(){return u({queryKey:a,queryFn:()=>i.get("/api/agim-skills/injection")})}function d(){const e=s();return t({mutationFn:n=>i.put("/api/agim-skills/injection",{body:{body:n}}),onSuccess:()=>e.invalidateQueries({queryKey:a})})}function S(){const e=s();return t({mutationFn:()=>i.delete("/api/agim-skills/injection"),onSuccess:()=>e.invalidateQueries({queryKey:a})})}export{p as a,y as b,m as c,g as d,k as e,q as f,d as g,S as h,r as u};
2
- //# sourceMappingURL=use-agim-skills-pFjfgqMF.js.map
1
+ import{r as u,y as i,t as s,v as t}from"./index-DCfdN5R7.js";const l={all:["agim-skills"],list:["agim-skills","list"],one:e=>["agim-skills","one",e]};function r(){return u({queryKey:l.list,queryFn:()=>i.get("/api/agim-skills")})}function m(e){return u({queryKey:e?l.one(e):["agim-skills","one","__none__"],queryFn:()=>i.get(`/api/agim-skills/${encodeURIComponent(e)}`),enabled:!!e})}function y(){const e=s();return t({mutationFn:n=>i.post("/api/agim-skills",{body:n}),onSuccess:()=>e.invalidateQueries({queryKey:l.all})})}function g(){const e=s();return t({mutationFn:({name:n,body:o})=>i.put(`/api/agim-skills/${encodeURIComponent(n)}`,{body:{body:o}}),onSuccess:()=>e.invalidateQueries({queryKey:l.all})})}function k(){const e=s();return t({mutationFn:n=>i.delete(`/api/agim-skills/${encodeURIComponent(n)}`),onSuccess:()=>e.invalidateQueries({queryKey:l.all})})}function p(){const e=s();return t({mutationFn:()=>i.post("/api/agim-skills/refresh"),onSuccess:()=>e.invalidateQueries({queryKey:l.all})})}const a=["agim-skills","injection"];function q(){return u({queryKey:a,queryFn:()=>i.get("/api/agim-skills/injection")})}function d(){const e=s();return t({mutationFn:n=>i.put("/api/agim-skills/injection",{body:{body:n}}),onSuccess:()=>e.invalidateQueries({queryKey:a})})}function S(){const e=s();return t({mutationFn:()=>i.delete("/api/agim-skills/injection"),onSuccess:()=>e.invalidateQueries({queryKey:a})})}export{q as a,p as b,y as c,m as d,g as e,k as f,d as g,S as h,r as u};
2
+ //# sourceMappingURL=use-agim-skills-BbuJP3NT.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-agim-skills-pFjfgqMF.js","sources":["../../src/hooks/use-agim-skills.ts"],"sourcesContent":["/**\n * use-agim-skills — react-query wrappers for the agim SKILL.md\n * editor (`/api/agim-skills/*`).\n *\n * Distinct from the pre-existing `useSkills*` hooks against\n * `/api/skills` (which lists per-agent workspace CLI skills);\n * this set targets the in-process loader from\n * src/core/skills/loader.ts.\n */\n\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { client } from '@/lib/api/client'\n\nexport interface AgimSkillMeta {\n name: string\n description: string\n source: 'workspace' | 'builtin'\n always: boolean\n available: boolean\n unavailableReason?: string\n requiresBins: string[]\n requiresEnv: string[]\n dir: string\n /** v1.2.152 — system-prompt injection bucket (0–4). See loader.ts\n * `rankSkillBucket`. SPA uses this to group + collapse the installed\n * list. Optional for backward compat with older agim builds. */\n bucket?: 0 | 1 | 2 | 3 | 4\n}\n\nexport interface AgimSkillsListResponse {\n skills: AgimSkillMeta[]\n count: number\n maxBodyChars: number\n}\n\nexport interface AgimSkillDetailResponse {\n meta: AgimSkillMeta\n body: string\n}\n\nconst skillKeys = {\n all: ['agim-skills'] as const,\n list: ['agim-skills', 'list'] as const,\n one: (name: string) => ['agim-skills', 'one', name] as const,\n}\n\nexport function useAgimSkillsList() {\n return useQuery<AgimSkillsListResponse>({\n queryKey: skillKeys.list,\n queryFn: () => client.get<AgimSkillsListResponse>('/api/agim-skills'),\n })\n}\n\nexport function useAgimSkill(name: string | null) {\n return useQuery<AgimSkillDetailResponse>({\n queryKey: name ? skillKeys.one(name) : ['agim-skills', 'one', '__none__'],\n queryFn: () => client.get<AgimSkillDetailResponse>(`/api/agim-skills/${encodeURIComponent(name!)}`),\n enabled: !!name,\n })\n}\n\nexport function useAgimSkillCreate() {\n const qc = useQueryClient()\n return useMutation<{ meta: AgimSkillMeta }, Error, { name: string; body: string }>({\n mutationFn: (body) => client.post('/api/agim-skills', { body }),\n onSuccess: () => qc.invalidateQueries({ queryKey: skillKeys.all }),\n })\n}\n\nexport function useAgimSkillUpdate() {\n const qc = useQueryClient()\n return useMutation<{ meta: AgimSkillMeta }, Error, { name: string; body: string }>({\n mutationFn: ({ name, body }) => client.put(\n `/api/agim-skills/${encodeURIComponent(name)}`, { body: { body } },\n ),\n onSuccess: () => qc.invalidateQueries({ queryKey: skillKeys.all }),\n })\n}\n\nexport function useAgimSkillDelete() {\n const qc = useQueryClient()\n return useMutation<unknown, Error, string>({\n mutationFn: (name) => client.delete(`/api/agim-skills/${encodeURIComponent(name)}`),\n onSuccess: () => qc.invalidateQueries({ queryKey: skillKeys.all }),\n })\n}\n\nexport function useAgimSkillsRefresh() {\n const qc = useQueryClient()\n return useMutation<{ count: number }, Error, void>({\n mutationFn: () => client.post('/api/agim-skills/refresh'),\n onSuccess: () => qc.invalidateQueries({ queryKey: skillKeys.all }),\n })\n}\n\n// ─── v1.2.151 — injection-block override editor (operator-facing) ──────\n\nexport interface AgimSkillsInjectionResponse {\n /** The auto-generated tier-1 skill block from the live loader state.\n * Read-only preview the SPA shows on the left. */\n auto: string\n autoChars: number\n /** Current override file content (null when no override is active). */\n override: string | null\n overrideChars: number\n /** Absolute filesystem path of the override file (display-only). */\n overridePath: string\n /** True when the loader is currently using the override instead of\n * the auto block. */\n overrideActive: boolean\n /** Server-enforced character cap on the override body. */\n maxOverrideChars: number\n}\n\nconst injectionKey = ['agim-skills', 'injection'] as const\n\nexport function useSkillInjection() {\n return useQuery<AgimSkillsInjectionResponse>({\n queryKey: injectionKey,\n queryFn: () => client.get<AgimSkillsInjectionResponse>('/api/agim-skills/injection'),\n })\n}\n\nexport function useSkillInjectionSave() {\n const qc = useQueryClient()\n return useMutation<{ saved: boolean; deleted?: boolean; length?: number }, Error, string>({\n mutationFn: (body) => client.put('/api/agim-skills/injection', { body: { body } }),\n onSuccess: () => qc.invalidateQueries({ queryKey: injectionKey }),\n })\n}\n\nexport function useSkillInjectionDelete() {\n const qc = useQueryClient()\n return useMutation<{ deleted: boolean }, Error, void>({\n mutationFn: () => client.delete('/api/agim-skills/injection'),\n onSuccess: () => qc.invalidateQueries({ queryKey: injectionKey }),\n })\n}\n"],"names":["skillKeys","name","useAgimSkillsList","useQuery","client","useAgimSkill","useAgimSkillCreate","qc","useQueryClient","useMutation","body","useAgimSkillUpdate","useAgimSkillDelete","useAgimSkillsRefresh","injectionKey","useSkillInjection","useSkillInjectionSave","useSkillInjectionDelete"],"mappings":"6DAwCA,MAAMA,EAAY,CAChB,IAAM,CAAC,aAAa,EACpB,KAAM,CAAC,cAAe,MAAM,EAC5B,IAAOC,GAAiB,CAAC,cAAe,MAAOA,CAAI,CACrD,EAEO,SAASC,GAAoB,CAClC,OAAOC,EAAiC,CACtC,SAAUH,EAAU,KACpB,QAAS,IAAMI,EAAO,IAA4B,kBAAkB,CAAA,CACrE,CACH,CAEO,SAASC,EAAaJ,EAAqB,CAChD,OAAOE,EAAkC,CACvC,SAAUF,EAAOD,EAAU,IAAIC,CAAI,EAAI,CAAC,cAAe,MAAO,UAAU,EACxE,QAAS,IAAMG,EAAO,IAA6B,oBAAoB,mBAAmBH,CAAK,CAAC,EAAE,EAClG,QAAS,CAAC,CAACA,CAAA,CACZ,CACH,CAEO,SAASK,GAAqB,CACnC,MAAMC,EAAKC,EAAA,EACX,OAAOC,EAA4E,CACjF,WAAaC,GAASN,EAAO,KAAK,mBAAoB,CAAE,KAAAM,EAAM,EAC9D,UAAW,IAAMH,EAAG,kBAAkB,CAAE,SAAUP,EAAU,IAAK,CAAA,CAClE,CACH,CAEO,SAASW,GAAqB,CACnC,MAAMJ,EAAKC,EAAA,EACX,OAAOC,EAA4E,CACjF,WAAY,CAAC,CAAE,KAAAR,EAAM,KAAAS,CAAA,IAAWN,EAAO,IACrC,oBAAoB,mBAAmBH,CAAI,CAAC,GAAI,CAAE,KAAM,CAAE,KAAAS,CAAA,CAAK,CAAE,EAEnE,UAAW,IAAMH,EAAG,kBAAkB,CAAE,SAAUP,EAAU,IAAK,CAAA,CAClE,CACH,CAEO,SAASY,GAAqB,CACnC,MAAML,EAAKC,EAAA,EACX,OAAOC,EAAoC,CACzC,WAAaR,GAASG,EAAO,OAAO,oBAAoB,mBAAmBH,CAAI,CAAC,EAAE,EAClF,UAAW,IAAMM,EAAG,kBAAkB,CAAE,SAAUP,EAAU,IAAK,CAAA,CAClE,CACH,CAEO,SAASa,GAAuB,CACrC,MAAMN,EAAKC,EAAA,EACX,OAAOC,EAA4C,CACjD,WAAY,IAAML,EAAO,KAAK,0BAA0B,EACxD,UAAW,IAAMG,EAAG,kBAAkB,CAAE,SAAUP,EAAU,IAAK,CAAA,CAClE,CACH,CAqBA,MAAMc,EAAe,CAAC,cAAe,WAAW,EAEzC,SAASC,GAAoB,CAClC,OAAOZ,EAAsC,CAC3C,SAAUW,EACV,QAAS,IAAMV,EAAO,IAAiC,4BAA4B,CAAA,CACpF,CACH,CAEO,SAASY,GAAwB,CACtC,MAAMT,EAAKC,EAAA,EACX,OAAOC,EAAmF,CACxF,WAAaC,GAASN,EAAO,IAAI,6BAA8B,CAAE,KAAM,CAAE,KAAAM,CAAA,EAAQ,EACjF,UAAW,IAAMH,EAAG,kBAAkB,CAAE,SAAUO,EAAc,CAAA,CACjE,CACH,CAEO,SAASG,GAA0B,CACxC,MAAMV,EAAKC,EAAA,EACX,OAAOC,EAA+C,CACpD,WAAY,IAAML,EAAO,OAAO,4BAA4B,EAC5D,UAAW,IAAMG,EAAG,kBAAkB,CAAE,SAAUO,EAAc,CAAA,CACjE,CACH"}
1
+ {"version":3,"file":"use-agim-skills-BbuJP3NT.js","sources":["../../src/hooks/use-agim-skills.ts"],"sourcesContent":["/**\n * use-agim-skills — react-query wrappers for the agim SKILL.md\n * editor (`/api/agim-skills/*`).\n *\n * Distinct from the pre-existing `useSkills*` hooks against\n * `/api/skills` (which lists per-agent workspace CLI skills);\n * this set targets the in-process loader from\n * src/core/skills/loader.ts.\n */\n\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { client } from '@/lib/api/client'\n\nexport interface AgimSkillMeta {\n name: string\n description: string\n source: 'workspace' | 'builtin'\n always: boolean\n available: boolean\n unavailableReason?: string\n requiresBins: string[]\n requiresEnv: string[]\n dir: string\n /** v1.2.152 — system-prompt injection bucket (0–4). See loader.ts\n * `rankSkillBucket`. SPA uses this to group + collapse the installed\n * list. Optional for backward compat with older agim builds. */\n bucket?: 0 | 1 | 2 | 3 | 4\n}\n\nexport interface AgimSkillsListResponse {\n skills: AgimSkillMeta[]\n count: number\n maxBodyChars: number\n}\n\nexport interface AgimSkillDetailResponse {\n meta: AgimSkillMeta\n body: string\n}\n\nconst skillKeys = {\n all: ['agim-skills'] as const,\n list: ['agim-skills', 'list'] as const,\n one: (name: string) => ['agim-skills', 'one', name] as const,\n}\n\nexport function useAgimSkillsList() {\n return useQuery<AgimSkillsListResponse>({\n queryKey: skillKeys.list,\n queryFn: () => client.get<AgimSkillsListResponse>('/api/agim-skills'),\n })\n}\n\nexport function useAgimSkill(name: string | null) {\n return useQuery<AgimSkillDetailResponse>({\n queryKey: name ? skillKeys.one(name) : ['agim-skills', 'one', '__none__'],\n queryFn: () => client.get<AgimSkillDetailResponse>(`/api/agim-skills/${encodeURIComponent(name!)}`),\n enabled: !!name,\n })\n}\n\nexport function useAgimSkillCreate() {\n const qc = useQueryClient()\n return useMutation<{ meta: AgimSkillMeta }, Error, { name: string; body: string }>({\n mutationFn: (body) => client.post('/api/agim-skills', { body }),\n onSuccess: () => qc.invalidateQueries({ queryKey: skillKeys.all }),\n })\n}\n\nexport function useAgimSkillUpdate() {\n const qc = useQueryClient()\n return useMutation<{ meta: AgimSkillMeta }, Error, { name: string; body: string }>({\n mutationFn: ({ name, body }) => client.put(\n `/api/agim-skills/${encodeURIComponent(name)}`, { body: { body } },\n ),\n onSuccess: () => qc.invalidateQueries({ queryKey: skillKeys.all }),\n })\n}\n\nexport function useAgimSkillDelete() {\n const qc = useQueryClient()\n return useMutation<unknown, Error, string>({\n mutationFn: (name) => client.delete(`/api/agim-skills/${encodeURIComponent(name)}`),\n onSuccess: () => qc.invalidateQueries({ queryKey: skillKeys.all }),\n })\n}\n\nexport function useAgimSkillsRefresh() {\n const qc = useQueryClient()\n return useMutation<{ count: number }, Error, void>({\n mutationFn: () => client.post('/api/agim-skills/refresh'),\n onSuccess: () => qc.invalidateQueries({ queryKey: skillKeys.all }),\n })\n}\n\n// ─── v1.2.151 — injection-block override editor (operator-facing) ──────\n\nexport interface AgimSkillsInjectionResponse {\n /** The auto-generated tier-1 skill block from the live loader state.\n * Read-only preview the SPA shows on the left. */\n auto: string\n autoChars: number\n /** Current override file content (null when no override is active). */\n override: string | null\n overrideChars: number\n /** Absolute filesystem path of the override file (display-only). */\n overridePath: string\n /** True when the loader is currently using the override instead of\n * the auto block. */\n overrideActive: boolean\n /** Server-enforced character cap on the override body. */\n maxOverrideChars: number\n}\n\nconst injectionKey = ['agim-skills', 'injection'] as const\n\nexport function useSkillInjection() {\n return useQuery<AgimSkillsInjectionResponse>({\n queryKey: injectionKey,\n queryFn: () => client.get<AgimSkillsInjectionResponse>('/api/agim-skills/injection'),\n })\n}\n\nexport function useSkillInjectionSave() {\n const qc = useQueryClient()\n return useMutation<{ saved: boolean; deleted?: boolean; length?: number }, Error, string>({\n mutationFn: (body) => client.put('/api/agim-skills/injection', { body: { body } }),\n onSuccess: () => qc.invalidateQueries({ queryKey: injectionKey }),\n })\n}\n\nexport function useSkillInjectionDelete() {\n const qc = useQueryClient()\n return useMutation<{ deleted: boolean }, Error, void>({\n mutationFn: () => client.delete('/api/agim-skills/injection'),\n onSuccess: () => qc.invalidateQueries({ queryKey: injectionKey }),\n })\n}\n"],"names":["skillKeys","name","useAgimSkillsList","useQuery","client","useAgimSkill","useAgimSkillCreate","qc","useQueryClient","useMutation","body","useAgimSkillUpdate","useAgimSkillDelete","useAgimSkillsRefresh","injectionKey","useSkillInjection","useSkillInjectionSave","useSkillInjectionDelete"],"mappings":"6DAwCA,MAAMA,EAAY,CAChB,IAAM,CAAC,aAAa,EACpB,KAAM,CAAC,cAAe,MAAM,EAC5B,IAAOC,GAAiB,CAAC,cAAe,MAAOA,CAAI,CACrD,EAEO,SAASC,GAAoB,CAClC,OAAOC,EAAiC,CACtC,SAAUH,EAAU,KACpB,QAAS,IAAMI,EAAO,IAA4B,kBAAkB,CAAA,CACrE,CACH,CAEO,SAASC,EAAaJ,EAAqB,CAChD,OAAOE,EAAkC,CACvC,SAAUF,EAAOD,EAAU,IAAIC,CAAI,EAAI,CAAC,cAAe,MAAO,UAAU,EACxE,QAAS,IAAMG,EAAO,IAA6B,oBAAoB,mBAAmBH,CAAK,CAAC,EAAE,EAClG,QAAS,CAAC,CAACA,CAAA,CACZ,CACH,CAEO,SAASK,GAAqB,CACnC,MAAMC,EAAKC,EAAA,EACX,OAAOC,EAA4E,CACjF,WAAaC,GAASN,EAAO,KAAK,mBAAoB,CAAE,KAAAM,EAAM,EAC9D,UAAW,IAAMH,EAAG,kBAAkB,CAAE,SAAUP,EAAU,IAAK,CAAA,CAClE,CACH,CAEO,SAASW,GAAqB,CACnC,MAAMJ,EAAKC,EAAA,EACX,OAAOC,EAA4E,CACjF,WAAY,CAAC,CAAE,KAAAR,EAAM,KAAAS,CAAA,IAAWN,EAAO,IACrC,oBAAoB,mBAAmBH,CAAI,CAAC,GAAI,CAAE,KAAM,CAAE,KAAAS,CAAA,CAAK,CAAE,EAEnE,UAAW,IAAMH,EAAG,kBAAkB,CAAE,SAAUP,EAAU,IAAK,CAAA,CAClE,CACH,CAEO,SAASY,GAAqB,CACnC,MAAML,EAAKC,EAAA,EACX,OAAOC,EAAoC,CACzC,WAAaR,GAASG,EAAO,OAAO,oBAAoB,mBAAmBH,CAAI,CAAC,EAAE,EAClF,UAAW,IAAMM,EAAG,kBAAkB,CAAE,SAAUP,EAAU,IAAK,CAAA,CAClE,CACH,CAEO,SAASa,GAAuB,CACrC,MAAMN,EAAKC,EAAA,EACX,OAAOC,EAA4C,CACjD,WAAY,IAAML,EAAO,KAAK,0BAA0B,EACxD,UAAW,IAAMG,EAAG,kBAAkB,CAAE,SAAUP,EAAU,IAAK,CAAA,CAClE,CACH,CAqBA,MAAMc,EAAe,CAAC,cAAe,WAAW,EAEzC,SAASC,GAAoB,CAClC,OAAOZ,EAAsC,CAC3C,SAAUW,EACV,QAAS,IAAMV,EAAO,IAAiC,4BAA4B,CAAA,CACpF,CACH,CAEO,SAASY,GAAwB,CACtC,MAAMT,EAAKC,EAAA,EACX,OAAOC,EAAmF,CACxF,WAAaC,GAASN,EAAO,IAAI,6BAA8B,CAAE,KAAM,CAAE,KAAAM,CAAA,EAAQ,EACjF,UAAW,IAAMH,EAAG,kBAAkB,CAAE,SAAUO,EAAc,CAAA,CACjE,CACH,CAEO,SAASG,GAA0B,CACxC,MAAMV,EAAKC,EAAA,EACX,OAAOC,EAA+C,CACpD,WAAY,IAAML,EAAO,OAAO,4BAA4B,EAC5D,UAAW,IAAMG,EAAG,kBAAkB,CAAE,SAAUO,EAAc,CAAA,CACjE,CACH"}
@@ -0,0 +1,2 @@
1
+ import{r as s,y as n,t as i,v as l}from"./index-DCfdN5R7.js";const r={all:["heartbeat"],list:["heartbeat","list"]};function c(e){return`${e.platform}:${e.channelId}:${e.threadId}`}function g(){return s({queryKey:r.list,queryFn:()=>n.get("/api/heartbeat/bindings"),refetchInterval:1e4,refetchIntervalInBackground:!1})}function f(){const e=i();return l({mutationFn:({row:t,op:a})=>n.post(`/api/heartbeat/bindings/${encodeURIComponent(c(t))}/${a}`),onSuccess:()=>e.invalidateQueries({queryKey:r.all})})}const u={all:["goals"],list:["goals","list"]};function p(){return s({queryKey:u.list,queryFn:()=>n.get("/api/goals"),refetchInterval:3e4})}function h(){const e=i();return l({mutationFn:({id:t,status:a})=>n.put(`/api/goals/${t}/status`,{body:{status:a}}),onSuccess:()=>e.invalidateQueries({queryKey:u.all})})}const o={all:["asks"],list:["asks","list"]};function q(){return s({queryKey:o.list,queryFn:()=>n.get("/api/asks/pending"),refetchInterval:5e3})}function K(){const e=i();return l({mutationFn:t=>n.post(`/api/asks/pending/${encodeURIComponent(t)}/cancel`),onSuccess:()=>e.invalidateQueries({queryKey:o.all})})}const y={all:["plans"],list:(e,t)=>["plans","list",e??null,t??null]};function m(e={}){const t=new URLSearchParams;e.threadKey&&t.set("thread_key",e.threadKey),e.limit!=null&&t.set("limit",String(e.limit));const a=t.toString();return s({queryKey:y.list(e.threadKey,e.limit),queryFn:()=>n.get(`/api/plans${a?`?${a}`:""}`)})}export{p as a,q as b,f as c,h as d,K as e,m as f,g as u};
2
+ //# sourceMappingURL=use-background-tasks-CwFmOokw.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-background-tasks-D1--hHjp.js","sources":["../../src/hooks/use-background-tasks.ts"],"sourcesContent":["/**\n * use-background-tasks — react-query hooks for the P1 follow-up\n * admin panels (heartbeat / goals / asks).\n *\n * All three sit under the same `/tasks/*` SPA group + share polling\n * intervals because operators tend to flip between them. Each list\n * polls every 10s while foreground so live activity (a new ask\n * landing, a heartbeat tick completing) shows up without a manual\n * refresh.\n */\n\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { client } from '@/lib/api/client'\n\n// ─── Heartbeat ──────────────────────────────────────────────────\n\nexport interface HeartbeatRow {\n platform: string\n channelId: string\n threadId: string\n userId: string\n body: string\n intervalMinutes: number\n enabled: boolean\n lastTickAt: string | null\n lastStatus: string\n lastReason: string\n lastTextPreview: string\n createdAt: string\n}\n\nexport interface HeartbeatListResponse {\n bindings: HeartbeatRow[]\n count: number\n}\n\nconst hbKeys = {\n all: ['heartbeat'] as const,\n list: ['heartbeat', 'list'] as const,\n}\n\nfunction bindingKey(r: { platform: string; channelId: string; threadId: string }): string {\n return `${r.platform}:${r.channelId}:${r.threadId}`\n}\n\nexport function useHeartbeatList() {\n return useQuery<HeartbeatListResponse>({\n queryKey: hbKeys.list,\n queryFn: () => client.get<HeartbeatListResponse>('/api/heartbeat/bindings'),\n refetchInterval: 10_000,\n refetchIntervalInBackground: false,\n })\n}\n\nexport function useHeartbeatToggle() {\n const qc = useQueryClient()\n return useMutation<unknown, Error, { row: HeartbeatRow; op: 'enable' | 'disable' }>({\n mutationFn: ({ row, op }) => client.post(\n `/api/heartbeat/bindings/${encodeURIComponent(bindingKey(row))}/${op}`,\n ),\n onSuccess: () => qc.invalidateQueries({ queryKey: hbKeys.all }),\n })\n}\n\n// ─── Goals ──────────────────────────────────────────────────────\n\nexport interface GoalRow {\n id: number\n platform: string\n channelId: string\n threadId: string\n userId: string\n title: string\n body: string\n status: 'active' | 'paused' | 'completed' | 'cancelled'\n progressLog: Array<{ ts: string; by: string; text: string }>\n progressCount: number\n createdAt: string\n updatedAt: string\n closedAt: string | null\n}\n\nexport interface GoalsListResponse {\n goals: GoalRow[]\n count: number\n scope: 'all-active' | 'thread'\n}\n\nconst goalKeys = {\n all: ['goals'] as const,\n list: ['goals', 'list'] as const,\n}\n\nexport function useGoalsList() {\n return useQuery<GoalsListResponse>({\n queryKey: goalKeys.list,\n queryFn: () => client.get<GoalsListResponse>('/api/goals'),\n refetchInterval: 30_000,\n })\n}\n\nexport function useGoalUpdateStatus() {\n const qc = useQueryClient()\n return useMutation<unknown, Error, { id: number; status: GoalRow['status'] }>({\n mutationFn: ({ id, status }) => client.put(\n `/api/goals/${id}/status`, { body: { status } },\n ),\n onSuccess: () => qc.invalidateQueries({ queryKey: goalKeys.all }),\n })\n}\n\n// ─── Pending asks ───────────────────────────────────────────────\n\nexport interface PendingAskRow {\n reqId: string\n platform: string\n threadId: string\n question: string\n choices: number\n ageMs: number\n}\n\nexport interface AsksListResponse {\n pending: PendingAskRow[]\n count: number\n}\n\nconst askKeys = {\n all: ['asks'] as const,\n list: ['asks', 'list'] as const,\n}\n\nexport function useAsksList() {\n return useQuery<AsksListResponse>({\n queryKey: askKeys.list,\n queryFn: () => client.get<AsksListResponse>('/api/asks/pending'),\n refetchInterval: 5_000, // asks are short-lived; poll faster\n })\n}\n\nexport function useAskCancel() {\n const qc = useQueryClient()\n return useMutation<unknown, Error, string>({\n mutationFn: (reqId) => client.post(`/api/asks/pending/${encodeURIComponent(reqId)}/cancel`),\n onSuccess: () => qc.invalidateQueries({ queryKey: askKeys.all }),\n })\n}\n\n// ─── Plan history (v1.2.133) ────────────────────────────────────\n\nexport type PlanOutcome = 'approved' | 'rejected' | 'edited' | 'expired'\n\nexport interface PlanHistoryRow {\n id: number\n threadKey: string\n planMd: string\n outcome: PlanOutcome\n detail: string | null\n resolvedAt: string\n pendingMs: number | null\n}\n\nexport interface PlansListResponse {\n plans: PlanHistoryRow[]\n total: number\n}\n\nconst planKeys = {\n all: ['plans'] as const,\n list: (threadKey?: string, limit?: number) =>\n ['plans', 'list', threadKey ?? null, limit ?? null] as const,\n}\n\n/** GET /api/plans — admin list of native_exit_plan_mode handshakes\n * with outcome + pending duration + the plan markdown. Filters on\n * thread_key (optional) and limit (clamped 1..500 server-side). */\nexport function usePlansList(opts: { threadKey?: string; limit?: number } = {}) {\n const params = new URLSearchParams()\n if (opts.threadKey) params.set('thread_key', opts.threadKey)\n if (opts.limit != null) params.set('limit', String(opts.limit))\n const qs = params.toString()\n return useQuery<PlansListResponse>({\n queryKey: planKeys.list(opts.threadKey, opts.limit),\n queryFn: () => client.get<PlansListResponse>(`/api/plans${qs ? `?${qs}` : ''}`),\n })\n}\n"],"names":["hbKeys","bindingKey","r","useHeartbeatList","useQuery","client","useHeartbeatToggle","qc","useQueryClient","useMutation","row","op","goalKeys","useGoalsList","useGoalUpdateStatus","id","status","askKeys","useAsksList","useAskCancel","reqId","planKeys","threadKey","limit","usePlansList","opts","params","qs"],"mappings":"6DAoCA,MAAMA,EAAS,CACb,IAAM,CAAC,WAAW,EAClB,KAAM,CAAC,YAAa,MAAM,CAC5B,EAEA,SAASC,EAAWC,EAAsE,CACxF,MAAO,GAAGA,EAAE,QAAQ,IAAIA,EAAE,SAAS,IAAIA,EAAE,QAAQ,EACnD,CAEO,SAASC,GAAmB,CACjC,OAAOC,EAAgC,CACrC,SAAUJ,EAAO,KACjB,QAAS,IAAMK,EAAO,IAA2B,yBAAyB,EAC1E,gBAAiB,IACjB,4BAA6B,EAAA,CAC9B,CACH,CAEO,SAASC,GAAqB,CACnC,MAAMC,EAAKC,EAAA,EACX,OAAOC,EAA6E,CAClF,WAAY,CAAC,CAAE,IAAAC,EAAK,GAAAC,CAAA,IAASN,EAAO,KAClC,2BAA2B,mBAAmBJ,EAAWS,CAAG,CAAC,CAAC,IAAIC,CAAE,EAAA,EAEtE,UAAW,IAAMJ,EAAG,kBAAkB,CAAE,SAAUP,EAAO,IAAK,CAAA,CAC/D,CACH,CA0BA,MAAMY,EAAW,CACf,IAAM,CAAC,OAAO,EACd,KAAM,CAAC,QAAS,MAAM,CACxB,EAEO,SAASC,GAAe,CAC7B,OAAOT,EAA4B,CACjC,SAAUQ,EAAS,KACnB,QAAS,IAAMP,EAAO,IAAuB,YAAY,EACzD,gBAAiB,GAAA,CAClB,CACH,CAEO,SAASS,GAAsB,CACpC,MAAMP,EAAKC,EAAA,EACX,OAAOC,EAAuE,CAC5E,WAAY,CAAC,CAAE,GAAAM,EAAI,OAAAC,CAAA,IAAaX,EAAO,IACrC,cAAcU,CAAE,UAAW,CAAE,KAAM,CAAE,OAAAC,CAAA,CAAO,CAAE,EAEhD,UAAW,IAAMT,EAAG,kBAAkB,CAAE,SAAUK,EAAS,IAAK,CAAA,CACjE,CACH,CAkBA,MAAMK,EAAU,CACd,IAAM,CAAC,MAAM,EACb,KAAM,CAAC,OAAQ,MAAM,CACvB,EAEO,SAASC,GAAc,CAC5B,OAAOd,EAA2B,CAChC,SAAUa,EAAQ,KAClB,QAAS,IAAMZ,EAAO,IAAsB,mBAAmB,EAC/D,gBAAiB,GAAA,CAClB,CACH,CAEO,SAASc,GAAe,CAC7B,MAAMZ,EAAKC,EAAA,EACX,OAAOC,EAAoC,CACzC,WAAaW,GAAUf,EAAO,KAAK,qBAAqB,mBAAmBe,CAAK,CAAC,SAAS,EAC1F,UAAW,IAAMb,EAAG,kBAAkB,CAAE,SAAUU,EAAQ,IAAK,CAAA,CAChE,CACH,CAqBA,MAAMI,EAAW,CACf,IAAM,CAAC,OAAO,EACd,KAAM,CAACC,EAAoBC,IACzB,CAAC,QAAS,OAAQD,GAAa,KAAMC,GAAS,IAAI,CACtD,EAKO,SAASC,EAAaC,EAA+C,GAAI,CAC9E,MAAMC,EAAS,IAAI,gBACfD,EAAK,WAAWC,EAAO,IAAI,aAAcD,EAAK,SAAS,EACvDA,EAAK,OAAS,MAAMC,EAAO,IAAI,QAAS,OAAOD,EAAK,KAAK,CAAC,EAC9D,MAAME,EAAKD,EAAO,SAAA,EAClB,OAAOtB,EAA4B,CACjC,SAAUiB,EAAS,KAAKI,EAAK,UAAWA,EAAK,KAAK,EAClD,QAAS,IAAMpB,EAAO,IAAuB,aAAasB,EAAK,IAAIA,CAAE,GAAK,EAAE,EAAE,CAAA,CAC/E,CACH"}
1
+ {"version":3,"file":"use-background-tasks-CwFmOokw.js","sources":["../../src/hooks/use-background-tasks.ts"],"sourcesContent":["/**\n * use-background-tasks — react-query hooks for the P1 follow-up\n * admin panels (heartbeat / goals / asks).\n *\n * All three sit under the same `/tasks/*` SPA group + share polling\n * intervals because operators tend to flip between them. Each list\n * polls every 10s while foreground so live activity (a new ask\n * landing, a heartbeat tick completing) shows up without a manual\n * refresh.\n */\n\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { client } from '@/lib/api/client'\n\n// ─── Heartbeat ──────────────────────────────────────────────────\n\nexport interface HeartbeatRow {\n platform: string\n channelId: string\n threadId: string\n userId: string\n body: string\n intervalMinutes: number\n enabled: boolean\n lastTickAt: string | null\n lastStatus: string\n lastReason: string\n lastTextPreview: string\n createdAt: string\n}\n\nexport interface HeartbeatListResponse {\n bindings: HeartbeatRow[]\n count: number\n}\n\nconst hbKeys = {\n all: ['heartbeat'] as const,\n list: ['heartbeat', 'list'] as const,\n}\n\nfunction bindingKey(r: { platform: string; channelId: string; threadId: string }): string {\n return `${r.platform}:${r.channelId}:${r.threadId}`\n}\n\nexport function useHeartbeatList() {\n return useQuery<HeartbeatListResponse>({\n queryKey: hbKeys.list,\n queryFn: () => client.get<HeartbeatListResponse>('/api/heartbeat/bindings'),\n refetchInterval: 10_000,\n refetchIntervalInBackground: false,\n })\n}\n\nexport function useHeartbeatToggle() {\n const qc = useQueryClient()\n return useMutation<unknown, Error, { row: HeartbeatRow; op: 'enable' | 'disable' }>({\n mutationFn: ({ row, op }) => client.post(\n `/api/heartbeat/bindings/${encodeURIComponent(bindingKey(row))}/${op}`,\n ),\n onSuccess: () => qc.invalidateQueries({ queryKey: hbKeys.all }),\n })\n}\n\n// ─── Goals ──────────────────────────────────────────────────────\n\nexport interface GoalRow {\n id: number\n platform: string\n channelId: string\n threadId: string\n userId: string\n title: string\n body: string\n status: 'active' | 'paused' | 'completed' | 'cancelled'\n progressLog: Array<{ ts: string; by: string; text: string }>\n progressCount: number\n createdAt: string\n updatedAt: string\n closedAt: string | null\n}\n\nexport interface GoalsListResponse {\n goals: GoalRow[]\n count: number\n scope: 'all-active' | 'thread'\n}\n\nconst goalKeys = {\n all: ['goals'] as const,\n list: ['goals', 'list'] as const,\n}\n\nexport function useGoalsList() {\n return useQuery<GoalsListResponse>({\n queryKey: goalKeys.list,\n queryFn: () => client.get<GoalsListResponse>('/api/goals'),\n refetchInterval: 30_000,\n })\n}\n\nexport function useGoalUpdateStatus() {\n const qc = useQueryClient()\n return useMutation<unknown, Error, { id: number; status: GoalRow['status'] }>({\n mutationFn: ({ id, status }) => client.put(\n `/api/goals/${id}/status`, { body: { status } },\n ),\n onSuccess: () => qc.invalidateQueries({ queryKey: goalKeys.all }),\n })\n}\n\n// ─── Pending asks ───────────────────────────────────────────────\n\nexport interface PendingAskRow {\n reqId: string\n platform: string\n threadId: string\n question: string\n choices: number\n ageMs: number\n}\n\nexport interface AsksListResponse {\n pending: PendingAskRow[]\n count: number\n}\n\nconst askKeys = {\n all: ['asks'] as const,\n list: ['asks', 'list'] as const,\n}\n\nexport function useAsksList() {\n return useQuery<AsksListResponse>({\n queryKey: askKeys.list,\n queryFn: () => client.get<AsksListResponse>('/api/asks/pending'),\n refetchInterval: 5_000, // asks are short-lived; poll faster\n })\n}\n\nexport function useAskCancel() {\n const qc = useQueryClient()\n return useMutation<unknown, Error, string>({\n mutationFn: (reqId) => client.post(`/api/asks/pending/${encodeURIComponent(reqId)}/cancel`),\n onSuccess: () => qc.invalidateQueries({ queryKey: askKeys.all }),\n })\n}\n\n// ─── Plan history (v1.2.133) ────────────────────────────────────\n\nexport type PlanOutcome = 'approved' | 'rejected' | 'edited' | 'expired'\n\nexport interface PlanHistoryRow {\n id: number\n threadKey: string\n planMd: string\n outcome: PlanOutcome\n detail: string | null\n resolvedAt: string\n pendingMs: number | null\n}\n\nexport interface PlansListResponse {\n plans: PlanHistoryRow[]\n total: number\n}\n\nconst planKeys = {\n all: ['plans'] as const,\n list: (threadKey?: string, limit?: number) =>\n ['plans', 'list', threadKey ?? null, limit ?? null] as const,\n}\n\n/** GET /api/plans — admin list of native_exit_plan_mode handshakes\n * with outcome + pending duration + the plan markdown. Filters on\n * thread_key (optional) and limit (clamped 1..500 server-side). */\nexport function usePlansList(opts: { threadKey?: string; limit?: number } = {}) {\n const params = new URLSearchParams()\n if (opts.threadKey) params.set('thread_key', opts.threadKey)\n if (opts.limit != null) params.set('limit', String(opts.limit))\n const qs = params.toString()\n return useQuery<PlansListResponse>({\n queryKey: planKeys.list(opts.threadKey, opts.limit),\n queryFn: () => client.get<PlansListResponse>(`/api/plans${qs ? `?${qs}` : ''}`),\n })\n}\n"],"names":["hbKeys","bindingKey","r","useHeartbeatList","useQuery","client","useHeartbeatToggle","qc","useQueryClient","useMutation","row","op","goalKeys","useGoalsList","useGoalUpdateStatus","id","status","askKeys","useAsksList","useAskCancel","reqId","planKeys","threadKey","limit","usePlansList","opts","params","qs"],"mappings":"6DAoCA,MAAMA,EAAS,CACb,IAAM,CAAC,WAAW,EAClB,KAAM,CAAC,YAAa,MAAM,CAC5B,EAEA,SAASC,EAAWC,EAAsE,CACxF,MAAO,GAAGA,EAAE,QAAQ,IAAIA,EAAE,SAAS,IAAIA,EAAE,QAAQ,EACnD,CAEO,SAASC,GAAmB,CACjC,OAAOC,EAAgC,CACrC,SAAUJ,EAAO,KACjB,QAAS,IAAMK,EAAO,IAA2B,yBAAyB,EAC1E,gBAAiB,IACjB,4BAA6B,EAAA,CAC9B,CACH,CAEO,SAASC,GAAqB,CACnC,MAAMC,EAAKC,EAAA,EACX,OAAOC,EAA6E,CAClF,WAAY,CAAC,CAAE,IAAAC,EAAK,GAAAC,CAAA,IAASN,EAAO,KAClC,2BAA2B,mBAAmBJ,EAAWS,CAAG,CAAC,CAAC,IAAIC,CAAE,EAAA,EAEtE,UAAW,IAAMJ,EAAG,kBAAkB,CAAE,SAAUP,EAAO,IAAK,CAAA,CAC/D,CACH,CA0BA,MAAMY,EAAW,CACf,IAAM,CAAC,OAAO,EACd,KAAM,CAAC,QAAS,MAAM,CACxB,EAEO,SAASC,GAAe,CAC7B,OAAOT,EAA4B,CACjC,SAAUQ,EAAS,KACnB,QAAS,IAAMP,EAAO,IAAuB,YAAY,EACzD,gBAAiB,GAAA,CAClB,CACH,CAEO,SAASS,GAAsB,CACpC,MAAMP,EAAKC,EAAA,EACX,OAAOC,EAAuE,CAC5E,WAAY,CAAC,CAAE,GAAAM,EAAI,OAAAC,CAAA,IAAaX,EAAO,IACrC,cAAcU,CAAE,UAAW,CAAE,KAAM,CAAE,OAAAC,CAAA,CAAO,CAAE,EAEhD,UAAW,IAAMT,EAAG,kBAAkB,CAAE,SAAUK,EAAS,IAAK,CAAA,CACjE,CACH,CAkBA,MAAMK,EAAU,CACd,IAAM,CAAC,MAAM,EACb,KAAM,CAAC,OAAQ,MAAM,CACvB,EAEO,SAASC,GAAc,CAC5B,OAAOd,EAA2B,CAChC,SAAUa,EAAQ,KAClB,QAAS,IAAMZ,EAAO,IAAsB,mBAAmB,EAC/D,gBAAiB,GAAA,CAClB,CACH,CAEO,SAASc,GAAe,CAC7B,MAAMZ,EAAKC,EAAA,EACX,OAAOC,EAAoC,CACzC,WAAaW,GAAUf,EAAO,KAAK,qBAAqB,mBAAmBe,CAAK,CAAC,SAAS,EAC1F,UAAW,IAAMb,EAAG,kBAAkB,CAAE,SAAUU,EAAQ,IAAK,CAAA,CAChE,CACH,CAqBA,MAAMI,EAAW,CACf,IAAM,CAAC,OAAO,EACd,KAAM,CAACC,EAAoBC,IACzB,CAAC,QAAS,OAAQD,GAAa,KAAMC,GAAS,IAAI,CACtD,EAKO,SAASC,EAAaC,EAA+C,GAAI,CAC9E,MAAMC,EAAS,IAAI,gBACfD,EAAK,WAAWC,EAAO,IAAI,aAAcD,EAAK,SAAS,EACvDA,EAAK,OAAS,MAAMC,EAAO,IAAI,QAAS,OAAOD,EAAK,KAAK,CAAC,EAC9D,MAAME,EAAKD,EAAO,SAAA,EAClB,OAAOtB,EAA4B,CACjC,SAAUiB,EAAS,KAAKI,EAAK,UAAWA,EAAK,KAAK,EAClD,QAAS,IAAMpB,EAAO,IAAuB,aAAasB,EAAK,IAAIA,CAAE,GAAK,EAAE,EAAE,CAAA,CAC/E,CACH"}
@@ -0,0 +1,2 @@
1
+ import{r as u,s as t,t as a,v as o}from"./index-DCfdN5R7.js";const e={all:["jobs"],list:s=>["jobs","list",s]};function r(s){return u({queryKey:e.list(s),queryFn:()=>t.listJobs(s)})}function l(){const s=a();return()=>s.invalidateQueries({queryKey:e.all})}function c(){const s=a();return o({mutationFn:n=>t.batchCancelJobs(n),onSuccess:()=>s.invalidateQueries({queryKey:e.all})})}export{l as a,c as b,r as u};
2
+ //# sourceMappingURL=use-jobs-BJjeJ5lh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-jobs-BJjeJ5lh.js","sources":["../../src/hooks/use-jobs.ts"],"sourcesContent":["/**\n * useJobs — react-query wrappers for the jobs domain.\n *\n * useJobs(query) — list with filter / pagination\n * useBatchCancelJobs() — bulk cancel mutation\n * useBatchRunJobs() — bulk re-run mutation\n *\n * Query keys: `['jobs', 'list', stableQuery]` so SSE invalidation\n * via useEventStream({ job: () => qc.invalidateQueries(['jobs']) })\n * clears every list view at once. The serialised query object is\n * stable across renders (react-query handles deep equality), so\n * keying on it directly is safe.\n *\n * Why hooks not raw `useQuery`: every route hits the same listJobs\n * endpoint with similar shapes; centralising the key + error toast\n * (caller-supplied) here keeps the route files focused on layout.\n */\n\nimport { useQueryClient, useMutation, useQuery } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type { BatchJobBody, ListJobsQuery, ListJobsResponse } from '@/types/api'\n\nexport const jobsKeys = {\n all: ['jobs'] as const,\n list: (q: ListJobsQuery) => ['jobs', 'list', q] as const,\n}\n\nexport function useJobs(query: ListJobsQuery) {\n return useQuery<ListJobsResponse>({\n queryKey: jobsKeys.list(query),\n queryFn: () => api.listJobs(query),\n })\n}\n\n/** Force-refresh every jobs list view. Call this from the SSE\n * `job` handler in route files. */\nexport function useInvalidateJobs() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: jobsKeys.all })\n}\n\nexport function useBatchCancelJobs() {\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (body: BatchJobBody) => api.batchCancelJobs(body),\n onSuccess: () => qc.invalidateQueries({ queryKey: jobsKeys.all }),\n })\n}\n\nexport function useBatchRunJobs() {\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (body: BatchJobBody) => api.batchRunJobs(body),\n onSuccess: () => qc.invalidateQueries({ queryKey: jobsKeys.all }),\n })\n}\n"],"names":["jobsKeys","q","useJobs","query","useQuery","api","useInvalidateJobs","qc","useQueryClient","useBatchCancelJobs","useMutation","body"],"mappings":"6DAsBO,MAAMA,EAAW,CACtB,IAAM,CAAC,MAAM,EACb,KAAOC,GAAqB,CAAC,OAAQ,OAAQA,CAAC,CAChD,EAEO,SAASC,EAAQC,EAAsB,CAC5C,OAAOC,EAA2B,CAChC,SAAUJ,EAAS,KAAKG,CAAK,EAC7B,QAAS,IAAME,EAAI,SAASF,CAAK,CAAA,CAClC,CACH,CAIO,SAASG,GAAoB,CAClC,MAAMC,EAAKC,EAAA,EACX,MAAO,IAAMD,EAAG,kBAAkB,CAAE,SAAUP,EAAS,IAAK,CAC9D,CAEO,SAASS,GAAqB,CACnC,MAAMF,EAAKC,EAAA,EACX,OAAOE,EAAY,CACjB,WAAaC,GAAuBN,EAAI,gBAAgBM,CAAI,EAC5D,UAAW,IAAMJ,EAAG,kBAAkB,CAAE,SAAUP,EAAS,IAAK,CAAA,CACjE,CACH"}
@@ -0,0 +1,2 @@
1
+ import{r as o,s as n,t as a,v as u,Q as i}from"./index-DCfdN5R7.js";const s={all:["memory"],users:["memory","users"],facts:e=>["memory","facts",e],persona:e=>["memory","persona",e],consolidate:["memory","consolidate"],distill:["memory","distill"]};function c(){return o({queryKey:s.users,queryFn:()=>n.listMemoryUsers()})}function y(e,t={}){return o({queryKey:s.facts(e),queryFn:()=>n.listMemoryFacts(e),enabled:t.enabled!==!1&&!!e.user_key})}function d(){const e=a();return u({mutationFn:({id:t,user_key:r})=>n.deleteMemoryFactById(t,{user_key:r}),onSuccess:()=>e.invalidateQueries({queryKey:s.all})})}function m(){const e=a();return u({mutationFn:({user_key:t,body:r})=>n.deleteMemoryFacts({user_key:t},r),onSuccess:()=>e.invalidateQueries({queryKey:s.all})})}function f(e,t={}){return o({queryKey:s.persona(e),queryFn:async()=>{try{return await n.getMemoryPersona({user_key:e})}catch(r){if(r instanceof i&&r.status===404)return null;throw r}},enabled:t.enabled!==!1&&!!e})}function q(){const e=a();return u({mutationFn:({user_key:t,body:r})=>n.updateMemoryPersona({user_key:t},r),onSuccess:(t,r)=>{e.invalidateQueries({queryKey:s.persona(r.user_key)}),e.invalidateQueries({queryKey:s.users})}})}function F(){const e=a();return u({mutationFn:t=>n.deleteMemoryPersona({user_key:t}),onSuccess:(t,r)=>{e.invalidateQueries({queryKey:s.persona(r)}),e.invalidateQueries({queryKey:s.users})}})}function K(e={}){return o({queryKey:s.consolidate,queryFn:()=>n.getMemoryConsolidateStatus(),refetchInterval:3e3,refetchIntervalInBackground:!1,enabled:e.enabled!==!1})}function v(){const e=a();return u({mutationFn:()=>n.consolidateMemory(),onSuccess:()=>{e.invalidateQueries({queryKey:s.consolidate}),e.invalidateQueries({queryKey:s.all})}})}function M(e={}){return o({queryKey:s.distill,queryFn:()=>n.getMemoryDistillStatus(),refetchInterval:3e3,refetchIntervalInBackground:!1,enabled:e.enabled!==!1})}function Q(){const e=a();return u({mutationFn:()=>n.triggerMemoryDistill(),onSuccess:()=>{e.invalidateQueries({queryKey:s.distill}),e.invalidateQueries({queryKey:s.all})}})}export{K as a,M as b,y as c,d,m as e,f,v as g,q as h,F as i,Q as j,s as m,c as u};
2
+ //# sourceMappingURL=use-memory-CXDwKCco.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-memory-Bz1Zao7g.js","sources":["../../src/hooks/use-memory.ts"],"sourcesContent":["/**\n * useMemory — react-query wrappers for the agent long-term memory.\n *\n * useMemoryUsers() — pick list of users that have\n * facts in the bank\n * useMemoryFacts(query) — pageable facts for one user\n * useDeleteFactById() — single-row delete\n * useBulkDeleteFacts() — multi / category / threshold\n *\n * No SSE channel; memory mutations are operator-driven and the\n * react-query 30s staleTime is enough. Mutations invalidate the\n * full ['memory'] tree so adjacent views (e.g. the user summary's\n * fact_count) stay in sync.\n */\n\nimport { useQueryClient, useQuery, useMutation } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport { ApiClientError } from '@/lib/api/client'\nimport type {\n ConsolidateMemoryResponse,\n ConsolidateStatusResponse,\n DistillStatusResponse,\n DistillTriggerResponse,\n DeleteMemoryFactsBody,\n DeleteMemoryFactsResponse,\n ListMemoryFactsQuery,\n ListMemoryFactsResponse,\n ListMemoryUsersResponse,\n OkResponse,\n Persona,\n UpdatePersonaBody,\n} from '@/types/api'\n\nexport const memoryKeys = {\n all: ['memory'] as const,\n users: ['memory', 'users'] as const,\n facts: (q: ListMemoryFactsQuery) => ['memory', 'facts', q] as const,\n persona: (user_key: string) => ['memory', 'persona', user_key] as const,\n consolidate: ['memory', 'consolidate'] as const,\n distill: ['memory', 'distill'] as const,\n}\n\nexport function useMemoryUsers() {\n return useQuery<ListMemoryUsersResponse>({\n queryKey: memoryKeys.users,\n queryFn: () => api.listMemoryUsers(),\n })\n}\n\nexport function useMemoryFacts(query: ListMemoryFactsQuery, opts: { enabled?: boolean } = {}) {\n return useQuery<ListMemoryFactsResponse>({\n queryKey: memoryKeys.facts(query),\n queryFn: () => api.listMemoryFacts(query),\n // Caller passes enabled=false until a user_key is chosen so the\n // hook doesn't fire with an empty key.\n enabled: opts.enabled !== false && Boolean(query.user_key),\n })\n}\n\nexport function useInvalidateMemory() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: memoryKeys.all })\n}\n\nexport function useDeleteFactById() {\n const qc = useQueryClient()\n return useMutation<\n OkResponse & { id: number },\n Error,\n { id: number; user_key: string }\n >({\n mutationFn: ({ id, user_key }) => api.deleteMemoryFactById(id, { user_key }),\n onSuccess: () => qc.invalidateQueries({ queryKey: memoryKeys.all }),\n })\n}\n\nexport function useBulkDeleteFacts() {\n const qc = useQueryClient()\n return useMutation<\n DeleteMemoryFactsResponse,\n Error,\n { user_key: string; body: DeleteMemoryFactsBody }\n >({\n mutationFn: ({ user_key, body }) => api.deleteMemoryFacts({ user_key }, body),\n onSuccess: () => qc.invalidateQueries({ queryKey: memoryKeys.all }),\n })\n}\n\n/* ─────────────── Persona ─────────────── */\n\n/** Fetch the persona for a user. The backend returns 404 when the\n * user has no persona yet — we map that to `data: null` so the\n * route can render the \"not set yet\" state without a try/catch. */\nexport function useMemoryPersona(user_key: string, opts: { enabled?: boolean } = {}) {\n return useQuery<Persona | null>({\n queryKey: memoryKeys.persona(user_key),\n queryFn: async () => {\n try {\n return await api.getMemoryPersona({ user_key })\n } catch (err) {\n if (err instanceof ApiClientError && err.status === 404) return null\n throw err\n }\n },\n enabled: opts.enabled !== false && Boolean(user_key),\n })\n}\n\nexport function useUpdatePersona() {\n const qc = useQueryClient()\n return useMutation<\n { ok: boolean },\n Error,\n { user_key: string; body: UpdatePersonaBody }\n >({\n mutationFn: ({ user_key, body }) => api.updateMemoryPersona({ user_key }, body),\n onSuccess: (_data, vars) => {\n qc.invalidateQueries({ queryKey: memoryKeys.persona(vars.user_key) })\n qc.invalidateQueries({ queryKey: memoryKeys.users })\n },\n })\n}\n\nexport function useDeletePersona() {\n const qc = useQueryClient()\n return useMutation<{ ok: boolean }, Error, string>({\n mutationFn: (user_key) => api.deleteMemoryPersona({ user_key }),\n onSuccess: (_data, user_key) => {\n qc.invalidateQueries({ queryKey: memoryKeys.persona(user_key) })\n qc.invalidateQueries({ queryKey: memoryKeys.users })\n },\n })\n}\n\n/* ─────────────── Consolidate ─────────────── */\n\n/** Status of the in-flight + recent consolidation jobs. Polls while\n * the page is open since consolidate runs asynchronously and we\n * want the operator to see when it completes without manual\n * refresh. */\nexport function useConsolidateStatus(opts: { enabled?: boolean } = {}) {\n return useQuery<ConsolidateStatusResponse>({\n queryKey: memoryKeys.consolidate,\n queryFn: () => api.getMemoryConsolidateStatus(),\n refetchInterval: 3000,\n refetchIntervalInBackground: false,\n enabled: opts.enabled !== false,\n })\n}\n\nexport function useTriggerConsolidate() {\n const qc = useQueryClient()\n return useMutation<ConsolidateMemoryResponse, Error, void>({\n mutationFn: () => api.consolidateMemory(),\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: memoryKeys.consolidate })\n qc.invalidateQueries({ queryKey: memoryKeys.all })\n },\n })\n}\n\n/* ─────────────── Distill (dream distillation) ─────────────── */\n\n/** Status of the background distiller: buffer depth + last-run telemetry.\n * Polls while the page is open so the operator watches a manual \"Run now\"\n * drain the buffer without manual refresh. */\nexport function useDistillStatus(opts: { enabled?: boolean } = {}) {\n return useQuery<DistillStatusResponse>({\n queryKey: memoryKeys.distill,\n queryFn: () => api.getMemoryDistillStatus(),\n refetchInterval: 3000,\n refetchIntervalInBackground: false,\n enabled: opts.enabled !== false,\n })\n}\n\nexport function useTriggerDistill() {\n const qc = useQueryClient()\n return useMutation<DistillTriggerResponse, Error, void>({\n mutationFn: () => api.triggerMemoryDistill(),\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: memoryKeys.distill })\n qc.invalidateQueries({ queryKey: memoryKeys.all })\n },\n })\n}\n"],"names":["memoryKeys","q","user_key","useMemoryUsers","useQuery","api","useMemoryFacts","query","opts","useDeleteFactById","qc","useQueryClient","useMutation","id","useBulkDeleteFacts","body","useMemoryPersona","err","ApiClientError","useUpdatePersona","_data","vars","useDeletePersona","useConsolidateStatus","useTriggerConsolidate","useDistillStatus","useTriggerDistill"],"mappings":"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"}
1
+ {"version":3,"file":"use-memory-CXDwKCco.js","sources":["../../src/hooks/use-memory.ts"],"sourcesContent":["/**\n * useMemory — react-query wrappers for the agent long-term memory.\n *\n * useMemoryUsers() — pick list of users that have\n * facts in the bank\n * useMemoryFacts(query) — pageable facts for one user\n * useDeleteFactById() — single-row delete\n * useBulkDeleteFacts() — multi / category / threshold\n *\n * No SSE channel; memory mutations are operator-driven and the\n * react-query 30s staleTime is enough. Mutations invalidate the\n * full ['memory'] tree so adjacent views (e.g. the user summary's\n * fact_count) stay in sync.\n */\n\nimport { useQueryClient, useQuery, useMutation } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport { ApiClientError } from '@/lib/api/client'\nimport type {\n ConsolidateMemoryResponse,\n ConsolidateStatusResponse,\n DistillStatusResponse,\n DistillTriggerResponse,\n DeleteMemoryFactsBody,\n DeleteMemoryFactsResponse,\n ListMemoryFactsQuery,\n ListMemoryFactsResponse,\n ListMemoryUsersResponse,\n OkResponse,\n Persona,\n UpdatePersonaBody,\n} from '@/types/api'\n\nexport const memoryKeys = {\n all: ['memory'] as const,\n users: ['memory', 'users'] as const,\n facts: (q: ListMemoryFactsQuery) => ['memory', 'facts', q] as const,\n persona: (user_key: string) => ['memory', 'persona', user_key] as const,\n consolidate: ['memory', 'consolidate'] as const,\n distill: ['memory', 'distill'] as const,\n}\n\nexport function useMemoryUsers() {\n return useQuery<ListMemoryUsersResponse>({\n queryKey: memoryKeys.users,\n queryFn: () => api.listMemoryUsers(),\n })\n}\n\nexport function useMemoryFacts(query: ListMemoryFactsQuery, opts: { enabled?: boolean } = {}) {\n return useQuery<ListMemoryFactsResponse>({\n queryKey: memoryKeys.facts(query),\n queryFn: () => api.listMemoryFacts(query),\n // Caller passes enabled=false until a user_key is chosen so the\n // hook doesn't fire with an empty key.\n enabled: opts.enabled !== false && Boolean(query.user_key),\n })\n}\n\nexport function useInvalidateMemory() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: memoryKeys.all })\n}\n\nexport function useDeleteFactById() {\n const qc = useQueryClient()\n return useMutation<\n OkResponse & { id: number },\n Error,\n { id: number; user_key: string }\n >({\n mutationFn: ({ id, user_key }) => api.deleteMemoryFactById(id, { user_key }),\n onSuccess: () => qc.invalidateQueries({ queryKey: memoryKeys.all }),\n })\n}\n\nexport function useBulkDeleteFacts() {\n const qc = useQueryClient()\n return useMutation<\n DeleteMemoryFactsResponse,\n Error,\n { user_key: string; body: DeleteMemoryFactsBody }\n >({\n mutationFn: ({ user_key, body }) => api.deleteMemoryFacts({ user_key }, body),\n onSuccess: () => qc.invalidateQueries({ queryKey: memoryKeys.all }),\n })\n}\n\n/* ─────────────── Persona ─────────────── */\n\n/** Fetch the persona for a user. The backend returns 404 when the\n * user has no persona yet — we map that to `data: null` so the\n * route can render the \"not set yet\" state without a try/catch. */\nexport function useMemoryPersona(user_key: string, opts: { enabled?: boolean } = {}) {\n return useQuery<Persona | null>({\n queryKey: memoryKeys.persona(user_key),\n queryFn: async () => {\n try {\n return await api.getMemoryPersona({ user_key })\n } catch (err) {\n if (err instanceof ApiClientError && err.status === 404) return null\n throw err\n }\n },\n enabled: opts.enabled !== false && Boolean(user_key),\n })\n}\n\nexport function useUpdatePersona() {\n const qc = useQueryClient()\n return useMutation<\n { ok: boolean },\n Error,\n { user_key: string; body: UpdatePersonaBody }\n >({\n mutationFn: ({ user_key, body }) => api.updateMemoryPersona({ user_key }, body),\n onSuccess: (_data, vars) => {\n qc.invalidateQueries({ queryKey: memoryKeys.persona(vars.user_key) })\n qc.invalidateQueries({ queryKey: memoryKeys.users })\n },\n })\n}\n\nexport function useDeletePersona() {\n const qc = useQueryClient()\n return useMutation<{ ok: boolean }, Error, string>({\n mutationFn: (user_key) => api.deleteMemoryPersona({ user_key }),\n onSuccess: (_data, user_key) => {\n qc.invalidateQueries({ queryKey: memoryKeys.persona(user_key) })\n qc.invalidateQueries({ queryKey: memoryKeys.users })\n },\n })\n}\n\n/* ─────────────── Consolidate ─────────────── */\n\n/** Status of the in-flight + recent consolidation jobs. Polls while\n * the page is open since consolidate runs asynchronously and we\n * want the operator to see when it completes without manual\n * refresh. */\nexport function useConsolidateStatus(opts: { enabled?: boolean } = {}) {\n return useQuery<ConsolidateStatusResponse>({\n queryKey: memoryKeys.consolidate,\n queryFn: () => api.getMemoryConsolidateStatus(),\n refetchInterval: 3000,\n refetchIntervalInBackground: false,\n enabled: opts.enabled !== false,\n })\n}\n\nexport function useTriggerConsolidate() {\n const qc = useQueryClient()\n return useMutation<ConsolidateMemoryResponse, Error, void>({\n mutationFn: () => api.consolidateMemory(),\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: memoryKeys.consolidate })\n qc.invalidateQueries({ queryKey: memoryKeys.all })\n },\n })\n}\n\n/* ─────────────── Distill (dream distillation) ─────────────── */\n\n/** Status of the background distiller: buffer depth + last-run telemetry.\n * Polls while the page is open so the operator watches a manual \"Run now\"\n * drain the buffer without manual refresh. */\nexport function useDistillStatus(opts: { enabled?: boolean } = {}) {\n return useQuery<DistillStatusResponse>({\n queryKey: memoryKeys.distill,\n queryFn: () => api.getMemoryDistillStatus(),\n refetchInterval: 3000,\n refetchIntervalInBackground: false,\n enabled: opts.enabled !== false,\n })\n}\n\nexport function useTriggerDistill() {\n const qc = useQueryClient()\n return useMutation<DistillTriggerResponse, Error, void>({\n mutationFn: () => api.triggerMemoryDistill(),\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: memoryKeys.distill })\n qc.invalidateQueries({ queryKey: memoryKeys.all })\n },\n })\n}\n"],"names":["memoryKeys","q","user_key","useMemoryUsers","useQuery","api","useMemoryFacts","query","opts","useDeleteFactById","qc","useQueryClient","useMutation","id","useBulkDeleteFacts","body","useMemoryPersona","err","ApiClientError","useUpdatePersona","_data","vars","useDeletePersona","useConsolidateStatus","useTriggerConsolidate","useDistillStatus","useTriggerDistill"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{r as a,s as n}from"./index-DCfdN5R7.js";const i={all:["observability"],health:e=>["observability","health",e],topN:(e,t,r,u)=>["observability","topn",e,t,r,u],audit:e=>["observability","audit",e]};function y(e){return a({queryKey:i.health(e),queryFn:()=>n.getHealthSummary({days:e}),refetchInterval:3e4,refetchIntervalInBackground:!1})}function s(e){const t=e.days??7,r=e.limit??10;return a({queryKey:i.topN(e.dim,e.by,t,r),queryFn:()=>n.getHealthTopN({dim:e.dim,by:e.by,days:t,limit:r}),refetchInterval:6e4,refetchIntervalInBackground:!1})}function o(e){return a({queryKey:i.audit(e),queryFn:()=>n.getAudit(e),refetchInterval:1e4,refetchIntervalInBackground:!1})}export{s as a,o as b,y as u};
2
+ //# sourceMappingURL=use-observability-CY5ZUPrC.js.map