agim-cli 1.3.2 → 1.3.3

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 (236) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/cli-ui/i18n.d.ts +2 -2
  3. package/dist/cli-ui/i18n.js +4 -4
  4. package/dist/cli-ui/i18n.js.map +1 -1
  5. package/dist/cli-ui/setup-llm.js +1 -1
  6. package/dist/cli-ui/setup-llm.js.map +1 -1
  7. package/dist/cli-ui/tui/app.d.ts +4 -1
  8. package/dist/cli-ui/tui/app.d.ts.map +1 -1
  9. package/dist/cli-ui/tui/app.js +229 -6
  10. package/dist/cli-ui/tui/app.js.map +1 -1
  11. package/dist/cli-ui/tui/approval-bridge.d.ts +61 -0
  12. package/dist/cli-ui/tui/approval-bridge.d.ts.map +1 -0
  13. package/dist/cli-ui/tui/approval-bridge.js +274 -0
  14. package/dist/cli-ui/tui/approval-bridge.js.map +1 -0
  15. package/dist/cli-ui/tui/index.d.ts.map +1 -1
  16. package/dist/cli-ui/tui/index.js +31 -0
  17. package/dist/cli-ui/tui/index.js.map +1 -1
  18. package/dist/core/agent-cwd.js +1 -1
  19. package/dist/core/ask-user-rpc.d.ts +36 -14
  20. package/dist/core/ask-user-rpc.d.ts.map +1 -1
  21. package/dist/core/ask-user-rpc.js +309 -34
  22. package/dist/core/ask-user-rpc.js.map +1 -1
  23. package/dist/core/commands/builtin.d.ts.map +1 -1
  24. package/dist/core/commands/builtin.js +15 -6
  25. package/dist/core/commands/builtin.js.map +1 -1
  26. package/dist/core/llm/imhub-dispatcher.d.ts.map +1 -1
  27. package/dist/core/llm/imhub-dispatcher.js +6 -1
  28. package/dist/core/llm/imhub-dispatcher.js.map +1 -1
  29. package/dist/core/onboarding.js +2 -2
  30. package/dist/core/onboarding.js.map +1 -1
  31. package/dist/core/router.d.ts.map +1 -1
  32. package/dist/core/router.js +12 -9
  33. package/dist/core/router.js.map +1 -1
  34. package/dist/core/types.d.ts +6 -0
  35. package/dist/core/types.d.ts.map +1 -1
  36. package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts +4 -0
  37. package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts.map +1 -1
  38. package/dist/plugins/agents/claude-code/mcp-approval-server.js +11 -6
  39. package/dist/plugins/agents/claude-code/mcp-approval-server.js.map +1 -1
  40. package/dist/plugins/agents/native/index.js +8 -8
  41. package/dist/plugins/agents/native/index.js.map +1 -1
  42. package/dist/plugins/agents/pi-native/factory.d.ts.map +1 -1
  43. package/dist/plugins/agents/pi-native/factory.js +4 -3
  44. package/dist/plugins/agents/pi-native/factory.js.map +1 -1
  45. package/dist/web/llm-api.js +7 -4
  46. package/dist/web/llm-api.js.map +1 -1
  47. package/dist/web/public/assets/{a2a-Dtc6AKjx.js → a2a-Y30Sn8pc.js} +2 -2
  48. package/dist/web/public/assets/{a2a-Dtc6AKjx.js.map → a2a-Y30Sn8pc.js.map} +1 -1
  49. package/dist/web/public/assets/{activity-CWFI_ke7.js → activity--oN7qxFJ.js} +2 -2
  50. package/dist/web/public/assets/{activity-CWFI_ke7.js.map → activity--oN7qxFJ.js.map} +1 -1
  51. package/dist/web/public/assets/{admins-CeQorJdU.js → admins-DONiT3ld.js} +2 -2
  52. package/dist/web/public/assets/{admins-CeQorJdU.js.map → admins-DONiT3ld.js.map} +1 -1
  53. package/dist/web/public/assets/agents-DRbQOH0K.js +7 -0
  54. package/dist/web/public/assets/agents-DRbQOH0K.js.map +1 -0
  55. package/dist/web/public/assets/{approvals-BEPKSyrL.js → approvals-C5jd7Wf9.js} +2 -2
  56. package/dist/web/public/assets/{approvals-BEPKSyrL.js.map → approvals-C5jd7Wf9.js.map} +1 -1
  57. package/dist/web/public/assets/{arrow-down-CzWGZc48.js → arrow-down-x-Lq92tn.js} +2 -2
  58. package/dist/web/public/assets/{arrow-down-CzWGZc48.js.map → arrow-down-x-Lq92tn.js.map} +1 -1
  59. package/dist/web/public/assets/{arrow-up-CXy94NPi.js → arrow-up-Cc28qbjN.js} +2 -2
  60. package/dist/web/public/assets/{arrow-up-CXy94NPi.js.map → arrow-up-Cc28qbjN.js.map} +1 -1
  61. package/dist/web/public/assets/{asks-BszsbhPn.js → asks-CeVcu8SD.js} +2 -2
  62. package/dist/web/public/assets/{asks-BszsbhPn.js.map → asks-CeVcu8SD.js.map} +1 -1
  63. package/dist/web/public/assets/{audit-ACrwMizd.js → audit-Dc9_FDkW.js} +2 -2
  64. package/dist/web/public/assets/{audit-ACrwMizd.js.map → audit-Dc9_FDkW.js.map} +1 -1
  65. package/dist/web/public/assets/{bell-BLwNOhXO.js → bell-CxPf_Xzs.js} +2 -2
  66. package/dist/web/public/assets/{bell-BLwNOhXO.js.map → bell-CxPf_Xzs.js.map} +1 -1
  67. package/dist/web/public/assets/{bgjobs-Cwp0PmTF.js → bgjobs-CYjmAJgs.js} +2 -2
  68. package/dist/web/public/assets/{bgjobs-Cwp0PmTF.js.map → bgjobs-CYjmAJgs.js.map} +1 -1
  69. package/dist/web/public/assets/{brain-5AJBYzXX.js → brain-DjCfwBAT.js} +2 -2
  70. package/dist/web/public/assets/{brain-5AJBYzXX.js.map → brain-DjCfwBAT.js.map} +1 -1
  71. package/dist/web/public/assets/{briefcase-BTDurkZz.js → briefcase-Br1bd_VG.js} +2 -2
  72. package/dist/web/public/assets/{briefcase-BTDurkZz.js.map → briefcase-Br1bd_VG.js.map} +1 -1
  73. package/dist/web/public/assets/chat-uqxuXn2X.js +17 -0
  74. package/dist/web/public/assets/chat-uqxuXn2X.js.map +1 -0
  75. package/dist/web/public/assets/{chevron-left-CnLOhWHE.js → chevron-left-CN-4SIfi.js} +2 -2
  76. package/dist/web/public/assets/{chevron-left-CnLOhWHE.js.map → chevron-left-CN-4SIfi.js.map} +1 -1
  77. package/dist/web/public/assets/{chevron-right-CpWYrqTa.js → chevron-right-BhSTLH2K.js} +2 -2
  78. package/dist/web/public/assets/{chevron-right-CpWYrqTa.js.map → chevron-right-BhSTLH2K.js.map} +1 -1
  79. package/dist/web/public/assets/{circle-check-DhcTh_uP.js → circle-check-B4UdHmdJ.js} +2 -2
  80. package/dist/web/public/assets/{circle-check-DhcTh_uP.js.map → circle-check-B4UdHmdJ.js.map} +1 -1
  81. package/dist/web/public/assets/{circle-check-big-CcknUEHz.js → circle-check-big-CvXnDqiF.js} +2 -2
  82. package/dist/web/public/assets/{circle-check-big-CcknUEHz.js.map → circle-check-big-CvXnDqiF.js.map} +1 -1
  83. package/dist/web/public/assets/{circle-x-QODE2UcL.js → circle-x-B8y8mLHr.js} +2 -2
  84. package/dist/web/public/assets/{circle-x-QODE2UcL.js.map → circle-x-B8y8mLHr.js.map} +1 -1
  85. package/dist/web/public/assets/{clock-BPBx4QWT.js → clock-CK2KO_Rc.js} +2 -2
  86. package/dist/web/public/assets/{clock-BPBx4QWT.js.map → clock-CK2KO_Rc.js.map} +1 -1
  87. package/dist/web/public/assets/{confirm-dialog-HsyBgWxC.js → confirm-dialog-GZyIzSwj.js} +2 -2
  88. package/dist/web/public/assets/{confirm-dialog-HsyBgWxC.js.map → confirm-dialog-GZyIzSwj.js.map} +1 -1
  89. package/dist/web/public/assets/{copy-VJNELMp7.js → copy-CDCgL5Yq.js} +2 -2
  90. package/dist/web/public/assets/{copy-VJNELMp7.js.map → copy-CDCgL5Yq.js.map} +1 -1
  91. package/dist/web/public/assets/{data-table-C0yaCeSS.js → data-table-1cGunUIX.js} +2 -2
  92. package/dist/web/public/assets/{data-table-C0yaCeSS.js.map → data-table-1cGunUIX.js.map} +1 -1
  93. package/dist/web/public/assets/{download-EUh-RXv5.js → download-CuLP0G-q.js} +2 -2
  94. package/dist/web/public/assets/{download-EUh-RXv5.js.map → download-CuLP0G-q.js.map} +1 -1
  95. package/dist/web/public/assets/{email-YUzrp4Tf.js → email-Q-SY9qC9.js} +2 -2
  96. package/dist/web/public/assets/{email-YUzrp4Tf.js.map → email-Q-SY9qC9.js.map} +1 -1
  97. package/dist/web/public/assets/{empty-state-DoiBKL4l.js → empty-state-BRsb30K6.js} +2 -2
  98. package/dist/web/public/assets/{empty-state-DoiBKL4l.js.map → empty-state-BRsb30K6.js.map} +1 -1
  99. package/dist/web/public/assets/{external-link-Bf2430Ji.js → external-link-D-E90Kfw.js} +2 -2
  100. package/dist/web/public/assets/{external-link-Bf2430Ji.js.map → external-link-D-E90Kfw.js.map} +1 -1
  101. package/dist/web/public/assets/{eye-vE4k-Us-.js → eye-DSu_4mW2.js} +2 -2
  102. package/dist/web/public/assets/{eye-vE4k-Us-.js.map → eye-DSu_4mW2.js.map} +1 -1
  103. package/dist/web/public/assets/{facts-BPVTGzM4.js → facts-pmGTfGmv.js} +2 -2
  104. package/dist/web/public/assets/{facts-BPVTGzM4.js.map → facts-pmGTfGmv.js.map} +1 -1
  105. package/dist/web/public/assets/goals-DpRm9-av.js +17 -0
  106. package/dist/web/public/assets/goals-DpRm9-av.js.map +1 -0
  107. package/dist/web/public/assets/{health-CSMAArAj.js → health-mqoH7KDV.js} +2 -2
  108. package/dist/web/public/assets/{health-CSMAArAj.js.map → health-mqoH7KDV.js.map} +1 -1
  109. package/dist/web/public/assets/{heart-pulse-8RDC8GWv.js → heart-pulse-CrCHhXtC.js} +2 -2
  110. package/dist/web/public/assets/{heart-pulse-8RDC8GWv.js.map → heart-pulse-CrCHhXtC.js.map} +1 -1
  111. package/dist/web/public/assets/{heartbeat-BzHZy7Mx.js → heartbeat-EGjLHWU0.js} +2 -2
  112. package/dist/web/public/assets/{heartbeat-BzHZy7Mx.js.map → heartbeat-EGjLHWU0.js.map} +1 -1
  113. package/dist/web/public/assets/hot-B9x1_5yx.js +12 -0
  114. package/dist/web/public/assets/hot-B9x1_5yx.js.map +1 -0
  115. package/dist/web/public/assets/index-BIBWEKxu.js +204 -0
  116. package/dist/web/public/assets/index-BIBWEKxu.js.map +1 -0
  117. package/dist/web/public/assets/{injection-a2kkgRbT.js → injection-CDx5n-mk.js} +2 -2
  118. package/dist/web/public/assets/{injection-a2kkgRbT.js.map → injection-CDx5n-mk.js.map} +1 -1
  119. package/dist/web/public/assets/{installed-XQQEPKh8.js → installed-DV7X4wfv.js} +5 -5
  120. package/dist/web/public/assets/{installed-XQQEPKh8.js.map → installed-DV7X4wfv.js.map} +1 -1
  121. package/dist/web/public/assets/{jobs-Cby1Eq4o.js → jobs-zAigElCl.js} +2 -2
  122. package/dist/web/public/assets/{jobs-Cby1Eq4o.js.map → jobs-zAigElCl.js.map} +1 -1
  123. package/dist/web/public/assets/{layout-BdtJtlu5.js → layout-7wcifbsm.js} +2 -2
  124. package/dist/web/public/assets/{layout-BdtJtlu5.js.map → layout-7wcifbsm.js.map} +1 -1
  125. package/dist/web/public/assets/{layout-BRnEPnky.js → layout-B0RjH6M2.js} +2 -2
  126. package/dist/web/public/assets/{layout-BRnEPnky.js.map → layout-B0RjH6M2.js.map} +1 -1
  127. package/dist/web/public/assets/{layout-Gh29ouFO.js → layout-C6q-GbBZ.js} +2 -2
  128. package/dist/web/public/assets/{layout-Gh29ouFO.js.map → layout-C6q-GbBZ.js.map} +1 -1
  129. package/dist/web/public/assets/layout-CzjqlPxW.js +2 -0
  130. package/dist/web/public/assets/layout-CzjqlPxW.js.map +1 -0
  131. package/dist/web/public/assets/{layout-CbqldDRj.js → layout-DOSpVfND.js} +2 -2
  132. package/dist/web/public/assets/{layout-CbqldDRj.js.map → layout-DOSpVfND.js.map} +1 -1
  133. package/dist/web/public/assets/llm-DwZX5fwY.js +27 -0
  134. package/dist/web/public/assets/llm-DwZX5fwY.js.map +1 -0
  135. package/dist/web/public/assets/{loader-circle-DO3Ni2RJ.js → loader-circle-BQkLEJZw.js} +2 -2
  136. package/dist/web/public/assets/{loader-circle-DO3Ni2RJ.js.map → loader-circle-BQkLEJZw.js.map} +1 -1
  137. package/dist/web/public/assets/{map-pin-BsL35E1s.js → map-pin-B-IMY07m.js} +2 -2
  138. package/dist/web/public/assets/{map-pin-BsL35E1s.js.map → map-pin-B-IMY07m.js.map} +1 -1
  139. package/dist/web/public/assets/{mcp-CWMdxcBf.js → mcp-K0P3-b6q.js} +2 -2
  140. package/dist/web/public/assets/{mcp-CWMdxcBf.js.map → mcp-K0P3-b6q.js.map} +1 -1
  141. package/dist/web/public/assets/{memos-BYQa4d2t.js → memos-DcpDEVN8.js} +2 -2
  142. package/dist/web/public/assets/{memos-BYQa4d2t.js.map → memos-DcpDEVN8.js.map} +1 -1
  143. package/dist/web/public/assets/{messengers-CebazAJ1.js → messengers-DmrNvPMS.js} +2 -2
  144. package/dist/web/public/assets/{messengers-CebazAJ1.js.map → messengers-DmrNvPMS.js.map} +1 -1
  145. package/dist/web/public/assets/{mobile-CMJRNHs2.js → mobile-a-oUiAoR.js} +2 -2
  146. package/dist/web/public/assets/{mobile-CMJRNHs2.js.map → mobile-a-oUiAoR.js.map} +1 -1
  147. package/dist/web/public/assets/{network-pNcx_slv.js → network-Bbh3j5ew.js} +2 -2
  148. package/dist/web/public/assets/{network-pNcx_slv.js.map → network-Bbh3j5ew.js.map} +1 -1
  149. package/dist/web/public/assets/{outbox-87hzZQLn.js → outbox-BP_hfANb.js} +2 -2
  150. package/dist/web/public/assets/{outbox-87hzZQLn.js.map → outbox-BP_hfANb.js.map} +1 -1
  151. package/dist/web/public/assets/{pagination-C4edFAqf.js → pagination-CPLj3V0r.js} +2 -2
  152. package/dist/web/public/assets/{pagination-C4edFAqf.js.map → pagination-CPLj3V0r.js.map} +1 -1
  153. package/dist/web/public/assets/{persona-BcOT3Wms.js → persona-CT38dLd4.js} +2 -2
  154. package/dist/web/public/assets/{persona-BcOT3Wms.js.map → persona-CT38dLd4.js.map} +1 -1
  155. package/dist/web/public/assets/plans-Msw85XkI.js +12 -0
  156. package/dist/web/public/assets/plans-Msw85XkI.js.map +1 -0
  157. package/dist/web/public/assets/{play-Bzdymasn.js → play-tH2nb1Kt.js} +2 -2
  158. package/dist/web/public/assets/{play-Bzdymasn.js.map → play-tH2nb1Kt.js.map} +1 -1
  159. package/dist/web/public/assets/{plus-BxjzY9Wh.js → plus-6MNGQidu.js} +2 -2
  160. package/dist/web/public/assets/{plus-BxjzY9Wh.js.map → plus-6MNGQidu.js.map} +1 -1
  161. package/dist/web/public/assets/{policy-Be-tMZZc.js → policy-BJ7zORVG.js} +2 -2
  162. package/dist/web/public/assets/{policy-Be-tMZZc.js.map → policy-BJ7zORVG.js.map} +1 -1
  163. package/dist/web/public/assets/{qr-code-D1V5cA_X.js → qr-code-DfsxFxoa.js} +2 -2
  164. package/dist/web/public/assets/{qr-code-D1V5cA_X.js.map → qr-code-DfsxFxoa.js.map} +1 -1
  165. package/dist/web/public/assets/{refresh-ccw-BhPAzZAa.js → refresh-ccw-CFPE6zD1.js} +2 -2
  166. package/dist/web/public/assets/{refresh-ccw-BhPAzZAa.js.map → refresh-ccw-CFPE6zD1.js.map} +1 -1
  167. package/dist/web/public/assets/{reminders-DEWtrlH_.js → reminders-CAUNAuDy.js} +2 -2
  168. package/dist/web/public/assets/{reminders-DEWtrlH_.js.map → reminders-CAUNAuDy.js.map} +1 -1
  169. package/dist/web/public/assets/{save-Cye8Vlu5.js → save-CNUmUMEf.js} +2 -2
  170. package/dist/web/public/assets/{save-Cye8Vlu5.js.map → save-CNUmUMEf.js.map} +1 -1
  171. package/dist/web/public/assets/{schedules-CuqRy3t8.js → schedules-C25NyoGh.js} +2 -2
  172. package/dist/web/public/assets/{schedules-CuqRy3t8.js.map → schedules-C25NyoGh.js.map} +1 -1
  173. package/dist/web/public/assets/{search-Dot_W5Eu.js → search-CaRTqZw1.js} +2 -2
  174. package/dist/web/public/assets/{search-Dot_W5Eu.js.map → search-CaRTqZw1.js.map} +1 -1
  175. package/dist/web/public/assets/{search-BQqVArrW.js → search-D9TZs0bG.js} +2 -2
  176. package/dist/web/public/assets/{search-BQqVArrW.js.map → search-D9TZs0bG.js.map} +1 -1
  177. package/dist/web/public/assets/{security-BB-YnetQ.js → security-BMGGzEwr.js} +2 -2
  178. package/dist/web/public/assets/{security-BB-YnetQ.js.map → security-BMGGzEwr.js.map} +1 -1
  179. package/dist/web/public/assets/{service-DgkqlAtM.js → service-BQBoddcT.js} +2 -2
  180. package/dist/web/public/assets/{service-DgkqlAtM.js.map → service-BQBoddcT.js.map} +1 -1
  181. package/dist/web/public/assets/{shield-alert-CBOmgn9W.js → shield-alert-eOBoc2yc.js} +2 -2
  182. package/dist/web/public/assets/{shield-alert-CBOmgn9W.js.map → shield-alert-eOBoc2yc.js.map} +1 -1
  183. package/dist/web/public/assets/{status-badge-9sMFH4uP.js → status-badge-CF1Cya26.js} +2 -2
  184. package/dist/web/public/assets/{status-badge-9sMFH4uP.js.map → status-badge-CF1Cya26.js.map} +1 -1
  185. package/dist/web/public/assets/{subtasks-BrqdQxw_.js → subtasks-CEPB2TSV.js} +2 -2
  186. package/dist/web/public/assets/{subtasks-BrqdQxw_.js.map → subtasks-CEPB2TSV.js.map} +1 -1
  187. package/dist/web/public/assets/{table-CSHCu7pz.js → table-Dww-k14l.js} +2 -2
  188. package/dist/web/public/assets/{table-CSHCu7pz.js.map → table-Dww-k14l.js.map} +1 -1
  189. package/dist/web/public/assets/{topn-DZWbwDge.js → topn-DwgKlIxc.js} +2 -2
  190. package/dist/web/public/assets/{topn-DZWbwDge.js.map → topn-DwgKlIxc.js.map} +1 -1
  191. package/dist/web/public/assets/{trash-2-Cco09tAA.js → trash-2-BF98SY8M.js} +2 -2
  192. package/dist/web/public/assets/{trash-2-Cco09tAA.js.map → trash-2-BF98SY8M.js.map} +1 -1
  193. package/dist/web/public/assets/{use-agim-skills-CJOJKeOZ.js → use-agim-skills-kDpiSMBP.js} +2 -2
  194. package/dist/web/public/assets/{use-agim-skills-CJOJKeOZ.js.map → use-agim-skills-kDpiSMBP.js.map} +1 -1
  195. package/dist/web/public/assets/{use-background-tasks-D77bcfrq.js → use-background-tasks-B1Pxq3JU.js} +2 -2
  196. package/dist/web/public/assets/{use-background-tasks-D77bcfrq.js.map → use-background-tasks-B1Pxq3JU.js.map} +1 -1
  197. package/dist/web/public/assets/{use-memory-CX4B1SYC.js → use-memory-w-EY79Zm.js} +2 -2
  198. package/dist/web/public/assets/{use-memory-CX4B1SYC.js.map → use-memory-w-EY79Zm.js.map} +1 -1
  199. package/dist/web/public/assets/{use-observability-rcc7fRmj.js → use-observability-Cd2dUHb7.js} +2 -2
  200. package/dist/web/public/assets/{use-observability-rcc7fRmj.js.map → use-observability-Cd2dUHb7.js.map} +1 -1
  201. package/dist/web/public/assets/{use-settings-DQnJkPXp.js → use-settings-DG1rm9KU.js} +2 -2
  202. package/dist/web/public/assets/{use-settings-DQnJkPXp.js.map → use-settings-DG1rm9KU.js.map} +1 -1
  203. package/dist/web/public/assets/{use-workspace-J5eeVxw9.js → use-workspace-DvW_xOmj.js} +2 -2
  204. package/dist/web/public/assets/{use-workspace-J5eeVxw9.js.map → use-workspace-DvW_xOmj.js.map} +1 -1
  205. package/dist/web/public/assets/{vector-xRphJ8hW.js → vector-CDJ4p6UI.js} +2 -2
  206. package/dist/web/public/assets/{vector-xRphJ8hW.js.map → vector-CDJ4p6UI.js.map} +1 -1
  207. package/dist/web/public/assets/{viewer-Bq7l2kE8.js → viewer-Bje5-HtQ.js} +2 -2
  208. package/dist/web/public/assets/{viewer-Bq7l2kE8.js.map → viewer-Bje5-HtQ.js.map} +1 -1
  209. package/dist/web/public/assets/workspace-B7QYGLix.js +17 -0
  210. package/dist/web/public/assets/workspace-B7QYGLix.js.map +1 -0
  211. package/dist/web/public/assets/{workspaces-D0pYJfxI.js → workspaces-BlodF0DP.js} +2 -2
  212. package/dist/web/public/assets/{workspaces-D0pYJfxI.js.map → workspaces-BlodF0DP.js.map} +1 -1
  213. package/dist/web/public/index.html +2 -2
  214. package/dist/web/server.js +2 -2
  215. package/dist/web/server.js.map +1 -1
  216. package/package.json +1 -1
  217. package/dist/web/public/assets/agents-DnJruPrS.js +0 -7
  218. package/dist/web/public/assets/agents-DnJruPrS.js.map +0 -1
  219. package/dist/web/public/assets/chat-D7jjr-Rn.js +0 -17
  220. package/dist/web/public/assets/chat-D7jjr-Rn.js.map +0 -1
  221. package/dist/web/public/assets/goals-HsKzf-PG.js +0 -17
  222. package/dist/web/public/assets/goals-HsKzf-PG.js.map +0 -1
  223. package/dist/web/public/assets/hot-DkFvD3H4.js +0 -12
  224. package/dist/web/public/assets/hot-DkFvD3H4.js.map +0 -1
  225. package/dist/web/public/assets/index-D7BuMEIr.js +0 -204
  226. package/dist/web/public/assets/index-D7BuMEIr.js.map +0 -1
  227. package/dist/web/public/assets/layout-0rDvqHCV.js +0 -2
  228. package/dist/web/public/assets/layout-0rDvqHCV.js.map +0 -1
  229. package/dist/web/public/assets/llm-COWnMdB9.js +0 -7
  230. package/dist/web/public/assets/llm-COWnMdB9.js.map +0 -1
  231. package/dist/web/public/assets/native-agent-MGgMeTHN.js +0 -22
  232. package/dist/web/public/assets/native-agent-MGgMeTHN.js.map +0 -1
  233. package/dist/web/public/assets/plans-Ddz5qwqp.js +0 -12
  234. package/dist/web/public/assets/plans-Ddz5qwqp.js.map +0 -1
  235. package/dist/web/public/assets/workspace-BqMuxPFF.js +0 -17
  236. package/dist/web/public/assets/workspace-BqMuxPFF.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agim-cli",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "Agim (阿吉姆) — universal messenger-to-agent bridge. Connect WeChat / Feishu / DingTalk / Email to Claude Code / Codex / OpenCode, or any custom agent via ACP. Installs the `agim` command.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,7 +0,0 @@
1
- import{o as le,u as L,j as e,B as k,L as V,S as Z,g as X,h as Y,i as J,k as O,l as R,X as re,m as f,n as F,c as K,I as _}from"./index-D7BuMEIr.js";import{r as h}from"./react-DlP5eolq.js";import{E as oe}from"./empty-state-DoiBKL4l.js";import{u as de}from"./use-workspace-J5eeVxw9.js";import{b as me,c as xe,h as ue,i as pe}from"./use-settings-DQnJkPXp.js";import{L as D}from"./loader-circle-DO3Ni2RJ.js";import{R as he}from"./refresh-ccw-BhPAzZAa.js";import{S as ge}from"./save-Cye8Vlu5.js";import{N as G}from"./network-pNcx_slv.js";import{S as I}from"./search-BQqVArrW.js";import{P as fe}from"./plus-BxjzY9Wh.js";import{T as je}from"./trash-2-Cco09tAA.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 be=le("Bot",[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]]),$={"claude-code":{aliases:["cc","claude"],pkg:"@anthropic-ai/claude-code",kind:"cli"},codex:{aliases:["cx"],pkg:"@openai/codex",kind:"cli"},opencode:{aliases:["oc"],pkg:"opencode-ai",kind:"cli"},cursor:{aliases:["cs","cur"],pkg:"cursor-agent (curl https://cursor.com/install)",kind:"cli"},native:{aliases:["na","llm","native-llm"],pkg:"in-process",kind:"in-process"}},Q=Object.keys($);function Ie(){const{t}=L(["settings","common"]),r=me(),s=de(),i=xe(),n=r.data,d=s.data??{},[p,o]=h.useState(null),[m,x]=h.useState(null),[S,j]=h.useState(null);h.useEffect(()=>{n&&p==null&&o(n.agents??[]),n&&m==null&&x(n.defaultAgent??""),n&&S==null&&j(n.acpAgents??[])},[n,p,m,S]);const g=p??n?.agents??[],b=m??n?.defaultAgent??"",w=S??n?.acpAgents??[],U=h.useMemo(()=>{if(!n)return!1;const c=g.length===(n.agents?.length??0)&&g.every(y=>n.agents?.includes(y)),N=b===(n.defaultAgent??""),v=ye(w,n.acpAgents??[]);return!c||!N||!v},[n,g,b,w]),T=h.useMemo(()=>Q.filter(c=>($[c].kind==="in-process"?!0:g.includes(c))&&d[c]),[g,d]);function P(c,N){const v=N?Array.from(new Set([...g,c])):g.filter(y=>y!==c);o(v),!N&&c===b&&x("")}async function M(){if(n)try{await i.mutateAsync({...n,agents:g,defaultAgent:b||n.defaultAgent,acpAgents:w}),f.success(t("agents.toast.saved")),o(null),x(null),j(null)}catch(c){f.error(F(c,t).message)}}function C(){o(null),x(null),j(null)}function z(c){j(c)}return e.jsxs("div",{className:"mx-auto flex max-w-4xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:t("agents.title")}),e.jsxs(k,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>{r.refetch(),s.refetch()},disabled:r.isFetching||s.isFetching,"aria-label":t("actions.refresh",{ns:"common"}),children:[r.isFetching||s.isFetching?e.jsx(D,{className:"h-4 w-4 animate-spin"}):e.jsx(he,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:t("actions.refresh",{ns:"common"})})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:t("agents.subtitle")})]}),r.isLoading?e.jsx("div",{className:"h-64 rounded-md bg-surface-2 animate-pulse"}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"flex flex-col divide-y divide-border rounded-md border border-border bg-surface",children:Q.map(c=>{const N=$[c],v=!!d[c],y=g.includes(c);return e.jsx(Ne,{name:c,aliases:N.aliases,pkg:N.pkg,kind:N.kind,installed:v,enabled:y,onToggle:H=>P(c,H)},c)})}),e.jsxs("section",{className:"rounded-md border border-border bg-surface p-4",children:[e.jsx(V,{htmlFor:"default-agent",className:"text-sm font-medium",children:t("agents.defaultAgent")}),e.jsx("p",{className:"mt-1 text-xs text-text-dim",children:t("agents.defaultAgentHint")}),e.jsxs(Z,{value:b||"__none__",onValueChange:c=>x(c==="__none__"?"":c),disabled:T.length===0,children:[e.jsx(X,{id:"default-agent",className:"mt-2 w-64",children:e.jsx(Y,{placeholder:t("agents.noEligible")})}),e.jsx(J,{children:T.length===0?e.jsx(O,{value:"__none__",disabled:!0,children:t("agents.noEligible")}):T.map(c=>e.jsx(O,{value:c,children:c},c))})]})]}),n?.features?.remoteAgent?e.jsx(we,{agents:w,onChange:z}):null,U&&e.jsxs("div",{className:"sticky bottom-0 flex items-center gap-2 rounded-md border border-border bg-surface px-4 py-2 shadow-md",children:[e.jsx(R,{variant:"info",children:t("agents.dirtyHint")}),e.jsxs(k,{variant:"secondary",size:"sm",onClick:C,disabled:i.isPending,children:[e.jsx(re,{className:"h-4 w-4"}),t("agents.discard")]}),e.jsxs(k,{size:"sm",onClick:()=>void M(),disabled:i.isPending,children:[i.isPending?e.jsx(D,{className:"h-4 w-4 animate-spin"}):e.jsx(ge,{className:"h-4 w-4"}),i.isPending?t("agents.saving"):t("agents.saveBtn")]})]})]})]})}function Ne({name:t,aliases:r,pkg:s,kind:i,installed:n,enabled:d,onToggle:p}){const{t:o}=L("settings"),m=i==="in-process";return e.jsxs("div",{className:"flex items-start gap-3 px-3 py-3",children:[e.jsx("div",{className:"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-surface-2 text-text-dim",children:e.jsx(be,{className:"h-4 w-4"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:t}),e.jsxs(R,{variant:n?"success":"outline",className:"text-[10px]",children:[e.jsx("span",{className:K("inline-block h-1.5 w-1.5 rounded-full",n?"bg-success":"bg-text-muted")}),o(n?"agents.online":"agents.offline")]}),m&&e.jsx(R,{variant:"outline",className:"text-[10px]",title:o("agents.inProcessHint"),children:o("agents.inProcessBadge")})]}),e.jsxs("p",{className:"mt-0.5 text-xs text-text-dim",children:[e.jsxs("span",{className:"text-text-muted",children:[o("agents.aliasesLabel"),": "]}),e.jsx("span",{className:"font-mono",children:r.map(x=>`/${x}`).join(", ")})]}),!n&&e.jsx("p",{className:"mt-1 text-xs text-warning",children:m?o("agents.nativeInstallHint"):o("agents.installHint",{pkg:s})})]}),e.jsx("input",{type:"checkbox",checked:d,onChange:x=>p(x.target.checked),className:"h-4 w-4 mt-2 accent-accent cursor-pointer"})]})}const ve=["none","apikey","bearer"],ke=/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;function ye(t,r){if(t.length!==r.length)return!1;for(let s=0;s<t.length;s++){const i=t[s],n=r[s];if(i.name!==n.name||i.endpoint!==n.endpoint||(i.enabled??!0)!==(n.enabled??!0))return!1;const d=(i.aliases??[]).join(","),p=(n.aliases??[]).join(",");if(d!==p)return!1;const o=i.auth?.type??"none",m=n.auth?.type??"none";if(o!==m||(i.auth?.token??"")!==(n.auth?.token??""))return!1}return!0}function we({agents:t,onChange:r}){const{t:s}=L(["settings","common"]),i=ue(),n=pe(),[d,p]=h.useState(""),[o,m]=h.useState(""),[x,S]=h.useState(""),[j,g]=h.useState("none"),[b,w]=h.useState(""),[U,T]=h.useState(!1),[P,M]=h.useState(""),C=d.trim(),z=C.length>0&&ke.test(C),c=t.some(a=>a.name===C),v=!(j!=="none")||b.trim().length>0,y=z&&x.trim().length>0&&v&&!c,H=x.trim().length>0&&v;function W(){p(""),m(""),S(""),g("none"),w("")}function ee(a){return a.split(",").map(l=>l.trim()).filter(Boolean)}function q(a,l){if(a==="none")return{type:"none"};const u=l.trim();return u?{type:a,token:u}:{type:a}}async function se(){if(!y)return;const a={name:C,endpoint:x.trim(),aliases:ee(o),auth:q(j,b),enabled:!0};r([...t,a]),W(),f.success(s("agents.acp.toast.staged"))}async function te(){if(H)try{const a=await i.mutateAsync({endpoint:x.trim(),auth:q(j,b)});f.success(s("agents.acp.toast.testOk",{name:a.name}))}catch(a){f.error(F(a,s).message)}}async function ae(a){const l=t[a];if(l){if(l.auth?.type!=="none"&&l.auth?.token&&Se(l.auth.token)){f.error(s("agents.acp.toast.testMasked"));return}try{const u=await i.mutateAsync({endpoint:l.endpoint,auth:l.auth});f.success(s("agents.acp.toast.testOk",{name:u.name}))}catch(u){f.error(F(u,s).message)}}}function ne(a,l){const u=t.map((E,A)=>A===a?{...E,enabled:l}:E);r(u)}function ce(a){r(t.filter((l,u)=>u!==a))}async function ie(){const a=P.trim();if(a)try{const l=await n.mutateAsync({baseUrl:a,register:!1}),u=new Set(t.map(A=>A.name)),E=l.agents.filter(A=>!u.has(A.name));if(E.length===0){f.info(s("agents.acp.toast.discoverEmpty"));return}r([...t,...E.map(A=>({...A,enabled:!0}))]),f.success(s("agents.acp.toast.discoverAdded",{count:E.length})),M(""),T(!1)}catch(l){f.error(F(l,s).message)}}return e.jsxs("section",{className:"rounded-md border border-border bg-surface",children:[e.jsxs("header",{className:"flex items-center gap-2 border-b border-border px-4 py-3",children:[e.jsx(G,{className:"h-4 w-4 text-text-dim"}),e.jsx("h2",{className:"text-sm font-semibold",children:s("agents.acp.title")}),e.jsx(R,{variant:"outline",className:"text-[10px]",children:t.length}),e.jsxs(k,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>T(a=>!a),children:[e.jsx(I,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("agents.acp.discoverBtn")})]})]}),e.jsx("p",{className:"px-4 pt-2 text-xs text-text-dim",children:s("agents.acp.subtitle")}),U&&e.jsxs("div",{className:"border-t border-border bg-surface-2 px-4 py-3",children:[e.jsx(V,{htmlFor:"acp-baseurl",className:"text-xs font-medium",children:s("agents.acp.baseUrl")}),e.jsx("p",{className:"mt-1 text-[11px] text-text-dim",children:s("agents.acp.baseUrlHint")}),e.jsxs("div",{className:"mt-2 flex flex-wrap gap-2",children:[e.jsx(_,{id:"acp-baseurl",value:P,onChange:a=>M(a.target.value),placeholder:"https://agents.example.com",className:"flex-1 min-w-[200px] font-mono text-xs"}),e.jsxs(k,{variant:"secondary",size:"sm",onClick:()=>void ie(),disabled:!P.trim()||n.isPending,children:[n.isPending?e.jsx(D,{className:"h-4 w-4 animate-spin"}):e.jsx(I,{className:"h-4 w-4"}),s("agents.acp.runDiscover")]})]})]}),t.length===0?e.jsx("div",{className:"px-4 py-6",children:e.jsx(oe,{icon:e.jsx(G,{}),title:s("agents.acp.empty.title"),description:s("agents.acp.empty.description")})}):e.jsx("ul",{className:"divide-y divide-border",children:t.map((a,l)=>e.jsx(Ae,{agent:a,onToggle:u=>ne(l,u),onTest:()=>void ae(l),onRemove:()=>ce(l),testing:i.isPending},`${a.name}-${l}`))}),e.jsxs("div",{className:"border-t border-border px-4 py-3",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-text-dim",children:s("agents.acp.addTitle")}),e.jsxs("div",{className:"mt-2 grid grid-cols-1 gap-2 sm:grid-cols-2",children:[e.jsx(B,{label:s("agents.acp.name"),hint:s("agents.acp.nameHint"),children:e.jsx(_,{value:d,onChange:a=>p(a.target.value),placeholder:"my-agent","aria-invalid":d.length>0&&!z})}),e.jsx(B,{label:s("agents.acp.aliases"),hint:s("agents.acp.aliasesHint"),children:e.jsx(_,{value:o,onChange:a=>m(a.target.value),placeholder:"ma, agent1"})}),e.jsx(B,{label:s("agents.acp.endpoint"),hint:s("agents.acp.endpointHint"),children:e.jsx(_,{value:x,onChange:a=>S(a.target.value),placeholder:"https://example.com/agents/weather",className:"font-mono text-xs"})}),e.jsx(B,{label:s("agents.acp.authType"),children:e.jsxs(Z,{value:j,onValueChange:a=>g(a),children:[e.jsx(X,{children:e.jsx(Y,{})}),e.jsx(J,{children:ve.map(a=>e.jsx(O,{value:a,children:s(`agents.acp.auth.${a}`)},a))})]})}),j!=="none"&&e.jsx(B,{label:s("agents.acp.token"),className:"sm:col-span-2",children:e.jsx(_,{type:"password",value:b,onChange:a=>w(a.target.value),placeholder:s("agents.acp.tokenPlaceholder"),autoComplete:"new-password"})})]}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsxs(k,{variant:"secondary",size:"sm",onClick:()=>void te(),disabled:!H||i.isPending,children:[i.isPending?e.jsx(D,{className:"h-4 w-4 animate-spin"}):e.jsx(I,{className:"h-4 w-4"}),s("agents.acp.testBtn")]}),e.jsxs(k,{size:"sm",onClick:()=>void se(),disabled:!y,children:[e.jsx(fe,{className:"h-4 w-4"}),s("agents.acp.addBtn")]}),c&&e.jsx("span",{className:"self-center text-xs text-warning",children:s("agents.acp.dupName")})]})]})]})}function Ae({agent:t,onToggle:r,onTest:s,onRemove:i,testing:n}){const{t:d}=L("settings"),p=t.enabled!==!1,o=t.auth?.type??"none";return e.jsxs("li",{className:"flex flex-wrap items-center gap-3 px-4 py-3",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:t.name}),e.jsx(R,{variant:"outline",className:"text-[10px] uppercase",children:d(`agents.acp.auth.${o}`)}),t.aliases&&t.aliases.length>0&&e.jsx("span",{className:"text-xs text-text-muted font-mono",children:t.aliases.map(m=>`/${m}`).join(", ")})]}),e.jsx("p",{className:"mt-0.5 truncate font-mono text-xs text-text-dim",title:t.endpoint,children:t.endpoint})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-text-dim",children:[e.jsx("input",{type:"checkbox",checked:p,onChange:m=>r(m.target.checked),className:"h-4 w-4 accent-accent cursor-pointer"}),d(p?"agents.acp.on":"agents.acp.off")]}),e.jsx(k,{variant:"ghost",size:"sm",onClick:s,disabled:n,"aria-label":d("agents.acp.testBtn"),children:n?e.jsx(D,{className:"h-4 w-4 animate-spin"}):e.jsx(I,{className:"h-4 w-4"})}),e.jsx(k,{variant:"ghost",size:"sm",onClick:i,"aria-label":d("agents.acp.removeBtn"),className:"text-danger hover:text-danger",children:e.jsx(je,{className:"h-4 w-4"})})]})}function B({label:t,hint:r,className:s,children:i}){return e.jsxs("div",{className:K("flex flex-col gap-1",s),children:[e.jsx(V,{className:"text-xs font-medium",children:t}),i,r&&e.jsx("p",{className:"text-[11px] text-text-dim",children:r})]})}function Se(t){return/\*{3,}/.test(t)}export{Ie as default};
7
- //# sourceMappingURL=agents-DnJruPrS.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"agents-DnJruPrS.js","sources":["../../node_modules/lucide-react/dist/esm/icons/bot.js","../../src/routes/settings/agents.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 Bot = createLucideIcon(\"Bot\", [\n [\"path\", { d: \"M12 8V4H8\", key: \"hb8ula\" }],\n [\"rect\", { width: \"16\", height: \"12\", x: \"4\", y: \"8\", rx: \"2\", key: \"enze0r\" }],\n [\"path\", { d: \"M2 14h2\", key: \"vft8re\" }],\n [\"path\", { d: \"M20 14h2\", key: \"4cs60a\" }],\n [\"path\", { d: \"M15 13v2\", key: \"1xurst\" }],\n [\"path\", { d: \"M9 13v2\", key: \"rq6x2g\" }]\n]);\n\nexport { Bot as default };\n//# sourceMappingURL=bot.js.map\n","/**\n * /settings/agents — built-in adapters + remote (ACP) agents.\n *\n * Two cards on one page:\n * 1. Built-in adapters (claude-code / codex / opencode):\n * enable/disable + default-agent picker. Mirrors v1's \"Agents\".\n * 2. Remote (ACP) agents: name/endpoint/auth-type table + manual\n * add form. Mirrors v1's \"Remote Agents (ACP)\" card. Discover\n * via `<baseUrl>/.well-known/acp` is available as a secondary\n * bulk-import form.\n *\n * Both cards share one save bar — PUT /api/config writes `agents[]`,\n * `defaultAgent`, and `acpAgents[]` atomically so the default never\n * goes out of sync with the enabled list, and partial ACP edits\n * don't ship without the user's intent.\n *\n * Masked tokens: GET returns `ab****yz` for ACP auth.token; PUT\n * detects this pattern and preserves the on-disk value so we never\n * overwrite a real token with its mask. New tokens (typed into the\n * add form or \"edit\" inline) flow through verbatim.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport {\n Bot, Loader2, Network, Plus, RefreshCcw, Save, Search, Trash2, X,\n} from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { useAgentsStatus } from '@/hooks/use-workspace'\nimport {\n useConfig,\n useDiscoverAcp,\n useTestAcp,\n useUpdateConfig,\n} from '@/hooks/use-settings'\nimport { describeError } from '@/lib/api/errors'\nimport { cn } from '@/lib/utils'\nimport type { ACPAgentConfig, ACPAuthConfig, ACPAuthType } from '@/types/api'\n\n/** Mirror of v1 settings.html:BUILTIN_AGENTS. Hardcoded because\n * backend doesn't expose this metadata yet; the table changes\n * rarely enough that copying it here is fine.\n *\n * `kind` distinguishes spawn flavor:\n * - 'cli' → external CLI subprocess, needs `npm install -g <pkg>`\n * - 'in-process' → runs inside agim, no install needed; `pkg` carries\n * a one-liner hint instead of an install command. The\n * runtime always exposes it via `isAgentEnabled`\n * regardless of config.agents, so default-picker\n * eligibility ignores the enabled-list constraint. */\nconst BUILTIN_AGENTS: Record<string, { aliases: string[]; pkg: string; kind: 'cli' | 'in-process' }> = {\n 'claude-code': { aliases: ['cc', 'claude'], pkg: '@anthropic-ai/claude-code', kind: 'cli' },\n 'codex': { aliases: ['cx'], pkg: '@openai/codex', kind: 'cli' },\n 'opencode': { aliases: ['oc'], pkg: 'opencode-ai', kind: 'cli' },\n 'cursor': { aliases: ['cs', 'cur'], pkg: 'cursor-agent (curl https://cursor.com/install)', kind: 'cli' },\n // v1.2.140 — surface the in-process `native` agent in the admin list.\n // Previously the agent was registered + always-enabled at runtime but\n // hidden from this page, so operators could only reach it via the CLI.\n 'native': { aliases: ['na', 'llm', 'native-llm'], pkg: 'in-process', kind: 'in-process' },\n}\n\nconst AGENT_NAMES = Object.keys(BUILTIN_AGENTS)\n\nexport default function SettingsAgentsRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const cfgQuery = useConfig()\n const statusQuery = useAgentsStatus()\n const updateCfg = useUpdateConfig()\n\n const cfg = cfgQuery.data\n const status = statusQuery.data ?? {}\n\n /** Local draft so toggles + default-picker + ACP edits can stage\n * changes before a single Save. `null` means \"sync from cfg on\n * next paint\". */\n const [draftEnabled, setDraftEnabled] = useState<string[] | null>(null)\n const [draftDefault, setDraftDefault] = useState<string | null>(null)\n const [draftAcp, setDraftAcp] = useState<ACPAgentConfig[] | null>(null)\n\n useEffect(() => {\n if (cfg && draftEnabled == null) setDraftEnabled(cfg.agents ?? [])\n if (cfg && draftDefault == null) setDraftDefault(cfg.defaultAgent ?? '')\n if (cfg && draftAcp == null) setDraftAcp(cfg.acpAgents ?? [])\n }, [cfg, draftEnabled, draftDefault, draftAcp])\n\n const enabled = draftEnabled ?? cfg?.agents ?? []\n const defaultAgent = draftDefault ?? cfg?.defaultAgent ?? ''\n const acpAgents = draftAcp ?? cfg?.acpAgents ?? []\n\n const isDirty = useMemo(() => {\n if (!cfg) return false\n const enabledSame =\n enabled.length === (cfg.agents?.length ?? 0)\n && enabled.every((a) => cfg.agents?.includes(a))\n const defaultSame = defaultAgent === (cfg.defaultAgent ?? '')\n const acpSame = acpEqual(acpAgents, cfg.acpAgents ?? [])\n return !enabledSame || !defaultSame || !acpSame\n }, [cfg, enabled, defaultAgent, acpAgents])\n\n /** Eligible defaults = installed + enabled. Picker disables when\n * empty (no agent is both).\n *\n * v1.2.140 — in-process agents (e.g. `native`) are exempt from the\n * enabled-list check. Runtime `isAgentEnabled('native')` always\n * returns true regardless of config.agents (see live-config.ts), so\n * the picker should mirror that and not require the user to flip the\n * toggle on first. */\n const eligibleDefaults = useMemo(\n () => AGENT_NAMES.filter((a) => {\n const info = BUILTIN_AGENTS[a]!\n const enabledOrInProcess = info.kind === 'in-process' ? true : enabled.includes(a)\n return enabledOrInProcess && status[a]\n }),\n [enabled, status],\n )\n\n function toggleAgent(name: string, on: boolean): void {\n const next = on\n ? Array.from(new Set([...enabled, name]))\n : enabled.filter((a) => a !== name)\n setDraftEnabled(next)\n // If the default just got disabled, clear it so save doesn't\n // ship an inconsistent pair.\n if (!on && name === defaultAgent) setDraftDefault('')\n }\n\n async function onSave(): Promise<void> {\n if (!cfg) return\n try {\n await updateCfg.mutateAsync({\n ...cfg,\n agents: enabled,\n defaultAgent: defaultAgent || cfg.defaultAgent,\n acpAgents,\n })\n toast.success(t('agents.toast.saved'))\n // Reset drafts so the next paint reads from refreshed cfg.\n setDraftEnabled(null)\n setDraftDefault(null)\n setDraftAcp(null)\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n function onDiscard(): void {\n setDraftEnabled(null)\n setDraftDefault(null)\n setDraftAcp(null)\n }\n\n function updateAcp(next: ACPAgentConfig[]): void {\n setDraftAcp(next)\n }\n\n return (\n <div className=\"mx-auto flex max-w-4xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('agents.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => {\n void cfgQuery.refetch()\n void statusQuery.refetch()\n }}\n disabled={cfgQuery.isFetching || statusQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {(cfgQuery.isFetching || statusQuery.isFetching)\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <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('agents.subtitle')}</p>\n </header>\n\n {cfgQuery.isLoading ? (\n <div className=\"h-64 rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <>\n {/* Agent rows */}\n <div className=\"flex flex-col divide-y divide-border rounded-md border border-border bg-surface\">\n {AGENT_NAMES.map((name) => {\n const info = BUILTIN_AGENTS[name]!\n const installed = !!status[name]\n const isEnabled = enabled.includes(name)\n return (\n <AgentRow\n key={name}\n name={name}\n aliases={info.aliases}\n pkg={info.pkg}\n kind={info.kind}\n installed={installed}\n enabled={isEnabled}\n onToggle={(on) => toggleAgent(name, on)}\n />\n )\n })}\n </div>\n\n {/* Default agent picker */}\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <Label htmlFor=\"default-agent\" className=\"text-sm font-medium\">\n {t('agents.defaultAgent')}\n </Label>\n <p className=\"mt-1 text-xs text-text-dim\">{t('agents.defaultAgentHint')}</p>\n <Select\n value={defaultAgent || '__none__'}\n onValueChange={(v) => setDraftDefault(v === '__none__' ? '' : v)}\n disabled={eligibleDefaults.length === 0}\n >\n <SelectTrigger id=\"default-agent\" className=\"mt-2 w-64\">\n <SelectValue placeholder={t('agents.noEligible')} />\n </SelectTrigger>\n <SelectContent>\n {eligibleDefaults.length === 0 ? (\n <SelectItem value=\"__none__\" disabled>{t('agents.noEligible')}</SelectItem>\n ) : (\n eligibleDefaults.map((a) => (\n <SelectItem key={a} value={a}>{a}</SelectItem>\n ))\n )}\n </SelectContent>\n </Select>\n </section>\n\n {/* Remote (ACP) agents — gated by features.remoteAgent\n (IMHUB_ENABLE_REMOTE_AGENT on server). Card is omitted\n entirely; no breadcrumb hint shown. */}\n {cfg?.features?.remoteAgent ? (\n <AcpCard\n agents={acpAgents}\n onChange={updateAcp}\n />\n ) : null}\n\n {/* Save bar */}\n {isDirty && (\n <div className=\"sticky bottom-0 flex items-center gap-2 rounded-md border border-border bg-surface px-4 py-2 shadow-md\">\n <Badge variant=\"info\">{t('agents.dirtyHint')}</Badge>\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={onDiscard}\n disabled={updateCfg.isPending}\n >\n <X className=\"h-4 w-4\" />\n {t('agents.discard')}\n </Button>\n <Button\n size=\"sm\"\n onClick={() => void onSave()}\n disabled={updateCfg.isPending}\n >\n {updateCfg.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Save className=\"h-4 w-4\" />}\n {updateCfg.isPending ? t('agents.saving') : t('agents.saveBtn')}\n </Button>\n </div>\n )}\n </>\n )}\n </div>\n )\n}\n\n/* ─────────────── Row ─────────────── */\n\ninterface AgentRowProps {\n name: string\n aliases: string[]\n pkg: string\n /** v1.2.140 — 'in-process' agents show a different \"not installed\"\n * hint (point at LLM-backend config rather than `npm install -g`)\n * and surface a small \"内置\" badge so operators understand they\n * don't need to install anything. */\n kind: 'cli' | 'in-process'\n installed: boolean\n enabled: boolean\n onToggle: (on: boolean) => void\n}\n\nfunction AgentRow({\n name, aliases, pkg, kind, installed, enabled, onToggle,\n}: AgentRowProps): JSX.Element {\n const { t } = useTranslation('settings')\n const inProcess = kind === 'in-process'\n return (\n <div className=\"flex items-start gap-3 px-3 py-3\">\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-surface-2 text-text-dim\">\n <Bot className=\"h-4 w-4\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium text-text\">{name}</span>\n <Badge variant={installed ? 'success' : 'outline'} className=\"text-[10px]\">\n <span className={cn(\n 'inline-block h-1.5 w-1.5 rounded-full',\n installed ? 'bg-success' : 'bg-text-muted',\n )} />\n {installed ? t('agents.online') : t('agents.offline')}\n </Badge>\n {inProcess && (\n <Badge variant=\"outline\" className=\"text-[10px]\" title={t('agents.inProcessHint')}>\n {t('agents.inProcessBadge')}\n </Badge>\n )}\n </div>\n <p className=\"mt-0.5 text-xs text-text-dim\">\n <span className=\"text-text-muted\">{t('agents.aliasesLabel')}: </span>\n <span className=\"font-mono\">{aliases.map((a) => `/${a}`).join(', ')}</span>\n </p>\n {!installed && (\n <p className=\"mt-1 text-xs text-warning\">\n {inProcess\n ? t('agents.nativeInstallHint')\n : t('agents.installHint', { pkg })}\n </p>\n )}\n </div>\n <input\n type=\"checkbox\"\n checked={enabled}\n onChange={(e) => onToggle(e.target.checked)}\n className=\"h-4 w-4 mt-2 accent-accent cursor-pointer\"\n />\n </div>\n )\n}\n\n/* ─────────────── Remote (ACP) ─────────────── */\n\nconst AUTH_TYPES: ACPAuthType[] = ['none', 'apikey', 'bearer']\nconst NAME_RE = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/\n\n/** Compare two ACP lists by value. Order matters because the backend\n * preserves index identity (`existing.acpAgents[i]`) when merging\n * masked tokens — reordering = mask drift risk. */\nfunction acpEqual(a: ACPAgentConfig[], b: ACPAgentConfig[]): boolean {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n const x = a[i]!\n const y = b[i]!\n if (x.name !== y.name) return false\n if (x.endpoint !== y.endpoint) return false\n if ((x.enabled ?? true) !== (y.enabled ?? true)) return false\n const xa = (x.aliases ?? []).join(',')\n const ya = (y.aliases ?? []).join(',')\n if (xa !== ya) return false\n const xat = x.auth?.type ?? 'none'\n const yat = y.auth?.type ?? 'none'\n if (xat !== yat) return false\n if ((x.auth?.token ?? '') !== (y.auth?.token ?? '')) return false\n }\n return true\n}\n\ninterface AcpCardProps {\n agents: ACPAgentConfig[]\n onChange: (next: ACPAgentConfig[]) => void\n}\n\nfunction AcpCard({ agents, onChange }: AcpCardProps): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const testMut = useTestAcp()\n const discoverMut = useDiscoverAcp()\n\n // Add-form state. We keep the typed token in plain state so the\n // user can paste before save; the masked round-trip from backend\n // only matters for existing rows.\n const [name, setName] = useState('')\n const [aliasesText, setAliasesText] = useState('')\n const [endpoint, setEndpoint] = useState('')\n const [authType, setAuthType] = useState<ACPAuthType>('none')\n const [token, setToken] = useState('')\n\n // Bulk-discover sub-form state. Hidden behind a toggle so the\n // primary path (manual add) stays uncluttered.\n const [showDiscover, setShowDiscover] = useState(false)\n const [baseUrl, setBaseUrl] = useState('')\n\n const trimmedName = name.trim()\n const nameValid = trimmedName.length > 0 && NAME_RE.test(trimmedName)\n const dup = agents.some((a) => a.name === trimmedName)\n const tokenRequired = authType !== 'none'\n const tokenOk = !tokenRequired || token.trim().length > 0\n const canAdd = nameValid && endpoint.trim().length > 0 && tokenOk && !dup\n const canTestNew = endpoint.trim().length > 0 && tokenOk\n\n function clearForm(): void {\n setName('')\n setAliasesText('')\n setEndpoint('')\n setAuthType('none')\n setToken('')\n }\n\n function parseAliases(text: string): string[] {\n return text.split(',').map((s) => s.trim()).filter(Boolean)\n }\n\n function buildAuth(type: ACPAuthType, tok: string): ACPAuthConfig | undefined {\n if (type === 'none') return { type: 'none' }\n const trimmed = tok.trim()\n if (!trimmed) return { type } // no token yet; save will reject\n return { type, token: trimmed }\n }\n\n async function onAdd(): Promise<void> {\n if (!canAdd) return\n const next: ACPAgentConfig = {\n name: trimmedName,\n endpoint: endpoint.trim(),\n aliases: parseAliases(aliasesText),\n auth: buildAuth(authType, token),\n enabled: true,\n }\n onChange([...agents, next])\n clearForm()\n toast.success(t('agents.acp.toast.staged'))\n }\n\n async function onTestNew(): Promise<void> {\n if (!canTestNew) return\n try {\n const res = await testMut.mutateAsync({\n endpoint: endpoint.trim(),\n auth: buildAuth(authType, token),\n })\n toast.success(t('agents.acp.toast.testOk', { name: res.name }))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n async function onTestRow(idx: number): Promise<void> {\n const a = agents[idx]\n if (!a) return\n // Masked tokens stay masked on the wire — backend's PUT mask-detect\n // is symmetric, but the test endpoint reads what we send. We can't\n // unmask client-side; warn the operator.\n if (a.auth?.type !== 'none' && a.auth?.token && isMaskedToken(a.auth.token)) {\n toast.error(t('agents.acp.toast.testMasked'))\n return\n }\n try {\n const res = await testMut.mutateAsync({\n endpoint: a.endpoint,\n auth: a.auth,\n })\n toast.success(t('agents.acp.toast.testOk', { name: res.name }))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n function onToggleRow(idx: number, on: boolean): void {\n const next = agents.map((a, i) => (i === idx ? { ...a, enabled: on } : a))\n onChange(next)\n }\n\n function onRemoveRow(idx: number): void {\n onChange(agents.filter((_, i) => i !== idx))\n }\n\n async function onDiscoverRun(): Promise<void> {\n const url = baseUrl.trim()\n if (!url) return\n try {\n const res = await discoverMut.mutateAsync({ baseUrl: url, register: false })\n // Stage new agents that aren't already in the list (by name).\n const existing = new Set(agents.map((a) => a.name))\n const incoming = res.agents.filter((a) => !existing.has(a.name))\n if (incoming.length === 0) {\n toast.info(t('agents.acp.toast.discoverEmpty'))\n return\n }\n onChange([...agents, ...incoming.map((a) => ({ ...a, enabled: true }))])\n toast.success(t('agents.acp.toast.discoverAdded', { count: incoming.length }))\n setBaseUrl('')\n setShowDiscover(false)\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"flex items-center gap-2 border-b border-border px-4 py-3\">\n <Network className=\"h-4 w-4 text-text-dim\" />\n <h2 className=\"text-sm font-semibold\">{t('agents.acp.title')}</h2>\n <Badge variant=\"outline\" className=\"text-[10px]\">{agents.length}</Badge>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => setShowDiscover((v) => !v)}\n >\n <Search className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">{t('agents.acp.discoverBtn')}</span>\n </Button>\n </header>\n <p className=\"px-4 pt-2 text-xs text-text-dim\">{t('agents.acp.subtitle')}</p>\n\n {/* Discover form (collapsed by default) */}\n {showDiscover && (\n <div className=\"border-t border-border bg-surface-2 px-4 py-3\">\n <Label htmlFor=\"acp-baseurl\" className=\"text-xs font-medium\">\n {t('agents.acp.baseUrl')}\n </Label>\n <p className=\"mt-1 text-[11px] text-text-dim\">{t('agents.acp.baseUrlHint')}</p>\n <div className=\"mt-2 flex flex-wrap gap-2\">\n <Input\n id=\"acp-baseurl\"\n value={baseUrl}\n onChange={(e) => setBaseUrl(e.target.value)}\n placeholder=\"https://agents.example.com\"\n className=\"flex-1 min-w-[200px] font-mono text-xs\"\n />\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => void onDiscoverRun()}\n disabled={!baseUrl.trim() || discoverMut.isPending}\n >\n {discoverMut.isPending\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <Search className=\"h-4 w-4\" />}\n {t('agents.acp.runDiscover')}\n </Button>\n </div>\n </div>\n )}\n\n {/* Registered ACP agents */}\n {agents.length === 0 ? (\n <div className=\"px-4 py-6\">\n <EmptyState\n icon={<Network />}\n title={t('agents.acp.empty.title')}\n description={t('agents.acp.empty.description')}\n />\n </div>\n ) : (\n <ul className=\"divide-y divide-border\">\n {agents.map((a, i) => (\n <AcpRow\n key={`${a.name}-${i}`}\n agent={a}\n onToggle={(on) => onToggleRow(i, on)}\n onTest={() => void onTestRow(i)}\n onRemove={() => onRemoveRow(i)}\n testing={testMut.isPending}\n />\n ))}\n </ul>\n )}\n\n {/* Add-agent form */}\n <div className=\"border-t border-border px-4 py-3\">\n <h3 className=\"text-xs font-semibold uppercase tracking-wide text-text-dim\">\n {t('agents.acp.addTitle')}\n </h3>\n <div className=\"mt-2 grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <Field label={t('agents.acp.name')} hint={t('agents.acp.nameHint')}>\n <Input\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"my-agent\"\n aria-invalid={name.length > 0 && !nameValid}\n />\n </Field>\n <Field label={t('agents.acp.aliases')} hint={t('agents.acp.aliasesHint')}>\n <Input\n value={aliasesText}\n onChange={(e) => setAliasesText(e.target.value)}\n placeholder=\"ma, agent1\"\n />\n </Field>\n <Field label={t('agents.acp.endpoint')} hint={t('agents.acp.endpointHint')}>\n <Input\n value={endpoint}\n onChange={(e) => setEndpoint(e.target.value)}\n placeholder=\"https://example.com/agents/weather\"\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field label={t('agents.acp.authType')}>\n <Select value={authType} onValueChange={(v) => setAuthType(v as ACPAuthType)}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n {AUTH_TYPES.map((a) => (\n <SelectItem key={a} value={a}>{t(`agents.acp.auth.${a}`)}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n {authType !== 'none' && (\n <Field label={t('agents.acp.token')} className=\"sm:col-span-2\">\n <Input\n type=\"password\"\n value={token}\n onChange={(e) => setToken(e.target.value)}\n placeholder={t('agents.acp.tokenPlaceholder')}\n autoComplete=\"new-password\"\n />\n </Field>\n )}\n </div>\n <div className=\"mt-3 flex flex-wrap gap-2\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => void onTestNew()}\n disabled={!canTestNew || testMut.isPending}\n >\n {testMut.isPending\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <Search className=\"h-4 w-4\" />}\n {t('agents.acp.testBtn')}\n </Button>\n <Button\n size=\"sm\"\n onClick={() => void onAdd()}\n disabled={!canAdd}\n >\n <Plus className=\"h-4 w-4\" />\n {t('agents.acp.addBtn')}\n </Button>\n {dup && (\n <span className=\"self-center text-xs text-warning\">\n {t('agents.acp.dupName')}\n </span>\n )}\n </div>\n </div>\n </section>\n )\n}\n\ninterface AcpRowProps {\n agent: ACPAgentConfig\n onToggle: (on: boolean) => void\n onTest: () => void\n onRemove: () => void\n testing: boolean\n}\n\nfunction AcpRow({ agent, onToggle, onTest, onRemove, testing }: AcpRowProps): JSX.Element {\n const { t } = useTranslation('settings')\n const isOn = agent.enabled !== false\n const authType = agent.auth?.type ?? 'none'\n return (\n <li className=\"flex flex-wrap items-center gap-3 px-4 py-3\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium text-text\">{agent.name}</span>\n <Badge variant=\"outline\" className=\"text-[10px] uppercase\">\n {t(`agents.acp.auth.${authType}`)}\n </Badge>\n {agent.aliases && agent.aliases.length > 0 && (\n <span className=\"text-xs text-text-muted font-mono\">\n {agent.aliases.map((a) => `/${a}`).join(', ')}\n </span>\n )}\n </div>\n <p className=\"mt-0.5 truncate font-mono text-xs text-text-dim\" title={agent.endpoint}>\n {agent.endpoint}\n </p>\n </div>\n <label className=\"flex items-center gap-1.5 text-xs text-text-dim\">\n <input\n type=\"checkbox\"\n checked={isOn}\n onChange={(e) => onToggle(e.target.checked)}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n {isOn ? t('agents.acp.on') : t('agents.acp.off')}\n </label>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onTest}\n disabled={testing}\n aria-label={t('agents.acp.testBtn')}\n >\n {testing ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Search className=\"h-4 w-4\" />}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onRemove}\n aria-label={t('agents.acp.removeBtn')}\n className=\"text-danger hover:text-danger\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </li>\n )\n}\n\ninterface FieldProps {\n label: string\n hint?: string\n className?: string\n children: React.ReactNode\n}\n\nfunction Field({ label, hint, className, children }: FieldProps): JSX.Element {\n return (\n <div className={cn('flex flex-col gap-1', className)}>\n <Label className=\"text-xs font-medium\">{label}</Label>\n {children}\n {hint && <p className=\"text-[11px] text-text-dim\">{hint}</p>}\n </div>\n )\n}\n\n/** Tokens look like `ab****yz` from the masked GET response. We\n * shouldn't send them back unchanged for test (the backend would\n * fail auth), and we shouldn't include them in the test mutation\n * body either. Treat any string with 3+ consecutive `*` as masked. */\nfunction isMaskedToken(s: string): boolean {\n return /\\*{3,}/.test(s)\n}\n"],"names":["Bot","createLucideIcon","BUILTIN_AGENTS","AGENT_NAMES","SettingsAgentsRoute","useTranslation","cfgQuery","useConfig","statusQuery","useAgentsStatus","updateCfg","useUpdateConfig","cfg","status","draftEnabled","setDraftEnabled","useState","draftDefault","setDraftDefault","draftAcp","setDraftAcp","useEffect","enabled","defaultAgent","acpAgents","isDirty","useMemo","enabledSame","a","defaultSame","acpSame","acpEqual","eligibleDefaults","toggleAgent","name","on","next","onSave","toast","err","describeError","onDiscard","updateAcp","jsxs","jsx","Button","Loader2","RefreshCcw","Fragment","info","installed","isEnabled","AgentRow","Label","Select","v","SelectTrigger","SelectValue","SelectContent","SelectItem","AcpCard","Badge","X","Save","aliases","pkg","kind","onToggle","t","inProcess","cn","e","AUTH_TYPES","NAME_RE","b","i","x","y","xa","ya","xat","yat","agents","onChange","testMut","useTestAcp","discoverMut","useDiscoverAcp","setName","aliasesText","setAliasesText","endpoint","setEndpoint","authType","setAuthType","token","setToken","showDiscover","setShowDiscover","baseUrl","setBaseUrl","trimmedName","nameValid","dup","tokenOk","canAdd","canTestNew","clearForm","parseAliases","text","s","buildAuth","type","tok","trimmed","onAdd","onTestNew","res","onTestRow","idx","isMaskedToken","onToggleRow","onRemoveRow","_","onDiscoverRun","url","existing","incoming","Network","Search","Input","EmptyState","AcpRow","Field","Plus","agent","onTest","onRemove","testing","isOn","Trash2","label","hint","className","children"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1,17 +0,0 @@
1
- import{o as N,u as Y,ai as _,aj as G,m as j,j as e,ak as J,B as f,c as g,al as Q,am as W,a8 as X,l as A,an as Z}from"./index-D7BuMEIr.js";import{r as n}from"./react-DlP5eolq.js";import{C as ee}from"./chevron-left-CnLOhWHE.js";import{A as te}from"./arrow-down-CzWGZc48.js";import{L as R}from"./loader-circle-DO3Ni2RJ.js";import{A as se}from"./activity-CWFI_ke7.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 ae=N("Clock3",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["polyline",{points:"12 6 12 12 16.5 12",key:"1aq6pp"}]]);/**
7
- * @license lucide-react v0.469.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const ne=N("EllipsisVertical",[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"12",cy:"5",r:"1",key:"gxeob9"}],["circle",{cx:"12",cy:"19",r:"1",key:"lyex9k"}]]);/**
12
- * @license lucide-react v0.469.0 - ISC
13
- *
14
- * This source code is licensed under the ISC license.
15
- * See the LICENSE file in the root directory of this source tree.
16
- */const re=N("Sparkles",[["path",{d:"M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z",key:"4pj2yx"}],["path",{d:"M20 3v4",key:"1olli1"}],["path",{d:"M22 5h-4",key:"1gvqau"}],["path",{d:"M4 17v2",key:"vumght"}],["path",{d:"M5 18H3",key:"zchphs"}]]),le={open:"bg-success",connecting:"bg-warning animate-pulse",closed:"bg-text-muted",error:"bg-danger"};function w(s){return Number.isFinite(s)?s:Date.now()}function oe(s){const l=new Date(w(s)),a=String(l.getMonth()+1).padStart(2,"0"),u=String(l.getDate()).padStart(2,"0");return`${l.getFullYear()}-${a}-${u}`}function ce(s,l){return new Intl.DateTimeFormat(l,{month:"short",day:"numeric",weekday:"short"}).format(new Date(w(s)))}function M(s,l){return new Intl.DateTimeFormat(l,{hour:"2-digit",minute:"2-digit"}).format(new Date(w(s)))}function D(s){return!s||s<=0?"0ms":s<1e3?`${s}ms`:`${(s/1e3).toFixed(s>=1e4?0:1)}s`}function ie(s,l){const a=[];let u="";for(const i of s){const m=oe(i.timestamp);m!==u&&(a.push({type:"divider",key:`d-${m}`,label:ce(i.timestamp,l)}),u=m),a.push({type:"message",key:i.id,msg:i})}return a}function de(s){switch(s){case"running":return"bg-info-bg text-info";case"success":return"bg-success-bg text-success";case"error":return"bg-danger-bg text-danger"}}function ge(){const{t:s,i18n:l}=Y(["chat","common"]),{state:a,send:u,switchAgent:i,approvalClick:m,newConversation:T,clearError:k}=_(),[p,b]=n.useState(""),[v,o]=n.useState("none"),[I,E]=n.useState(!1),[L,S]=n.useState(!1),[B,F]=n.useState(""),h=n.useRef(null),x=n.useRef(null),q=n.useMemo(()=>[s("chat.quickPrompt.plan",{defaultValue:"帮我先拆解这个任务"}),s("chat.quickPrompt.risks",{defaultValue:"先列出风险与回滚方案"}),s("chat.quickPrompt.summary",{defaultValue:"输出一版可发给老板的摘要"})],[s]),d=n.useMemo(()=>a.messages.filter(t=>!t.approval),[a.messages]),H=n.useMemo(()=>ie(d,l.language),[d,l.language]),z=n.useMemo(()=>{const t=d.find(c=>c.role==="user"&&c.content.trim());if(!t)return s("chat.mobileTitle",{defaultValue:"agim chat"});const r=t.content.replace(/\s+/g," ").trim();return r.length>24?`${r.slice(0,24)}…`:r},[d,s]),C=n.useMemo(()=>a.runActivities.slice(0,12),[a.runActivities]),y=n.useMemo(()=>a.runActivities.find(t=>t.runId===a.activeRunId),[a.activeRunId,a.runActivities]);n.useEffect(()=>{const t=h.current;!t||t.scrollHeight-t.scrollTop-t.clientHeight>200&&a.currentReplyId==null||requestAnimationFrame(()=>{t.scrollTop=t.scrollHeight})},[a.messages,a.currentReplyId]),n.useEffect(()=>{const t=h.current;if(!t)return;const r=()=>{const c=t.scrollHeight-t.scrollTop-t.clientHeight;E(c>200)};return t.addEventListener("scroll",r,{passive:!0}),r(),()=>t.removeEventListener("scroll",r)},[]),n.useEffect(()=>{a.error&&(G(a.error)?(F(a.error),S(!0)):j.error(a.error),k())},[a.error,k]),n.useEffect(()=>{const t=x.current;t&&(t.style.height="auto",t.style.height=`${Math.min(t.scrollHeight,24*6+16)}px`)},[p]);function P(t){t?.preventDefault();const r=p.trim();if(r){if(a.status!=="open"){j.error(s("chat.notConnected",{defaultValue:"Not connected. Reconnecting…"}));return}a.currentReplyId||(u(r),b(""),requestAnimationFrame(()=>x.current?.focus()))}}function $(t){t.nativeEvent.isComposing||t.keyCode}function O(){const t=h.current;t&&t.scrollTo({top:t.scrollHeight,behavior:"smooth"})}function U(){fetch("/api/auth/logout",{method:"POST"}).finally(()=>{try{localStorage.removeItem("agim_token")}catch{}window.location.replace("/login")})}function V(){T(),j.success(s("chat.newConvToast",{defaultValue:"Started a new conversation"})),o("none"),requestAnimationFrame(()=>x.current?.focus())}return e.jsxs("div",{className:"relative flex h-dvh flex-col bg-bg",children:[e.jsx(J,{open:L,reason:B,onOpenChange:S,onConfigured:()=>i("native")}),e.jsxs("header",{className:"flex items-center gap-2 border-b border-border bg-surface px-3 py-2",style:{paddingTop:"calc(env(safe-area-inset-top) + 0.5rem)"},children:[e.jsx(f,{variant:"ghost",size:"sm","aria-label":s("chat.back",{defaultValue:"Back"}),onClick:()=>window.history.length>1?window.history.back():window.location.assign("/"),className:"h-9 w-9 p-0",children:e.jsx(ee,{className:"h-5 w-5"})}),e.jsxs("div",{className:"flex min-w-0 flex-1 flex-col items-center",children:[e.jsx("span",{className:"truncate text-sm font-semibold",children:z}),e.jsxs("span",{className:"flex items-center gap-1.5 text-[11px] text-text-dim",children:[e.jsx("span",{className:g("inline-block h-1.5 w-1.5 rounded-full",le[a.status])}),e.jsx("span",{children:a.agent||"—"}),e.jsx("span",{children:"·"}),e.jsx("span",{children:a.activeRunId?s("chat.running",{defaultValue:"Running"}):a.status})]})]}),e.jsx(f,{variant:"ghost",size:"sm","aria-label":s("chat.menu",{defaultValue:"Menu"}),onClick:()=>o("menu"),className:"h-9 w-9 p-0",children:e.jsx(ne,{className:"h-5 w-5"})})]}),e.jsx("div",{ref:h,className:"flex-1 overflow-y-auto",children:e.jsxs("div",{className:"mx-auto flex w-full max-w-3xl flex-col gap-3 px-3 py-4",children:[d.length===0&&a.status==="open"&&e.jsxs("div",{className:"flex flex-col items-center gap-2 py-14 text-center",children:[e.jsx("div",{className:"flex h-12 w-12 items-center justify-center rounded-full bg-surface-2 text-2xl",children:"💬"}),e.jsx("h2",{className:"text-base font-semibold",children:s("chat.welcomeTitle",{defaultValue:"Start a conversation"})}),e.jsx("p",{className:"max-w-xs text-sm text-text-dim",children:s("chat.welcomeBodyMobile",{defaultValue:"Type a message below. Switch agent or start over from the menu."})})]}),d.length===0&&a.status!=="open"&&e.jsx("div",{className:"grid place-items-center py-16 text-center",children:e.jsx("p",{className:"text-sm text-text-dim",children:a.status==="connecting"?s("chat.connecting",{defaultValue:"Connecting to agim…"}):s("chat.disconnected",{defaultValue:"Disconnected. Reconnecting automatically."})})}),H.map(t=>t.type==="divider"?e.jsx("div",{className:"py-1 text-center text-[11px] text-text-muted",children:t.label},t.key):e.jsxs("div",{className:"space-y-1",children:[e.jsx(Q,{msg:t.msg,onApprove:(r,c,K)=>m(r,c,K)}),e.jsx("div",{className:g("px-1 text-[11px] text-text-muted",t.msg.role==="user"?"text-right":"text-left"),children:M(t.msg.timestamp,l.language)})]},t.key))]})}),I&&e.jsx("button",{type:"button",onClick:O,className:"absolute bottom-28 left-1/2 z-20 -translate-x-1/2 rounded-full border border-border bg-surface p-2 shadow-md","aria-label":s("chat.scrollDown",{defaultValue:"Scroll to bottom"}),children:e.jsx(te,{className:"h-4 w-4"})}),e.jsx(W,{approvals:a.pendingApprovals,onApprove:(t,r,c)=>m(t,r,c)}),e.jsxs("form",{onSubmit:P,className:"sticky bottom-0 border-t border-border bg-surface px-3 py-2",style:{paddingBottom:"calc(env(safe-area-inset-bottom) + 0.5rem)"},children:[d.length===0&&a.status==="open"&&e.jsx("div",{className:"mb-2 flex gap-2 overflow-x-auto pb-1",children:q.map(t=>e.jsx("button",{type:"button",onClick:()=>{b(t),requestAnimationFrame(()=>x.current?.focus())},className:"shrink-0 rounded-full border border-border bg-surface-2 px-3 py-1.5 text-xs text-text-dim hover:bg-surface-hover",children:t},t))}),y&&e.jsxs("div",{className:"mb-2 flex items-center justify-between rounded-xl border border-info/30 bg-info-bg/50 px-3 py-1.5",children:[e.jsxs("span",{className:"inline-flex items-center gap-1 text-xs text-info",children:[e.jsx(R,{className:"h-3.5 w-3.5 animate-spin"}),s("chat.running",{defaultValue:"Running"})]}),e.jsxs("span",{className:"truncate text-xs text-text-dim",children:[y.agent," · ",D(y.durationMs)]})]}),e.jsxs("div",{className:"flex items-end gap-2",children:[e.jsx(f,{type:"button",variant:"ghost",onClick:V,disabled:a.status!=="open"||!!a.currentReplyId,"aria-label":s("chat.newConv",{defaultValue:"New conversation"}),className:"h-11 w-11 shrink-0 rounded-full p-0",children:e.jsx(re,{className:"h-4 w-4"})}),e.jsx("textarea",{ref:x,value:p,onChange:t=>b(t.target.value),onKeyDown:$,placeholder:s("chat.inputPlaceholderMobile",{defaultValue:"Message…"}),rows:1,className:g("flex-1 resize-none rounded-3xl border border-border bg-bg","px-3 py-2 text-[15px] leading-6","focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-1 focus:ring-offset-bg")}),e.jsx(f,{type:"submit",disabled:!p.trim()||a.status!=="open"||!!a.currentReplyId,"aria-label":s("chat.send",{defaultValue:"Send"}),className:"h-11 w-11 shrink-0 rounded-full p-0",children:a.currentReplyId?e.jsx(R,{className:"h-4 w-4 animate-spin"}):e.jsx(X,{className:"h-4 w-4"})})]}),e.jsxs("div",{className:"mt-2 flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[a.currentReplyId&&e.jsx(A,{variant:"info",children:s("chat.streaming",{defaultValue:"… streaming"})}),!a.currentReplyId&&e.jsx("span",{className:"text-[11px] text-text-muted",children:s("chat.mobileHint",{defaultValue:"Enter 换行,点发送提交。"})})]}),e.jsxs("button",{type:"button",onClick:()=>o("activity"),className:"inline-flex items-center gap-1 rounded px-1.5 py-1 text-xs text-text-dim hover:bg-surface-hover hover:text-text",children:[e.jsx(se,{className:"h-3.5 w-3.5"}),s("chat.activity",{defaultValue:"Activity"})]})]})]}),v!=="none"&&e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button","aria-label":s("actions.close",{ns:"common",defaultValue:"Close"}),className:"fixed inset-0 z-30 bg-black/35",onClick:()=>o("none")}),e.jsxs("div",{className:"fixed inset-x-0 bottom-0 z-40 rounded-t-2xl border border-border bg-surface px-4 pb-safe pt-3 shadow-lg",children:[e.jsx("div",{className:"mx-auto mb-3 h-1.5 w-12 rounded-full bg-border"}),v==="menu"&&e.jsxs("div",{className:"space-y-3 pb-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"mb-1 text-[11px] uppercase text-text-dim",children:s("chat.agent",{defaultValue:"Agent"})}),e.jsx(Z,{agents:a.agents,value:a.agent,onChange:t=>{i(t),o("none")}})]}),e.jsx("button",{type:"button",className:"block w-full rounded-md border border-border px-3 py-2 text-left text-sm hover:bg-surface-hover disabled:opacity-50",disabled:a.status!=="open"||!!a.currentReplyId,onClick:V,children:s("chat.newConv",{defaultValue:"New conversation"})}),e.jsx("button",{type:"button",className:"block w-full rounded-md border border-border px-3 py-2 text-left text-sm hover:bg-surface-hover",onClick:()=>o("activity"),children:s("chat.activity",{defaultValue:"Activity"})}),e.jsx("button",{type:"button",className:"block w-full rounded-md border border-border px-3 py-2 text-left text-sm hover:bg-surface-hover",onClick:()=>{o("none"),window.location.assign("/settings/llm")},children:s("chat.llmSettings",{defaultValue:"LLM settings"})}),e.jsx("button",{type:"button",className:"block w-full rounded-md border border-danger/30 px-3 py-2 text-left text-sm text-danger hover:bg-danger/10",onClick:U,children:s("chat.logout",{defaultValue:"Log out"})})]}),v==="activity"&&e.jsxs("div",{className:"space-y-3 pb-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{className:"text-sm font-semibold",children:s("chat.activityTitle",{defaultValue:"Run activity"})}),e.jsx("button",{type:"button",className:"text-xs text-text-dim hover:text-text",onClick:()=>o("menu"),children:s("actions.back",{ns:"common",defaultValue:"Back"})})]}),e.jsxs("div",{className:"rounded-md border border-border bg-surface-2 px-3 py-2 text-xs text-text-dim",children:[s("chat.pendingApprovals",{defaultValue:"Pending approvals"}),": ",a.pendingApprovals.length]}),e.jsxs("div",{className:"max-h-72 space-y-2 overflow-y-auto pr-1",children:[C.length===0&&e.jsx("div",{className:"rounded-md border border-border px-3 py-5 text-center text-xs text-text-dim",children:s("chat.activityEmpty",{defaultValue:"No recent runs yet."})}),C.map(t=>e.jsxs("div",{className:"rounded-md border border-border px-3 py-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(A,{className:g("border-0",de(t.status)),children:t.status}),e.jsx("span",{className:"truncate text-xs font-medium",children:t.agent}),e.jsx("span",{className:"ml-auto text-[11px] text-text-muted",children:D(t.durationMs)})]}),e.jsxs("div",{className:"mt-1 flex items-center gap-1 text-[11px] text-text-muted",children:[e.jsx(ae,{className:"h-3 w-3"}),M(t.startedAt,l.language),t.outputChars!=null&&e.jsxs("span",{children:["· ",t.outputChars," chars"]})]}),t.error&&e.jsx("p",{className:"mt-1 text-[11px] text-danger",children:t.error})]},t.runId))]})]})]})]})]})}export{ge as default};
17
- //# sourceMappingURL=chat-D7jjr-Rn.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chat-D7jjr-Rn.js","sources":["../../node_modules/lucide-react/dist/esm/icons/clock-3.js","../../node_modules/lucide-react/dist/esm/icons/ellipsis-vertical.js","../../node_modules/lucide-react/dist/esm/icons/sparkles.js","../../src/routes/m/chat.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 Clock3 = createLucideIcon(\"Clock3\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"polyline\", { points: \"12 6 12 12 16.5 12\", key: \"1aq6pp\" }]\n]);\n\nexport { Clock3 as default };\n//# sourceMappingURL=clock-3.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst EllipsisVertical = createLucideIcon(\"EllipsisVertical\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"1\", key: \"41hilf\" }],\n [\"circle\", { cx: \"12\", cy: \"5\", r: \"1\", key: \"gxeob9\" }],\n [\"circle\", { cx: \"12\", cy: \"19\", r: \"1\", key: \"lyex9k\" }]\n]);\n\nexport { EllipsisVertical as default };\n//# sourceMappingURL=ellipsis-vertical.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Sparkles = createLucideIcon(\"Sparkles\", [\n [\n \"path\",\n {\n d: \"M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z\",\n key: \"4pj2yx\"\n }\n ],\n [\"path\", { d: \"M20 3v4\", key: \"1olli1\" }],\n [\"path\", { d: \"M22 5h-4\", key: \"1gvqau\" }],\n [\"path\", { d: \"M4 17v2\", key: \"vumght\" }],\n [\"path\", { d: \"M5 18H3\", key: \"zchphs\" }]\n]);\n\nexport { Sparkles as default };\n//# sourceMappingURL=sparkles.js.map\n","/**\n * /m/chat — mobile-first chat surface (production-oriented UX pass).\n *\n * Upgrades over v1:\n * - richer hierarchy (thread title + status + execution rail)\n * - date separators + per-message timestamps\n * - quick prompts + larger mobile composer controls\n * - bottom-sheet menu and activity panel for recent runs\n *\n * Keeps compatibility with the existing useChat() transport:\n * same message flow / approvals / reconnect behavior.\n */\n\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport {\n Activity,\n ArrowDown,\n ChevronLeft,\n Clock3,\n Loader2,\n MoreVertical,\n Sparkles,\n Send,\n} from 'lucide-react'\nimport { toast } from 'sonner'\n\nimport { useChat, type ChatMessage, type RunActivity } from '@/hooks/use-chat'\nimport { Button } from '@/components/ui/button'\nimport { Badge } from '@/components/ui/badge'\nimport { MessageBubble } from '@/components/chat/message-bubble'\nimport { ApprovalDock } from '@/components/chat/approval-dock'\nimport { AgentPicker } from '@/components/chat/agent-picker'\nimport { isNativeSetupError } from '@/components/chat/error-hints'\nimport { NativeSetupDialog } from '@/components/chat/native-setup-dialog'\nimport { cn } from '@/lib/utils'\n\nconst STATUS_STYLES: Record<string, string> = {\n open: 'bg-success',\n connecting: 'bg-warning animate-pulse',\n closed: 'bg-text-muted',\n error: 'bg-danger',\n}\n\ntype SheetMode = 'none' | 'menu' | 'activity'\ntype MessageRow =\n | { type: 'divider'; key: string; label: string }\n | { type: 'message'; key: string; msg: ChatMessage }\n\nfunction safeTs(ts: number): number {\n return Number.isFinite(ts) ? ts : Date.now()\n}\n\nfunction dayKey(ts: number): string {\n const d = new Date(safeTs(ts))\n const m = String(d.getMonth() + 1).padStart(2, '0')\n const day = String(d.getDate()).padStart(2, '0')\n return `${d.getFullYear()}-${m}-${day}`\n}\n\nfunction formatDay(ts: number, locale: string): string {\n return new Intl.DateTimeFormat(locale, {\n month: 'short',\n day: 'numeric',\n weekday: 'short',\n }).format(new Date(safeTs(ts)))\n}\n\nfunction formatClock(ts: number, locale: string): string {\n return new Intl.DateTimeFormat(locale, {\n hour: '2-digit',\n minute: '2-digit',\n }).format(new Date(safeTs(ts)))\n}\n\nfunction formatDurationMs(ms?: number): string {\n if (!ms || ms <= 0) return '0ms'\n if (ms < 1000) return `${ms}ms`\n return `${(ms / 1000).toFixed(ms >= 10_000 ? 0 : 1)}s`\n}\n\nfunction buildRows(messages: ChatMessage[], locale: string): MessageRow[] {\n const rows: MessageRow[] = []\n let prevDay = ''\n for (const msg of messages) {\n const k = dayKey(msg.timestamp)\n if (k !== prevDay) {\n rows.push({ type: 'divider', key: `d-${k}`, label: formatDay(msg.timestamp, locale) })\n prevDay = k\n }\n rows.push({ type: 'message', key: msg.id, msg })\n }\n return rows\n}\n\nfunction runStatusBadgeClass(status: RunActivity['status']): string {\n switch (status) {\n case 'running': return 'bg-info-bg text-info'\n case 'success': return 'bg-success-bg text-success'\n case 'error': return 'bg-danger-bg text-danger'\n }\n}\n\nexport default function MobileChatRoute(): JSX.Element {\n const { t, i18n } = useTranslation(['chat', 'common'])\n const {\n state, send, switchAgent, approvalClick, newConversation, clearError,\n } = useChat()\n const [input, setInput] = useState('')\n const [sheet, setSheet] = useState<SheetMode>('none')\n const [showScrollDown, setShowScrollDown] = useState(false)\n const [nativeSetupDialogOpen, setNativeSetupDialogOpen] = useState(false)\n const [nativeSetupReason, setNativeSetupReason] = useState('')\n const listRef = useRef<HTMLDivElement>(null)\n const inputRef = useRef<HTMLTextAreaElement>(null)\n\n const quickPrompts = useMemo(\n () => [\n t('chat.quickPrompt.plan', { defaultValue: '帮我先拆解这个任务' }),\n t('chat.quickPrompt.risks', { defaultValue: '先列出风险与回滚方案' }),\n t('chat.quickPrompt.summary', { defaultValue: '输出一版可发给老板的摘要' }),\n ],\n [t],\n )\n\n const chatMessages = useMemo(\n () => state.messages.filter((m) => !m.approval),\n [state.messages],\n )\n const rows = useMemo(\n () => buildRows(chatMessages, i18n.language),\n [chatMessages, i18n.language],\n )\n\n const latestUserTitle = useMemo(() => {\n const firstUser = chatMessages.find((m) => m.role === 'user' && m.content.trim())\n if (!firstUser) return t('chat.mobileTitle', { defaultValue: 'agim chat' })\n const compact = firstUser.content.replace(/\\s+/g, ' ').trim()\n return compact.length > 24 ? `${compact.slice(0, 24)}…` : compact\n }, [chatMessages, t])\n\n const latestRuns = useMemo(() => state.runActivities.slice(0, 12), [state.runActivities])\n const activeRun = useMemo(\n () => state.runActivities.find((r) => r.runId === state.activeRunId),\n [state.activeRunId, state.runActivities],\n )\n\n // Auto-scroll to bottom on new messages OR streaming chunk. Same\n // pinch-tolerance as desktop: hold position when user is reading up.\n useEffect(() => {\n const el = listRef.current\n if (!el) return\n const distFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight\n if (distFromBottom > 200 && state.currentReplyId == null) return\n requestAnimationFrame(() => { el.scrollTop = el.scrollHeight })\n }, [state.messages, state.currentReplyId])\n\n // Floating \"scroll to bottom\" pill.\n useEffect(() => {\n const el = listRef.current\n if (!el) return\n const onScroll = (): void => {\n const dist = el.scrollHeight - el.scrollTop - el.clientHeight\n setShowScrollDown(dist > 200)\n }\n el.addEventListener('scroll', onScroll, { passive: true })\n onScroll()\n return () => el.removeEventListener('scroll', onScroll)\n }, [])\n\n // Surface WS errors as toast and clear.\n useEffect(() => {\n if (!state.error) return\n if (isNativeSetupError(state.error)) {\n setNativeSetupReason(state.error)\n setNativeSetupDialogOpen(true)\n } else {\n toast.error(state.error)\n }\n clearError()\n }, [state.error, clearError])\n\n // Auto-grow textarea up to 6 lines.\n useEffect(() => {\n const ta = inputRef.current\n if (!ta) return\n ta.style.height = 'auto'\n ta.style.height = `${Math.min(ta.scrollHeight, 24 * 6 + 16)}px`\n }, [input])\n\n function onSubmit(e?: React.FormEvent): void {\n e?.preventDefault()\n const v = input.trim()\n if (!v) return\n if (state.status !== 'open') {\n toast.error(t('chat.notConnected', { defaultValue: 'Not connected. Reconnecting…' }))\n return\n }\n if (state.currentReplyId) return\n send(v)\n setInput('')\n requestAnimationFrame(() => inputRef.current?.focus())\n }\n\n function onKeyDown(e: React.KeyboardEvent<HTMLTextAreaElement>): void {\n // IME-safe: never submit while composition is active.\n const ne = e.nativeEvent as KeyboardEvent & { isComposing?: boolean }\n if (ne.isComposing || e.keyCode === 229) return\n // Mobile keeps Enter for newline; explicit Send button submits.\n }\n\n function onScrollToBottom(): void {\n const el = listRef.current\n if (!el) return\n el.scrollTo({ top: el.scrollHeight, behavior: 'smooth' })\n }\n\n function onLogout(): void {\n void fetch('/api/auth/logout', { method: 'POST' }).finally(() => {\n try { localStorage.removeItem('agim_token') } catch { /* noop */ }\n window.location.replace('/login')\n })\n }\n\n function onStartNewConversation(): void {\n newConversation()\n toast.success(t('chat.newConvToast', { defaultValue: 'Started a new conversation' }))\n setSheet('none')\n requestAnimationFrame(() => inputRef.current?.focus())\n }\n\n return (\n <div className=\"relative flex h-dvh flex-col bg-bg\">\n <NativeSetupDialog\n open={nativeSetupDialogOpen}\n reason={nativeSetupReason}\n onOpenChange={setNativeSetupDialogOpen}\n onConfigured={() => switchAgent('native')}\n />\n\n <header\n className=\"flex items-center gap-2 border-b border-border bg-surface px-3 py-2\"\n style={{ paddingTop: 'calc(env(safe-area-inset-top) + 0.5rem)' }}\n >\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label={t('chat.back', { defaultValue: 'Back' })}\n onClick={() => (window.history.length > 1 ? window.history.back() : window.location.assign('/'))}\n className=\"h-9 w-9 p-0\"\n >\n <ChevronLeft className=\"h-5 w-5\" />\n </Button>\n <div className=\"flex min-w-0 flex-1 flex-col items-center\">\n <span className=\"truncate text-sm font-semibold\">{latestUserTitle}</span>\n <span className=\"flex items-center gap-1.5 text-[11px] text-text-dim\">\n <span className={cn('inline-block h-1.5 w-1.5 rounded-full', STATUS_STYLES[state.status])} />\n <span>{state.agent || '—'}</span>\n <span>·</span>\n <span>{state.activeRunId ? t('chat.running', { defaultValue: 'Running' }) : state.status}</span>\n </span>\n </div>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label={t('chat.menu', { defaultValue: 'Menu' })}\n onClick={() => setSheet('menu')}\n className=\"h-9 w-9 p-0\"\n >\n <MoreVertical className=\"h-5 w-5\" />\n </Button>\n </header>\n\n <div ref={listRef} className=\"flex-1 overflow-y-auto\">\n <div className=\"mx-auto flex w-full max-w-3xl flex-col gap-3 px-3 py-4\">\n {chatMessages.length === 0 && state.status === 'open' && (\n <div className=\"flex flex-col items-center gap-2 py-14 text-center\">\n <div className=\"flex h-12 w-12 items-center justify-center rounded-full bg-surface-2 text-2xl\">\n 💬\n </div>\n <h2 className=\"text-base font-semibold\">\n {t('chat.welcomeTitle', { defaultValue: 'Start a conversation' })}\n </h2>\n <p className=\"max-w-xs text-sm text-text-dim\">\n {t('chat.welcomeBodyMobile', {\n defaultValue: 'Type a message below. Switch agent or start over from the menu.',\n })}\n </p>\n </div>\n )}\n {chatMessages.length === 0 && state.status !== 'open' && (\n <div className=\"grid place-items-center py-16 text-center\">\n <p className=\"text-sm text-text-dim\">\n {state.status === 'connecting'\n ? t('chat.connecting', { defaultValue: 'Connecting to agim…' })\n : t('chat.disconnected', {\n defaultValue: 'Disconnected. Reconnecting automatically.',\n })}\n </p>\n </div>\n )}\n {rows.map((row) => row.type === 'divider' ? (\n <div key={row.key} className=\"py-1 text-center text-[11px] text-text-muted\">\n {row.label}\n </div>\n ) : (\n <div key={row.key} className=\"space-y-1\">\n <MessageBubble\n msg={row.msg}\n onApprove={(mid, reqId, choice) => approvalClick(mid, reqId, choice)}\n />\n <div className={cn(\n 'px-1 text-[11px] text-text-muted',\n row.msg.role === 'user' ? 'text-right' : 'text-left',\n )}\n >\n {formatClock(row.msg.timestamp, i18n.language)}\n </div>\n </div>\n ))}\n </div>\n </div>\n\n {showScrollDown && (\n <button\n type=\"button\"\n onClick={onScrollToBottom}\n className=\"absolute bottom-28 left-1/2 z-20 -translate-x-1/2 rounded-full border border-border bg-surface p-2 shadow-md\"\n aria-label={t('chat.scrollDown', { defaultValue: 'Scroll to bottom' })}\n >\n <ArrowDown className=\"h-4 w-4\" />\n </button>\n )}\n\n <ApprovalDock\n approvals={state.pendingApprovals}\n onApprove={(mid, reqId, choice) => approvalClick(mid, reqId, choice)}\n />\n\n <form\n onSubmit={onSubmit}\n className=\"sticky bottom-0 border-t border-border bg-surface px-3 py-2\"\n style={{ paddingBottom: 'calc(env(safe-area-inset-bottom) + 0.5rem)' }}\n >\n {chatMessages.length === 0 && state.status === 'open' && (\n <div className=\"mb-2 flex gap-2 overflow-x-auto pb-1\">\n {quickPrompts.map((prompt) => (\n <button\n key={prompt}\n type=\"button\"\n onClick={() => {\n setInput(prompt)\n requestAnimationFrame(() => inputRef.current?.focus())\n }}\n className=\"shrink-0 rounded-full border border-border bg-surface-2 px-3 py-1.5 text-xs text-text-dim hover:bg-surface-hover\"\n >\n {prompt}\n </button>\n ))}\n </div>\n )}\n\n {activeRun && (\n <div className=\"mb-2 flex items-center justify-between rounded-xl border border-info/30 bg-info-bg/50 px-3 py-1.5\">\n <span className=\"inline-flex items-center gap-1 text-xs text-info\">\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" />\n {t('chat.running', { defaultValue: 'Running' })}\n </span>\n <span className=\"truncate text-xs text-text-dim\">\n {activeRun.agent} · {formatDurationMs(activeRun.durationMs)}\n </span>\n </div>\n )}\n\n <div className=\"flex items-end gap-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={onStartNewConversation}\n disabled={state.status !== 'open' || !!state.currentReplyId}\n aria-label={t('chat.newConv', { defaultValue: 'New conversation' })}\n className=\"h-11 w-11 shrink-0 rounded-full p-0\"\n >\n <Sparkles className=\"h-4 w-4\" />\n </Button>\n <textarea\n ref={inputRef}\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={onKeyDown}\n placeholder={t('chat.inputPlaceholderMobile', { defaultValue: 'Message…' })}\n rows={1}\n className={cn(\n 'flex-1 resize-none rounded-3xl border border-border bg-bg',\n 'px-3 py-2 text-[15px] leading-6',\n 'focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-1 focus:ring-offset-bg',\n )}\n />\n <Button\n type=\"submit\"\n disabled={!input.trim() || state.status !== 'open' || !!state.currentReplyId}\n aria-label={t('chat.send', { defaultValue: 'Send' })}\n className=\"h-11 w-11 shrink-0 rounded-full p-0\"\n >\n {state.currentReplyId ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send className=\"h-4 w-4\" />\n )}\n </Button>\n </div>\n\n <div className=\"mt-2 flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n {state.currentReplyId && (\n <Badge variant=\"info\">\n {t('chat.streaming', { defaultValue: '… streaming' })}\n </Badge>\n )}\n {!state.currentReplyId && (\n <span className=\"text-[11px] text-text-muted\">\n {t('chat.mobileHint', { defaultValue: 'Enter 换行,点发送提交。' })}\n </span>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => setSheet('activity')}\n className=\"inline-flex items-center gap-1 rounded px-1.5 py-1 text-xs text-text-dim hover:bg-surface-hover hover:text-text\"\n >\n <Activity className=\"h-3.5 w-3.5\" />\n {t('chat.activity', { defaultValue: 'Activity' })}\n </button>\n </div>\n </form>\n\n {sheet !== 'none' && (\n <>\n <button\n type=\"button\"\n aria-label={t('actions.close', { ns: 'common', defaultValue: 'Close' })}\n className=\"fixed inset-0 z-30 bg-black/35\"\n onClick={() => setSheet('none')}\n />\n <div className=\"fixed inset-x-0 bottom-0 z-40 rounded-t-2xl border border-border bg-surface px-4 pb-safe pt-3 shadow-lg\">\n <div className=\"mx-auto mb-3 h-1.5 w-12 rounded-full bg-border\" />\n\n {sheet === 'menu' && (\n <div className=\"space-y-3 pb-3\">\n <div>\n <div className=\"mb-1 text-[11px] uppercase text-text-dim\">\n {t('chat.agent', { defaultValue: 'Agent' })}\n </div>\n <AgentPicker\n agents={state.agents}\n value={state.agent}\n onChange={(a) => {\n switchAgent(a)\n setSheet('none')\n }}\n />\n </div>\n\n <button\n type=\"button\"\n className=\"block w-full rounded-md border border-border px-3 py-2 text-left text-sm hover:bg-surface-hover disabled:opacity-50\"\n disabled={state.status !== 'open' || !!state.currentReplyId}\n onClick={onStartNewConversation}\n >\n {t('chat.newConv', { defaultValue: 'New conversation' })}\n </button>\n\n <button\n type=\"button\"\n className=\"block w-full rounded-md border border-border px-3 py-2 text-left text-sm hover:bg-surface-hover\"\n onClick={() => setSheet('activity')}\n >\n {t('chat.activity', { defaultValue: 'Activity' })}\n </button>\n\n <button\n type=\"button\"\n className=\"block w-full rounded-md border border-border px-3 py-2 text-left text-sm hover:bg-surface-hover\"\n onClick={() => {\n setSheet('none')\n window.location.assign('/settings/llm')\n }}\n >\n {t('chat.llmSettings', { defaultValue: 'LLM settings' })}\n </button>\n\n <button\n type=\"button\"\n className=\"block w-full rounded-md border border-danger/30 px-3 py-2 text-left text-sm text-danger hover:bg-danger/10\"\n onClick={onLogout}\n >\n {t('chat.logout', { defaultValue: 'Log out' })}\n </button>\n </div>\n )}\n\n {sheet === 'activity' && (\n <div className=\"space-y-3 pb-3\">\n <div className=\"flex items-center justify-between\">\n <div className=\"text-sm font-semibold\">\n {t('chat.activityTitle', { defaultValue: 'Run activity' })}\n </div>\n <button\n type=\"button\"\n className=\"text-xs text-text-dim hover:text-text\"\n onClick={() => setSheet('menu')}\n >\n {t('actions.back', { ns: 'common', defaultValue: 'Back' })}\n </button>\n </div>\n\n <div className=\"rounded-md border border-border bg-surface-2 px-3 py-2 text-xs text-text-dim\">\n {t('chat.pendingApprovals', { defaultValue: 'Pending approvals' })}: {state.pendingApprovals.length}\n </div>\n\n <div className=\"max-h-72 space-y-2 overflow-y-auto pr-1\">\n {latestRuns.length === 0 && (\n <div className=\"rounded-md border border-border px-3 py-5 text-center text-xs text-text-dim\">\n {t('chat.activityEmpty', { defaultValue: 'No recent runs yet.' })}\n </div>\n )}\n {latestRuns.map((run) => (\n <div key={run.runId} className=\"rounded-md border border-border px-3 py-2\">\n <div className=\"flex items-center gap-2\">\n <Badge className={cn('border-0', runStatusBadgeClass(run.status))}>\n {run.status}\n </Badge>\n <span className=\"truncate text-xs font-medium\">{run.agent}</span>\n <span className=\"ml-auto text-[11px] text-text-muted\">\n {formatDurationMs(run.durationMs)}\n </span>\n </div>\n <div className=\"mt-1 flex items-center gap-1 text-[11px] text-text-muted\">\n <Clock3 className=\"h-3 w-3\" />\n {formatClock(run.startedAt, i18n.language)}\n {run.outputChars != null && (\n <span>· {run.outputChars} chars</span>\n )}\n </div>\n {run.error && (\n <p className=\"mt-1 text-[11px] text-danger\">{run.error}</p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n </>\n )}\n </div>\n )\n}\n"],"names":["Clock3","createLucideIcon","EllipsisVertical","Sparkles","STATUS_STYLES","safeTs","ts","dayKey","d","m","day","formatDay","locale","formatClock","formatDurationMs","ms","buildRows","messages","rows","prevDay","msg","k","runStatusBadgeClass","status","MobileChatRoute","t","i18n","useTranslation","state","send","switchAgent","approvalClick","newConversation","clearError","useChat","input","setInput","useState","sheet","setSheet","showScrollDown","setShowScrollDown","nativeSetupDialogOpen","setNativeSetupDialogOpen","nativeSetupReason","setNativeSetupReason","listRef","useRef","inputRef","quickPrompts","useMemo","chatMessages","latestUserTitle","firstUser","compact","latestRuns","activeRun","r","useEffect","el","onScroll","dist","isNativeSetupError","toast","ta","onSubmit","e","v","onKeyDown","onScrollToBottom","onLogout","onStartNewConversation","jsxs","jsx","NativeSetupDialog","Button","ChevronLeft","cn","MoreVertical","row","MessageBubble","mid","reqId","choice","ArrowDown","ApprovalDock","prompt","Loader2","Send","Badge","Activity","Fragment","AgentPicker","a","run"],"mappings":"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","x_google_ignoreList":[0,1,2]}
@@ -1,17 +0,0 @@
1
- import{o as h,u as g,j as e,l as p,B as d,m as j}from"./index-D7BuMEIr.js";import{r as u}from"./react-DlP5eolq.js";import{T as N,a as v,b as m,c as i,d as k,e as t}from"./table-CSHCu7pz.js";import{b as w,c as C}from"./use-background-tasks-D77bcfrq.js";import{L as T}from"./loader-circle-DO3Ni2RJ.js";import{R as L}from"./refresh-ccw-BhPAzZAa.js";import{C as M}from"./circle-check-DhcTh_uP.js";import{C as S}from"./circle-x-QODE2UcL.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 z=h("CircleDashed",[["path",{d:"M10.1 2.182a10 10 0 0 1 3.8 0",key:"5ilxe3"}],["path",{d:"M13.9 21.818a10 10 0 0 1-3.8 0",key:"11zvb9"}],["path",{d:"M17.609 3.721a10 10 0 0 1 2.69 2.7",key:"1iw5b2"}],["path",{d:"M2.182 13.9a10 10 0 0 1 0-3.8",key:"c0bmvh"}],["path",{d:"M20.279 17.609a10 10 0 0 1-2.7 2.69",key:"1ruxm7"}],["path",{d:"M21.818 10.1a10 10 0 0 1 0 3.8",key:"qkgqxc"}],["path",{d:"M3.721 6.391a10 10 0 0 1 2.7-2.69",key:"1mcia2"}],["path",{d:"M6.391 20.279a10 10 0 0 1-2.69-2.7",key:"1fvljs"}]]);/**
7
- * @license lucide-react v0.469.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const B=h("CirclePause",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"10",x2:"10",y1:"15",y2:"9",key:"c1nkhi"}],["line",{x1:"14",x2:"14",y1:"15",y2:"9",key:"h65svq"}]]);/**
12
- * @license lucide-react v0.469.0 - ISC
13
- *
14
- * This source code is licensed under the ISC license.
15
- * See the LICENSE file in the root directory of this source tree.
16
- */const P=h("Target",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["circle",{cx:"12",cy:"12",r:"6",key:"1vlfrh"}],["circle",{cx:"12",cy:"12",r:"2",key:"1c9p78"}]]);function U(){const{t:s}=g(["tasks","common"]),r=w(),o=C(),[y,f]=u.useState(null);async function n(a,l){try{await o.mutateAsync({id:a.id,status:l}),j.success(s("goals.statusUpdated",{status:l}))}catch(c){j.error(c?.message??String(c))}}const x=r.data?.goals??[];return e.jsxs("div",{className:"mx-auto flex max-w-6xl flex-col gap-4 p-4",children:[e.jsxs("header",{className:"flex items-center gap-3",children:[e.jsx(P,{className:"h-5 w-5 text-text-dim"}),e.jsx("h1",{className:"text-xl font-semibold",children:s("goals.title")}),e.jsx(p,{variant:"info",children:x.length}),e.jsxs(d,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>void r.refetch(),disabled:r.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[r.isFetching?e.jsx(T,{className:"h-4 w-4 animate-spin"}):e.jsx(L,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("goals.refresh")})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("goals.subtitle")}),r.isLoading?e.jsx("div",{className:"h-48 rounded-md bg-surface-2 animate-pulse"}):x.length===0?e.jsx(A,{}):e.jsx("section",{className:"rounded-md border border-border bg-surface",children:e.jsxs(N,{children:[e.jsx(v,{children:e.jsxs(m,{children:[e.jsx(i,{className:"w-12",children:s("goals.col.id")}),e.jsx(i,{children:s("goals.col.thread")}),e.jsx(i,{children:s("goals.col.title")}),e.jsx(i,{children:s("goals.col.progress")}),e.jsx(i,{children:s("goals.col.updated")}),e.jsx(i,{children:s("goals.col.actions")})]})}),e.jsx(k,{children:x.map(a=>{const l=y===a.id;return e.jsxs(u.Fragment,{children:[e.jsxs(m,{children:[e.jsx(t,{className:"font-mono text-xs",children:a.id}),e.jsxs(t,{className:"font-mono text-[11px]",children:[a.platform,":",a.threadId]}),e.jsx(t,{children:e.jsx(d,{variant:"ghost",size:"sm",className:"-ml-2 text-left",onClick:()=>f(l?null:a.id),title:s(l?"goals.hideBody":"goals.showBody"),children:a.title})}),e.jsx(t,{children:e.jsx(p,{variant:"outline",children:a.progressCount})}),e.jsx(t,{className:"text-[11px] text-text-dim",children:a.updatedAt}),e.jsxs(t,{className:"flex flex-wrap gap-1",children:[e.jsx(d,{variant:"ghost",size:"sm",title:s("goals.pause"),onClick:()=>void n(a,"paused"),disabled:o.isPending,children:e.jsx(B,{className:"h-4 w-4"})}),e.jsx(d,{variant:"ghost",size:"sm",title:s("goals.complete"),onClick:()=>void n(a,"completed"),disabled:o.isPending,children:e.jsx(M,{className:"h-4 w-4 text-success"})}),e.jsx(d,{variant:"ghost",size:"sm",title:s("goals.cancel"),onClick:()=>void n(a,"cancelled"),disabled:o.isPending,className:"text-danger hover:text-danger",children:e.jsx(S,{className:"h-4 w-4"})})]})]}),l&&e.jsxs(m,{children:[e.jsx(t,{}),e.jsx(t,{colSpan:5,children:e.jsxs("div",{className:"space-y-2 rounded bg-surface-2 p-3 text-xs",children:[a.body&&e.jsxs("div",{children:[e.jsx("div",{className:"text-text-dim",children:s("goals.body")}),e.jsx("pre",{className:"mt-1 whitespace-pre-wrap break-words",children:a.body})]}),a.progressLog.length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"text-text-dim",children:s("goals.recentProgress",{count:a.progressLog.length})}),e.jsx("ul",{className:"mt-1 space-y-1",children:a.progressLog.slice().reverse().map((c,b)=>e.jsxs("li",{className:"font-mono text-[11px]",children:[e.jsxs("span",{className:"text-text-dim",children:[c.ts.slice(0,19)," (",c.by,")"]})," ",c.text]},b))})]}),e.jsxs("div",{className:"text-[11px] text-text-dim",children:[s("goals.created",{at:a.createdAt}),a.closedAt?` · ${s("goals.closed",{at:a.closedAt})}`:""]})]})})]})]},a.id)})})]})})]})}function A(){const{t:s}=g("tasks");return e.jsxs("section",{className:"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim",children:[s("goals.empty"),e.jsx("div",{className:"mt-2",children:e.jsx(z,{className:"mx-auto h-8 w-8 opacity-30"})})]})}export{U as default};
17
- //# sourceMappingURL=goals-HsKzf-PG.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"goals-HsKzf-PG.js","sources":["../../node_modules/lucide-react/dist/esm/icons/circle-dashed.js","../../node_modules/lucide-react/dist/esm/icons/circle-pause.js","../../node_modules/lucide-react/dist/esm/icons/target.js","../../src/routes/tasks/goals.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CircleDashed = createLucideIcon(\"CircleDashed\", [\n [\"path\", { d: \"M10.1 2.182a10 10 0 0 1 3.8 0\", key: \"5ilxe3\" }],\n [\"path\", { d: \"M13.9 21.818a10 10 0 0 1-3.8 0\", key: \"11zvb9\" }],\n [\"path\", { d: \"M17.609 3.721a10 10 0 0 1 2.69 2.7\", key: \"1iw5b2\" }],\n [\"path\", { d: \"M2.182 13.9a10 10 0 0 1 0-3.8\", key: \"c0bmvh\" }],\n [\"path\", { d: \"M20.279 17.609a10 10 0 0 1-2.7 2.69\", key: \"1ruxm7\" }],\n [\"path\", { d: \"M21.818 10.1a10 10 0 0 1 0 3.8\", key: \"qkgqxc\" }],\n [\"path\", { d: \"M3.721 6.391a10 10 0 0 1 2.7-2.69\", key: \"1mcia2\" }],\n [\"path\", { d: \"M6.391 20.279a10 10 0 0 1-2.69-2.7\", key: \"1fvljs\" }]\n]);\n\nexport { CircleDashed as default };\n//# sourceMappingURL=circle-dashed.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CirclePause = createLucideIcon(\"CirclePause\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"10\", x2: \"10\", y1: \"15\", y2: \"9\", key: \"c1nkhi\" }],\n [\"line\", { x1: \"14\", x2: \"14\", y1: \"15\", y2: \"9\", key: \"h65svq\" }]\n]);\n\nexport { CirclePause as default };\n//# sourceMappingURL=circle-pause.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Target = createLucideIcon(\"Target\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"6\", key: \"1vlfrh\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"2\", key: \"1c9p78\" }]\n]);\n\nexport { Target as default };\n//# sourceMappingURL=target.js.map\n","/**\n * /tasks/goals — admin overview of every ACTIVE goal (P1).\n */\n\nimport { Fragment, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { CheckCircle2, CircleDashed, Loader2, PauseCircle, RefreshCcw, Target, XCircle } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useGoalsList, useGoalUpdateStatus, type GoalRow,\n} from '@/hooks/use-background-tasks'\n\nexport default function TasksGoalsRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const listQuery = useGoalsList()\n const updateStatus = useGoalUpdateStatus()\n const [expandedId, setExpandedId] = useState<number | null>(null)\n\n async function onChangeStatus(g: GoalRow, status: GoalRow['status']): Promise<void> {\n try {\n await updateStatus.mutateAsync({ id: g.id, status })\n toast.success(t('goals.statusUpdated', { status }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n const rows = listQuery.data?.goals ?? []\n return (\n <div className=\"mx-auto flex max-w-6xl flex-col gap-4 p-4\">\n <header className=\"flex items-center gap-3\">\n <Target className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('goals.title')}</h1>\n <Badge variant=\"info\">{rows.length}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('goals.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('goals.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : rows.length === 0 ? (\n <EmptySection />\n ) : (\n <section className=\"rounded-md border border-border bg-surface\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-12\">{t('goals.col.id')}</TableHead>\n <TableHead>{t('goals.col.thread')}</TableHead>\n <TableHead>{t('goals.col.title')}</TableHead>\n <TableHead>{t('goals.col.progress')}</TableHead>\n <TableHead>{t('goals.col.updated')}</TableHead>\n <TableHead>{t('goals.col.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((g) => {\n const isExpanded = expandedId === g.id\n return (\n <Fragment key={g.id}>\n <TableRow>\n <TableCell className=\"font-mono text-xs\">{g.id}</TableCell>\n <TableCell className=\"font-mono text-[11px]\">{g.platform}:{g.threadId}</TableCell>\n <TableCell>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"-ml-2 text-left\"\n onClick={() => setExpandedId(isExpanded ? null : g.id)}\n title={isExpanded ? t('goals.hideBody') : t('goals.showBody')}\n >\n {g.title}\n </Button>\n </TableCell>\n <TableCell><Badge variant=\"outline\">{g.progressCount}</Badge></TableCell>\n <TableCell className=\"text-[11px] text-text-dim\">{g.updatedAt}</TableCell>\n <TableCell className=\"flex flex-wrap gap-1\">\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.pause')}\n onClick={() => void onChangeStatus(g, 'paused')}\n disabled={updateStatus.isPending}\n >\n <PauseCircle className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.complete')}\n onClick={() => void onChangeStatus(g, 'completed')}\n disabled={updateStatus.isPending}\n >\n <CheckCircle2 className=\"h-4 w-4 text-success\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.cancel')}\n onClick={() => void onChangeStatus(g, 'cancelled')}\n disabled={updateStatus.isPending}\n className=\"text-danger hover:text-danger\"\n >\n <XCircle className=\"h-4 w-4\" />\n </Button>\n </TableCell>\n </TableRow>\n {isExpanded && (\n <TableRow>\n <TableCell />\n <TableCell colSpan={5}>\n <div className=\"space-y-2 rounded bg-surface-2 p-3 text-xs\">\n {g.body && (\n <div>\n <div className=\"text-text-dim\">{t('goals.body')}</div>\n <pre className=\"mt-1 whitespace-pre-wrap break-words\">{g.body}</pre>\n </div>\n )}\n {g.progressLog.length > 0 && (\n <div>\n <div className=\"text-text-dim\">\n {t('goals.recentProgress', { count: g.progressLog.length })}\n </div>\n <ul className=\"mt-1 space-y-1\">\n {g.progressLog.slice().reverse().map((n, i) => (\n <li key={i} className=\"font-mono text-[11px]\">\n <span className=\"text-text-dim\">{n.ts.slice(0, 19)} ({n.by})</span> {n.text}\n </li>\n ))}\n </ul>\n </div>\n )}\n <div className=\"text-[11px] text-text-dim\">\n {t('goals.created', { at: g.createdAt })}\n {g.closedAt ? ` · ${t('goals.closed', { at: g.closedAt })}` : ''}\n </div>\n </div>\n </TableCell>\n </TableRow>\n )}\n </Fragment>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )}\n </div>\n )\n}\n\nfunction EmptySection(): JSX.Element {\n const { t } = useTranslation('tasks')\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('goals.empty')}\n <div className=\"mt-2\">\n <CircleDashed className=\"mx-auto h-8 w-8 opacity-30\" />\n </div>\n </section>\n )\n}\n"],"names":["CircleDashed","createLucideIcon","CirclePause","Target","TasksGoalsRoute","t","useTranslation","listQuery","useGoalsList","updateStatus","useGoalUpdateStatus","expandedId","setExpandedId","useState","onChangeStatus","g","status","toast","err","rows","jsxs","jsx","Badge","Button","Loader2","RefreshCcw","EmptySection","Table","TableHeader","TableRow","TableHead","TableBody","isExpanded","Fragment","TableCell","PauseCircle","CheckCircle2","XCircle","n","i"],"mappings":"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","x_google_ignoreList":[0,1,2]}
@@ -1,12 +0,0 @@
1
- import{o as w,b as y,d as C,u as x,j as e,B as u,I as S,l as m,c as k,D as L,t as D,v as F,w as H,x as R,m as j}from"./index-D7BuMEIr.js";import{r as o}from"./react-DlP5eolq.js";import{E}from"./empty-state-DoiBKL4l.js";import{E as M}from"./external-link-Bf2430Ji.js";import{L as T}from"./loader-circle-DO3Ni2RJ.js";import{R as z}from"./refresh-ccw-BhPAzZAa.js";import{S as I}from"./search-BQqVArrW.js";import{D as A}from"./download-EUh-RXv5.js";import{C as B}from"./copy-VJNELMp7.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 N=w("Flame",[["path",{d:"M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z",key:"96xj49"}]]);/**
7
- * @license lucide-react v0.469.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const $=w("Star",[["path",{d:"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z",key:"r04s7s"}]]),q={remoteHot:["skills","remote","hot"]};function K(){return y({queryKey:q.remoteHot,queryFn:()=>C.getSkillsRemoteHot(),staleTime:6e4})}function ee(){const{t:s}=x(["skills","common"]),{data:l,isLoading:a,isFetching:r,refetch:i}=K(),n=l?.skills??[],[h,b]=o.useState(""),[p,f]=o.useState(null),g=o.useMemo(()=>{const t=h.trim().toLowerCase();return t?n.filter(d=>d.slug.toLowerCase().includes(t)||(d.name||"").toLowerCase().includes(t)||(d.description||"").toLowerCase().includes(t)||(d.category||"").toLowerCase().includes(t)):n},[n,h]),v=p?n.find(t=>t.slug===p)??null:null;return e.jsxs("div",{className:"mx-auto flex max-w-5xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs("h1",{className:"text-xl font-semibold inline-flex items-center gap-2",children:[e.jsx(N,{className:"h-5 w-5 text-warning"}),s("hot.title")]}),e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[e.jsx(u,{asChild:!0,variant:"ghost",size:"sm",children:e.jsxs("a",{href:"https://skillhub.cn",target:"_blank",rel:"noopener noreferrer",children:[e.jsx(M,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("hot.openHub")})]})}),e.jsxs(u,{variant:"ghost",size:"sm",onClick:()=>i(),disabled:r,"aria-label":s("actions.refresh",{ns:"common"}),children:[r?e.jsx(T,{className:"h-4 w-4 animate-spin"}):e.jsx(z,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("hot.subtitle")}),l&&e.jsx(O,{cached:!!l.cached,stale:!!l.stale,fetchedAt:l.fetchedAt})]}),n.length>0&&e.jsxs("div",{className:"flex flex-wrap items-end gap-2",children:[e.jsxs("div",{className:"relative flex-1 min-w-[180px] max-w-md",children:[e.jsx(I,{className:"pointer-events-none absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-text-muted"}),e.jsx(S,{value:h,onChange:t=>b(t.target.value),placeholder:s("actions.search",{ns:"common"}),className:"pl-7"})]}),e.jsxs(m,{variant:"secondary",className:"ml-auto",children:[g.length," / ",n.length]})]}),a?e.jsx("div",{className:"h-48 w-full rounded-md bg-surface-2 animate-pulse"}):n.length===0?e.jsx(E,{icon:e.jsx(N,{}),title:s("hot.empty")}):e.jsx("ul",{className:"flex flex-col gap-2",children:g.map(t=>e.jsx("li",{children:e.jsxs("button",{type:"button",onClick:()=>f(t.slug),className:k("flex w-full flex-col gap-1 rounded-md border border-border bg-surface px-3 py-2 text-left","transition-colors hover:border-border-strong hover:bg-surface-hover"),children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:t.name||t.slug}),t.version&&e.jsxs("span",{className:"text-text-muted text-xs font-mono",children:["v",t.version]}),t.category&&e.jsx(m,{variant:"outline",children:t.category}),e.jsxs("div",{className:"ml-auto flex items-center gap-3 text-xs text-text-dim tabular-nums",children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx($,{className:"h-3 w-3"}),c(t.stars)]}),e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(A,{className:"h-3 w-3"}),c(t.installs)]})]})]}),e.jsx("code",{className:"text-text-muted text-xs font-mono",children:t.slug}),t.description&&e.jsx("p",{className:"line-clamp-2 text-sm text-text-dim",children:t.description})]})},t.slug))}),e.jsx(Q,{skill:v,onOpenChange:t=>{t||f(null)}})]})}function O({cached:s,stale:l,fetchedAt:a}){const{t:r}=x("skills"),i=o.useMemo(()=>{try{const n=new Date(a);return Number.isNaN(n.getTime())?"":n.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return""}},[a]);return e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs text-text-muted",children:[e.jsx("span",{children:r("hot.updatedAt",{at:i})}),s&&e.jsx(m,{variant:"outline",children:r("hot.cached")}),l&&e.jsx(m,{variant:"warning",children:r("hot.stale")})]})}function Q({skill:s,onOpenChange:l}){const{t:a}=x("skills"),r=o.useMemo(()=>s?[{key:"cliInstall",cmd:`skillhub install ${s.slug}`},{key:"cliSearch",cmd:`skillhub search ${s.slug}`},{key:"imAsk",cmd:`请用 skillhub 安装 ${s.slug} 技能`}]:[],[s]);return e.jsx(L,{open:s!=null,onOpenChange:l,children:e.jsxs(D,{className:"sm:max-w-2xl",children:[e.jsxs(F,{children:[e.jsx(H,{children:s?.name||s?.slug||""}),s?.description&&e.jsx(R,{children:s.description})]}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("dl",{className:"grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-xs",children:[e.jsx("dt",{className:"text-text-dim",children:"slug"}),e.jsx("dd",{className:"font-mono",children:s.slug}),s.version&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:a("hot.detail.version")}),e.jsxs("dd",{className:"font-mono",children:["v",s.version]})]}),s.category&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:a("hot.detail.category")}),e.jsx("dd",{children:s.category})]}),e.jsx("dt",{className:"text-text-dim",children:a("hot.detail.stars")}),e.jsx("dd",{className:"tabular-nums",children:c(s.stars)}),e.jsx("dt",{className:"text-text-dim",children:a("hot.detail.installs")}),e.jsx("dd",{className:"tabular-nums",children:c(s.installs)}),s.downloads!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:a("hot.detail.downloads")}),e.jsx("dd",{className:"tabular-nums",children:c(s.downloads)})]})]}),e.jsxs("div",{className:"mt-4 border-t border-border pt-3",children:[e.jsx("h3",{className:"text-sm font-medium",children:a("hot.detail.howInstall")}),e.jsx("ul",{className:"mt-2 flex flex-col gap-2",children:r.map(i=>e.jsxs("li",{className:"flex flex-col gap-1 sm:flex-row sm:items-center sm:gap-2",children:[e.jsx("span",{className:"text-xs text-text-dim sm:w-40 sm:shrink-0",children:a(`hot.detail.label.${i.key}`)}),e.jsx("code",{className:"flex-1 rounded bg-surface-2 px-2 py-1 font-mono text-xs break-all",children:i.cmd}),e.jsx(_,{text:i.cmd})]},i.key))}),e.jsx("p",{className:"mt-3 text-[11px] text-text-muted",children:a("hot.detail.hint")})]})]})]})})}function _({text:s}){const{t:l}=x("skills"),[a,r]=o.useState(!1);async function i(){try{await navigator.clipboard.writeText(s),r(!0),j.success(l("hot.detail.copied")),setTimeout(()=>r(!1),1500)}catch(n){j.error(String(n?.message??n))}}return e.jsxs(u,{type:"button",variant:"secondary",size:"sm",onClick:()=>void i(),className:"shrink-0",children:[e.jsx(B,{className:"h-3 w-3"}),l(a?"hot.detail.copied":"hot.detail.copy")]})}function c(s){return s==null||!Number.isFinite(s)?"—":s.toLocaleString()}export{ee as default};
12
- //# sourceMappingURL=hot-DkFvD3H4.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hot-DkFvD3H4.js","sources":["../../node_modules/lucide-react/dist/esm/icons/flame.js","../../node_modules/lucide-react/dist/esm/icons/star.js","../../src/hooks/use-skills.ts","../../src/routes/settings/agim-skills/hot.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Flame = createLucideIcon(\"Flame\", [\n [\n \"path\",\n {\n d: \"M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z\",\n key: \"96xj49\"\n }\n ]\n]);\n\nexport { Flame as default };\n//# sourceMappingURL=flame.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Star = createLucideIcon(\"Star\", [\n [\n \"path\",\n {\n d: \"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\",\n key: \"r04s7s\"\n }\n ]\n]);\n\nexport { Star as default };\n//# sourceMappingURL=star.js.map\n","/**\n * useSkills — read-only browse of the agent skills.\n *\n * useSkills() — list of every skill on disk\n * useSkillDetail(slug) — markdown body, fetched on demand\n * when the modal opens\n *\n * No mutations: installs happen via the skillhub CLI on the host,\n * agim is strictly read-only here.\n */\n\nimport { useQuery } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type {\n ListSkillsResponse,\n RemoteHotSkillsResponse,\n SkillDetail,\n} from '@/types/api'\n\nexport const skillsKeys = {\n all: ['skills'] as const,\n list: ['skills', 'list'] as const,\n detail: (slug: string) => ['skills', 'detail', slug] as const,\n remoteHot: ['skills', 'remote', 'hot'] as const,\n}\n\nexport function useSkills() {\n return useQuery<ListSkillsResponse>({\n queryKey: skillsKeys.list,\n queryFn: () => api.listSkills(),\n })\n}\n\nexport function useSkillDetail(slug: string | null) {\n return useQuery<SkillDetail>({\n queryKey: skillsKeys.detail(slug ?? ''),\n queryFn: () => api.getSkillDetail(slug as string),\n enabled: Boolean(slug),\n })\n}\n\n/** skillhub.cn hot list. The proxy on the server caches for 5 min and\n * serves stale-while-error, so we don't need an aggressive client-side\n * refresh — the operator hits the refresh button when they want fresh\n * data. staleTime keeps tab-switch round-trips cheap. */\nexport function useSkillsRemoteHot() {\n return useQuery<RemoteHotSkillsResponse>({\n queryKey: skillsKeys.remoteHot,\n queryFn: () => api.getSkillsRemoteHot(),\n staleTime: 60_000,\n })\n}\n","/**\n * /skills/hot — read-only browse of skillhub.cn's hot list.\n *\n * Backed by /api/skills/remote/hot (server proxies upstream with a\n * 5-min cache + stale-while-error). agim never auto-runs an install:\n * the detail dialog surfaces three copy-pasteable commands and the\n * operator decides where to execute.\n *\n * Restored from v1's tasks.html in 2026-05; the v2 SPA had the\n * installed-skills view but had dropped the hot list during the\n * memory-tab port.\n */\n\nimport { useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport {\n Copy,\n Download,\n ExternalLink,\n Flame,\n Loader2,\n RefreshCcw,\n Search,\n Star,\n} from 'lucide-react'\n\nimport { EmptyState } from '@/components/common/empty-state'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '@/components/ui/dialog'\nimport { Input } from '@/components/ui/input'\nimport { useSkillsRemoteHot } from '@/hooks/use-skills'\nimport type { RemoteSkill } from '@/types/api'\nimport { cn } from '@/lib/utils'\n\nexport default function SkillsHotRoute(): JSX.Element {\n const { t } = useTranslation(['skills', 'common'])\n const { data, isLoading, isFetching, refetch } = useSkillsRemoteHot()\n\n const skills: RemoteSkill[] = data?.skills ?? []\n const [q, setQ] = useState('')\n const [openSlug, setOpenSlug] = useState<string | null>(null)\n\n const filtered = useMemo(() => {\n const needle = q.trim().toLowerCase()\n if (!needle) return skills\n return skills.filter((s) =>\n s.slug.toLowerCase().includes(needle)\n || (s.name || '').toLowerCase().includes(needle)\n || (s.description || '').toLowerCase().includes(needle)\n || (s.category || '').toLowerCase().includes(needle)\n )\n }, [skills, q])\n\n const openSkill = openSlug ? skills.find((s) => s.slug === openSlug) ?? null : null\n\n return (\n <div className=\"mx-auto flex max-w-5xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold inline-flex items-center gap-2\">\n <Flame className=\"h-5 w-5 text-warning\" />\n {t('hot.title')}\n </h1>\n <div className=\"ml-auto flex items-center gap-2\">\n <Button\n asChild\n variant=\"ghost\"\n size=\"sm\"\n >\n <a\n href=\"https://skillhub.cn\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <ExternalLink className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">{t('hot.openHub')}</span>\n </a>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n </div>\n <p className=\"text-sm text-text-dim\">{t('hot.subtitle')}</p>\n {data && (\n <CacheMeta\n cached={!!data.cached}\n stale={!!data.stale}\n fetchedAt={data.fetchedAt}\n />\n )}\n </header>\n\n {skills.length > 0 && (\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"relative flex-1 min-w-[180px] max-w-md\">\n <Search className=\"pointer-events-none absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-text-muted\" />\n <Input\n value={q}\n onChange={(e) => setQ(e.target.value)}\n placeholder={t('actions.search', { ns: 'common' })}\n className=\"pl-7\"\n />\n </div>\n <Badge variant=\"secondary\" className=\"ml-auto\">\n {filtered.length} / {skills.length}\n </Badge>\n </div>\n )}\n\n {isLoading ? (\n <div className=\"h-48 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : skills.length === 0 ? (\n <EmptyState icon={<Flame />} title={t('hot.empty')} />\n ) : (\n <ul className=\"flex flex-col gap-2\">\n {filtered.map((s) => (\n <li key={s.slug}>\n <button\n type=\"button\"\n onClick={() => setOpenSlug(s.slug)}\n className={cn(\n 'flex w-full flex-col gap-1 rounded-md border border-border bg-surface px-3 py-2 text-left',\n 'transition-colors hover:border-border-strong hover:bg-surface-hover',\n )}\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium text-text\">{s.name || s.slug}</span>\n {s.version && (\n <span className=\"text-text-muted text-xs font-mono\">v{s.version}</span>\n )}\n {s.category && (\n <Badge variant=\"outline\">{s.category}</Badge>\n )}\n <div className=\"ml-auto flex items-center gap-3 text-xs text-text-dim tabular-nums\">\n <span className=\"inline-flex items-center gap-1\">\n <Star className=\"h-3 w-3\" />\n {formatNum(s.stars)}\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <Download className=\"h-3 w-3\" />\n {formatNum(s.installs)}\n </span>\n </div>\n </div>\n <code className=\"text-text-muted text-xs font-mono\">{s.slug}</code>\n {s.description && (\n <p className=\"line-clamp-2 text-sm text-text-dim\">{s.description}</p>\n )}\n </button>\n </li>\n ))}\n </ul>\n )}\n\n <RemoteSkillDialog\n skill={openSkill}\n onOpenChange={(open) => { if (!open) setOpenSlug(null) }}\n />\n </div>\n )\n}\n\nfunction CacheMeta({\n cached,\n stale,\n fetchedAt,\n}: {\n cached: boolean\n stale: boolean\n fetchedAt: number\n}): JSX.Element | null {\n const { t } = useTranslation('skills')\n const when = useMemo(() => {\n try {\n const d = new Date(fetchedAt)\n if (Number.isNaN(d.getTime())) return ''\n return d.toLocaleString(undefined, {\n month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit',\n })\n } catch {\n return ''\n }\n }, [fetchedAt])\n return (\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-text-muted\">\n <span>{t('hot.updatedAt', { at: when })}</span>\n {cached && <Badge variant=\"outline\">{t('hot.cached')}</Badge>}\n {stale && <Badge variant=\"warning\">{t('hot.stale')}</Badge>}\n </div>\n )\n}\n\ninterface RemoteSkillDialogProps {\n skill: RemoteSkill | null\n onOpenChange: (open: boolean) => void\n}\n\nfunction RemoteSkillDialog({ skill, onOpenChange }: RemoteSkillDialogProps): JSX.Element {\n const { t } = useTranslation('skills')\n\n // Three copy-pasteable install paths. agim never executes them itself\n // — the operator chooses CLI or IM.\n const commands = useMemo(() => {\n if (!skill) return []\n return [\n { key: 'cliInstall', cmd: `skillhub install ${skill.slug}` },\n { key: 'cliSearch', cmd: `skillhub search ${skill.slug}` },\n { key: 'imAsk', cmd: `请用 skillhub 安装 ${skill.slug} 技能` },\n ]\n }, [skill])\n\n return (\n <Dialog open={skill != null} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-2xl\">\n <DialogHeader>\n <DialogTitle>{skill?.name || skill?.slug || ''}</DialogTitle>\n {skill?.description && (\n <DialogDescription>{skill.description}</DialogDescription>\n )}\n </DialogHeader>\n\n {skill && (\n <>\n <dl className=\"grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-xs\">\n <dt className=\"text-text-dim\">slug</dt>\n <dd className=\"font-mono\">{skill.slug}</dd>\n {skill.version && (\n <>\n <dt className=\"text-text-dim\">{t('hot.detail.version')}</dt>\n <dd className=\"font-mono\">v{skill.version}</dd>\n </>\n )}\n {skill.category && (\n <>\n <dt className=\"text-text-dim\">{t('hot.detail.category')}</dt>\n <dd>{skill.category}</dd>\n </>\n )}\n <dt className=\"text-text-dim\">{t('hot.detail.stars')}</dt>\n <dd className=\"tabular-nums\">{formatNum(skill.stars)}</dd>\n <dt className=\"text-text-dim\">{t('hot.detail.installs')}</dt>\n <dd className=\"tabular-nums\">{formatNum(skill.installs)}</dd>\n {skill.downloads != null && (\n <>\n <dt className=\"text-text-dim\">{t('hot.detail.downloads')}</dt>\n <dd className=\"tabular-nums\">{formatNum(skill.downloads)}</dd>\n </>\n )}\n </dl>\n\n <div className=\"mt-4 border-t border-border pt-3\">\n <h3 className=\"text-sm font-medium\">{t('hot.detail.howInstall')}</h3>\n <ul className=\"mt-2 flex flex-col gap-2\">\n {commands.map((c) => (\n <li key={c.key} className=\"flex flex-col gap-1 sm:flex-row sm:items-center sm:gap-2\">\n <span className=\"text-xs text-text-dim sm:w-40 sm:shrink-0\">\n {t(`hot.detail.label.${c.key}`)}\n </span>\n <code className=\"flex-1 rounded bg-surface-2 px-2 py-1 font-mono text-xs break-all\">\n {c.cmd}\n </code>\n <CopyButton text={c.cmd} />\n </li>\n ))}\n </ul>\n <p className=\"mt-3 text-[11px] text-text-muted\">{t('hot.detail.hint')}</p>\n </div>\n </>\n )}\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction CopyButton({ text }: { text: string }): JSX.Element {\n const { t } = useTranslation('skills')\n const [copied, setCopied] = useState(false)\n async function onClick(): Promise<void> {\n try {\n await navigator.clipboard.writeText(text)\n setCopied(true)\n toast.success(t('hot.detail.copied'))\n setTimeout(() => setCopied(false), 1500)\n } catch (err) {\n toast.error(String((err as Error)?.message ?? err))\n }\n }\n return (\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => void onClick()}\n className=\"shrink-0\"\n >\n <Copy className=\"h-3 w-3\" />\n {copied ? t('hot.detail.copied') : t('hot.detail.copy')}\n </Button>\n )\n}\n\nfunction formatNum(n: number | undefined): string {\n if (n == null || !Number.isFinite(n)) return '—'\n return n.toLocaleString()\n}\n"],"names":["Flame","createLucideIcon","Star","skillsKeys","useSkillsRemoteHot","useQuery","api","SkillsHotRoute","t","useTranslation","data","isLoading","isFetching","refetch","skills","q","setQ","useState","openSlug","setOpenSlug","filtered","useMemo","needle","s","openSkill","jsxs","jsx","Button","ExternalLink","Loader2","RefreshCcw","CacheMeta","Search","Input","e","Badge","EmptyState","cn","formatNum","Download","RemoteSkillDialog","open","cached","stale","fetchedAt","when","d","skill","onOpenChange","commands","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","Fragment","c","CopyButton","text","copied","setCopied","onClick","toast","err","Copy","n"],"mappings":"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","x_google_ignoreList":[0,1]}