agim-cli 1.5.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +39 -3
  3. package/README.zh-CN.md +42 -7
  4. package/dist/cli-ui/cmd-handlers.d.ts +22 -1
  5. package/dist/cli-ui/cmd-handlers.d.ts.map +1 -1
  6. package/dist/cli-ui/cmd-handlers.js +304 -40
  7. package/dist/cli-ui/cmd-handlers.js.map +1 -1
  8. package/dist/cli-ui/config-wizard.d.ts +13 -1
  9. package/dist/cli-ui/config-wizard.d.ts.map +1 -1
  10. package/dist/cli-ui/config-wizard.js +93 -21
  11. package/dist/cli-ui/config-wizard.js.map +1 -1
  12. package/dist/cli-ui/doctor.d.ts +15 -0
  13. package/dist/cli-ui/doctor.d.ts.map +1 -0
  14. package/dist/cli-ui/doctor.js +151 -0
  15. package/dist/cli-ui/doctor.js.map +1 -0
  16. package/dist/cli-ui/entry-menu.d.ts +6 -0
  17. package/dist/cli-ui/entry-menu.d.ts.map +1 -1
  18. package/dist/cli-ui/entry-menu.js +67 -30
  19. package/dist/cli-ui/entry-menu.js.map +1 -1
  20. package/dist/cli-ui/i18n.d.ts +15 -6
  21. package/dist/cli-ui/i18n.d.ts.map +1 -1
  22. package/dist/cli-ui/i18n.js +30 -12
  23. package/dist/cli-ui/i18n.js.map +1 -1
  24. package/dist/cli-ui/quickstart.d.ts +3 -0
  25. package/dist/cli-ui/quickstart.d.ts.map +1 -0
  26. package/dist/cli-ui/quickstart.js +108 -0
  27. package/dist/cli-ui/quickstart.js.map +1 -0
  28. package/dist/cli-ui/readiness.d.ts +10 -0
  29. package/dist/cli-ui/readiness.d.ts.map +1 -0
  30. package/dist/cli-ui/readiness.js +75 -0
  31. package/dist/cli-ui/readiness.js.map +1 -0
  32. package/dist/cli-ui/service.d.ts +23 -0
  33. package/dist/cli-ui/service.d.ts.map +1 -1
  34. package/dist/cli-ui/service.js +114 -5
  35. package/dist/cli-ui/service.js.map +1 -1
  36. package/dist/cli.js +99 -396
  37. package/dist/cli.js.map +1 -1
  38. package/dist/core/acp-server.d.ts.map +1 -1
  39. package/dist/core/acp-server.js +16 -2
  40. package/dist/core/acp-server.js.map +1 -1
  41. package/dist/core/agent-cwd.d.ts +8 -0
  42. package/dist/core/agent-cwd.d.ts.map +1 -1
  43. package/dist/core/agent-cwd.js +57 -7
  44. package/dist/core/agent-cwd.js.map +1 -1
  45. package/dist/core/commands/builtin.d.ts.map +1 -1
  46. package/dist/core/commands/builtin.js +12 -2
  47. package/dist/core/commands/builtin.js.map +1 -1
  48. package/dist/core/commands/model.d.ts.map +1 -1
  49. package/dist/core/commands/model.js +31 -2
  50. package/dist/core/commands/model.js.map +1 -1
  51. package/dist/core/llm/anthropic-provider.js +2 -1
  52. package/dist/core/llm/anthropic-provider.js.map +1 -1
  53. package/dist/core/llm/openai-compat-provider.js +3 -2
  54. package/dist/core/llm/openai-compat-provider.js.map +1 -1
  55. package/dist/core/llm/provider-base.d.ts +4 -4
  56. package/dist/core/llm/provider-base.d.ts.map +1 -1
  57. package/dist/core/llm/provider-base.js +1 -1
  58. package/dist/core/llm/provider-base.js.map +1 -1
  59. package/dist/plugins/agents/native/index.d.ts +1 -0
  60. package/dist/plugins/agents/native/index.d.ts.map +1 -1
  61. package/dist/plugins/agents/native/index.js +14 -0
  62. package/dist/plugins/agents/native/index.js.map +1 -1
  63. package/dist/plugins/agents/pi-native/factory.d.ts.map +1 -1
  64. package/dist/plugins/agents/pi-native/factory.js +19 -3
  65. package/dist/plugins/agents/pi-native/factory.js.map +1 -1
  66. package/dist/plugins/agents/pi-native/index.d.ts +11 -0
  67. package/dist/plugins/agents/pi-native/index.d.ts.map +1 -1
  68. package/dist/plugins/agents/pi-native/index.js +56 -2
  69. package/dist/plugins/agents/pi-native/index.js.map +1 -1
  70. package/dist/plugins/agents/pi-native/provider-resolver.d.ts +2 -0
  71. package/dist/plugins/agents/pi-native/provider-resolver.d.ts.map +1 -1
  72. package/dist/plugins/agents/pi-native/provider-resolver.js +9 -1
  73. package/dist/plugins/agents/pi-native/provider-resolver.js.map +1 -1
  74. package/dist/web/public/assets/a2a-CTsDMefo.js +7 -0
  75. package/dist/web/public/assets/a2a-CTsDMefo.js.map +1 -0
  76. package/dist/web/public/assets/{activity-BAgb2WZC.js → activity-ul8Os7Pz.js} +2 -2
  77. package/dist/web/public/assets/{activity-BAgb2WZC.js.map → activity-ul8Os7Pz.js.map} +1 -1
  78. package/dist/web/public/assets/{admins-CZYANmhn.js → admins-ByMAuquy.js} +3 -3
  79. package/dist/web/public/assets/{admins-CZYANmhn.js.map → admins-ByMAuquy.js.map} +1 -1
  80. package/dist/web/public/assets/agents-Ds1zyxBj.js +2 -0
  81. package/dist/web/public/assets/{agents-BXThDW6f.js.map → agents-Ds1zyxBj.js.map} +1 -1
  82. package/dist/web/public/assets/{approvals-ByPXIYVl.js → approvals-DOWlWI7Z.js} +3 -3
  83. package/dist/web/public/assets/{approvals-ByPXIYVl.js.map → approvals-DOWlWI7Z.js.map} +1 -1
  84. package/dist/web/public/assets/{arrow-down-B8DkdbEY.js → arrow-down-7i0xwCI2.js} +2 -2
  85. package/dist/web/public/assets/{arrow-down-B8DkdbEY.js.map → arrow-down-7i0xwCI2.js.map} +1 -1
  86. package/dist/web/public/assets/arrow-right-A889Wof8.js +7 -0
  87. package/dist/web/public/assets/arrow-right-A889Wof8.js.map +1 -0
  88. package/dist/web/public/assets/{arrow-up-i_dEdXkz.js → arrow-up-Dm0U4-6U.js} +2 -2
  89. package/dist/web/public/assets/{arrow-up-i_dEdXkz.js.map → arrow-up-Dm0U4-6U.js.map} +1 -1
  90. package/dist/web/public/assets/{asks-yD_inOnM.js → asks-DGuBsrJ7.js} +3 -3
  91. package/dist/web/public/assets/{asks-yD_inOnM.js.map → asks-DGuBsrJ7.js.map} +1 -1
  92. package/dist/web/public/assets/{audit-teCIRtgN.js → audit-BRXsplJ2.js} +2 -2
  93. package/dist/web/public/assets/{audit-teCIRtgN.js.map → audit-BRXsplJ2.js.map} +1 -1
  94. package/dist/web/public/assets/{bell-CeWDMs8_.js → bell-B-UdeJsp.js} +2 -2
  95. package/dist/web/public/assets/{bell-CeWDMs8_.js.map → bell-B-UdeJsp.js.map} +1 -1
  96. package/dist/web/public/assets/bgjobs-CcRiffyJ.js +2 -0
  97. package/dist/web/public/assets/bgjobs-CcRiffyJ.js.map +1 -0
  98. package/dist/web/public/assets/book-open-CSCq5cjL.js +7 -0
  99. package/dist/web/public/assets/book-open-CSCq5cjL.js.map +1 -0
  100. package/dist/web/public/assets/{brain-BQqv0Zhc.js → brain-Dl4DF5kX.js} +2 -2
  101. package/dist/web/public/assets/{brain-BQqv0Zhc.js.map → brain-Dl4DF5kX.js.map} +1 -1
  102. package/dist/web/public/assets/{briefcase-DUXbR4xs.js → briefcase-CeKUkFSq.js} +2 -2
  103. package/dist/web/public/assets/{briefcase-DUXbR4xs.js.map → briefcase-CeKUkFSq.js.map} +1 -1
  104. package/dist/web/public/assets/chat-rLJMdJBk.js +12 -0
  105. package/dist/web/public/assets/chat-rLJMdJBk.js.map +1 -0
  106. package/dist/web/public/assets/{chevron-left-RC6mMSiX.js → chevron-left-01fAFVpo.js} +2 -2
  107. package/dist/web/public/assets/{chevron-left-RC6mMSiX.js.map → chevron-left-01fAFVpo.js.map} +1 -1
  108. package/dist/web/public/assets/{chevron-right-DrkYVi19.js → chevron-right-CFRb-SM_.js} +3 -3
  109. package/dist/web/public/assets/{chevron-right-DrkYVi19.js.map → chevron-right-CFRb-SM_.js.map} +1 -1
  110. package/dist/web/public/assets/{circle-check-big-BC8ntMsz.js → circle-check-big-DBg2BD6o.js} +2 -2
  111. package/dist/web/public/assets/{circle-check-big-BC8ntMsz.js.map → circle-check-big-DBg2BD6o.js.map} +1 -1
  112. package/dist/web/public/assets/{circle-x-DHK7ypFY.js → circle-x-CqFMzO-x.js} +2 -2
  113. package/dist/web/public/assets/{circle-x-DHK7ypFY.js.map → circle-x-CqFMzO-x.js.map} +1 -1
  114. package/dist/web/public/assets/clipboard-list-lnqdk2_J.js +7 -0
  115. package/dist/web/public/assets/clipboard-list-lnqdk2_J.js.map +1 -0
  116. package/dist/web/public/assets/{clock-DXHhWqJH.js → clock-4hd1joQe.js} +3 -3
  117. package/dist/web/public/assets/{clock-DXHhWqJH.js.map → clock-4hd1joQe.js.map} +1 -1
  118. package/dist/web/public/assets/confirm-dialog-BDb0NLny.js +2 -0
  119. package/dist/web/public/assets/{confirm-dialog-gPKJnvEW.js.map → confirm-dialog-BDb0NLny.js.map} +1 -1
  120. package/dist/web/public/assets/{copy-DtQxgcR0.js → copy-CD4A7VD8.js} +3 -3
  121. package/dist/web/public/assets/{copy-DtQxgcR0.js.map → copy-CD4A7VD8.js.map} +1 -1
  122. package/dist/web/public/assets/dashboard-CG3WiG7h.js +2 -0
  123. package/dist/web/public/assets/dashboard-CG3WiG7h.js.map +1 -0
  124. package/dist/web/public/assets/{data-table-DOKUic1J.js → data-table-BkUshOZz.js} +2 -2
  125. package/dist/web/public/assets/{data-table-DOKUic1J.js.map → data-table-BkUshOZz.js.map} +1 -1
  126. package/dist/web/public/assets/database-lQzk64rV.js +7 -0
  127. package/dist/web/public/assets/database-lQzk64rV.js.map +1 -0
  128. package/dist/web/public/assets/{distill-p6P7-1UR.js → distill-CPurVW3v.js} +3 -3
  129. package/dist/web/public/assets/{distill-p6P7-1UR.js.map → distill-CPurVW3v.js.map} +1 -1
  130. package/dist/web/public/assets/{download-CqNiIHa8.js → download-CVZnHcwj.js} +2 -2
  131. package/dist/web/public/assets/{download-CqNiIHa8.js.map → download-CVZnHcwj.js.map} +1 -1
  132. package/dist/web/public/assets/dropdown-menu-BNH5SrVb.js +7 -0
  133. package/dist/web/public/assets/dropdown-menu-BNH5SrVb.js.map +1 -0
  134. package/dist/web/public/assets/{email-DwbfTUlV.js → email-YlI4MWLp.js} +3 -3
  135. package/dist/web/public/assets/{email-DwbfTUlV.js.map → email-YlI4MWLp.js.map} +1 -1
  136. package/dist/web/public/assets/{empty-state-CTwOQemt.js → empty-state-CuiqdZiB.js} +2 -2
  137. package/dist/web/public/assets/{empty-state-CTwOQemt.js.map → empty-state-CuiqdZiB.js.map} +1 -1
  138. package/dist/web/public/assets/{external-link-BY7Ye8yi.js → external-link-1WPpVvdu.js} +2 -2
  139. package/dist/web/public/assets/{external-link-BY7Ye8yi.js.map → external-link-1WPpVvdu.js.map} +1 -1
  140. package/dist/web/public/assets/{eye-6RUADoDS.js → eye-BfPyNFzk.js} +2 -2
  141. package/dist/web/public/assets/{eye-6RUADoDS.js.map → eye-BfPyNFzk.js.map} +1 -1
  142. package/dist/web/public/assets/{facts-DXE0aJmb.js → facts-xT_24pH8.js} +2 -2
  143. package/dist/web/public/assets/{facts-DXE0aJmb.js.map → facts-xT_24pH8.js.map} +1 -1
  144. package/dist/web/public/assets/file-text-BxfdLM0-.js +7 -0
  145. package/dist/web/public/assets/file-text-BxfdLM0-.js.map +1 -0
  146. package/dist/web/public/assets/{goals-C1LCm3qL.js → goals-C8ZQfbhj.js} +3 -3
  147. package/dist/web/public/assets/{goals-C1LCm3qL.js.map → goals-C8ZQfbhj.js.map} +1 -1
  148. package/dist/web/public/assets/health-A2StNEfn.js +2 -0
  149. package/dist/web/public/assets/{health-wqCp-K_o.js.map → health-A2StNEfn.js.map} +1 -1
  150. package/dist/web/public/assets/{heart-pulse-DfqI4GF7.js → heart-pulse-DXlE9oic.js} +2 -2
  151. package/dist/web/public/assets/{heart-pulse-DfqI4GF7.js.map → heart-pulse-DXlE9oic.js.map} +1 -1
  152. package/dist/web/public/assets/{heartbeat-Bumv4XtQ.js → heartbeat-ClO5gJrj.js} +3 -3
  153. package/dist/web/public/assets/{heartbeat-Bumv4XtQ.js.map → heartbeat-ClO5gJrj.js.map} +1 -1
  154. package/dist/web/public/assets/hot-bfTA-V_z.js +7 -0
  155. package/dist/web/public/assets/{hot-B-CMjQIr.js.map → hot-bfTA-V_z.js.map} +1 -1
  156. package/dist/web/public/assets/index-Bi2qWb-u.css +1 -0
  157. package/dist/web/public/assets/index-DCfdN5R7.js +244 -0
  158. package/dist/web/public/assets/index-DCfdN5R7.js.map +1 -0
  159. package/dist/web/public/assets/{injection-Dn_XqgLG.js → injection-omvCR6-p.js} +2 -2
  160. package/dist/web/public/assets/{injection-Dn_XqgLG.js.map → injection-omvCR6-p.js.map} +1 -1
  161. package/dist/web/public/assets/{installed-Cet-1M2Q.js → installed-DL6r3ktm.js} +4 -9
  162. package/dist/web/public/assets/installed-DL6r3ktm.js.map +1 -0
  163. package/dist/web/public/assets/jobs-Biy5lYd4.js +2 -0
  164. package/dist/web/public/assets/jobs-Biy5lYd4.js.map +1 -0
  165. package/dist/web/public/assets/layout-BLm6NJ3V.js +2 -0
  166. package/dist/web/public/assets/layout-BLm6NJ3V.js.map +1 -0
  167. package/dist/web/public/assets/layout-BTKafRVZ.js +2 -0
  168. package/dist/web/public/assets/layout-BTKafRVZ.js.map +1 -0
  169. package/dist/web/public/assets/layout-Bm-2s2fp.js +2 -0
  170. package/dist/web/public/assets/layout-Bm-2s2fp.js.map +1 -0
  171. package/dist/web/public/assets/layout-DsZ8eR4i.js +2 -0
  172. package/dist/web/public/assets/layout-DsZ8eR4i.js.map +1 -0
  173. package/dist/web/public/assets/{layout-D_3ZcVG7.js → layout-sxvovjEH.js} +2 -2
  174. package/dist/web/public/assets/{layout-D_3ZcVG7.js.map → layout-sxvovjEH.js.map} +1 -1
  175. package/dist/web/public/assets/llm-JjZDbBvJ.js +37 -0
  176. package/dist/web/public/assets/llm-JjZDbBvJ.js.map +1 -0
  177. package/dist/web/public/assets/loader-circle-DDdmcH0k.js +7 -0
  178. package/dist/web/public/assets/{loader-circle-DgdBWYl0.js.map → loader-circle-DDdmcH0k.js.map} +1 -1
  179. package/dist/web/public/assets/{map-pin-3QS1A0-I.js → map-pin-C_jAxukI.js} +2 -2
  180. package/dist/web/public/assets/{map-pin-3QS1A0-I.js.map → map-pin-C_jAxukI.js.map} +1 -1
  181. package/dist/web/public/assets/{mcp-DwKZULET.js → mcp-vKajK1F8.js} +3 -3
  182. package/dist/web/public/assets/{mcp-DwKZULET.js.map → mcp-vKajK1F8.js.map} +1 -1
  183. package/dist/web/public/assets/memos-DAt4k3DO.js +7 -0
  184. package/dist/web/public/assets/memos-DAt4k3DO.js.map +1 -0
  185. package/dist/web/public/assets/messengers-GYVTFlAj.js +2 -0
  186. package/dist/web/public/assets/messengers-GYVTFlAj.js.map +1 -0
  187. package/dist/web/public/assets/{mobile-Bq0FH9JV.js → mobile-VUyTo40E.js} +3 -3
  188. package/dist/web/public/assets/{mobile-Bq0FH9JV.js.map → mobile-VUyTo40E.js.map} +1 -1
  189. package/dist/web/public/assets/{network--s113Jkm.js → network-BUeWK3bs.js} +2 -2
  190. package/dist/web/public/assets/{network--s113Jkm.js.map → network-BUeWK3bs.js.map} +1 -1
  191. package/dist/web/public/assets/outbox-CEE0rwN3.js +2 -0
  192. package/dist/web/public/assets/outbox-CEE0rwN3.js.map +1 -0
  193. package/dist/web/public/assets/overview-BSOZ5gTD.js +12 -0
  194. package/dist/web/public/assets/overview-BSOZ5gTD.js.map +1 -0
  195. package/dist/web/public/assets/overview-COop5K2Y.js +12 -0
  196. package/dist/web/public/assets/overview-COop5K2Y.js.map +1 -0
  197. package/dist/web/public/assets/overview-DeH5ud6d.js +2 -0
  198. package/dist/web/public/assets/overview-DeH5ud6d.js.map +1 -0
  199. package/dist/web/public/assets/{pagination-DkdCTctJ.js → pagination-BBicLzXP.js} +3 -3
  200. package/dist/web/public/assets/{pagination-DkdCTctJ.js.map → pagination-BBicLzXP.js.map} +1 -1
  201. package/dist/web/public/assets/persona-CElXQZ4p.js +2 -0
  202. package/dist/web/public/assets/{persona-BvtcZh6G.js.map → persona-CElXQZ4p.js.map} +1 -1
  203. package/dist/web/public/assets/{plans-i3a6lrqF.js → plans-Bo5LlLeH.js} +3 -8
  204. package/dist/web/public/assets/plans-Bo5LlLeH.js.map +1 -0
  205. package/dist/web/public/assets/{play-CPoE_JnS.js → play-DX5wp4WH.js} +2 -2
  206. package/dist/web/public/assets/{play-CPoE_JnS.js.map → play-DX5wp4WH.js.map} +1 -1
  207. package/dist/web/public/assets/{plus-CfzKV_0u.js → plus-DH4J_YhN.js} +2 -2
  208. package/dist/web/public/assets/{plus-CfzKV_0u.js.map → plus-DH4J_YhN.js.map} +1 -1
  209. package/dist/web/public/assets/policy-BrgOuDt_.js +2 -0
  210. package/dist/web/public/assets/{policy-Cm88P8LO.js.map → policy-BrgOuDt_.js.map} +1 -1
  211. package/dist/web/public/assets/{qr-code-DMkV8nv2.js → qr-code-YrEuhMPC.js} +2 -2
  212. package/dist/web/public/assets/{qr-code-DMkV8nv2.js.map → qr-code-YrEuhMPC.js.map} +1 -1
  213. package/dist/web/public/assets/{refresh-ccw-nBMm5Xal.js → refresh-ccw-DlAd-eTQ.js} +2 -2
  214. package/dist/web/public/assets/{refresh-ccw-nBMm5Xal.js.map → refresh-ccw-DlAd-eTQ.js.map} +1 -1
  215. package/dist/web/public/assets/{reminders-DjEujanC.js → reminders-DBEE0zXG.js} +3 -3
  216. package/dist/web/public/assets/{reminders-DjEujanC.js.map → reminders-DBEE0zXG.js.map} +1 -1
  217. package/dist/web/public/assets/{save-DbrrCFDM.js → save-BDOtZrfp.js} +2 -2
  218. package/dist/web/public/assets/{save-DbrrCFDM.js.map → save-BDOtZrfp.js.map} +1 -1
  219. package/dist/web/public/assets/schedules-DAyhVI8-.js +2 -0
  220. package/dist/web/public/assets/schedules-DAyhVI8-.js.map +1 -0
  221. package/dist/web/public/assets/{search-5q3dkINm.js → search-55mtgHrB.js} +3 -3
  222. package/dist/web/public/assets/{search-5q3dkINm.js.map → search-55mtgHrB.js.map} +1 -1
  223. package/dist/web/public/assets/{search-DbE4VEm9.js → search-CAICU3aU.js} +2 -2
  224. package/dist/web/public/assets/{search-DbE4VEm9.js.map → search-CAICU3aU.js.map} +1 -1
  225. package/dist/web/public/assets/security-CbP4QgVp.js +2 -0
  226. package/dist/web/public/assets/security-CbP4QgVp.js.map +1 -0
  227. package/dist/web/public/assets/server-Dg4e8pvm.js +7 -0
  228. package/dist/web/public/assets/server-Dg4e8pvm.js.map +1 -0
  229. package/dist/web/public/assets/service-gWZa3sup.js +7 -0
  230. package/dist/web/public/assets/service-gWZa3sup.js.map +1 -0
  231. package/dist/web/public/assets/{shield-alert-WOa69jy3.js → shield-alert-DOKK9EnJ.js} +2 -2
  232. package/dist/web/public/assets/{shield-alert-WOa69jy3.js.map → shield-alert-DOKK9EnJ.js.map} +1 -1
  233. package/dist/web/public/assets/sparkles-G0QIs9nP.js +7 -0
  234. package/dist/web/public/assets/sparkles-G0QIs9nP.js.map +1 -0
  235. package/dist/web/public/assets/start-D-abhl3q.js +2 -0
  236. package/dist/web/public/assets/start-D-abhl3q.js.map +1 -0
  237. package/dist/web/public/assets/{status-badge-D5xhwquL.js → status-badge-CyLdpsXq.js} +2 -2
  238. package/dist/web/public/assets/{status-badge-D5xhwquL.js.map → status-badge-CyLdpsXq.js.map} +1 -1
  239. package/dist/web/public/assets/{subtasks-DMRyk6YS.js → subtasks-BnEjSGUR.js} +3 -3
  240. package/dist/web/public/assets/{subtasks-DMRyk6YS.js.map → subtasks-BnEjSGUR.js.map} +1 -1
  241. package/dist/web/public/assets/{table-Dx65w6V0.js → table-sCMZBe_Z.js} +2 -2
  242. package/dist/web/public/assets/{table-Dx65w6V0.js.map → table-sCMZBe_Z.js.map} +1 -1
  243. package/dist/web/public/assets/terminal-_pXeEjXG.js +7 -0
  244. package/dist/web/public/assets/terminal-_pXeEjXG.js.map +1 -0
  245. package/dist/web/public/assets/{topn-L7Juczp3.js → topn-D1B-gS1M.js} +3 -3
  246. package/dist/web/public/assets/{topn-L7Juczp3.js.map → topn-D1B-gS1M.js.map} +1 -1
  247. package/dist/web/public/assets/{trash-2-7xrfqd-v.js → trash-2-D2x2UPuZ.js} +2 -2
  248. package/dist/web/public/assets/{trash-2-7xrfqd-v.js.map → trash-2-D2x2UPuZ.js.map} +1 -1
  249. package/dist/web/public/assets/use-a2a-C98e2Via.js +2 -0
  250. package/dist/web/public/assets/use-a2a-C98e2Via.js.map +1 -0
  251. package/dist/web/public/assets/{use-agim-skills-pFjfgqMF.js → use-agim-skills-BbuJP3NT.js} +2 -2
  252. package/dist/web/public/assets/{use-agim-skills-pFjfgqMF.js.map → use-agim-skills-BbuJP3NT.js.map} +1 -1
  253. package/dist/web/public/assets/use-background-tasks-CwFmOokw.js +2 -0
  254. package/dist/web/public/assets/{use-background-tasks-D1--hHjp.js.map → use-background-tasks-CwFmOokw.js.map} +1 -1
  255. package/dist/web/public/assets/use-jobs-BJjeJ5lh.js +2 -0
  256. package/dist/web/public/assets/use-jobs-BJjeJ5lh.js.map +1 -0
  257. package/dist/web/public/assets/use-memory-CXDwKCco.js +2 -0
  258. package/dist/web/public/assets/{use-memory-Bz1Zao7g.js.map → use-memory-CXDwKCco.js.map} +1 -1
  259. package/dist/web/public/assets/use-observability-CY5ZUPrC.js +2 -0
  260. package/dist/web/public/assets/{use-observability-DtqSWVjM.js.map → use-observability-CY5ZUPrC.js.map} +1 -1
  261. package/dist/web/public/assets/use-outbox-DT_XWB_7.js +7 -0
  262. package/dist/web/public/assets/use-outbox-DT_XWB_7.js.map +1 -0
  263. package/dist/web/public/assets/use-schedules-D4W8fMwo.js +7 -0
  264. package/dist/web/public/assets/use-schedules-D4W8fMwo.js.map +1 -0
  265. package/dist/web/public/assets/use-settings-DGIjmUX0.js +2 -0
  266. package/dist/web/public/assets/use-settings-DGIjmUX0.js.map +1 -0
  267. package/dist/web/public/assets/use-skills-D2bMM580.js +7 -0
  268. package/dist/web/public/assets/use-skills-D2bMM580.js.map +1 -0
  269. package/dist/web/public/assets/use-vector-BYOFwjU0.js +2 -0
  270. package/dist/web/public/assets/use-vector-BYOFwjU0.js.map +1 -0
  271. package/dist/web/public/assets/use-workspace-CuytyHwb.js +2 -0
  272. package/dist/web/public/assets/{use-workspace-CConjEx0.js.map → use-workspace-CuytyHwb.js.map} +1 -1
  273. package/dist/web/public/assets/vector-CL8ezpSR.js +2 -0
  274. package/dist/web/public/assets/vector-CL8ezpSR.js.map +1 -0
  275. package/dist/web/public/assets/viewer-CD0iEfPU.js +7 -0
  276. package/dist/web/public/assets/viewer-CD0iEfPU.js.map +1 -0
  277. package/dist/web/public/assets/workspace-BA1_hso3.js +17 -0
  278. package/dist/web/public/assets/workspace-BA1_hso3.js.map +1 -0
  279. package/dist/web/public/assets/workspaces-DyGLJUgB.js +7 -0
  280. package/dist/web/public/assets/workspaces-DyGLJUgB.js.map +1 -0
  281. package/dist/web/public/index.html +2 -2
  282. package/dist/web/server.d.ts +0 -3
  283. package/dist/web/server.d.ts.map +1 -1
  284. package/dist/web/server.js +138 -3
  285. package/dist/web/server.js.map +1 -1
  286. package/package.json +1 -1
  287. package/dist/web/public/assets/a2a-D7MoJ1iT.js +0 -7
  288. package/dist/web/public/assets/a2a-D7MoJ1iT.js.map +0 -1
  289. package/dist/web/public/assets/agents-BXThDW6f.js +0 -7
  290. package/dist/web/public/assets/bgjobs-Rc05aEy9.js +0 -7
  291. package/dist/web/public/assets/bgjobs-Rc05aEy9.js.map +0 -1
  292. package/dist/web/public/assets/chat-DQpQLW9j.js +0 -17
  293. package/dist/web/public/assets/chat-DQpQLW9j.js.map +0 -1
  294. package/dist/web/public/assets/circle-check-DZnkaUdk.js +0 -7
  295. package/dist/web/public/assets/circle-check-DZnkaUdk.js.map +0 -1
  296. package/dist/web/public/assets/confirm-dialog-gPKJnvEW.js +0 -2
  297. package/dist/web/public/assets/health-wqCp-K_o.js +0 -2
  298. package/dist/web/public/assets/hot-B-CMjQIr.js +0 -12
  299. package/dist/web/public/assets/index-DHh1LYlA.js +0 -209
  300. package/dist/web/public/assets/index-DHh1LYlA.js.map +0 -1
  301. package/dist/web/public/assets/index-DknVjPYB.css +0 -1
  302. package/dist/web/public/assets/installed-Cet-1M2Q.js.map +0 -1
  303. package/dist/web/public/assets/jobs-CfEzOOAC.js +0 -2
  304. package/dist/web/public/assets/jobs-CfEzOOAC.js.map +0 -1
  305. package/dist/web/public/assets/layout-BX43KyXM.js +0 -2
  306. package/dist/web/public/assets/layout-BX43KyXM.js.map +0 -1
  307. package/dist/web/public/assets/layout-BcYZlaqf.js +0 -2
  308. package/dist/web/public/assets/layout-BcYZlaqf.js.map +0 -1
  309. package/dist/web/public/assets/layout-Cb7looUv.js +0 -2
  310. package/dist/web/public/assets/layout-Cb7looUv.js.map +0 -1
  311. package/dist/web/public/assets/layout-D7xH78OU.js +0 -2
  312. package/dist/web/public/assets/layout-D7xH78OU.js.map +0 -1
  313. package/dist/web/public/assets/llm-BZ9qqp-D.js +0 -27
  314. package/dist/web/public/assets/llm-BZ9qqp-D.js.map +0 -1
  315. package/dist/web/public/assets/loader-circle-DgdBWYl0.js +0 -7
  316. package/dist/web/public/assets/memos-BBtqFcoH.js +0 -12
  317. package/dist/web/public/assets/memos-BBtqFcoH.js.map +0 -1
  318. package/dist/web/public/assets/messengers-i7WvNT3o.js +0 -2
  319. package/dist/web/public/assets/messengers-i7WvNT3o.js.map +0 -1
  320. package/dist/web/public/assets/outbox-BbfC5kuG.js +0 -7
  321. package/dist/web/public/assets/outbox-BbfC5kuG.js.map +0 -1
  322. package/dist/web/public/assets/persona-BvtcZh6G.js +0 -2
  323. package/dist/web/public/assets/plans-i3a6lrqF.js.map +0 -1
  324. package/dist/web/public/assets/policy-Cm88P8LO.js +0 -2
  325. package/dist/web/public/assets/schedules-DzwDWykc.js +0 -7
  326. package/dist/web/public/assets/schedules-DzwDWykc.js.map +0 -1
  327. package/dist/web/public/assets/security-BIcnUrAs.js +0 -2
  328. package/dist/web/public/assets/security-BIcnUrAs.js.map +0 -1
  329. package/dist/web/public/assets/service-CnorFHzZ.js +0 -7
  330. package/dist/web/public/assets/service-CnorFHzZ.js.map +0 -1
  331. package/dist/web/public/assets/use-background-tasks-D1--hHjp.js +0 -2
  332. package/dist/web/public/assets/use-memory-Bz1Zao7g.js +0 -2
  333. package/dist/web/public/assets/use-observability-DtqSWVjM.js +0 -2
  334. package/dist/web/public/assets/use-settings-DKbDqCEJ.js +0 -2
  335. package/dist/web/public/assets/use-settings-DKbDqCEJ.js.map +0 -1
  336. package/dist/web/public/assets/use-workspace-CConjEx0.js +0 -2
  337. package/dist/web/public/assets/vector-D8sEa2W-.js +0 -2
  338. package/dist/web/public/assets/vector-D8sEa2W-.js.map +0 -1
  339. package/dist/web/public/assets/viewer-aSIjAKVA.js +0 -12
  340. package/dist/web/public/assets/viewer-aSIjAKVA.js.map +0 -1
  341. package/dist/web/public/assets/workspace-BqwWoinI.js +0 -17
  342. package/dist/web/public/assets/workspace-BqwWoinI.js.map +0 -1
  343. package/dist/web/public/assets/workspaces-ChsJcrav.js +0 -7
  344. package/dist/web/public/assets/workspaces-ChsJcrav.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"use-observability-DtqSWVjM.js","sources":["../../src/hooks/use-observability.ts"],"sourcesContent":["/**\n * useObservability — react-query wrappers for the operational\n * dashboard.\n *\n * useHealthSummary({ days }) — totals + byDay roll-up\n * useTopN({ dim, by, days, limit }) — leaderboard by dimension\n * useAudit(query) — recent invocations\n *\n * All three are read-only; observability stays a passive view.\n * Refetch intervals are tuned to match operator expectations:\n * health summary every 30s (background sweep latency); audit\n * every 10s (fresher); TopN every 60s (the leaderboard moves\n * slowly enough).\n */\n\nimport { useQuery } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type {\n AuditResponse,\n HealthSummary,\n ListAuditQuery,\n TopNDim,\n TopNMetric,\n TopNResponse,\n} from '@/types/api'\n\nexport const observabilityKeys = {\n all: ['observability'] as const,\n health: (days: number) => ['observability', 'health', days] as const,\n topN: (dim: TopNDim, by: TopNMetric, days: number, limit: number) =>\n ['observability', 'topn', dim, by, days, limit] as const,\n audit: (q: ListAuditQuery) => ['observability', 'audit', q] as const,\n}\n\nexport function useHealthSummary(days: number) {\n return useQuery<HealthSummary>({\n queryKey: observabilityKeys.health(days),\n queryFn: () => api.getHealthSummary({ days }),\n refetchInterval: 30_000,\n refetchIntervalInBackground: false,\n })\n}\n\nexport function useTopN(opts: { dim: TopNDim; by: TopNMetric; days?: number; limit?: number }) {\n const days = opts.days ?? 7\n const limit = opts.limit ?? 10\n return useQuery<TopNResponse>({\n queryKey: observabilityKeys.topN(opts.dim, opts.by, days, limit),\n queryFn: () => api.getHealthTopN({ dim: opts.dim, by: opts.by, days, limit }),\n refetchInterval: 60_000,\n refetchIntervalInBackground: false,\n })\n}\n\nexport function useAudit(query: ListAuditQuery) {\n return useQuery<AuditResponse>({\n queryKey: observabilityKeys.audit(query),\n queryFn: () => api.getAudit(query),\n refetchInterval: 10_000,\n refetchIntervalInBackground: false,\n })\n}\n"],"names":["observabilityKeys","days","dim","by","limit","q","useHealthSummary","useQuery","api","useTopN","opts","useAudit","query"],"mappings":"+CA0BO,MAAMA,EAAoB,CAC/B,IAAS,CAAC,eAAe,EACzB,OAAUC,GAAiB,CAAC,gBAAiB,SAAUA,CAAI,EAC3D,KAAS,CAACC,EAAcC,EAAgBF,EAAcG,IACpD,CAAC,gBAAiB,OAAQF,EAAKC,EAAIF,EAAMG,CAAK,EAChD,MAAUC,GAAsB,CAAC,gBAAiB,QAASA,CAAC,CAC9D,EAEO,SAASC,EAAiBL,EAAc,CAC7C,OAAOM,EAAwB,CAC7B,SAAUP,EAAkB,OAAOC,CAAI,EACvC,QAAS,IAAMO,EAAI,iBAAiB,CAAE,KAAAP,EAAM,EAC5C,gBAAiB,IACjB,4BAA6B,EAAA,CAC9B,CACH,CAEO,SAASQ,EAAQC,EAAuE,CAC7F,MAAMT,EAAOS,EAAK,MAAQ,EACpBN,EAAQM,EAAK,OAAS,GAC5B,OAAOH,EAAuB,CAC5B,SAAUP,EAAkB,KAAKU,EAAK,IAAKA,EAAK,GAAIT,EAAMG,CAAK,EAC/D,QAAS,IAAMI,EAAI,cAAc,CAAE,IAAKE,EAAK,IAAK,GAAIA,EAAK,GAAI,KAAAT,EAAM,MAAAG,EAAO,EAC5E,gBAAiB,IACjB,4BAA6B,EAAA,CAC9B,CACH,CAEO,SAASO,EAASC,EAAuB,CAC9C,OAAOL,EAAwB,CAC7B,SAAUP,EAAkB,MAAMY,CAAK,EACvC,QAAS,IAAMJ,EAAI,SAASI,CAAK,EACjC,gBAAiB,IACjB,4BAA6B,EAAA,CAC9B,CACH"}
1
+ {"version":3,"file":"use-observability-CY5ZUPrC.js","sources":["../../src/hooks/use-observability.ts"],"sourcesContent":["/**\n * useObservability — react-query wrappers for the operational\n * dashboard.\n *\n * useHealthSummary({ days }) — totals + byDay roll-up\n * useTopN({ dim, by, days, limit }) — leaderboard by dimension\n * useAudit(query) — recent invocations\n *\n * All three are read-only; observability stays a passive view.\n * Refetch intervals are tuned to match operator expectations:\n * health summary every 30s (background sweep latency); audit\n * every 10s (fresher); TopN every 60s (the leaderboard moves\n * slowly enough).\n */\n\nimport { useQuery } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type {\n AuditResponse,\n HealthSummary,\n ListAuditQuery,\n TopNDim,\n TopNMetric,\n TopNResponse,\n} from '@/types/api'\n\nexport const observabilityKeys = {\n all: ['observability'] as const,\n health: (days: number) => ['observability', 'health', days] as const,\n topN: (dim: TopNDim, by: TopNMetric, days: number, limit: number) =>\n ['observability', 'topn', dim, by, days, limit] as const,\n audit: (q: ListAuditQuery) => ['observability', 'audit', q] as const,\n}\n\nexport function useHealthSummary(days: number) {\n return useQuery<HealthSummary>({\n queryKey: observabilityKeys.health(days),\n queryFn: () => api.getHealthSummary({ days }),\n refetchInterval: 30_000,\n refetchIntervalInBackground: false,\n })\n}\n\nexport function useTopN(opts: { dim: TopNDim; by: TopNMetric; days?: number; limit?: number }) {\n const days = opts.days ?? 7\n const limit = opts.limit ?? 10\n return useQuery<TopNResponse>({\n queryKey: observabilityKeys.topN(opts.dim, opts.by, days, limit),\n queryFn: () => api.getHealthTopN({ dim: opts.dim, by: opts.by, days, limit }),\n refetchInterval: 60_000,\n refetchIntervalInBackground: false,\n })\n}\n\nexport function useAudit(query: ListAuditQuery) {\n return useQuery<AuditResponse>({\n queryKey: observabilityKeys.audit(query),\n queryFn: () => api.getAudit(query),\n refetchInterval: 10_000,\n refetchIntervalInBackground: false,\n })\n}\n"],"names":["observabilityKeys","days","dim","by","limit","q","useHealthSummary","useQuery","api","useTopN","opts","useAudit","query"],"mappings":"+CA0BO,MAAMA,EAAoB,CAC/B,IAAS,CAAC,eAAe,EACzB,OAAUC,GAAiB,CAAC,gBAAiB,SAAUA,CAAI,EAC3D,KAAS,CAACC,EAAcC,EAAgBF,EAAcG,IACpD,CAAC,gBAAiB,OAAQF,EAAKC,EAAIF,EAAMG,CAAK,EAChD,MAAUC,GAAsB,CAAC,gBAAiB,QAASA,CAAC,CAC9D,EAEO,SAASC,EAAiBL,EAAc,CAC7C,OAAOM,EAAwB,CAC7B,SAAUP,EAAkB,OAAOC,CAAI,EACvC,QAAS,IAAMO,EAAI,iBAAiB,CAAE,KAAAP,EAAM,EAC5C,gBAAiB,IACjB,4BAA6B,EAAA,CAC9B,CACH,CAEO,SAASQ,EAAQC,EAAuE,CAC7F,MAAMT,EAAOS,EAAK,MAAQ,EACpBN,EAAQM,EAAK,OAAS,GAC5B,OAAOH,EAAuB,CAC5B,SAAUP,EAAkB,KAAKU,EAAK,IAAKA,EAAK,GAAIT,EAAMG,CAAK,EAC/D,QAAS,IAAMI,EAAI,cAAc,CAAE,IAAKE,EAAK,IAAK,GAAIA,EAAK,GAAI,KAAAT,EAAM,MAAAG,EAAO,EAC5E,gBAAiB,IACjB,4BAA6B,EAAA,CAC9B,CACH,CAEO,SAASO,EAASC,EAAuB,CAC9C,OAAOL,EAAwB,CAC7B,SAAUP,EAAkB,MAAMY,CAAK,EACvC,QAAS,IAAMJ,EAAI,SAASI,CAAK,EACjC,gBAAiB,IACjB,4BAA6B,EAAA,CAC9B,CACH"}
@@ -0,0 +1,7 @@
1
+ import{h as a,r as o,s as e,t as n,v as r}from"./index-DCfdN5R7.js";/**
2
+ * @license lucide-react v0.469.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const c=a("Inbox",[["polyline",{points:"22 12 16 12 14 15 10 15 8 12 2 12",key:"o97t9d"}],["path",{d:"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",key:"oot6mr"}]]),s={all:["outbox"],list:t=>["outbox","list",t],stats:["outbox","stats"]};function i(t){return o({queryKey:s.list(t),queryFn:()=>e.listOutbox(t),refetchInterval:5e3,refetchIntervalInBackground:!1})}function y(){return o({queryKey:s.stats,queryFn:()=>e.getOutboxStats(),refetchInterval:1e4,refetchIntervalInBackground:!1})}function b(){const t=n();return r({mutationFn:u=>e.retryOutbox(u),onSuccess:()=>t.invalidateQueries({queryKey:s.all})})}export{c as I,i as a,b,y as u};
7
+ //# sourceMappingURL=use-outbox-DT_XWB_7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-outbox-DT_XWB_7.js","sources":["../../node_modules/lucide-react/dist/esm/icons/inbox.js","../../src/hooks/use-outbox.ts"],"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 Inbox = createLucideIcon(\"Inbox\", [\n [\"polyline\", { points: \"22 12 16 12 14 15 10 15 8 12 2 12\", key: \"o97t9d\" }],\n [\n \"path\",\n {\n d: \"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\",\n key: \"oot6mr\"\n }\n ]\n]);\n\nexport { Inbox as default };\n//# sourceMappingURL=inbox.js.map\n","/**\n * useOutbox — react-query wrappers for the delivery queue.\n *\n * useOutbox(query) — list rows (status / thread / limit)\n * useOutboxStats() — small summary for KPI cards\n * useRetryOutbox() — retry a giving_up row by id\n *\n * The outbox isn't on the SSE bus. Routes use the react-query\n * polling fallback (5s) plus the existing SSE `job` event, which\n * effectively covers any newly-enqueued row (a job that runs to\n * completion enqueues one or more outbox rows).\n */\n\nimport { useQueryClient, useQuery, useMutation } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type { ListOutboxQuery, ListOutboxResponse, OutboxStats } from '@/types/api'\n\nexport const outboxKeys = {\n all: ['outbox'] as const,\n list: (q: ListOutboxQuery) => ['outbox', 'list', q] as const,\n stats: ['outbox', 'stats'] as const,\n}\n\nexport function useOutbox(query: ListOutboxQuery) {\n return useQuery<ListOutboxResponse>({\n queryKey: outboxKeys.list(query),\n queryFn: () => api.listOutbox(query),\n refetchInterval: 5000,\n refetchIntervalInBackground: false,\n })\n}\n\nexport function useOutboxStats() {\n return useQuery<OutboxStats>({\n queryKey: outboxKeys.stats,\n queryFn: () => api.getOutboxStats(),\n refetchInterval: 10000,\n refetchIntervalInBackground: false,\n })\n}\n\nexport function useInvalidateOutbox() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: outboxKeys.all })\n}\n\nexport function useRetryOutbox() {\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (id: number) => api.retryOutbox(id),\n onSuccess: () => qc.invalidateQueries({ queryKey: outboxKeys.all }),\n })\n}\n"],"names":["Inbox","createLucideIcon","outboxKeys","q","useOutbox","query","useQuery","api","useOutboxStats","useRetryOutbox","qc","useQueryClient","useMutation","id"],"mappings":"oEAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAQC,EAAiB,QAAS,CACtC,CAAC,WAAY,CAAE,OAAQ,oCAAqC,IAAK,QAAQ,CAAE,EAC3E,CACE,OACA,CACE,EAAG,6GACH,IAAK,QACX,CACA,CACA,CAAC,ECDYC,EAAa,CACxB,IAAO,CAAC,QAAQ,EAChB,KAAQC,GAAuB,CAAC,SAAU,OAAQA,CAAC,EACnD,MAAO,CAAC,SAAU,OAAO,CAC3B,EAEO,SAASC,EAAUC,EAAwB,CAChD,OAAOC,EAA6B,CAClC,SAAUJ,EAAW,KAAKG,CAAK,EAC/B,QAAS,IAAME,EAAI,WAAWF,CAAK,EACnC,gBAAiB,IACjB,4BAA6B,EAAA,CAC9B,CACH,CAEO,SAASG,GAAiB,CAC/B,OAAOF,EAAsB,CAC3B,SAAUJ,EAAW,MACrB,QAAS,IAAMK,EAAI,eAAA,EACnB,gBAAiB,IACjB,4BAA6B,EAAA,CAC9B,CACH,CAOO,SAASE,GAAiB,CAC/B,MAAMC,EAAKC,EAAA,EACX,OAAOC,EAAY,CACjB,WAAaC,GAAeN,EAAI,YAAYM,CAAE,EAC9C,UAAW,IAAMH,EAAG,kBAAkB,CAAE,SAAUR,EAAW,IAAK,CAAA,CACnE,CACH","x_google_ignoreList":[0]}
@@ -0,0 +1,7 @@
1
+ import{h as s,r as a,s as c}from"./index-DCfdN5R7.js";/**
2
+ * @license lucide-react v0.469.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const d=s("CalendarClock",[["path",{d:"M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5",key:"1osxxc"}],["path",{d:"M16 2v4",key:"4m81vk"}],["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M3 10h5",key:"r794hk"}],["path",{d:"M17.5 17.5 16 16.3V14",key:"akvzfd"}],["circle",{cx:"16",cy:"16",r:"6",key:"qoo3c4"}]]),l={all:["schedules"],list:e=>["schedules","list",e]};function h(e){return a({queryKey:l.list(e),queryFn:()=>c.listSchedules(e)})}export{d as C,h as u};
7
+ //# sourceMappingURL=use-schedules-D4W8fMwo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-schedules-D4W8fMwo.js","sources":["../../node_modules/lucide-react/dist/esm/icons/calendar-clock.js","../../src/hooks/use-schedules.ts"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CalendarClock = createLucideIcon(\"CalendarClock\", [\n [\"path\", { d: \"M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5\", key: \"1osxxc\" }],\n [\"path\", { d: \"M16 2v4\", key: \"4m81vk\" }],\n [\"path\", { d: \"M8 2v4\", key: \"1cmpym\" }],\n [\"path\", { d: \"M3 10h5\", key: \"r794hk\" }],\n [\"path\", { d: \"M17.5 17.5 16 16.3V14\", key: \"akvzfd\" }],\n [\"circle\", { cx: \"16\", cy: \"16\", r: \"6\", key: \"qoo3c4\" }]\n]);\n\nexport { CalendarClock as default };\n//# sourceMappingURL=calendar-clock.js.map\n","/**\n * useSchedules — react-query wrapper for /api/schedules.\n *\n * Read-only: schedule create / delete / toggle isn't exposed via\n * /api today (only via CLI). When that lands the mutations slot in\n * here next to useSchedules.\n */\n\nimport { useQueryClient, useQuery } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type { ListSchedulesQuery, ListSchedulesResponse } from '@/types/api'\n\nexport const schedulesKeys = {\n all: ['schedules'] as const,\n list: (q: ListSchedulesQuery) => ['schedules', 'list', q] as const,\n}\n\nexport function useSchedules(query: ListSchedulesQuery) {\n return useQuery<ListSchedulesResponse>({\n queryKey: schedulesKeys.list(query),\n queryFn: () => api.listSchedules(query),\n })\n}\n\nexport function useInvalidateSchedules() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: schedulesKeys.all })\n}\n"],"names":["CalendarClock","createLucideIcon","schedulesKeys","q","useSchedules","query","useQuery","api"],"mappings":"sDAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAgBC,EAAiB,gBAAiB,CACtD,CAAC,OAAQ,CAAE,EAAG,+DAAgE,IAAK,QAAQ,CAAE,EAC7F,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAQ,CAAE,EACxC,CAAC,OAAQ,CAAE,EAAG,SAAU,IAAK,QAAQ,CAAE,EACvC,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAQ,CAAE,EACxC,CAAC,OAAQ,CAAE,EAAG,wBAAyB,IAAK,QAAQ,CAAE,EACtD,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,QAAQ,CAAE,CAC1D,CAAC,ECJYC,EAAgB,CAC3B,IAAM,CAAC,WAAW,EAClB,KAAOC,GAA0B,CAAC,YAAa,OAAQA,CAAC,CAC1D,EAEO,SAASC,EAAaC,EAA2B,CACtD,OAAOC,EAAgC,CACrC,SAAUJ,EAAc,KAAKG,CAAK,EAClC,QAAS,IAAME,EAAI,cAAcF,CAAK,CAAA,CACvC,CACH","x_google_ignoreList":[0]}
@@ -0,0 +1,2 @@
1
+ import{r as u,s as t,t as i,v as s}from"./index-DCfdN5R7.js";const r={all:["settings"],env:e=>["settings","env",e],service:["settings","service"],serviceLog:e=>["settings","service","log-tail",e],admins:["settings","admins"],config:["settings","config"],workspaces:["settings","workspaces"]};function o(e={}){const n=!!e.reveal;return u({queryKey:r.env(n),queryFn:()=>t.getEnv({reveal:n})})}function v(){const e=i();return s({mutationFn:n=>t.updateEnv(n),onSuccess:()=>e.invalidateQueries({queryKey:["settings","env"]})})}function l(){return u({queryKey:r.service,queryFn:()=>t.getServiceStatus(),refetchInterval:5e3,refetchIntervalInBackground:!1})}function y(e=120){return u({queryKey:r.serviceLog(e),queryFn:()=>t.getServiceLogTail({lines:e}),refetchInterval:5e3,refetchIntervalInBackground:!1})}function a(e,n){return s({mutationFn:e,onSuccess:()=>n.invalidateQueries({queryKey:r.service})})}function f(){const e=i();return a(()=>t.startService(),e)}function d(){const e=i();return a(()=>t.stopService(),e)}function g(){const e=i();return a(()=>t.restartService(),e)}function q(){return u({queryKey:r.admins,queryFn:()=>t.listAdminAllowlist()})}function m(){const e=i();return s({mutationFn:n=>t.addAdminAllowlist(n),onSuccess:()=>e.invalidateQueries({queryKey:r.admins})})}function S(){const e=i();return s({mutationFn:n=>t.removeAdminAllowlist(n),onSuccess:()=>e.invalidateQueries({queryKey:r.admins})})}function p(){return u({queryKey:r.config,queryFn:()=>t.getConfig()})}function F(){const e=i();return s({mutationFn:n=>t.updateConfig(n),onSuccess:()=>e.invalidateQueries({queryKey:r.config})})}function h(){return u({queryKey:r.workspaces,queryFn:()=>t.listWorkspacesFull()})}function A(){const e=i();return s({mutationFn:n=>t.upsertWorkspace(n),onSuccess:()=>e.invalidateQueries({queryKey:r.workspaces})})}function K(){const e=i();return s({mutationFn:n=>t.deleteWorkspace(n),onSuccess:()=>e.invalidateQueries({queryKey:r.workspaces})})}function k(){return s({mutationFn:()=>t.startWechatQr()})}function w(e){return u({queryKey:["settings","wechat-qr",e??""],queryFn:()=>t.getWechatQrStatus({token:e}),enabled:!!e,refetchInterval:2e3,refetchIntervalInBackground:!1})}function Q(){return s({mutationFn:e=>t.testAcpAgent(e)})}function W(){return s({mutationFn:e=>t.discoverAcpAgents(e)})}function I(){return s({mutationFn:()=>t.testEmail()})}function T(){return u({queryKey:["settings","search","providers"],queryFn:()=>t.getSearchProviders()})}function E(){return s({mutationFn:e=>t.testSearchProvider(e)})}function C(){return u({queryKey:["settings","viewer-tunnel"],queryFn:()=>t.getViewerTunnel()})}export{l as a,o as b,v as c,F as d,f as e,g as f,k as g,w as h,I as i,C as j,Q as k,W as l,q as m,d as n,y as o,m as p,S as q,h as r,A as s,K as t,p as u,T as v,E as w};
2
+ //# sourceMappingURL=use-settings-DGIjmUX0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-settings-DGIjmUX0.js","sources":["../../src/hooks/use-settings.ts"],"sourcesContent":["/**\n * useSettings — react-query wrappers for the env editor + service\n * control surfaces.\n *\n * useEnv({ reveal }) — env file values (masked when\n * reveal is false)\n * useUpdateEnv() — bulk update\n * useServiceStatus() — pid / mode / uptime\n * useStart/Stop/Restart() — service lifecycle\n *\n * Service status polls every 5s while the page is foreground so\n * the operator sees restart progress live.\n */\n\nimport { useQueryClient, useQuery, useMutation } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type {\n ACPDiscoverBody,\n ACPDiscoverResponse,\n ACPTestBody,\n ACPTestResponse,\n EmailTestResponse,\n ViewerTunnelStatusResponse,\n AddAdminBody,\n AdminAllowlistResponse,\n AdminMutationResponse,\n AppConfig,\n EnvResponse,\n RemoveAdminBody,\n SearchProvidersResponse,\n SearchTestBody,\n SearchTestResponse,\n ServiceActionResponse,\n ServiceLogTailResponse,\n ServiceStatus,\n UpdateEnvBody,\n WechatQrStartResponse,\n WechatQrStatusResponse,\n WorkspaceConfig,\n} from '@/types/api'\n\nexport const settingsKeys = {\n all: ['settings'] as const,\n env: (reveal: boolean) => ['settings', 'env', reveal] as const,\n service: ['settings', 'service'] as const,\n serviceLog: (lines: number) => ['settings', 'service', 'log-tail', lines] as const,\n admins: ['settings', 'admins'] as const,\n config: ['settings', 'config'] as const,\n workspaces: ['settings', 'workspaces'] as const,\n}\n\nexport function useEnv(opts: { reveal?: boolean } = {}) {\n const reveal = !!opts.reveal\n return useQuery<EnvResponse>({\n queryKey: settingsKeys.env(reveal),\n queryFn: () => api.getEnv({ reveal }),\n })\n}\n\nexport function useUpdateEnv() {\n const qc = useQueryClient()\n return useMutation<EnvResponse, Error, UpdateEnvBody>({\n mutationFn: (body) => api.updateEnv(body),\n onSuccess: () => qc.invalidateQueries({ queryKey: ['settings', 'env'] }),\n })\n}\n\nexport function useServiceStatus() {\n return useQuery<ServiceStatus>({\n queryKey: settingsKeys.service,\n queryFn: () => api.getServiceStatus(),\n refetchInterval: 5000,\n refetchIntervalInBackground: false,\n })\n}\n\nexport function useServiceLogTail(lines = 120) {\n return useQuery<ServiceLogTailResponse>({\n queryKey: settingsKeys.serviceLog(lines),\n queryFn: () => api.getServiceLogTail({ lines }),\n refetchInterval: 5000,\n refetchIntervalInBackground: false,\n })\n}\n\nfunction makeServiceMutation(\n fn: () => Promise<ServiceActionResponse>,\n qc: ReturnType<typeof useQueryClient>,\n) {\n return useMutation<ServiceActionResponse, Error, void>({\n mutationFn: fn,\n onSuccess: () => qc.invalidateQueries({ queryKey: settingsKeys.service }),\n })\n}\n\nexport function useStartService() {\n const qc = useQueryClient()\n return makeServiceMutation(() => api.startService(), qc)\n}\n\nexport function useStopService() {\n const qc = useQueryClient()\n return makeServiceMutation(() => api.stopService(), qc)\n}\n\nexport function useRestartService() {\n const qc = useQueryClient()\n return makeServiceMutation(() => api.restartService(), qc)\n}\n\n/* ─────────────── Admin allowlist ─────────────── */\n\nexport function useAdminAllowlist() {\n return useQuery<AdminAllowlistResponse>({\n queryKey: settingsKeys.admins,\n queryFn: () => api.listAdminAllowlist(),\n })\n}\n\nexport function useAddAdmin() {\n const qc = useQueryClient()\n return useMutation<AdminMutationResponse, Error, AddAdminBody>({\n mutationFn: (body) => api.addAdminAllowlist(body),\n onSuccess: () => qc.invalidateQueries({ queryKey: settingsKeys.admins }),\n })\n}\n\nexport function useRemoveAdmin() {\n const qc = useQueryClient()\n return useMutation<AdminMutationResponse, Error, RemoveAdminBody>({\n mutationFn: (body) => api.removeAdminAllowlist(body),\n onSuccess: () => qc.invalidateQueries({ queryKey: settingsKeys.admins }),\n })\n}\n\n/* ─────────────── App config ─────────────── */\n\nexport function useConfig() {\n return useQuery<AppConfig>({\n queryKey: settingsKeys.config,\n queryFn: () => api.getConfig(),\n })\n}\n\nexport function useUpdateConfig() {\n const qc = useQueryClient()\n return useMutation<AppConfig, Error, Partial<AppConfig>>({\n mutationFn: (body) => api.updateConfig(body),\n onSuccess: () => qc.invalidateQueries({ queryKey: settingsKeys.config }),\n })\n}\n\n/* ─────────────── Workspaces ─────────────── */\n\nexport function useWorkspaces() {\n return useQuery<{ workspaces: WorkspaceConfig[] }>({\n queryKey: settingsKeys.workspaces,\n queryFn: () => api.listWorkspacesFull(),\n })\n}\n\nexport function useUpsertWorkspace() {\n const qc = useQueryClient()\n return useMutation<\n { ok: boolean; workspace: WorkspaceConfig },\n Error,\n WorkspaceConfig\n >({\n mutationFn: (body) => api.upsertWorkspace(body),\n onSuccess: () => qc.invalidateQueries({ queryKey: settingsKeys.workspaces }),\n })\n}\n\nexport function useDeleteWorkspace() {\n const qc = useQueryClient()\n return useMutation<{ ok: boolean }, Error, string>({\n mutationFn: (id) => api.deleteWorkspace(id),\n onSuccess: () => qc.invalidateQueries({ queryKey: settingsKeys.workspaces }),\n })\n}\n\n/* ─────────────── WeChat QR ─────────────── */\n\nexport function useStartWechatQr() {\n return useMutation<WechatQrStartResponse, Error, void>({\n mutationFn: () => api.startWechatQr(),\n })\n}\n\n/** Poll the QR status every 2s while the modal is open. Caller\n * passes `token` once it has it from the start mutation; passing\n * null disables the polling. On status='confirmed' the backend\n * persists wechat-ilink → re-fetch config to update the toggle. */\nexport function useWechatQrStatus(token: string | null) {\n return useQuery<WechatQrStatusResponse>({\n queryKey: ['settings', 'wechat-qr', token ?? ''],\n queryFn: () => api.getWechatQrStatus({ token: token as string }),\n enabled: Boolean(token),\n refetchInterval: 2000,\n refetchIntervalInBackground: false,\n })\n}\n\n/** Probe a single ACP endpoint by fetching its manifest. Used by\n * the \"Test\" buttons in /settings/agents to validate an entry\n * before saving it to config. Errors flow back as ApiError. */\nexport function useTestAcp() {\n return useMutation<ACPTestResponse, Error, ACPTestBody>({\n mutationFn: (body) => api.testAcpAgent(body),\n })\n}\n\n/** Probe a `<baseUrl>/.well-known/acp` doc for an agent list. Used\n * by the \"Discover\" form in /settings/agents to bulk-import. The\n * caller still has to PUT /api/config { acpAgents } to persist. */\nexport function useDiscoverAcp() {\n return useMutation<ACPDiscoverResponse, Error, ACPDiscoverBody>({\n mutationFn: (body) => api.discoverAcpAgents(body),\n })\n}\n\n/** Verify SMTP creds in the running env. Doesn't actually send mail —\n * just `nodemailer.verify()`. Returns `{ ok, message }` on success or\n * throws ApiError otherwise (the route catches + toasts the message). */\nexport function useTestEmail() {\n return useMutation<EmailTestResponse, Error, void>({\n mutationFn: () => api.testEmail(),\n })\n}\n\n/** v1.2.126 — registered web_search providers + their current\n * availability + the resolved chain. Used by /settings/search to\n * paint per-provider rows and the chain preview at the top. Polls\n * once on mount; manual refetch after Save. */\nexport function useSearchProviders() {\n return useQuery<SearchProvidersResponse>({\n queryKey: ['settings', 'search', 'providers'],\n queryFn: () => api.getSearchProviders(),\n })\n}\n\n/** Ping one provider. Always resolves (no throw on provider error —\n * the response carries `{ ok, error }`); throws only on transport\n * error. The page renders the result inline beside the row. */\nexport function useTestSearchProvider() {\n return useMutation<SearchTestResponse, Error, SearchTestBody>({\n mutationFn: (body) => api.testSearchProvider(body),\n })\n}\n\n/** Live viewer config + cloudflared tunnel state. Used by the Viewer\n * card on /settings/viewer to render the \"Tunnel: running / URL: X /\n * binary: …\" panel. Operators click a manual Refresh button to\n * re-fetch — no auto-polling because tunnel state is essentially\n * static between operator actions (start / stop / link expiry). */\nexport function useViewerTunnel() {\n return useQuery<ViewerTunnelStatusResponse>({\n queryKey: ['settings', 'viewer-tunnel'],\n queryFn: () => api.getViewerTunnel(),\n })\n}\n"],"names":["settingsKeys","reveal","lines","useEnv","opts","useQuery","api","useUpdateEnv","qc","useQueryClient","useMutation","body","useServiceStatus","useServiceLogTail","makeServiceMutation","fn","useStartService","useStopService","useRestartService","useAdminAllowlist","useAddAdmin","useRemoveAdmin","useConfig","useUpdateConfig","useWorkspaces","useUpsertWorkspace","useDeleteWorkspace","id","useStartWechatQr","useWechatQrStatus","token","useTestAcp","useDiscoverAcp","useTestEmail","useSearchProviders","useTestSearchProvider","useViewerTunnel"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import{h as e,r as t,s}from"./index-DCfdN5R7.js";/**
2
+ * @license lucide-react v0.469.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const r=e("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"}]]),o={remoteHot:["skills","remote","hot"]};function l(){return t({queryKey:o.remoteHot,queryFn:()=>s.getSkillsRemoteHot(),staleTime:6e4})}export{r as F,l as u};
7
+ //# sourceMappingURL=use-skills-D2bMM580.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-skills-D2bMM580.js","sources":["../../node_modules/lucide-react/dist/esm/icons/flame.js","../../src/hooks/use-skills.ts"],"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 * 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"],"names":["Flame","createLucideIcon","skillsKeys","useSkillsRemoteHot","useQuery","api"],"mappings":"iDAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAQC,EAAiB,QAAS,CACtC,CACE,OACA,CACE,EAAG,4KACH,IAAK,QACX,CACA,CACA,CAAC,ECEYC,EAAa,CAIxB,UAAY,CAAC,SAAU,SAAU,KAAK,CACxC,EAqBO,SAASC,GAAqB,CACnC,OAAOC,EAAkC,CACvC,SAAUF,EAAW,UACrB,QAAS,IAAMG,EAAI,mBAAA,EACnB,UAAW,GAAA,CACZ,CACH","x_google_ignoreList":[0]}
@@ -0,0 +1,2 @@
1
+ import{r as c,s as r,v as t,t as n}from"./index-DCfdN5R7.js";import{m as i}from"./use-memory-CXDwKCco.js";const a={all:["memory","vector"],status:e=>["memory","vector","status",e??null]};function y(e={}){return c({queryKey:a.status(e.user_key),queryFn:()=>r.getMemoryVectorStatus(e),refetchInterval:3e3,refetchIntervalInBackground:!1})}function u(e){return()=>{e.invalidateQueries({queryKey:a.all}),e.invalidateQueries({queryKey:i.all})}}function f(){const e=n(),o=u(e);return t({mutationFn:s=>r.backfillMemoryVector({user_key:s?.user_key},s?.max_rows?{max_rows:s.max_rows}:void 0),onSuccess:o})}function d(){const e=n();return t({mutationFn:()=>r.downloadMemoryVector(),onSuccess:u(e)})}function g(){const e=n();return t({mutationFn:o=>r.clearMemoryVector({user_key:o?.user_key}),onSuccess:u(e)})}function V(){return t({mutationFn:()=>r.testMemoryVector()})}export{V as a,d as b,f as c,g as d,y as u};
2
+ //# sourceMappingURL=use-vector-BYOFwjU0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-vector-BYOFwjU0.js","sources":["../../src/hooks/use-vector.ts"],"sourcesContent":["/**\n * useVector — react-query wrappers for the embedding/vector backend.\n *\n * useVectorStatus({ user_key }) — status + coverage + jobs\n * (polls every 3s; jobs\n * are async)\n * useTriggerVectorBackfill()\n * useTriggerVectorDownload()\n * useTriggerVectorClear() — DESTRUCTIVE; route gates\n * with ConfirmDialog\n * useTriggerVectorTest()\n *\n * Status polling stops backgrounded (refetchIntervalInBackground:\n * false) so an idle tab on a phone doesn't drain battery.\n */\n\nimport { useQueryClient, useQuery, useMutation } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport { memoryKeys } from './use-memory'\nimport type {\n VectorActionResponse,\n VectorClearResponse,\n VectorStatus,\n VectorTestResponse,\n} from '@/types/api'\n\nexport const vectorKeys = {\n all: ['memory', 'vector'] as const,\n status: (user_key?: string) => ['memory', 'vector', 'status', user_key ?? null] as const,\n}\n\nexport function useVectorStatus(query: { user_key?: string } = {}) {\n return useQuery<VectorStatus>({\n queryKey: vectorKeys.status(query.user_key),\n queryFn: () => api.getMemoryVectorStatus(query),\n refetchInterval: 3000,\n refetchIntervalInBackground: false,\n })\n}\n\nfunction invalidateAfter(qc: ReturnType<typeof useQueryClient>): () => void {\n return () => {\n qc.invalidateQueries({ queryKey: vectorKeys.all })\n qc.invalidateQueries({ queryKey: memoryKeys.all })\n }\n}\n\nexport function useTriggerVectorBackfill() {\n const qc = useQueryClient()\n const invalidate = invalidateAfter(qc)\n return useMutation<\n VectorActionResponse,\n Error,\n { user_key?: string; max_rows?: number } | undefined\n >({\n mutationFn: (vars) => api.backfillMemoryVector(\n { user_key: vars?.user_key },\n vars?.max_rows ? { max_rows: vars.max_rows } : undefined,\n ),\n onSuccess: invalidate,\n })\n}\n\nexport function useTriggerVectorDownload() {\n const qc = useQueryClient()\n return useMutation<VectorActionResponse, Error, void>({\n mutationFn: () => api.downloadMemoryVector(),\n onSuccess: invalidateAfter(qc),\n })\n}\n\nexport function useTriggerVectorClear() {\n const qc = useQueryClient()\n return useMutation<VectorClearResponse, Error, { user_key?: string } | undefined>({\n mutationFn: (vars) => api.clearMemoryVector({ user_key: vars?.user_key }),\n onSuccess: invalidateAfter(qc),\n })\n}\n\nexport function useTriggerVectorTest() {\n return useMutation<VectorTestResponse, Error, void>({\n mutationFn: () => api.testMemoryVector(),\n })\n}\n"],"names":["vectorKeys","user_key","useVectorStatus","query","useQuery","api","invalidateAfter","qc","memoryKeys","useTriggerVectorBackfill","useQueryClient","invalidate","useMutation","vars","useTriggerVectorDownload","useTriggerVectorClear","useTriggerVectorTest"],"mappings":"0GA0BO,MAAMA,EAAa,CACxB,IAAQ,CAAC,SAAU,QAAQ,EAC3B,OAASC,GAAsB,CAAC,SAAU,SAAU,SAAUA,GAAY,IAAI,CAChF,EAEO,SAASC,EAAgBC,EAA+B,GAAI,CACjE,OAAOC,EAAuB,CAC5B,SAAUJ,EAAW,OAAOG,EAAM,QAAQ,EAC1C,QAAS,IAAME,EAAI,sBAAsBF,CAAK,EAC9C,gBAAiB,IACjB,4BAA6B,EAAA,CAC9B,CACH,CAEA,SAASG,EAAgBC,EAAmD,CAC1E,MAAO,IAAM,CACXA,EAAG,kBAAkB,CAAE,SAAUP,EAAW,IAAK,EACjDO,EAAG,kBAAkB,CAAE,SAAUC,EAAW,IAAK,CACnD,CACF,CAEO,SAASC,GAA2B,CACzC,MAAMF,EAAKG,EAAA,EACLC,EAAaL,EAAgBC,CAAE,EACrC,OAAOK,EAIL,CACA,WAAaC,GAASR,EAAI,qBACxB,CAAE,SAAUQ,GAAM,QAAA,EAClBA,GAAM,SAAW,CAAE,SAAUA,EAAK,UAAa,MAAA,EAEjD,UAAWF,CAAA,CACZ,CACH,CAEO,SAASG,GAA2B,CACzC,MAAMP,EAAKG,EAAA,EACX,OAAOE,EAA+C,CACpD,WAAY,IAAMP,EAAI,qBAAA,EACtB,UAAWC,EAAgBC,CAAE,CAAA,CAC9B,CACH,CAEO,SAASQ,GAAwB,CACtC,MAAMR,EAAKG,EAAA,EACX,OAAOE,EAA2E,CAChF,WAAaC,GAASR,EAAI,kBAAkB,CAAE,SAAUQ,GAAM,SAAU,EACxE,UAAWP,EAAgBC,CAAE,CAAA,CAC9B,CACH,CAEO,SAASS,GAAuB,CACrC,OAAOJ,EAA6C,CAClD,WAAY,IAAMP,EAAI,iBAAA,CAAiB,CACxC,CACH"}
@@ -0,0 +1,2 @@
1
+ import{r as a,s as u,t as i,v as o}from"./index-DCfdN5R7.js";const t={all:["workspace"],files:(e,s)=>["workspace","files",e,s]};function c(){return a({queryKey:["agents","status"],queryFn:()=>u.getAgentsStatus()})}function y(e,s,r={}){return a({queryKey:t.files(e,s),queryFn:()=>u.getWorkspaceFiles({agent:e,...s?{path:s}:{}}),enabled:r.enabled!==!1&&!!e})}function f(){const e=i();return o({mutationFn:({agent:s,path:r,body:n})=>u.writeWorkspaceFile({agent:s,path:r},n),onSuccess:()=>e.invalidateQueries({queryKey:t.all})})}export{y as a,f as b,c as u};
2
+ //# sourceMappingURL=use-workspace-CuytyHwb.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-workspace-CConjEx0.js","sources":["../../src/hooks/use-workspace.ts"],"sourcesContent":["/**\n * useWorkspace — agent picker source + per-agent file browser +\n * write mutation.\n *\n * useAgentsStatus() — populate the picker\n * useWorkspaceFiles(agent, path) — dir listing or file\n * content (discriminated\n * by `type`)\n * useWriteWorkspaceFile() — PUT a file\n *\n * Both reads stay cached at the default 30s staleTime; the write\n * invalidates so the saved size/mtime re-paint immediately.\n */\n\nimport { useQueryClient, useQuery, useMutation } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type {\n WorkspaceFilesResponse,\n WriteWorkspaceFileBody,\n WriteWorkspaceFileResponse,\n} from '@/types/api'\n\nexport const workspaceKeys = {\n all: ['workspace'] as const,\n files: (agent: string, path: string) =>\n ['workspace', 'files', agent, path] as const,\n}\n\nexport function useAgentsStatus() {\n return useQuery<Record<string, boolean>>({\n queryKey: ['agents', 'status'],\n queryFn: () => api.getAgentsStatus(),\n })\n}\n\nexport function useWorkspaceFiles(\n agent: string,\n path: string,\n opts: { enabled?: boolean } = {},\n) {\n return useQuery<WorkspaceFilesResponse>({\n queryKey: workspaceKeys.files(agent, path),\n queryFn: () => api.getWorkspaceFiles({ agent, ...(path ? { path } : {}) }),\n enabled: opts.enabled !== false && Boolean(agent),\n })\n}\n\nexport function useInvalidateWorkspace() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: workspaceKeys.all })\n}\n\nexport function useWriteWorkspaceFile() {\n const qc = useQueryClient()\n return useMutation<\n WriteWorkspaceFileResponse,\n Error,\n { agent: string; path: string; body: WriteWorkspaceFileBody }\n >({\n mutationFn: ({ agent, path, body }) =>\n api.writeWorkspaceFile({ agent, path }, body),\n onSuccess: () => qc.invalidateQueries({ queryKey: workspaceKeys.all }),\n })\n}\n"],"names":["workspaceKeys","agent","path","useAgentsStatus","useQuery","api","useWorkspaceFiles","opts","useWriteWorkspaceFile","qc","useQueryClient","useMutation","body"],"mappings":"6DAsBO,MAAMA,EAAgB,CAC3B,IAAO,CAAC,WAAW,EACnB,MAAO,CAACC,EAAeC,IACrB,CAAC,YAAa,QAASD,EAAOC,CAAI,CACtC,EAEO,SAASC,GAAkB,CAChC,OAAOC,EAAkC,CACvC,SAAU,CAAC,SAAU,QAAQ,EAC7B,QAAS,IAAMC,EAAI,gBAAA,CAAgB,CACpC,CACH,CAEO,SAASC,EACdL,EACAC,EACAK,EAA8B,CAAA,EAC9B,CACA,OAAOH,EAAiC,CACtC,SAAUJ,EAAc,MAAMC,EAAOC,CAAI,EACzC,QAAS,IAAMG,EAAI,kBAAkB,CAAE,MAAAJ,EAAO,GAAIC,EAAO,CAAE,KAAAA,GAAS,CAAA,EAAK,EACzE,QAASK,EAAK,UAAY,IAAS,EAAQN,CAAK,CACjD,CACH,CAOO,SAASO,GAAwB,CACtC,MAAMC,EAAKC,EAAA,EACX,OAAOC,EAIL,CACA,WAAY,CAAC,CAAE,MAAAV,EAAO,KAAAC,EAAM,KAAAU,CAAA,IAC1BP,EAAI,mBAAmB,CAAE,MAAAJ,EAAO,KAAAC,CAAA,EAAQU,CAAI,EAC9C,UAAW,IAAMH,EAAG,kBAAkB,CAAE,SAAUT,EAAc,IAAK,CAAA,CACtE,CACH"}
1
+ {"version":3,"file":"use-workspace-CuytyHwb.js","sources":["../../src/hooks/use-workspace.ts"],"sourcesContent":["/**\n * useWorkspace — agent picker source + per-agent file browser +\n * write mutation.\n *\n * useAgentsStatus() — populate the picker\n * useWorkspaceFiles(agent, path) — dir listing or file\n * content (discriminated\n * by `type`)\n * useWriteWorkspaceFile() — PUT a file\n *\n * Both reads stay cached at the default 30s staleTime; the write\n * invalidates so the saved size/mtime re-paint immediately.\n */\n\nimport { useQueryClient, useQuery, useMutation } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type {\n WorkspaceFilesResponse,\n WriteWorkspaceFileBody,\n WriteWorkspaceFileResponse,\n} from '@/types/api'\n\nexport const workspaceKeys = {\n all: ['workspace'] as const,\n files: (agent: string, path: string) =>\n ['workspace', 'files', agent, path] as const,\n}\n\nexport function useAgentsStatus() {\n return useQuery<Record<string, boolean>>({\n queryKey: ['agents', 'status'],\n queryFn: () => api.getAgentsStatus(),\n })\n}\n\nexport function useWorkspaceFiles(\n agent: string,\n path: string,\n opts: { enabled?: boolean } = {},\n) {\n return useQuery<WorkspaceFilesResponse>({\n queryKey: workspaceKeys.files(agent, path),\n queryFn: () => api.getWorkspaceFiles({ agent, ...(path ? { path } : {}) }),\n enabled: opts.enabled !== false && Boolean(agent),\n })\n}\n\nexport function useInvalidateWorkspace() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: workspaceKeys.all })\n}\n\nexport function useWriteWorkspaceFile() {\n const qc = useQueryClient()\n return useMutation<\n WriteWorkspaceFileResponse,\n Error,\n { agent: string; path: string; body: WriteWorkspaceFileBody }\n >({\n mutationFn: ({ agent, path, body }) =>\n api.writeWorkspaceFile({ agent, path }, body),\n onSuccess: () => qc.invalidateQueries({ queryKey: workspaceKeys.all }),\n })\n}\n"],"names":["workspaceKeys","agent","path","useAgentsStatus","useQuery","api","useWorkspaceFiles","opts","useWriteWorkspaceFile","qc","useQueryClient","useMutation","body"],"mappings":"6DAsBO,MAAMA,EAAgB,CAC3B,IAAO,CAAC,WAAW,EACnB,MAAO,CAACC,EAAeC,IACrB,CAAC,YAAa,QAASD,EAAOC,CAAI,CACtC,EAEO,SAASC,GAAkB,CAChC,OAAOC,EAAkC,CACvC,SAAU,CAAC,SAAU,QAAQ,EAC7B,QAAS,IAAMC,EAAI,gBAAA,CAAgB,CACpC,CACH,CAEO,SAASC,EACdL,EACAC,EACAK,EAA8B,CAAA,EAC9B,CACA,OAAOH,EAAiC,CACtC,SAAUJ,EAAc,MAAMC,EAAOC,CAAI,EACzC,QAAS,IAAMG,EAAI,kBAAkB,CAAE,MAAAJ,EAAO,GAAIC,EAAO,CAAE,KAAAA,GAAS,CAAA,EAAK,EACzE,QAASK,EAAK,UAAY,IAAS,EAAQN,CAAK,CACjD,CACH,CAOO,SAASO,GAAwB,CACtC,MAAMC,EAAKC,EAAA,EACX,OAAOC,EAIL,CACA,WAAY,CAAC,CAAE,MAAAV,EAAO,KAAAC,EAAM,KAAAU,CAAA,IAC1BP,EAAI,mBAAmB,CAAE,MAAAJ,EAAO,KAAAC,CAAA,EAAQU,CAAI,EAC9C,UAAW,IAAMH,EAAG,kBAAkB,CAAE,SAAUT,EAAc,IAAK,CAAA,CACtE,CACH"}
@@ -0,0 +1,2 @@
1
+ import{u as L,j as e,d as A,e as p,k as D,l as G,m as F,n as W,o as B,I as j,p as c,q as y,w as H,i as q,f as z}from"./index-DCfdN5R7.js";import{r as g}from"./react-DlP5eolq.js";import{b as Q,c as X}from"./use-settings-DGIjmUX0.js";import{a as P,u as Z,b as J,c as $,d as ee}from"./use-vector-BYOFwjU0.js";import{L as N}from"./loader-circle-DDdmcH0k.js";import{S as se}from"./save-BDOtZrfp.js";import{E as te,a as ae}from"./eye-BfPyNFzk.js";import{C as re}from"./confirm-dialog-BDb0NLny.js";import{E as oe}from"./empty-state-CuiqdZiB.js";import{C as Y}from"./circle-x-CqFMzO-x.js";import{R as ie}from"./refresh-ccw-DlAd-eTQ.js";import{P as V}from"./play-DX5wp4WH.js";import{D as ne}from"./download-CVZnHcwj.js";import{T as ce}from"./trash-2-D2x2UPuZ.js";import{C as le}from"./circle-check-big-DBg2BD6o.js";import"./use-memory-CXDwKCco.js";const m={backend:"off",localModel:"Xenova/bge-base-zh-v1.5",openaiBaseUrl:"https://api.openai.com/v1",openaiModel:"text-embedding-3-small",openaiApiKey:"",batchSize:"32",hybridWeight:"0.5"};function de(s){const t=(s.AGIM_MEMORY_VECTOR_BACKEND||"").toLowerCase();return{backend:t==="local"||t==="openai"?t:"off",localModel:s.AGIM_MEMORY_VECTOR_LOCAL_MODEL||"",openaiBaseUrl:s.AGIM_MEMORY_VECTOR_OPENAI_BASE_URL||"",openaiModel:s.AGIM_MEMORY_VECTOR_OPENAI_MODEL||"",openaiApiKey:"",batchSize:s.AGIM_MEMORY_VECTOR_BATCH_SIZE||"",hybridWeight:s.AGIM_MEMORY_VECTOR_HYBRID_WEIGHT||""}}function me({onSaved:s}){const{t}=L(["memory","common"]),n=Q({reveal:!1}),l=g.useMemo(()=>n.data?.env??{},[n.data?.env]),[r,f]=g.useState(m),[M,E]=g.useState(!1),u=g.useRef(m);g.useEffect(()=>{if(!n.data)return;const a=de(l);f(a),u.current=a},[l,n.data]);const b=X(),_=P(),C=g.useMemo(()=>{const a=u.current;return Object.keys(r).some(d=>r[d]!==a[d])},[r]);function h(a,d){f(o=>({...o,[a]:d}))}function R(a){f(d=>{const o={...d,backend:a};return a==="local"&&!o.localModel.trim()&&(o.localModel=m.localModel),a==="openai"&&(o.openaiBaseUrl.trim()||(o.openaiBaseUrl=m.openaiBaseUrl),o.openaiModel.trim()||(o.openaiModel=m.openaiModel)),a!=="off"&&(o.batchSize.trim()||(o.batchSize=m.batchSize),o.hybridWeight.trim()||(o.hybridWeight=m.hybridWeight)),o})}function k(){if(r.backend==="openai"){if(!r.openaiBaseUrl.trim())return t("vector.form.errors.baseUrlRequired");try{new URL(r.openaiBaseUrl.trim())}catch{return t("vector.form.errors.baseUrlInvalid")}if(!r.openaiModel.trim())return t("vector.form.errors.openaiModelRequired");if(!!!l.AGIM_MEMORY_VECTOR_OPENAI_API_KEY&&!r.openaiApiKey.trim())return t("vector.form.errors.apiKeyRequired")}if(r.backend==="local"&&!r.localModel.trim())return t("vector.form.errors.localModelRequired");if(r.batchSize.trim()){const a=Number(r.batchSize);if(!Number.isFinite(a)||a<1||a>1024)return t("vector.form.errors.batchSizeRange")}if(r.hybridWeight.trim()){const a=Number(r.hybridWeight);if(!Number.isFinite(a)||a<0||a>1)return t("vector.form.errors.hybridWeightRange")}return null}function S(){const a=u.current,d={},o=(w,T,U)=>{T!==U&&(d[w]=T.trim()===""?null:T.trim())};return o("AGIM_MEMORY_VECTOR_BACKEND",r.backend,a.backend),o("AGIM_MEMORY_VECTOR_LOCAL_MODEL",r.localModel,a.localModel),o("AGIM_MEMORY_VECTOR_OPENAI_BASE_URL",r.openaiBaseUrl,a.openaiBaseUrl),o("AGIM_MEMORY_VECTOR_OPENAI_MODEL",r.openaiModel,a.openaiModel),o("AGIM_MEMORY_VECTOR_BATCH_SIZE",r.batchSize,a.batchSize),o("AGIM_MEMORY_VECTOR_HYBRID_WEIGHT",r.hybridWeight,a.hybridWeight),r.openaiApiKey.trim()&&(d.AGIM_MEMORY_VECTOR_OPENAI_API_KEY=r.openaiApiKey.trim()),d}async function I(){const a=k();if(a){c.error(a);return}const d=S();if(Object.keys(d).length===0){c.info(t("vector.form.nothingChanged"));return}try{await b.mutateAsync({updates:d}),c.success(t("vector.form.savedToast"));try{const o=await _.mutateAsync();o.ok?c.success(t("vector.actions.testOk")):c.error(t("vector.actions.testFail",{detail:o.error??""}))}catch(o){const{message:w}=y(o,t);c.error(t("vector.actions.testFail",{detail:w}))}s?.()}catch(o){const{message:w}=y(o,t);c.error(w)}}function O(){f(u.current)}const i=b.isPending||_.isPending,x=!!l.AGIM_MEMORY_VECTOR_OPENAI_API_KEY;return e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("h2",{className:"text-sm font-medium",children:t("vector.form.title")}),C&&e.jsx(A,{variant:"info",children:t("vector.form.dirty")}),e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[C&&e.jsx(p,{type:"button",variant:"secondary",size:"sm",onClick:O,disabled:i,children:t("vector.form.discard")}),e.jsxs(p,{type:"button",size:"sm",onClick:()=>void I(),disabled:!C||i,children:[i?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(se,{className:"h-4 w-4"}),t("vector.form.saveAndTest")]})]})]}),e.jsx("p",{className:"mt-1 text-xs text-text-dim",children:t("vector.form.hint")}),n.isLoading?e.jsx("div",{className:"mt-3 h-32 w-full rounded-md bg-surface-2 animate-pulse"}):e.jsxs("div",{className:"mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2",children:[e.jsx(v,{label:t("vector.form.backend"),help:t("vector.form.backendHelp"),children:e.jsxs(D,{value:r.backend,onValueChange:a=>R(a),children:[e.jsx(G,{children:e.jsx(F,{})}),e.jsxs(W,{children:[e.jsx(B,{value:"off",children:t("vector.form.backendOff")}),e.jsx(B,{value:"local",children:t("vector.form.backendLocal")}),e.jsx(B,{value:"openai",children:t("vector.form.backendOpenai")})]})]})}),r.backend==="local"&&e.jsx(v,{label:t("vector.form.localModel"),help:t("vector.form.localModelHelp"),children:e.jsx(j,{value:r.localModel,placeholder:m.localModel,onChange:a=>h("localModel",a.target.value),className:"font-mono text-xs"})}),r.backend==="openai"&&e.jsxs(e.Fragment,{children:[e.jsx(v,{label:t("vector.form.openaiBaseUrl"),help:t("vector.form.openaiBaseUrlHelp"),children:e.jsx(j,{value:r.openaiBaseUrl,placeholder:m.openaiBaseUrl,onChange:a=>h("openaiBaseUrl",a.target.value),className:"font-mono text-xs"})}),e.jsx(v,{label:t("vector.form.openaiModel"),help:t("vector.form.openaiModelHelp"),children:e.jsx(j,{value:r.openaiModel,placeholder:m.openaiModel,onChange:a=>h("openaiModel",a.target.value),className:"font-mono text-xs"})}),e.jsx(v,{label:t("vector.form.openaiApiKey"),help:t(x?"vector.form.apiKeyKeepHint":"vector.form.apiKeyNewHint"),children:e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(j,{type:M?"text":"password",value:r.openaiApiKey,placeholder:x?l.AGIM_MEMORY_VECTOR_OPENAI_API_KEY||"••••":"sk-…",onChange:a=>h("openaiApiKey",a.target.value),className:"font-mono text-xs",autoComplete:"off"}),e.jsx(p,{type:"button",variant:"ghost",size:"icon",onClick:()=>E(a=>!a),"aria-label":t("vector.form.toggleApiKey"),children:M?e.jsx(te,{className:"h-4 w-4"}):e.jsx(ae,{className:"h-4 w-4"})})]})})]}),r.backend!=="off"&&e.jsxs(e.Fragment,{children:[e.jsx(v,{label:t("vector.form.batchSize"),help:t("vector.form.batchSizeHelp"),children:e.jsx(j,{type:"number",min:1,max:1024,step:1,value:r.batchSize,placeholder:m.batchSize,onChange:a=>h("batchSize",a.target.value),className:"font-mono text-xs"})}),e.jsx(v,{label:t("vector.form.hybridWeight"),help:t("vector.form.hybridWeightHelp"),children:e.jsx(j,{type:"number",min:0,max:1,step:.05,value:r.hybridWeight,placeholder:m.hybridWeight,onChange:a=>h("hybridWeight",a.target.value),className:"font-mono text-xs"})})]})]})]})}function v({label:s,help:t,children:n}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(H,{className:"text-xs text-text-dim",children:s}),n,t&&e.jsx("p",{className:"text-[11px] text-text-muted",children:t})]})}function ke(){const{t:s}=L(["memory","common"]),[t]=q(),n=t.get("user")??"",l=Z(n?{user_key:n}:{}),r=l.data?.status,f=l.data?.coverage,M=l.data?.jobs??[],E=P(),u=J(),b=$(),_=ee(),[C,h]=g.useState(!1);async function R(){try{const i=await E.mutateAsync();i.ok?c.success(s("vector.actions.testOk")):c.error(s("vector.actions.testFail",{detail:i.error??""}))}catch(i){const{message:x}=y(i,s);c.error(x)}}async function k(){try{const i=await u.mutateAsync();c.success(i.alreadyReady?s("vector.actions.downloadAlreadyReady"):s("vector.actions.downloadStarted"))}catch(i){const{message:x}=y(i,s);c.error(x)}}async function S(){try{await b.mutateAsync(n?{user_key:n}:void 0),c.success(s("vector.actions.backfillStarted"))}catch(i){const{message:x}=y(i,s);c.error(x)}}async function I(){try{const i=await _.mutateAsync(n?{user_key:n}:void 0);c.success(s("vector.actions.clearStarted",{count:i.cleared}))}catch(i){const{message:x}=y(i,s);throw c.error(x),i}}if(l.isLoading)return e.jsx("div",{className:"h-48 w-full rounded-md bg-surface-2 animate-pulse"});if(!r)return e.jsx(oe,{icon:e.jsx(Y,{}),title:s("common:states.error"),description:l.error?.message??""});const O=n?s("vector.coverage.scope_user",{userKey:n}):s("vector.coverage.scope_global");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.jsx("h1",{className:"text-xl font-semibold",children:s("vector.title")}),e.jsxs(p,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>l.refetch(),disabled:l.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[l.isFetching?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(ie,{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("vector.subtitle")})]}),e.jsx(me,{onSaved:()=>void l.refetch()}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[e.jsx("span",{className:"font-medium",children:s("vector.backendLabel")}),e.jsx(A,{variant:"secondary",children:r.backend}),e.jsx(A,{variant:r.ready?"success":"warning",children:r.ready?s("vector.readyTrue"):s("vector.readyFalse")}),r.downloaded&&e.jsx(A,{variant:"info",children:s("vector.downloadedTrue")})]}),e.jsxs("dl",{className:"mt-3 grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-sm",children:[e.jsx("dt",{className:"text-text-dim",children:s("vector.modelLabel")}),e.jsx("dd",{className:"font-mono text-text",children:r.modelId||"—"}),e.jsx("dt",{className:"text-text-dim",children:s("vector.dimsLabel")}),e.jsx("dd",{className:"tabular-nums text-text",children:r.dims||"—"}),r.lastError&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:s("vector.lastError")}),e.jsx("dd",{className:"text-danger text-xs break-all",children:r.lastError})]})]})]}),e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsx("div",{className:"text-sm font-medium",children:s("vector.coverage.title")}),e.jsx("div",{className:"mt-1 text-xs text-text-dim",children:O}),e.jsxs("div",{className:"mt-3 grid grid-cols-3 gap-2",children:[e.jsx(K,{label:s("vector.coverage.total"),value:f?.total??0,tone:"info"}),e.jsx(K,{label:s("vector.coverage.withEmbedding"),value:f?.withEmbedding??0,tone:"success"}),e.jsx(K,{label:s("vector.coverage.withDifferentModel"),value:f?.withDifferentModel??0,tone:"warning"})]})]})]}),e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsx("div",{className:"text-sm font-medium",children:s("vector.actions.title")}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsxs(p,{variant:"secondary",size:"sm",onClick:()=>void R(),disabled:E.isPending,children:[E.isPending?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(V,{className:"h-4 w-4"}),s("vector.actions.test")]}),r.backend==="local"&&e.jsxs(p,{variant:"secondary",size:"sm",onClick:()=>void k(),disabled:u.isPending,children:[u.isPending?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(ne,{className:"h-4 w-4"}),s("vector.actions.download")]}),e.jsxs(p,{variant:"default",size:"sm",onClick:()=>void S(),disabled:b.isPending||!r.ready,children:[b.isPending?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(V,{className:"h-4 w-4"}),s("vector.actions.backfill")]}),e.jsxs(p,{variant:"destructive",size:"sm",onClick:()=>h(!0),disabled:_.isPending,children:[e.jsx(ce,{className:"h-4 w-4"}),s("vector.actions.clear")]})]})]}),e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsx("div",{className:"text-sm font-medium",children:s("vector.jobs.title")}),M.length===0?e.jsx("div",{className:"mt-2 text-sm text-text-muted",children:s("vector.jobs.empty")}):e.jsx("ul",{className:"mt-2 flex flex-col gap-1.5 text-sm",children:M.map(i=>e.jsx("li",{children:e.jsx(he,{job:i})},i.id))})]}),e.jsx(re,{open:C,onOpenChange:h,title:s("vector.actions.confirmClear"),description:s("vector.actions.confirmClearDesc",{scope:O}),intent:"danger",confirmLabel:s("vector.actions.clear"),onConfirm:I})]})}const xe={info:"border-info/30 text-info",success:"border-success/30 text-success",warning:"border-warning/30 text-warning",danger:"border-danger/30 text-danger"};function K({label:s,value:t,tone:n}){return e.jsxs("div",{className:z("rounded-md border bg-bg px-2 py-2",xe[n]),children:[e.jsx("div",{className:"text-[10px] uppercase tracking-wide text-text-dim",children:s}),e.jsx("div",{className:"text-xl font-semibold tabular-nums",children:t})]})}function he({job:s}){const{t}=L("memory"),n=s.phase==="done"?"text-success":s.phase==="failed"?"text-danger":"text-info";return e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs",children:[e.jsx(A,{variant:"outline",children:s.kind}),e.jsxs("span",{className:z("font-medium",n),children:[s.phase==="running"&&e.jsx(N,{className:"inline h-3 w-3 animate-spin"}),s.phase==="done"&&e.jsx(le,{className:"inline h-3 w-3"}),s.phase==="failed"&&e.jsx(Y,{className:"inline h-3 w-3"})," ",t(`vector.jobs.phase.${s.phase}`)]}),e.jsx("span",{className:"text-text-dim",children:s.message}),e.jsx("span",{className:"ml-auto text-text-muted tabular-nums",children:fe(s.finishedAt??s.startedAt)})]})}function fe(s){try{const t=new Date(s);return Number.isNaN(t.getTime())?String(s):t.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(s)}}export{ke as default};
2
+ //# sourceMappingURL=vector-CL8ezpSR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector-CL8ezpSR.js","sources":["../../src/routes/memory/vector-backend-form.tsx","../../src/routes/memory/vector.tsx"],"sourcesContent":["/**\n * VectorBackendForm — inline, form-based editor for the seven\n * AGIM_MEMORY_VECTOR_* keys that drive the embedding backend.\n *\n * Replaces the older \"Edit in env\" link path: operators no longer\n * have to know which env var maps to which knob, and the on-the-wire\n * format (numbers, OpenAI URL shape) is enforced by the widget.\n *\n * Save flow: PUT /api/env (backend-side allowlist filters to just\n * these keys), then auto-trigger a single `vector/test` so the user\n * sees in toast whether the new config produces an embedding.\n *\n * API key: the GET /api/env response returns secrets masked (e.g.\n * \"sk-1***...abcd\"). The widget shows the mask as placeholder and\n * leaves the input empty by default — typing a value sends it as a\n * real update, leaving it empty sends nothing for that key (the\n * server already rejects masked echoes as \"no change\").\n */\n\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Eye, EyeOff, Loader2, Save } 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 { useEnv, useUpdateEnv } from '@/hooks/use-settings'\nimport { useTriggerVectorTest } from '@/hooks/use-vector'\nimport { describeError } from '@/lib/api/errors'\n\ntype BackendName = 'off' | 'local' | 'openai'\n\ninterface FormState {\n backend: BackendName\n localModel: string\n openaiBaseUrl: string\n openaiModel: string\n openaiApiKey: string // empty = \"keep existing\"\n batchSize: string\n hybridWeight: string\n}\n\nconst DEFAULTS: FormState = {\n backend: 'off',\n localModel: 'Xenova/bge-base-zh-v1.5',\n openaiBaseUrl: 'https://api.openai.com/v1',\n openaiModel: 'text-embedding-3-small',\n openaiApiKey: '',\n batchSize: '32',\n hybridWeight: '0.5',\n}\n\nfunction readFormFromEnv(env: Record<string, string>): FormState {\n const raw = (env.AGIM_MEMORY_VECTOR_BACKEND || '').toLowerCase()\n const backend: BackendName = raw === 'local' || raw === 'openai' ? raw : 'off'\n return {\n backend,\n localModel: env.AGIM_MEMORY_VECTOR_LOCAL_MODEL || '',\n openaiBaseUrl: env.AGIM_MEMORY_VECTOR_OPENAI_BASE_URL || '',\n openaiModel: env.AGIM_MEMORY_VECTOR_OPENAI_MODEL || '',\n openaiApiKey: '',\n batchSize: env.AGIM_MEMORY_VECTOR_BATCH_SIZE || '',\n hybridWeight: env.AGIM_MEMORY_VECTOR_HYBRID_WEIGHT || '',\n }\n}\n\nexport interface VectorBackendFormProps {\n /** Called after a successful save + test cycle so the parent page can\n * refresh status + coverage. */\n onSaved?: () => void\n}\n\nexport function VectorBackendForm({ onSaved }: VectorBackendFormProps): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n\n // Pull masked env (we never need real key on the client; the masked\n // value is shown as placeholder so the operator can tell a value is\n // configured without revealing it).\n const envQuery = useEnv({ reveal: false })\n const env = useMemo(() => envQuery.data?.env ?? {}, [envQuery.data?.env])\n\n const [form, setForm] = useState<FormState>(DEFAULTS)\n const [showApiKey, setShowApiKey] = useState(false)\n const initialRef = useRef<FormState>(DEFAULTS)\n\n // Reset from server only when the underlying env object identity\n // changes (after refetch). useEffect avoids stomping on local edits\n // mid-typing.\n useEffect(() => {\n if (!envQuery.data) return\n const next = readFormFromEnv(env)\n setForm(next)\n initialRef.current = next\n }, [env, envQuery.data])\n\n const updateEnv = useUpdateEnv()\n const test = useTriggerVectorTest()\n\n const dirty = useMemo(() => {\n const initial = initialRef.current\n return (Object.keys(form) as Array<keyof FormState>).some((k) => form[k] !== initial[k])\n }, [form])\n\n function set<K extends keyof FormState>(k: K, v: FormState[K]): void {\n setForm((prev) => ({ ...prev, [k]: v }))\n }\n\n // v1.2.75 — when the operator switches backend off→local / off→openai\n // and the per-backend fields are still empty, auto-prefill defaults so\n // they don't have to look up the BGE model id by hand. They can still\n // edit afterwards. Also fills shared numeric knobs (batch / weight)\n // since those have well-known sensible defaults too.\n function selectBackend(next: BackendName): void {\n setForm((prev) => {\n const out = { ...prev, backend: next }\n if (next === 'local' && !out.localModel.trim()) {\n out.localModel = DEFAULTS.localModel\n }\n if (next === 'openai') {\n if (!out.openaiBaseUrl.trim()) out.openaiBaseUrl = DEFAULTS.openaiBaseUrl\n if (!out.openaiModel.trim()) out.openaiModel = DEFAULTS.openaiModel\n }\n if (next !== 'off') {\n if (!out.batchSize.trim()) out.batchSize = DEFAULTS.batchSize\n if (!out.hybridWeight.trim()) out.hybridWeight = DEFAULTS.hybridWeight\n }\n return out\n })\n }\n\n function validate(): string | null {\n if (form.backend === 'openai') {\n if (!form.openaiBaseUrl.trim()) return t('vector.form.errors.baseUrlRequired')\n try { new URL(form.openaiBaseUrl.trim()) } catch { return t('vector.form.errors.baseUrlInvalid') }\n if (!form.openaiModel.trim()) return t('vector.form.errors.openaiModelRequired')\n const hasExistingKey = !!env.AGIM_MEMORY_VECTOR_OPENAI_API_KEY\n if (!hasExistingKey && !form.openaiApiKey.trim()) {\n return t('vector.form.errors.apiKeyRequired')\n }\n }\n if (form.backend === 'local' && !form.localModel.trim()) {\n return t('vector.form.errors.localModelRequired')\n }\n if (form.batchSize.trim()) {\n const n = Number(form.batchSize)\n if (!Number.isFinite(n) || n < 1 || n > 1024) return t('vector.form.errors.batchSizeRange')\n }\n if (form.hybridWeight.trim()) {\n const n = Number(form.hybridWeight)\n if (!Number.isFinite(n) || n < 0 || n > 1) return t('vector.form.errors.hybridWeightRange')\n }\n return null\n }\n\n function buildUpdates(): Record<string, string | null> {\n const initial = initialRef.current\n const out: Record<string, string | null> = {}\n const diff = (key: string, current: string, prev: string): void => {\n if (current === prev) return\n out[key] = current.trim() === '' ? null : current.trim()\n }\n diff('AGIM_MEMORY_VECTOR_BACKEND', form.backend, initial.backend)\n diff('AGIM_MEMORY_VECTOR_LOCAL_MODEL', form.localModel, initial.localModel)\n diff('AGIM_MEMORY_VECTOR_OPENAI_BASE_URL', form.openaiBaseUrl, initial.openaiBaseUrl)\n diff('AGIM_MEMORY_VECTOR_OPENAI_MODEL', form.openaiModel, initial.openaiModel)\n diff('AGIM_MEMORY_VECTOR_BATCH_SIZE', form.batchSize, initial.batchSize)\n diff('AGIM_MEMORY_VECTOR_HYBRID_WEIGHT', form.hybridWeight, initial.hybridWeight)\n // API key: only send if the user actually typed a non-empty new value.\n // Empty input = keep current (which is the whole point of the placeholder UX).\n if (form.openaiApiKey.trim()) {\n out.AGIM_MEMORY_VECTOR_OPENAI_API_KEY = form.openaiApiKey.trim()\n }\n return out\n }\n\n async function onSave(): Promise<void> {\n const err = validate()\n if (err) {\n toast.error(err)\n return\n }\n const updates = buildUpdates()\n if (Object.keys(updates).length === 0) {\n toast.info(t('vector.form.nothingChanged'))\n return\n }\n try {\n await updateEnv.mutateAsync({ updates })\n toast.success(t('vector.form.savedToast'))\n // Auto-test against the freshly applied config. We don't await\n // the parent's refresh — the toast is the source of truth for the\n // operator; the status card behind it picks up dims / lastError\n // on its next 3s poll anyway.\n try {\n const r = await test.mutateAsync()\n if (r.ok) toast.success(t('vector.actions.testOk'))\n else toast.error(t('vector.actions.testFail', { detail: r.error ?? '' }))\n } catch (terr) {\n const { message } = describeError(terr, t)\n toast.error(t('vector.actions.testFail', { detail: message }))\n }\n onSaved?.()\n } catch (serr) {\n const { message } = describeError(serr, t)\n toast.error(message)\n }\n }\n\n function onDiscard(): void {\n setForm(initialRef.current)\n }\n\n const busy = updateEnv.isPending || test.isPending\n const hasExistingKey = !!env.AGIM_MEMORY_VECTOR_OPENAI_API_KEY\n\n return (\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h2 className=\"text-sm font-medium\">{t('vector.form.title')}</h2>\n {dirty && <Badge variant=\"info\">{t('vector.form.dirty')}</Badge>}\n <div className=\"ml-auto flex items-center gap-2\">\n {dirty && (\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n onClick={onDiscard}\n disabled={busy}\n >\n {t('vector.form.discard')}\n </Button>\n )}\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={() => void onSave()}\n disabled={!dirty || busy}\n >\n {busy ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Save className=\"h-4 w-4\" />}\n {t('vector.form.saveAndTest')}\n </Button>\n </div>\n </div>\n <p className=\"mt-1 text-xs text-text-dim\">{t('vector.form.hint')}</p>\n\n {envQuery.isLoading ? (\n <div className=\"mt-3 h-32 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <div className=\"mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2\">\n {/* Backend selector — full row on mobile, half on desktop */}\n <Field label={t('vector.form.backend')} help={t('vector.form.backendHelp')}>\n <Select value={form.backend} onValueChange={(v) => selectBackend(v as BackendName)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"off\">{t('vector.form.backendOff')}</SelectItem>\n <SelectItem value=\"local\">{t('vector.form.backendLocal')}</SelectItem>\n <SelectItem value=\"openai\">{t('vector.form.backendOpenai')}</SelectItem>\n </SelectContent>\n </Select>\n </Field>\n\n {/* Local-only field */}\n {form.backend === 'local' && (\n <Field label={t('vector.form.localModel')} help={t('vector.form.localModelHelp')}>\n <Input\n value={form.localModel}\n placeholder={DEFAULTS.localModel}\n onChange={(e) => set('localModel', e.target.value)}\n className=\"font-mono text-xs\"\n />\n </Field>\n )}\n\n {/* OpenAI-only fields */}\n {form.backend === 'openai' && (\n <>\n <Field label={t('vector.form.openaiBaseUrl')} help={t('vector.form.openaiBaseUrlHelp')}>\n <Input\n value={form.openaiBaseUrl}\n placeholder={DEFAULTS.openaiBaseUrl}\n onChange={(e) => set('openaiBaseUrl', e.target.value)}\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field label={t('vector.form.openaiModel')} help={t('vector.form.openaiModelHelp')}>\n <Input\n value={form.openaiModel}\n placeholder={DEFAULTS.openaiModel}\n onChange={(e) => set('openaiModel', e.target.value)}\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field\n label={t('vector.form.openaiApiKey')}\n help={hasExistingKey ? t('vector.form.apiKeyKeepHint') : t('vector.form.apiKeyNewHint')}\n >\n <div className=\"flex items-center gap-1\">\n <Input\n type={showApiKey ? 'text' : 'password'}\n value={form.openaiApiKey}\n placeholder={hasExistingKey\n ? (env.AGIM_MEMORY_VECTOR_OPENAI_API_KEY || '••••')\n : 'sk-…'}\n onChange={(e) => set('openaiApiKey', e.target.value)}\n className=\"font-mono text-xs\"\n autoComplete=\"off\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setShowApiKey((v) => !v)}\n aria-label={t('vector.form.toggleApiKey')}\n >\n {showApiKey ? <EyeOff className=\"h-4 w-4\" /> : <Eye className=\"h-4 w-4\" />}\n </Button>\n </div>\n </Field>\n </>\n )}\n\n {/* Shared numeric knobs (hidden when off so they don't visually\n suggest the operator can tune anything without picking a\n backend first). */}\n {form.backend !== 'off' && (\n <>\n <Field label={t('vector.form.batchSize')} help={t('vector.form.batchSizeHelp')}>\n <Input\n type=\"number\"\n min={1}\n max={1024}\n step={1}\n value={form.batchSize}\n placeholder={DEFAULTS.batchSize}\n onChange={(e) => set('batchSize', e.target.value)}\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field label={t('vector.form.hybridWeight')} help={t('vector.form.hybridWeightHelp')}>\n <Input\n type=\"number\"\n min={0}\n max={1}\n step={0.05}\n value={form.hybridWeight}\n placeholder={DEFAULTS.hybridWeight}\n onChange={(e) => set('hybridWeight', e.target.value)}\n className=\"font-mono text-xs\"\n />\n </Field>\n </>\n )}\n </div>\n )}\n </div>\n )\n}\n\nfunction Field({\n label,\n help,\n children,\n}: {\n label: string\n help?: string\n children: React.ReactNode\n}): JSX.Element {\n return (\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs text-text-dim\">{label}</Label>\n {children}\n {help && <p className=\"text-[11px] text-text-muted\">{help}</p>}\n </div>\n )\n}\n","/**\n * /memory/vector — backend status + maintenance actions.\n *\n * Status (left): backend name + ready badge + model + dims + last\n * error. Coverage (right): three KPI tiles (total / embedded /\n * mismatched). Actions (bottom): test, download, backfill, clear\n * (destructive — ConfirmDialog). Recent-job strip pulls from the\n * shared in-memory tracker via the status endpoint.\n *\n * The clear action picks up the ?user= filter from the layout, so\n * clearing scoped to a single user is a one-click operation.\n */\n\nimport { useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { CheckCircle, Download, Loader2, Play, RefreshCcw, Trash2, XCircle } from 'lucide-react'\n\nimport { VectorBackendForm } from './vector-backend-form'\n\nimport { ConfirmDialog } from '@/components/common/confirm-dialog'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n useVectorStatus,\n useTriggerVectorBackfill,\n useTriggerVectorClear,\n useTriggerVectorDownload,\n useTriggerVectorTest,\n} from '@/hooks/use-vector'\nimport { describeError } from '@/lib/api/errors'\nimport type { VectorJob } from '@/types/api'\nimport { cn } from '@/lib/utils'\n\nexport default function MemoryVectorRoute(): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n const [params] = useSearchParams()\n const userKey = params.get('user') ?? ''\n\n const statusQuery = useVectorStatus(userKey ? { user_key: userKey } : {})\n const status = statusQuery.data?.status\n const coverage = statusQuery.data?.coverage\n const jobs = statusQuery.data?.jobs ?? []\n\n const test = useTriggerVectorTest()\n const download = useTriggerVectorDownload()\n const backfill = useTriggerVectorBackfill()\n const clear = useTriggerVectorClear()\n const [confirmClear, setConfirmClear] = useState(false)\n\n async function onTest(): Promise<void> {\n try {\n const r = await test.mutateAsync()\n if (r.ok) toast.success(t('vector.actions.testOk'))\n else toast.error(t('vector.actions.testFail', { detail: r.error ?? '' }))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n async function onDownload(): Promise<void> {\n try {\n const r = await download.mutateAsync()\n toast.success(r.alreadyReady ? t('vector.actions.downloadAlreadyReady') : t('vector.actions.downloadStarted'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n async function onBackfill(): Promise<void> {\n try {\n await backfill.mutateAsync(userKey ? { user_key: userKey } : undefined)\n toast.success(t('vector.actions.backfillStarted'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n async function onConfirmClear(): Promise<void> {\n try {\n const r = await clear.mutateAsync(userKey ? { user_key: userKey } : undefined)\n toast.success(t('vector.actions.clearStarted', { count: r.cleared }))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n throw err\n }\n }\n\n if (statusQuery.isLoading) {\n return <div className=\"h-48 w-full rounded-md bg-surface-2 animate-pulse\" />\n }\n if (!status) {\n return (\n <EmptyState\n icon={<XCircle />}\n title={t('common:states.error')}\n description={statusQuery.error?.message ?? ''}\n />\n )\n }\n\n const coverageScope = userKey\n ? t('vector.coverage.scope_user', { userKey })\n : t('vector.coverage.scope_global')\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\">{t('vector.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => statusQuery.refetch()}\n disabled={statusQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {statusQuery.isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('vector.subtitle')}</p>\n </header>\n\n {/* Backend configuration — inline form replaces the older\n \"Edit in env\" link. Saving runs PUT /api/env + an auto\n vector test against the freshly applied config. */}\n <VectorBackendForm onSaved={() => void statusQuery.refetch()} />\n\n {/* Status + Coverage */}\n <div className=\"grid gap-3 md:grid-cols-2\">\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"flex flex-wrap items-center gap-2 text-sm\">\n <span className=\"font-medium\">{t('vector.backendLabel')}</span>\n <Badge variant=\"secondary\">{status.backend}</Badge>\n <Badge variant={status.ready ? 'success' : 'warning'}>\n {status.ready ? t('vector.readyTrue') : t('vector.readyFalse')}\n </Badge>\n {status.downloaded && <Badge variant=\"info\">{t('vector.downloadedTrue')}</Badge>}\n </div>\n <dl className=\"mt-3 grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-sm\">\n <dt className=\"text-text-dim\">{t('vector.modelLabel')}</dt>\n <dd className=\"font-mono text-text\">{status.modelId || '—'}</dd>\n <dt className=\"text-text-dim\">{t('vector.dimsLabel')}</dt>\n <dd className=\"tabular-nums text-text\">{status.dims || '—'}</dd>\n {status.lastError && (\n <>\n <dt className=\"text-text-dim\">{t('vector.lastError')}</dt>\n <dd className=\"text-danger text-xs break-all\">{status.lastError}</dd>\n </>\n )}\n </dl>\n </div>\n\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"text-sm font-medium\">{t('vector.coverage.title')}</div>\n <div className=\"mt-1 text-xs text-text-dim\">{coverageScope}</div>\n <div className=\"mt-3 grid grid-cols-3 gap-2\">\n <CoverageTile label={t('vector.coverage.total')} value={coverage?.total ?? 0} tone=\"info\" />\n <CoverageTile label={t('vector.coverage.withEmbedding')} value={coverage?.withEmbedding ?? 0} tone=\"success\" />\n <CoverageTile label={t('vector.coverage.withDifferentModel')} value={coverage?.withDifferentModel ?? 0} tone=\"warning\" />\n </div>\n </div>\n </div>\n\n {/* Maintenance actions */}\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"text-sm font-medium\">{t('vector.actions.title')}</div>\n <div className=\"mt-3 flex flex-wrap gap-2\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => void onTest()}\n disabled={test.isPending}\n >\n {test.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Play className=\"h-4 w-4\" />}\n {t('vector.actions.test')}\n </Button>\n {status.backend === 'local' && (\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => void onDownload()}\n disabled={download.isPending}\n >\n {download.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Download className=\"h-4 w-4\" />}\n {t('vector.actions.download')}\n </Button>\n )}\n <Button\n variant=\"default\"\n size=\"sm\"\n onClick={() => void onBackfill()}\n disabled={backfill.isPending || !status.ready}\n >\n {backfill.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Play className=\"h-4 w-4\" />}\n {t('vector.actions.backfill')}\n </Button>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => setConfirmClear(true)}\n disabled={clear.isPending}\n >\n <Trash2 className=\"h-4 w-4\" />\n {t('vector.actions.clear')}\n </Button>\n </div>\n </div>\n\n {/* Jobs strip */}\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"text-sm font-medium\">{t('vector.jobs.title')}</div>\n {jobs.length === 0 ? (\n <div className=\"mt-2 text-sm text-text-muted\">{t('vector.jobs.empty')}</div>\n ) : (\n <ul className=\"mt-2 flex flex-col gap-1.5 text-sm\">\n {jobs.map((j) => <li key={j.id}><JobRow job={j} /></li>)}\n </ul>\n )}\n </div>\n\n <ConfirmDialog\n open={confirmClear}\n onOpenChange={setConfirmClear}\n title={t('vector.actions.confirmClear')}\n description={t('vector.actions.confirmClearDesc', { scope: coverageScope })}\n intent=\"danger\"\n confirmLabel={t('vector.actions.clear')}\n onConfirm={onConfirmClear}\n />\n </div>\n )\n}\n\ninterface CoverageTileProps {\n label: string\n value: number\n tone: 'info' | 'success' | 'warning' | 'danger'\n}\n\nconst TONE_STYLES: Record<CoverageTileProps['tone'], string> = {\n info: 'border-info/30 text-info',\n success: 'border-success/30 text-success',\n warning: 'border-warning/30 text-warning',\n danger: 'border-danger/30 text-danger',\n}\n\nfunction CoverageTile({ label, value, tone }: CoverageTileProps): JSX.Element {\n return (\n <div className={cn('rounded-md border bg-bg px-2 py-2', TONE_STYLES[tone])}>\n <div className=\"text-[10px] uppercase tracking-wide text-text-dim\">{label}</div>\n <div className=\"text-xl font-semibold tabular-nums\">{value}</div>\n </div>\n )\n}\n\nfunction JobRow({ job }: { job: VectorJob }): JSX.Element {\n const { t } = useTranslation('memory')\n const phaseClass =\n job.phase === 'done' ? 'text-success' :\n job.phase === 'failed' ? 'text-danger' :\n 'text-info'\n return (\n <div className=\"flex flex-wrap items-center gap-2 text-xs\">\n <Badge variant=\"outline\">{job.kind}</Badge>\n <span className={cn('font-medium', phaseClass)}>\n {job.phase === 'running' && <Loader2 className=\"inline h-3 w-3 animate-spin\" />}\n {job.phase === 'done' && <CheckCircle className=\"inline h-3 w-3\" />}\n {job.phase === 'failed' && <XCircle className=\"inline h-3 w-3\" />}\n {' '}\n {t(`vector.jobs.phase.${job.phase}`)}\n </span>\n <span className=\"text-text-dim\">{job.message}</span>\n <span className=\"ml-auto text-text-muted tabular-nums\">{formatEpoch(job.finishedAt ?? job.startedAt)}</span>\n </div>\n )\n}\n\nfunction formatEpoch(ms: number): string {\n try {\n const d = new Date(ms)\n if (Number.isNaN(d.getTime())) return String(ms)\n return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n } catch {\n return String(ms)\n }\n}\n"],"names":["DEFAULTS","readFormFromEnv","env","raw","VectorBackendForm","onSaved","useTranslation","envQuery","useEnv","useMemo","form","setForm","useState","showApiKey","setShowApiKey","initialRef","useRef","useEffect","next","updateEnv","useUpdateEnv","test","useTriggerVectorTest","dirty","initial","k","set","v","prev","selectBackend","out","validate","n","buildUpdates","diff","key","current","onSave","err","toast","updates","r","terr","message","describeError","serr","onDiscard","busy","hasExistingKey","jsxs","jsx","Badge","Button","Loader2","Save","Field","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Input","e","Fragment","EyeOff","Eye","label","help","children","Label","MemoryVectorRoute","t","params","useSearchParams","userKey","statusQuery","useVectorStatus","status","coverage","jobs","download","useTriggerVectorDownload","backfill","useTriggerVectorBackfill","clear","useTriggerVectorClear","confirmClear","setConfirmClear","onTest","onDownload","onBackfill","onConfirmClear","EmptyState","XCircle","coverageScope","RefreshCcw","CoverageTile","Play","Download","Trash2","j","JobRow","ConfirmDialog","TONE_STYLES","value","tone","cn","job","phaseClass","CheckCircle","formatEpoch","ms","d"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import{h as W,u as R,j as e,e as h,d as f,I as y,k as O,l as T,m as B,n as F,o as k,f as C,C as H,X as D,w as V,p as g,q as M}from"./index-DCfdN5R7.js";import{r as m}from"./react-DlP5eolq.js";import{b as z,c as G,j as q}from"./use-settings-DGIjmUX0.js";import{E as K,a as X}from"./eye-BfPyNFzk.js";import{L as N}from"./loader-circle-DDdmcH0k.js";import{R as P}from"./refresh-ccw-DlAd-eTQ.js";import{F as J}from"./file-text-BxfdLM0-.js";import{E as Q}from"./external-link-1WPpVvdu.js";import{S as U}from"./save-BDOtZrfp.js";import{M as Y}from"./map-pin-C_jAxukI.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=W("Earth",[["path",{d:"M21.54 15H17a2 2 0 0 0-2 2v4.54",key:"1djwo0"}],["path",{d:"M7 3.34V5a3 3 0 0 0 3 3a2 2 0 0 1 2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2c0-1.1.9-2 2-2h3.17",key:"1tzkfa"}],["path",{d:"M11 21.95V18a2 2 0 0 0-2-2a2 2 0 0 1-2-2v-1a2 2 0 0 0-2-2H2.05",key:"14pb5j"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]]);function xe(){const{t:i}=R(["settings","common"]),[s,r]=m.useState(!1),a=z({reveal:s});return e.jsxs("div",{className:"mx-auto flex max-w-4xl flex-col gap-6",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:i("viewerSettings.title")}),e.jsxs(h,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>r(t=>!t),disabled:a.isFetching,"aria-label":i(s?"viewerSettings.hide":"viewerSettings.reveal"),children:[s?e.jsx(K,{className:"h-4 w-4"}):e.jsx(X,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:i(s?"viewerSettings.hide":"viewerSettings.reveal")})]}),e.jsxs(h,{variant:"ghost",size:"sm",onClick:()=>void a.refetch(),disabled:a.isFetching,"aria-label":i("actions.refresh",{ns:"common"}),children:[a.isFetching?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(P,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:i("actions.refresh",{ns:"common"})})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:i("viewerSettings.subtitle")})]}),a.isLoading?e.jsx("div",{className:"h-64 rounded-md bg-surface-2 animate-pulse"}):e.jsxs(e.Fragment,{children:[e.jsx($,{env:a.data?.env??{}}),e.jsx(ee,{env:a.data?.env??{}})]})]})}function A(i){return{enabled:i.AGIM_VIEWER_ENABLED==="1"||i.AGIM_VIEWER_ENABLED?.toLowerCase()==="true",publicUrl:i.AGIM_VIEWER_PUBLIC_BASE_URL??"",tunnelMode:i.AGIM_VIEWER_TUNNEL_MODE==="quick"?"quick":"off",noDefaultRemote:i.AGIM_VIEWER_NO_DEFAULT_REMOTE==="1"||i.AGIM_VIEWER_NO_DEFAULT_REMOTE?.toLowerCase()==="true",chars:i.AGIM_VIEWER_CHARS??"",lines:i.AGIM_VIEWER_LINES??"",codeLines:i.AGIM_VIEWER_CODE_LINES??"",maxPastes:i.AGIM_VIEWER_MAX_PASTES??""}}function $({env:i}){const{t:s}=R(["settings","common"]),r=G(),a=q(),[t,d]=m.useState(()=>A(i)),[w,S]=m.useState("");m.useEffect(()=>{const n=A(i),x=JSON.stringify(n);x!==w&&(d(n),S(x))},[i.AGIM_VIEWER_ENABLED,i.AGIM_VIEWER_PUBLIC_BASE_URL,i.AGIM_VIEWER_TUNNEL_MODE,i.AGIM_VIEWER_CHARS,i.AGIM_VIEWER_LINES,i.AGIM_VIEWER_CODE_LINES,i.AGIM_VIEWER_MAX_PASTES,i.AGIM_VIEWER_NO_DEFAULT_REMOTE]);const c=m.useMemo(()=>A(i),[i]),b=m.useMemo(()=>JSON.stringify(t)!==JSON.stringify(c),[t,c]);function o(n,x){d(j=>({...j,[n]:x}))}async function _(){const n={};if(t.enabled!==c.enabled&&(n.AGIM_VIEWER_ENABLED=t.enabled?"1":"0"),t.publicUrl!==c.publicUrl&&(n.AGIM_VIEWER_PUBLIC_BASE_URL=t.publicUrl.trim()||null),t.tunnelMode!==c.tunnelMode&&(n.AGIM_VIEWER_TUNNEL_MODE=t.tunnelMode),t.chars!==c.chars&&(n.AGIM_VIEWER_CHARS=t.chars.trim()||null),t.lines!==c.lines&&(n.AGIM_VIEWER_LINES=t.lines.trim()||null),t.codeLines!==c.codeLines&&(n.AGIM_VIEWER_CODE_LINES=t.codeLines.trim()||null),t.maxPastes!==c.maxPastes&&(n.AGIM_VIEWER_MAX_PASTES=t.maxPastes.trim()||null),t.noDefaultRemote!==c.noDefaultRemote&&(n.AGIM_VIEWER_NO_DEFAULT_REMOTE=t.noDefaultRemote?"1":null),Object.keys(n).length!==0)try{await r.mutateAsync({updates:n}),g.success(s("viewerSettings.toast.saved"))}catch(x){g.error(M(x,s).message)}}function I(){d(c)}const l=a.data,L=l?.effectivePublicUrl;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(J,{className:"h-4 w-4 text-text-dim"}),e.jsx("h2",{className:"text-sm font-semibold",children:s("viewerSettings.viewer.title")}),t.enabled?e.jsx(f,{variant:"success",children:s("viewerSettings.viewer.on")}):e.jsx(f,{variant:"outline",children:s("viewerSettings.viewer.off")})]}),e.jsx("p",{className:"px-4 pt-2 text-xs text-text-dim",children:s("viewerSettings.viewer.subtitle")}),e.jsx("div",{className:"flex items-center gap-3 px-4 py-3",children:e.jsxs("label",{className:"flex items-center gap-2 text-sm",children:[e.jsx("input",{type:"checkbox",checked:t.enabled,onChange:n=>{const x=n.target.checked;d(j=>({...j,enabled:x,noDefaultRemote:x?j.noDefaultRemote:!1}))},className:"h-4 w-4 accent-accent cursor-pointer"}),e.jsx("span",{className:"font-medium",children:s("viewerSettings.viewer.enableLabel")})]})}),e.jsxs("div",{className:"grid grid-cols-1 gap-3 px-4 pb-3 sm:grid-cols-2",children:[e.jsx(u,{label:s("viewerSettings.viewer.publicUrl"),hint:s("viewerSettings.viewer.publicUrlHint"),children:e.jsx(y,{value:t.publicUrl,onChange:n=>o("publicUrl",n.target.value),placeholder:"https://agim.example.com",className:"font-mono text-xs"})}),e.jsx(u,{label:s("viewerSettings.viewer.tunnelMode"),hint:s("viewerSettings.viewer.tunnelHint"),children:e.jsxs(O,{value:t.tunnelMode,onValueChange:n=>o("tunnelMode",n),children:[e.jsx(T,{children:e.jsx(B,{})}),e.jsxs(F,{children:[e.jsx(k,{value:"off",children:s("viewerSettings.viewer.tunnelOff")}),e.jsx(k,{value:"quick",children:s("viewerSettings.viewer.tunnelQuick")})]})]})}),e.jsx(u,{label:s("viewerSettings.viewer.noDefaultRemote"),hint:s("viewerSettings.viewer.noDefaultRemoteHint"),children:e.jsxs("label",{className:C("inline-flex items-center gap-2 text-xs",!t.enabled&&"opacity-50 cursor-not-allowed"),children:[e.jsx("input",{type:"checkbox",checked:t.noDefaultRemote,disabled:!t.enabled,onChange:n=>o("noDefaultRemote",n.target.checked),className:"h-4 w-4 accent-accent cursor-pointer disabled:cursor-not-allowed"}),e.jsx("span",{children:s("viewerSettings.viewer.noDefaultRemoteLabel")})]})})]}),t.tunnelMode==="quick"&&e.jsxs("div",{className:"mx-4 mb-3 rounded-md border border-border bg-surface-2 p-3",children:[e.jsxs("div",{className:"mb-1 flex items-center gap-2",children:[e.jsx(Z,{className:"h-4 w-4 text-text-dim"}),e.jsx("span",{className:"text-xs font-medium uppercase tracking-wide text-text-dim",children:s("viewerSettings.viewer.tunnelStatus")}),e.jsxs(h,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>void a.refetch(),disabled:a.isFetching,"aria-label":s("viewerSettings.viewer.refreshTunnel"),children:[a.isFetching?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(P,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("viewerSettings.viewer.refreshTunnel")})]})]}),l?e.jsxs("div",{className:"flex flex-col gap-1 text-xs",children:[e.jsx(p,{label:s("viewerSettings.viewer.tunnelRunning"),children:l.tunnel.running?e.jsxs("span",{className:"inline-flex items-center gap-1 text-success",children:[e.jsx(H,{className:"h-3 w-3"}),s("viewerSettings.viewer.yes")]}):e.jsx("span",{className:"text-text-dim",children:s("viewerSettings.viewer.no")})}),e.jsx(p,{label:s("viewerSettings.viewer.tunnelUrl"),children:l.tunnel.url?e.jsxs("a",{href:l.tunnel.url,target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1 break-all font-mono text-info hover:underline",children:[l.tunnel.url,e.jsx(Q,{className:"h-3 w-3 shrink-0"})]}):e.jsx("span",{className:"text-text-muted",children:"—"})}),e.jsx(p,{label:s("viewerSettings.viewer.effectiveUrl"),children:L?e.jsx("span",{className:"break-all font-mono text-text",children:L}):e.jsx("span",{className:"text-text-muted",children:"—"})}),e.jsx(p,{label:s("viewerSettings.viewer.binary"),children:l.tunnel.binaryFound?e.jsx("span",{className:"font-mono text-text",children:l.tunnel.binaryPath}):e.jsx("span",{className:"text-warning",children:s("viewerSettings.viewer.binaryMissing")})}),l.tunnel.lastError&&e.jsx(p,{label:s("viewerSettings.viewer.lastError"),children:e.jsx("span",{className:"break-words text-danger",children:l.tunnel.lastError})})]}):e.jsx("p",{className:"text-xs text-text-dim",children:s("viewerSettings.viewer.tunnelLoading")})]}),e.jsx("h3",{className:"border-t border-border px-4 pt-3 text-xs font-semibold uppercase tracking-wide text-text-dim",children:s("viewerSettings.viewer.thresholds")}),e.jsxs("div",{className:"grid grid-cols-2 gap-3 px-4 py-3 sm:grid-cols-4",children:[e.jsx(u,{label:s("viewerSettings.viewer.chars"),hint:s("viewerSettings.viewer.charsHint"),children:e.jsx(E,{value:t.chars,onChange:n=>o("chars",n),min:100,max:1e4,placeholder:"500"})}),e.jsx(u,{label:s("viewerSettings.viewer.lines"),hint:s("viewerSettings.viewer.linesHint"),children:e.jsx(E,{value:t.lines,onChange:n=>o("lines",n),min:5,max:200,placeholder:"12"})}),e.jsx(u,{label:s("viewerSettings.viewer.codeLines"),hint:s("viewerSettings.viewer.codeLinesHint"),children:e.jsx(E,{value:t.codeLines,onChange:n=>o("codeLines",n),min:5,max:200,placeholder:"10"})}),e.jsx(u,{label:s("viewerSettings.viewer.maxPastes"),hint:s("viewerSettings.viewer.maxPastesHint"),children:e.jsx(E,{value:t.maxPastes,onChange:n=>o("maxPastes",n),min:100,max:1e6,placeholder:"10000"})})]}),b&&e.jsxs("div",{className:"flex items-center gap-2 border-t border-border px-4 py-3",children:[e.jsx(f,{variant:"info",children:s("viewerSettings.dirtyHint")}),e.jsxs(h,{variant:"ghost",size:"sm",className:"ml-auto",onClick:I,disabled:r.isPending,children:[e.jsx(D,{className:"h-4 w-4"}),s("viewerSettings.discard")]}),e.jsxs(h,{size:"sm",onClick:()=>void _(),disabled:r.isPending,children:[r.isPending?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(U,{className:"h-4 w-4"}),r.isPending?s("viewerSettings.saving"):s("viewerSettings.save")]})]})]})}function v(i){return/\*{3,}/.test(i)}function ee({env:i}){const{t:s}=R(["settings","common"]),r=G(),a=i.AGIM_BAIDU_MAP_AK??"",[t,d]=m.useState(a),[w,S]=m.useState("");m.useEffect(()=>{a!==w&&(d(a),S(a))},[a,w]);const c=!!a,b=t!==a&&!(v(t)&&t===a),o=t.length>0&&!v(t)&&t.length!==32;async function _(){if(b&&!v(t))try{await r.mutateAsync({updates:{AGIM_BAIDU_MAP_AK:t.trim()||null}}),g.success(s("viewerSettings.baidu.toast.saved"))}catch(l){g.error(M(l,s).message)}}async function I(){try{await r.mutateAsync({updates:{AGIM_BAIDU_MAP_AK:null}}),d(""),g.success(s("viewerSettings.baidu.toast.cleared"))}catch(l){g.error(M(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(Y,{className:"h-4 w-4 text-text-dim"}),e.jsx("h2",{className:"text-sm font-semibold",children:s("viewerSettings.baidu.title")}),c?e.jsx(f,{variant:"success",children:s("viewerSettings.baidu.configured")}):e.jsx(f,{variant:"outline",children:s("viewerSettings.baidu.empty")})]}),e.jsx("p",{className:"px-4 pt-2 text-xs text-text-dim",children:s("viewerSettings.baidu.subtitle")}),e.jsxs("div",{className:"px-4 py-3",children:[e.jsx(V,{htmlFor:"baidu-ak",className:"text-xs font-medium",children:"AGIM_BAIDU_MAP_AK"}),e.jsx(y,{id:"baidu-ak",value:t,onChange:l=>d(l.target.value),placeholder:s("viewerSettings.baidu.placeholder"),autoComplete:"off",className:C("mt-1 font-mono text-xs",v(t)&&"text-text-muted")}),o&&e.jsx("p",{className:"mt-1 text-[11px] text-warning",children:s("viewerSettings.baidu.suspicious",{length:t.length})}),e.jsx("p",{className:"mt-1 text-[11px] text-text-dim",children:s("viewerSettings.baidu.hint")})]}),e.jsxs("div",{className:"flex items-center gap-2 border-t border-border px-4 py-3",children:[e.jsxs(h,{variant:"ghost",size:"sm",onClick:()=>void I(),disabled:!c||r.isPending,className:"text-danger hover:text-danger",children:[e.jsx(D,{className:"h-4 w-4"}),s("viewerSettings.baidu.clear")]}),e.jsx("span",{className:"ml-auto"}),b&&e.jsxs(h,{size:"sm",onClick:()=>void _(),disabled:r.isPending||v(t),children:[r.isPending?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(U,{className:"h-4 w-4"}),r.isPending?s("viewerSettings.saving"):s("viewerSettings.save")]})]})]})}function u({label:i,hint:s,children:r}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(V,{className:"text-xs font-medium",children:i}),r,s&&e.jsx("p",{className:"text-[11px] text-text-dim",children:s})]})}function p({label:i,children:s}){return e.jsxs("div",{className:"flex flex-wrap items-baseline gap-2",children:[e.jsxs("span",{className:"shrink-0 font-medium text-text-dim",children:[i,":"]}),e.jsx("span",{className:"min-w-0 flex-1",children:s})]})}function E({value:i,onChange:s,min:r,max:a,placeholder:t}){return e.jsx(y,{type:"number",inputMode:"numeric",min:r,max:a,value:i,onChange:d=>s(d.target.value),placeholder:t})}export{xe as default};
7
+ //# sourceMappingURL=viewer-CD0iEfPU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewer-CD0iEfPU.js","sources":["../../node_modules/lucide-react/dist/esm/icons/earth.js","../../src/routes/settings/viewer.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 Earth = createLucideIcon(\"Earth\", [\n [\"path\", { d: \"M21.54 15H17a2 2 0 0 0-2 2v4.54\", key: \"1djwo0\" }],\n [\n \"path\",\n {\n d: \"M7 3.34V5a3 3 0 0 0 3 3a2 2 0 0 1 2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2c0-1.1.9-2 2-2h3.17\",\n key: \"1tzkfa\"\n }\n ],\n [\"path\", { d: \"M11 21.95V18a2 2 0 0 0-2-2a2 2 0 0 1-2-2v-1a2 2 0 0 0-2-2H2.05\", key: \"14pb5j\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }]\n]);\n\nexport { Earth as default };\n//# sourceMappingURL=earth.js.map\n","/**\n * /settings/viewer — long-message Viewer card + Baidu Maps AK card.\n *\n * Both cards are env-driven (~/.agim/.env), each with its own dirty /\n * Save / Discard state so a change to one doesn't force re-save of the\n * other. The Viewer card additionally surfaces cloudflared tunnel\n * status via `GET /api/viewer/tunnel`, with a manual Refresh button\n * since tunnel state is essentially static between operator actions.\n *\n * Env keys covered:\n * * Viewer: AGIM_VIEWER_ENABLED / _PUBLIC_BASE_URL / _TUNNEL_MODE /\n * _CHARS / _LINES / _CODE_LINES / _MAX_PASTES\n * * Baidu: AGIM_BAIDU_MAP_AK (in SECRET_KEYS — masked unless\n * reveal=1 is passed)\n *\n * AK validation: v1 mentioned \"32-char AK starting with non-digit\" as\n * a hint, but isn't strictly enforced (Baidu has refreshed AK formats\n * over the years). We surface a `pattern-looks-suspicious` warning\n * rather than blocking save.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport {\n CheckCircle2, Eye, EyeOff, ExternalLink, FileText, Globe2, Loader2,\n MapPin, RefreshCcw, Save, 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 { useEnv, useUpdateEnv, useViewerTunnel } from '@/hooks/use-settings'\nimport { describeError } from '@/lib/api/errors'\nimport { cn } from '@/lib/utils'\n\n/* ─────────────── Page wrapper ─────────────── */\n\nexport default function SettingsViewerRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const [reveal, setReveal] = useState(false)\n const envQuery = useEnv({ reveal })\n\n return (\n <div className=\"mx-auto flex max-w-4xl flex-col gap-6\">\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('viewerSettings.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => setReveal((v) => !v)}\n disabled={envQuery.isFetching}\n aria-label={reveal ? t('viewerSettings.hide') : t('viewerSettings.reveal')}\n >\n {reveal ? <EyeOff className=\"h-4 w-4\" /> : <Eye className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">\n {reveal ? t('viewerSettings.hide') : t('viewerSettings.reveal')}\n </span>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => void envQuery.refetch()}\n disabled={envQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {envQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('viewerSettings.subtitle')}</p>\n </header>\n\n {envQuery.isLoading ? (\n <div className=\"h-64 rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <>\n <ViewerCard env={envQuery.data?.env ?? {}} />\n <BaiduCard env={envQuery.data?.env ?? {}} />\n </>\n )}\n </div>\n )\n}\n\n/* ─────────────── Viewer card ─────────────── */\n\ninterface ViewerDraft {\n enabled: boolean\n publicUrl: string\n tunnelMode: 'off' | 'quick'\n // v1.2.45 — remote-paste URL/Token are env-only advanced knobs.\n // Only the opt-out toggle stays in the UI.\n noDefaultRemote: boolean\n chars: string\n lines: string\n codeLines: string\n maxPastes: string\n}\n\nfunction viewerDraftFromEnv(env: Record<string, string>): ViewerDraft {\n return {\n enabled: env.AGIM_VIEWER_ENABLED === '1' || env.AGIM_VIEWER_ENABLED?.toLowerCase() === 'true',\n publicUrl: env.AGIM_VIEWER_PUBLIC_BASE_URL ?? '',\n tunnelMode: env.AGIM_VIEWER_TUNNEL_MODE === 'quick' ? 'quick' : 'off',\n noDefaultRemote: env.AGIM_VIEWER_NO_DEFAULT_REMOTE === '1' || env.AGIM_VIEWER_NO_DEFAULT_REMOTE?.toLowerCase() === 'true',\n chars: env.AGIM_VIEWER_CHARS ?? '',\n lines: env.AGIM_VIEWER_LINES ?? '',\n codeLines: env.AGIM_VIEWER_CODE_LINES ?? '',\n maxPastes: env.AGIM_VIEWER_MAX_PASTES ?? '',\n }\n}\n\nfunction ViewerCard({ env }: { env: Record<string, string> }): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const updateEnv = useUpdateEnv()\n const tunnelQuery = useViewerTunnel()\n\n const [draft, setDraft] = useState<ViewerDraft>(() => viewerDraftFromEnv(env))\n const [syncedHash, setSyncedHash] = useState('')\n\n // Sync draft when env changes (initial load + post-save refetch).\n useEffect(() => {\n const next = viewerDraftFromEnv(env)\n const hash = JSON.stringify(next)\n if (hash !== syncedHash) {\n setDraft(next)\n setSyncedHash(hash)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [env.AGIM_VIEWER_ENABLED, env.AGIM_VIEWER_PUBLIC_BASE_URL,\n env.AGIM_VIEWER_TUNNEL_MODE, env.AGIM_VIEWER_CHARS,\n env.AGIM_VIEWER_LINES, env.AGIM_VIEWER_CODE_LINES,\n env.AGIM_VIEWER_MAX_PASTES, env.AGIM_VIEWER_NO_DEFAULT_REMOTE])\n\n const current = useMemo(() => viewerDraftFromEnv(env), [env])\n const isDirty = useMemo(\n () => JSON.stringify(draft) !== JSON.stringify(current),\n [draft, current],\n )\n\n function setField<K extends keyof ViewerDraft>(k: K, v: ViewerDraft[K]): void {\n setDraft((d) => ({ ...d, [k]: v }))\n }\n\n async function onSave(): Promise<void> {\n const updates: Record<string, string | null> = {}\n if (draft.enabled !== current.enabled) {\n updates.AGIM_VIEWER_ENABLED = draft.enabled ? '1' : '0'\n }\n if (draft.publicUrl !== current.publicUrl) {\n updates.AGIM_VIEWER_PUBLIC_BASE_URL = draft.publicUrl.trim() || null\n }\n if (draft.tunnelMode !== current.tunnelMode) {\n updates.AGIM_VIEWER_TUNNEL_MODE = draft.tunnelMode\n }\n if (draft.chars !== current.chars) {\n updates.AGIM_VIEWER_CHARS = draft.chars.trim() || null\n }\n if (draft.lines !== current.lines) {\n updates.AGIM_VIEWER_LINES = draft.lines.trim() || null\n }\n if (draft.codeLines !== current.codeLines) {\n updates.AGIM_VIEWER_CODE_LINES = draft.codeLines.trim() || null\n }\n if (draft.maxPastes !== current.maxPastes) {\n updates.AGIM_VIEWER_MAX_PASTES = draft.maxPastes.trim() || null\n }\n if (draft.noDefaultRemote !== current.noDefaultRemote) {\n updates.AGIM_VIEWER_NO_DEFAULT_REMOTE = draft.noDefaultRemote ? '1' : null\n }\n if (Object.keys(updates).length === 0) return\n try {\n await updateEnv.mutateAsync({ updates })\n toast.success(t('viewerSettings.toast.saved'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n function onDiscard(): void {\n setDraft(current)\n }\n\n const tunnel = tunnelQuery.data\n const effectivePublicUrl = tunnel?.effectivePublicUrl\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 <FileText className=\"h-4 w-4 text-text-dim\" />\n <h2 className=\"text-sm font-semibold\">{t('viewerSettings.viewer.title')}</h2>\n {draft.enabled\n ? <Badge variant=\"success\">{t('viewerSettings.viewer.on')}</Badge>\n : <Badge variant=\"outline\">{t('viewerSettings.viewer.off')}</Badge>}\n </header>\n <p className=\"px-4 pt-2 text-xs text-text-dim\">{t('viewerSettings.viewer.subtitle')}</p>\n\n {/* Enable toggle */}\n <div className=\"flex items-center gap-3 px-4 py-3\">\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={draft.enabled}\n onChange={(e) => {\n const on = e.target.checked\n setDraft((d) => ({\n ...d,\n enabled: on,\n // Opt-out only applies when viewer is on; clear when disabling.\n noDefaultRemote: on ? d.noDefaultRemote : false,\n }))\n }}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n <span className=\"font-medium\">{t('viewerSettings.viewer.enableLabel')}</span>\n </label>\n </div>\n\n {/* Public URL + tunnel mode */}\n <div className=\"grid grid-cols-1 gap-3 px-4 pb-3 sm:grid-cols-2\">\n <Field label={t('viewerSettings.viewer.publicUrl')} hint={t('viewerSettings.viewer.publicUrlHint')}>\n <Input\n value={draft.publicUrl}\n onChange={(e) => setField('publicUrl', e.target.value)}\n placeholder=\"https://agim.example.com\"\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field label={t('viewerSettings.viewer.tunnelMode')} hint={t('viewerSettings.viewer.tunnelHint')}>\n <Select\n value={draft.tunnelMode}\n onValueChange={(v) => setField('tunnelMode', v as 'off' | 'quick')}\n >\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"off\">{t('viewerSettings.viewer.tunnelOff')}</SelectItem>\n <SelectItem value=\"quick\">{t('viewerSettings.viewer.tunnelQuick')}</SelectItem>\n </SelectContent>\n </Select>\n </Field>\n\n {/* v1.2.45 — only the opt-out toggle is in the UI. The\n community default endpoint (viewer.iclaw.host) is the\n implicit fallback when neither public base URL nor tunnel\n is set; operators who need to point at a different paste\n server use the AGIM_VIEWER_REMOTE_PASTE_URL env var\n (documented in docs/viewer-modes.md). */}\n <Field\n label={t('viewerSettings.viewer.noDefaultRemote')}\n hint={t('viewerSettings.viewer.noDefaultRemoteHint')}\n >\n <label className={cn(\n 'inline-flex items-center gap-2 text-xs',\n !draft.enabled && 'opacity-50 cursor-not-allowed',\n )}>\n <input\n type=\"checkbox\"\n checked={draft.noDefaultRemote}\n disabled={!draft.enabled}\n onChange={(e) => setField('noDefaultRemote', e.target.checked)}\n className=\"h-4 w-4 accent-accent cursor-pointer disabled:cursor-not-allowed\"\n />\n <span>{t('viewerSettings.viewer.noDefaultRemoteLabel')}</span>\n </label>\n </Field>\n </div>\n\n {/* Tunnel status panel (only when quick mode is selected) */}\n {draft.tunnelMode === 'quick' && (\n <div className=\"mx-4 mb-3 rounded-md border border-border bg-surface-2 p-3\">\n <div className=\"mb-1 flex items-center gap-2\">\n <Globe2 className=\"h-4 w-4 text-text-dim\" />\n <span className=\"text-xs font-medium uppercase tracking-wide text-text-dim\">\n {t('viewerSettings.viewer.tunnelStatus')}\n </span>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => void tunnelQuery.refetch()}\n disabled={tunnelQuery.isFetching}\n aria-label={t('viewerSettings.viewer.refreshTunnel')}\n >\n {tunnelQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('viewerSettings.viewer.refreshTunnel')}</span>\n </Button>\n </div>\n {tunnel ? (\n <div className=\"flex flex-col gap-1 text-xs\">\n <Row label={t('viewerSettings.viewer.tunnelRunning')}>\n {tunnel.tunnel.running ? (\n <span className=\"inline-flex items-center gap-1 text-success\">\n <CheckCircle2 className=\"h-3 w-3\" />\n {t('viewerSettings.viewer.yes')}\n </span>\n ) : (\n <span className=\"text-text-dim\">{t('viewerSettings.viewer.no')}</span>\n )}\n </Row>\n <Row label={t('viewerSettings.viewer.tunnelUrl')}>\n {tunnel.tunnel.url ? (\n <a\n href={tunnel.tunnel.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 break-all font-mono text-info hover:underline\"\n >\n {tunnel.tunnel.url}\n <ExternalLink className=\"h-3 w-3 shrink-0\" />\n </a>\n ) : <span className=\"text-text-muted\">—</span>}\n </Row>\n <Row label={t('viewerSettings.viewer.effectiveUrl')}>\n {effectivePublicUrl ? (\n <span className=\"break-all font-mono text-text\">{effectivePublicUrl}</span>\n ) : <span className=\"text-text-muted\">—</span>}\n </Row>\n <Row label={t('viewerSettings.viewer.binary')}>\n {tunnel.tunnel.binaryFound ? (\n <span className=\"font-mono text-text\">{tunnel.tunnel.binaryPath}</span>\n ) : (\n <span className=\"text-warning\">{t('viewerSettings.viewer.binaryMissing')}</span>\n )}\n </Row>\n {tunnel.tunnel.lastError && (\n <Row label={t('viewerSettings.viewer.lastError')}>\n <span className=\"break-words text-danger\">{tunnel.tunnel.lastError}</span>\n </Row>\n )}\n </div>\n ) : (\n <p className=\"text-xs text-text-dim\">{t('viewerSettings.viewer.tunnelLoading')}</p>\n )}\n </div>\n )}\n\n {/* Thresholds */}\n <h3 className=\"border-t border-border px-4 pt-3 text-xs font-semibold uppercase tracking-wide text-text-dim\">\n {t('viewerSettings.viewer.thresholds')}\n </h3>\n <div className=\"grid grid-cols-2 gap-3 px-4 py-3 sm:grid-cols-4\">\n <Field label={t('viewerSettings.viewer.chars')} hint={t('viewerSettings.viewer.charsHint')}>\n <NumberInput value={draft.chars} onChange={(v) => setField('chars', v)} min={100} max={10000} placeholder=\"500\" />\n </Field>\n <Field label={t('viewerSettings.viewer.lines')} hint={t('viewerSettings.viewer.linesHint')}>\n <NumberInput value={draft.lines} onChange={(v) => setField('lines', v)} min={5} max={200} placeholder=\"12\" />\n </Field>\n <Field label={t('viewerSettings.viewer.codeLines')} hint={t('viewerSettings.viewer.codeLinesHint')}>\n <NumberInput value={draft.codeLines} onChange={(v) => setField('codeLines', v)} min={5} max={200} placeholder=\"10\" />\n </Field>\n <Field label={t('viewerSettings.viewer.maxPastes')} hint={t('viewerSettings.viewer.maxPastesHint')}>\n <NumberInput value={draft.maxPastes} onChange={(v) => setField('maxPastes', v)} min={100} max={1000000} placeholder=\"10000\" />\n </Field>\n </div>\n\n {/* Save bar */}\n {isDirty && (\n <div className=\"flex items-center gap-2 border-t border-border px-4 py-3\">\n <Badge variant=\"info\">{t('viewerSettings.dirtyHint')}</Badge>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={onDiscard}\n disabled={updateEnv.isPending}\n >\n <X className=\"h-4 w-4\" />\n {t('viewerSettings.discard')}\n </Button>\n <Button\n size=\"sm\"\n onClick={() => void onSave()}\n disabled={updateEnv.isPending}\n >\n {updateEnv.isPending\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <Save className=\"h-4 w-4\" />}\n {updateEnv.isPending ? t('viewerSettings.saving') : t('viewerSettings.save')}\n </Button>\n </div>\n )}\n </section>\n )\n}\n\n/* ─────────────── Baidu Maps card ─────────────── */\n\nfunction isMasked(s: string): boolean {\n return /\\*{3,}/.test(s)\n}\n\nfunction BaiduCard({ env }: { env: Record<string, string> }): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const updateEnv = useUpdateEnv()\n\n const currentAk = env.AGIM_BAIDU_MAP_AK ?? ''\n const [draftAk, setDraftAk] = useState(currentAk)\n const [syncedHash, setSyncedHash] = useState('')\n\n useEffect(() => {\n if (currentAk !== syncedHash) {\n setDraftAk(currentAk)\n setSyncedHash(currentAk)\n }\n }, [currentAk, syncedHash])\n\n const isConfigured = !!currentAk\n // Treat masked echo as no-change. Operator either typed something\n // new, or cleared. AK validity = looks-suspicious warning.\n const isDirty = draftAk !== currentAk && !(isMasked(draftAk) && draftAk === currentAk)\n const suspicious = draftAk.length > 0 && !isMasked(draftAk) && draftAk.length !== 32\n\n async function onSave(): Promise<void> {\n if (!isDirty) return\n if (isMasked(draftAk)) return // server would skip anyway; be explicit\n try {\n await updateEnv.mutateAsync({\n updates: { AGIM_BAIDU_MAP_AK: draftAk.trim() || null },\n })\n toast.success(t('viewerSettings.baidu.toast.saved'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n async function onClear(): Promise<void> {\n try {\n await updateEnv.mutateAsync({ updates: { AGIM_BAIDU_MAP_AK: null } })\n setDraftAk('')\n toast.success(t('viewerSettings.baidu.toast.cleared'))\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 <MapPin className=\"h-4 w-4 text-text-dim\" />\n <h2 className=\"text-sm font-semibold\">{t('viewerSettings.baidu.title')}</h2>\n {isConfigured\n ? <Badge variant=\"success\">{t('viewerSettings.baidu.configured')}</Badge>\n : <Badge variant=\"outline\">{t('viewerSettings.baidu.empty')}</Badge>}\n </header>\n <p className=\"px-4 pt-2 text-xs text-text-dim\">{t('viewerSettings.baidu.subtitle')}</p>\n\n <div className=\"px-4 py-3\">\n <Label htmlFor=\"baidu-ak\" className=\"text-xs font-medium\">AGIM_BAIDU_MAP_AK</Label>\n <Input\n id=\"baidu-ak\"\n value={draftAk}\n onChange={(e) => setDraftAk(e.target.value)}\n placeholder={t('viewerSettings.baidu.placeholder')}\n autoComplete=\"off\"\n className={cn('mt-1 font-mono text-xs', isMasked(draftAk) && 'text-text-muted')}\n />\n {suspicious && (\n <p className=\"mt-1 text-[11px] text-warning\">\n {t('viewerSettings.baidu.suspicious', { length: draftAk.length })}\n </p>\n )}\n <p className=\"mt-1 text-[11px] text-text-dim\">{t('viewerSettings.baidu.hint')}</p>\n </div>\n\n <div className=\"flex items-center gap-2 border-t border-border px-4 py-3\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => void onClear()}\n disabled={!isConfigured || updateEnv.isPending}\n className=\"text-danger hover:text-danger\"\n >\n <X className=\"h-4 w-4\" />\n {t('viewerSettings.baidu.clear')}\n </Button>\n <span className=\"ml-auto\" />\n {isDirty && (\n <Button\n size=\"sm\"\n onClick={() => void onSave()}\n disabled={updateEnv.isPending || isMasked(draftAk)}\n >\n {updateEnv.isPending\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <Save className=\"h-4 w-4\" />}\n {updateEnv.isPending ? t('viewerSettings.saving') : t('viewerSettings.save')}\n </Button>\n )}\n </div>\n </section>\n )\n}\n\n/* ─────────────── Helpers ─────────────── */\n\ninterface FieldProps {\n label: string\n hint?: string\n children: React.ReactNode\n}\n\nfunction Field({ label, hint, children }: FieldProps): JSX.Element {\n return (\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">{label}</Label>\n {children}\n {hint && <p className=\"text-[11px] text-text-dim\">{hint}</p>}\n </div>\n )\n}\n\ninterface RowProps {\n label: string\n children: React.ReactNode\n}\n\nfunction Row({ label, children }: RowProps): JSX.Element {\n return (\n <div className=\"flex flex-wrap items-baseline gap-2\">\n <span className=\"shrink-0 font-medium text-text-dim\">{label}:</span>\n <span className=\"min-w-0 flex-1\">{children}</span>\n </div>\n )\n}\n\ninterface NumberInputProps {\n value: string\n onChange: (v: string) => void\n min?: number\n max?: number\n placeholder?: string\n}\n\nfunction NumberInput({ value, onChange, min, max, placeholder }: NumberInputProps): JSX.Element {\n return (\n <Input\n type=\"number\"\n inputMode=\"numeric\"\n min={min}\n max={max}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n placeholder={placeholder}\n />\n )\n}\n"],"names":["Earth","createLucideIcon","SettingsViewerRoute","t","useTranslation","reveal","setReveal","useState","envQuery","useEnv","jsxs","jsx","Button","v","EyeOff","Eye","Loader2","RefreshCcw","Fragment","ViewerCard","BaiduCard","viewerDraftFromEnv","env","updateEnv","useUpdateEnv","tunnelQuery","useViewerTunnel","draft","setDraft","syncedHash","setSyncedHash","useEffect","next","hash","current","useMemo","isDirty","setField","k","d","onSave","updates","toast","err","describeError","onDiscard","tunnel","effectivePublicUrl","FileText","Badge","e","on","Field","Input","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","cn","Globe2","Row","CheckCircle2","ExternalLink","NumberInput","X","Save","isMasked","s","currentAk","draftAk","setDraftAk","isConfigured","suspicious","onClear","MapPin","Label","label","hint","children","value","onChange","min","max","placeholder"],"mappings":"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","x_google_ignoreList":[0]}
@@ -0,0 +1,17 @@
1
+ import{h as F,u as f,i as W,j as e,T as V,e as u,w as $,k as H,l as Z,m as I,n as Q,o as L,b as _,f as N,d as j,U as C,p as y,q}from"./index-DCfdN5R7.js";import{r as k}from"./react-DlP5eolq.js";import{E as P}from"./empty-state-CuiqdZiB.js";import{u as K,a as Y,b as A}from"./use-workspace-CuytyHwb.js";import{u as G}from"./use-settings-DGIjmUX0.js";import{L as M}from"./loader-circle-DDdmcH0k.js";import{R as J}from"./refresh-ccw-DlAd-eTQ.js";import{B as X}from"./book-open-CSCq5cjL.js";import{F as v}from"./file-text-BxfdLM0-.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 ee=F("File",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}]]);/**
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 T=F("FolderTree",[["path",{d:"M20 10a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z",key:"hod4my"}],["path",{d:"M20 21a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.92-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z",key:"w4yl2u"}],["path",{d:"M3 5a2 2 0 0 0 2 2h3",key:"f2jnh7"}],["path",{d:"M3 3v13a2 2 0 0 0 2 2h3",key:"k8epm1"}]]);/**
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 se=F("Folder",[["path",{d:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",key:"1kt360"}]]);function je(){const{t:s}=f(["workspace","common"]),[a,n]=W(),t=a.get("agent")??"",i=a.get("path")??"",l=K(),o=G(),c=l.data??{},x=k.useMemo(()=>Object.keys(c).sort(),[c]),g=x.join("\0"),h=o.data?.defaultAgent,d=Y(t,i,{enabled:!!t}),p=d.data,R=p?.type==="dir",U=p?.type==="file";function z(r){const m=new URLSearchParams(a);for(const[E,w]of Object.entries(r))w==null||w===""?m.delete(E):m.set(E,w);n(m,{replace:!1})}k.useEffect(()=>{if(t||l.isLoading)return;const r=h&&x.includes(h)?h:x.length===1?x[0]:"";if(!r)return;const m=new URLSearchParams(a);m.set("agent",r),m.delete("path"),n(m,{replace:!0})},[t,g,x,l.isLoading,h,a,n]);function O(r){z({agent:r||null,path:null})}function b(r){z({path:r||null})}function S(){if(!i)return;const r=i.lastIndexOf("/"),m=r>=0?i.slice(0,r):"";b(m)}return e.jsxs("div",{className:"flex min-h-dvh flex-col bg-bg",children:[e.jsx(V,{}),e.jsxs("main",{className:"mx-auto flex w-full max-w-7xl flex-1 flex-col gap-4 px-3 py-4 sm:px-4 pb-safe",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("pageTitle")}),e.jsxs(u,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>d.refetch(),disabled:!t||d.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[d.isFetching?e.jsx(M,{className:"h-4 w-4 animate-spin"}):e.jsx(J,{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("subtitle")})]}),e.jsx("div",{className:"flex flex-wrap items-end gap-2",children:e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx($,{htmlFor:"agent",className:"text-xs text-text-dim",children:s("agentPicker.label")}),e.jsxs(H,{value:t||"__placeholder__",onValueChange:r=>O(r==="__placeholder__"?"":r),children:[e.jsx(Z,{id:"agent",className:"w-64",children:e.jsx(I,{placeholder:s("agentPicker.placeholder")})}),e.jsxs(Q,{children:[e.jsx(L,{value:"__placeholder__",disabled:!0,children:s("agentPicker.placeholder")}),x.map(r=>e.jsx(L,{value:r,children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-mono text-xs",children:_(r)}),e.jsx("span",{className:N("inline-block h-1.5 w-1.5 rounded-full",c[r]?"bg-success":"bg-text-muted")}),e.jsx("span",{className:"text-text-dim text-xs",children:c[r]?s("agentPicker.online"):s("agentPicker.offline")})]})},r))]})]})]})}),t?e.jsxs(e.Fragment,{children:[e.jsx(te,{agent:t,onNavigate:b}),e.jsx(ie,{path:i,onNavigate:b,onUp:S}),d.isLoading?e.jsx("div",{className:"h-32 rounded-md bg-surface-2 animate-pulse"}):R&&p?.type==="dir"?e.jsx(ce,{entries:p.entries,onEnter:r=>b(i?`${i}/${r.name}`:r.name)}):U&&p?.type==="file"?e.jsx(le,{file:p,agent:t,onBack:S}):i&&d.isError&&re(i,d.error)?e.jsx(ne,{agent:t,path:i,onCreated:()=>{d.refetch()}}):e.jsx(P,{icon:e.jsx(T,{}),title:s("editor.loadFailed"),description:d.error?.message??""})]}):e.jsx(P,{icon:e.jsx(T,{}),title:s("noAgent.title"),description:s("noAgent.description")})]})]})}function te({agent:s,onNavigate:a}){const{t:n}=f("workspace"),t=ae(s);return e.jsx("section",{className:"rounded-md border border-border bg-surface p-4",children:e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center",children:[e.jsx("span",{className:"flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-accent-bg text-accent",children:e.jsx(X,{className:"h-4 w-4"})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold",children:n("quick.title")}),e.jsx(j,{variant:"info",children:_(s)})]}),e.jsx("p",{className:"mt-1 text-sm text-text-dim",children:n("quick.detail")})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(u,{type:"button",size:"sm",onClick:()=>a(t),children:[e.jsx(v,{className:"h-4 w-4"}),e.jsx("span",{children:n("quick.openRoleFile")})]}),e.jsxs(u,{type:"button",variant:"secondary",size:"sm",onClick:()=>a("MEMORY.md"),children:[e.jsx(v,{className:"h-4 w-4"}),e.jsx("span",{children:n("quick.openMemory")})]})]})]})})}function ae(s){return s==="claude-code"?"CLAUDE.md":"AGENTS.md"}function ne({agent:s,path:a,onCreated:n}){const{t}=f("workspace"),i=A(),l=a==="MEMORY.md";async function o(){try{await i.mutateAsync({agent:s,path:a,body:{content:t(l?"quick.memoryTemplate":"quick.fileTemplate")}}),y.success(t("toast.created",{path:a})),n()}catch(c){y.error(q(c,t).message)}}return e.jsx("section",{className:"rounded-md border border-border bg-surface p-4",children:e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center",children:[e.jsx("span",{className:"flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-surface-2 text-text-dim",children:e.jsx(v,{className:"h-4 w-4"})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("h2",{className:"text-sm font-semibold",children:t("quick.missingTitle")}),e.jsx("p",{className:"mt-1 text-sm text-text-dim",children:t("quick.missingDetail",{path:a})})]}),e.jsxs(u,{type:"button",size:"sm",onClick:()=>void o(),disabled:i.isPending,children:[i.isPending?e.jsx(M,{className:"h-4 w-4 animate-spin"}):e.jsx(v,{className:"h-4 w-4"}),e.jsx("span",{children:t(l?"quick.createMemory":"quick.createFile")})]})]})})}function re(s,a){if(s.includes("/")||!s.endsWith(".md"))return!1;const n=a instanceof Error?a.message.toLowerCase():String(a).toLowerCase();return n.includes("not found")||n.includes("enoent")||n.includes("no such file")}function ie({path:s,onNavigate:a,onUp:n}){const{t}=f("workspace"),i=s?s.split("/"):[];return e.jsxs("div",{className:"flex flex-wrap items-center gap-1 text-sm",children:[e.jsx(u,{type:"button",variant:"ghost",size:"sm",onClick:n,disabled:!s,"aria-label":t("tree.up"),children:e.jsx(C,{className:"h-4 w-4"})}),e.jsx("button",{type:"button",onClick:()=>a(""),className:"text-text-dim hover:text-text rounded px-1 py-0.5",children:t("tree.rootLabel")}),i.map((l,o)=>{const c=i.slice(0,o+1).join("/");return e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"text-text-muted",children:"/"}),e.jsx("button",{type:"button",onClick:()=>a(c),className:"text-text-dim hover:text-text rounded px-1 py-0.5",children:l})]},c)})]})}function ce({entries:s,onEnter:a}){const{t:n}=f("workspace");return s.length===0?e.jsx("div",{className:"rounded-md border border-border bg-surface p-3 text-sm text-text-dim",children:n("tree.empty")}):e.jsx("ul",{className:"divide-y divide-border rounded-md border border-border bg-surface",children:s.map(t=>e.jsx("li",{children:e.jsxs("button",{type:"button",onClick:()=>a(t),disabled:t.broken||t.symlink_escape,className:N("flex w-full items-center gap-2 px-3 py-2 text-sm text-left","transition-colors hover:bg-surface-hover disabled:opacity-50 disabled:cursor-not-allowed"),children:[t.isDir?e.jsx(se,{className:"h-4 w-4 text-accent"}):e.jsx(ee,{className:"h-4 w-4 text-text-dim"}),e.jsx("span",{className:t.isDir?"font-medium text-text":"text-text",children:t.name}),t.symlink_escape&&e.jsx(j,{variant:"warning",className:"ml-2",children:n("tree.symlinkEscape")}),t.broken&&!t.symlink_escape&&e.jsx(j,{variant:"danger",className:"ml-2",children:n("tree.broken")}),!t.isDir&&t.size!=null&&e.jsx("span",{className:"ml-auto text-xs text-text-muted tabular-nums",children:B(t.size)}),t.mtime&&e.jsx("span",{className:N("text-xs text-text-muted tabular-nums",!t.isDir&&t.size!=null?"ml-3":"ml-auto"),children:D(t.mtime)})]})},t.name))})}function le({file:s,agent:a,onBack:n}){const{t}=f(["workspace","common"]),[i,l]=k.useState(s.content);k.useEffect(()=>{l(s.content)},[s.content]);const o=i!==s.content,c=A();async function x(){try{await c.mutateAsync({agent:a,path:s.path,body:{content:i}}),y.success(t("toast.saved",{path:s.path}))}catch(g){const{message:h}=q(g,t);y.error(h)}}return s.encoding==="base64"?e.jsxs("div",{className:"rounded-md border border-border bg-surface p-4 text-sm",children:[e.jsxs(u,{variant:"ghost",size:"sm",onClick:n,className:"mb-3",children:[e.jsx(C,{className:"h-4 w-4"}),t("tree.up")]}),e.jsx("p",{className:"text-text-dim",children:t("editor.binary")}),e.jsxs("p",{className:"mt-2 text-xs text-text-muted tabular-nums",children:[s.path," · ",B(s.size)]})]}):e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs(u,{variant:"ghost",size:"sm",onClick:n,children:[e.jsx(C,{className:"h-4 w-4"}),t("tree.up")]}),e.jsx("code",{className:"rounded bg-surface-2 px-1.5 py-0.5 text-xs font-mono",children:s.path}),s.truncated&&e.jsx(j,{variant:"warning",children:t("editor.truncatedBadge")}),o&&e.jsx(j,{variant:"info",children:t("editor.dirtyHint")}),e.jsxs(u,{type:"button",size:"sm",className:"ml-auto",onClick:()=>void x(),disabled:!o||c.isPending||s.truncated,children:[c.isPending?e.jsx(M,{className:"h-4 w-4 animate-spin"}):null,c.isPending?t("editor.saving"):t("editor.save")]})]}),s.truncated&&e.jsx("p",{className:"text-xs text-warning",children:t("editor.truncated")}),e.jsx("textarea",{value:i,onChange:g=>l(g.target.value),rows:24,spellCheck:!1,className:N("w-full resize-y rounded-md border bg-bg px-3 py-2","font-mono text-xs leading-5","focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-1 focus:ring-offset-bg",o?"border-accent":"border-border")}),!o&&e.jsx("p",{className:"text-xs text-text-muted",children:t("editor.savedMeta",{size:s.size,at:D(s.mtime)})})]})}function D(s){if(s==null)return"—";try{const a=new Date(s);return Number.isNaN(a.getTime())?s:a.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return s}}function B(s){return s<1024?`${s} B`:s<1024*1024?`${(s/1024).toFixed(1)} KiB`:`${(s/1024/1024).toFixed(1)} MiB`}export{je as default};
17
+ //# sourceMappingURL=workspace-BA1_hso3.js.map