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.
- package/CHANGELOG.md +22 -0
- package/README.md +39 -3
- package/README.zh-CN.md +42 -7
- package/dist/cli-ui/cmd-handlers.d.ts +22 -1
- package/dist/cli-ui/cmd-handlers.d.ts.map +1 -1
- package/dist/cli-ui/cmd-handlers.js +304 -40
- package/dist/cli-ui/cmd-handlers.js.map +1 -1
- package/dist/cli-ui/config-wizard.d.ts +13 -1
- package/dist/cli-ui/config-wizard.d.ts.map +1 -1
- package/dist/cli-ui/config-wizard.js +93 -21
- package/dist/cli-ui/config-wizard.js.map +1 -1
- package/dist/cli-ui/doctor.d.ts +15 -0
- package/dist/cli-ui/doctor.d.ts.map +1 -0
- package/dist/cli-ui/doctor.js +151 -0
- package/dist/cli-ui/doctor.js.map +1 -0
- package/dist/cli-ui/entry-menu.d.ts +6 -0
- package/dist/cli-ui/entry-menu.d.ts.map +1 -1
- package/dist/cli-ui/entry-menu.js +67 -30
- package/dist/cli-ui/entry-menu.js.map +1 -1
- package/dist/cli-ui/i18n.d.ts +15 -6
- package/dist/cli-ui/i18n.d.ts.map +1 -1
- package/dist/cli-ui/i18n.js +30 -12
- package/dist/cli-ui/i18n.js.map +1 -1
- package/dist/cli-ui/quickstart.d.ts +3 -0
- package/dist/cli-ui/quickstart.d.ts.map +1 -0
- package/dist/cli-ui/quickstart.js +108 -0
- package/dist/cli-ui/quickstart.js.map +1 -0
- package/dist/cli-ui/readiness.d.ts +10 -0
- package/dist/cli-ui/readiness.d.ts.map +1 -0
- package/dist/cli-ui/readiness.js +75 -0
- package/dist/cli-ui/readiness.js.map +1 -0
- package/dist/cli-ui/service.d.ts +23 -0
- package/dist/cli-ui/service.d.ts.map +1 -1
- package/dist/cli-ui/service.js +114 -5
- package/dist/cli-ui/service.js.map +1 -1
- package/dist/cli.js +99 -396
- package/dist/cli.js.map +1 -1
- package/dist/core/acp-server.d.ts.map +1 -1
- package/dist/core/acp-server.js +16 -2
- package/dist/core/acp-server.js.map +1 -1
- package/dist/core/agent-cwd.d.ts +8 -0
- package/dist/core/agent-cwd.d.ts.map +1 -1
- package/dist/core/agent-cwd.js +57 -7
- package/dist/core/agent-cwd.js.map +1 -1
- package/dist/core/commands/builtin.d.ts.map +1 -1
- package/dist/core/commands/builtin.js +12 -2
- package/dist/core/commands/builtin.js.map +1 -1
- package/dist/core/commands/model.d.ts.map +1 -1
- package/dist/core/commands/model.js +31 -2
- package/dist/core/commands/model.js.map +1 -1
- package/dist/core/llm/anthropic-provider.js +2 -1
- package/dist/core/llm/anthropic-provider.js.map +1 -1
- package/dist/core/llm/openai-compat-provider.js +3 -2
- package/dist/core/llm/openai-compat-provider.js.map +1 -1
- package/dist/core/llm/provider-base.d.ts +4 -4
- package/dist/core/llm/provider-base.d.ts.map +1 -1
- package/dist/core/llm/provider-base.js +1 -1
- package/dist/core/llm/provider-base.js.map +1 -1
- package/dist/plugins/agents/native/index.d.ts +1 -0
- package/dist/plugins/agents/native/index.d.ts.map +1 -1
- package/dist/plugins/agents/native/index.js +14 -0
- package/dist/plugins/agents/native/index.js.map +1 -1
- package/dist/plugins/agents/pi-native/factory.d.ts.map +1 -1
- package/dist/plugins/agents/pi-native/factory.js +19 -3
- package/dist/plugins/agents/pi-native/factory.js.map +1 -1
- package/dist/plugins/agents/pi-native/index.d.ts +11 -0
- package/dist/plugins/agents/pi-native/index.d.ts.map +1 -1
- package/dist/plugins/agents/pi-native/index.js +56 -2
- package/dist/plugins/agents/pi-native/index.js.map +1 -1
- package/dist/plugins/agents/pi-native/provider-resolver.d.ts +2 -0
- package/dist/plugins/agents/pi-native/provider-resolver.d.ts.map +1 -1
- package/dist/plugins/agents/pi-native/provider-resolver.js +9 -1
- package/dist/plugins/agents/pi-native/provider-resolver.js.map +1 -1
- package/dist/web/public/assets/a2a-CTsDMefo.js +7 -0
- package/dist/web/public/assets/a2a-CTsDMefo.js.map +1 -0
- package/dist/web/public/assets/{activity-BAgb2WZC.js → activity-ul8Os7Pz.js} +2 -2
- package/dist/web/public/assets/{activity-BAgb2WZC.js.map → activity-ul8Os7Pz.js.map} +1 -1
- package/dist/web/public/assets/{admins-CZYANmhn.js → admins-ByMAuquy.js} +3 -3
- package/dist/web/public/assets/{admins-CZYANmhn.js.map → admins-ByMAuquy.js.map} +1 -1
- package/dist/web/public/assets/agents-Ds1zyxBj.js +2 -0
- package/dist/web/public/assets/{agents-BXThDW6f.js.map → agents-Ds1zyxBj.js.map} +1 -1
- package/dist/web/public/assets/{approvals-ByPXIYVl.js → approvals-DOWlWI7Z.js} +3 -3
- package/dist/web/public/assets/{approvals-ByPXIYVl.js.map → approvals-DOWlWI7Z.js.map} +1 -1
- package/dist/web/public/assets/{arrow-down-B8DkdbEY.js → arrow-down-7i0xwCI2.js} +2 -2
- package/dist/web/public/assets/{arrow-down-B8DkdbEY.js.map → arrow-down-7i0xwCI2.js.map} +1 -1
- package/dist/web/public/assets/arrow-right-A889Wof8.js +7 -0
- package/dist/web/public/assets/arrow-right-A889Wof8.js.map +1 -0
- package/dist/web/public/assets/{arrow-up-i_dEdXkz.js → arrow-up-Dm0U4-6U.js} +2 -2
- package/dist/web/public/assets/{arrow-up-i_dEdXkz.js.map → arrow-up-Dm0U4-6U.js.map} +1 -1
- package/dist/web/public/assets/{asks-yD_inOnM.js → asks-DGuBsrJ7.js} +3 -3
- package/dist/web/public/assets/{asks-yD_inOnM.js.map → asks-DGuBsrJ7.js.map} +1 -1
- package/dist/web/public/assets/{audit-teCIRtgN.js → audit-BRXsplJ2.js} +2 -2
- package/dist/web/public/assets/{audit-teCIRtgN.js.map → audit-BRXsplJ2.js.map} +1 -1
- package/dist/web/public/assets/{bell-CeWDMs8_.js → bell-B-UdeJsp.js} +2 -2
- package/dist/web/public/assets/{bell-CeWDMs8_.js.map → bell-B-UdeJsp.js.map} +1 -1
- package/dist/web/public/assets/bgjobs-CcRiffyJ.js +2 -0
- package/dist/web/public/assets/bgjobs-CcRiffyJ.js.map +1 -0
- package/dist/web/public/assets/book-open-CSCq5cjL.js +7 -0
- package/dist/web/public/assets/book-open-CSCq5cjL.js.map +1 -0
- package/dist/web/public/assets/{brain-BQqv0Zhc.js → brain-Dl4DF5kX.js} +2 -2
- package/dist/web/public/assets/{brain-BQqv0Zhc.js.map → brain-Dl4DF5kX.js.map} +1 -1
- package/dist/web/public/assets/{briefcase-DUXbR4xs.js → briefcase-CeKUkFSq.js} +2 -2
- package/dist/web/public/assets/{briefcase-DUXbR4xs.js.map → briefcase-CeKUkFSq.js.map} +1 -1
- package/dist/web/public/assets/chat-rLJMdJBk.js +12 -0
- package/dist/web/public/assets/chat-rLJMdJBk.js.map +1 -0
- package/dist/web/public/assets/{chevron-left-RC6mMSiX.js → chevron-left-01fAFVpo.js} +2 -2
- package/dist/web/public/assets/{chevron-left-RC6mMSiX.js.map → chevron-left-01fAFVpo.js.map} +1 -1
- package/dist/web/public/assets/{chevron-right-DrkYVi19.js → chevron-right-CFRb-SM_.js} +3 -3
- package/dist/web/public/assets/{chevron-right-DrkYVi19.js.map → chevron-right-CFRb-SM_.js.map} +1 -1
- package/dist/web/public/assets/{circle-check-big-BC8ntMsz.js → circle-check-big-DBg2BD6o.js} +2 -2
- package/dist/web/public/assets/{circle-check-big-BC8ntMsz.js.map → circle-check-big-DBg2BD6o.js.map} +1 -1
- package/dist/web/public/assets/{circle-x-DHK7ypFY.js → circle-x-CqFMzO-x.js} +2 -2
- package/dist/web/public/assets/{circle-x-DHK7ypFY.js.map → circle-x-CqFMzO-x.js.map} +1 -1
- package/dist/web/public/assets/clipboard-list-lnqdk2_J.js +7 -0
- package/dist/web/public/assets/clipboard-list-lnqdk2_J.js.map +1 -0
- package/dist/web/public/assets/{clock-DXHhWqJH.js → clock-4hd1joQe.js} +3 -3
- package/dist/web/public/assets/{clock-DXHhWqJH.js.map → clock-4hd1joQe.js.map} +1 -1
- package/dist/web/public/assets/confirm-dialog-BDb0NLny.js +2 -0
- package/dist/web/public/assets/{confirm-dialog-gPKJnvEW.js.map → confirm-dialog-BDb0NLny.js.map} +1 -1
- package/dist/web/public/assets/{copy-DtQxgcR0.js → copy-CD4A7VD8.js} +3 -3
- package/dist/web/public/assets/{copy-DtQxgcR0.js.map → copy-CD4A7VD8.js.map} +1 -1
- package/dist/web/public/assets/dashboard-CG3WiG7h.js +2 -0
- package/dist/web/public/assets/dashboard-CG3WiG7h.js.map +1 -0
- package/dist/web/public/assets/{data-table-DOKUic1J.js → data-table-BkUshOZz.js} +2 -2
- package/dist/web/public/assets/{data-table-DOKUic1J.js.map → data-table-BkUshOZz.js.map} +1 -1
- package/dist/web/public/assets/database-lQzk64rV.js +7 -0
- package/dist/web/public/assets/database-lQzk64rV.js.map +1 -0
- package/dist/web/public/assets/{distill-p6P7-1UR.js → distill-CPurVW3v.js} +3 -3
- package/dist/web/public/assets/{distill-p6P7-1UR.js.map → distill-CPurVW3v.js.map} +1 -1
- package/dist/web/public/assets/{download-CqNiIHa8.js → download-CVZnHcwj.js} +2 -2
- package/dist/web/public/assets/{download-CqNiIHa8.js.map → download-CVZnHcwj.js.map} +1 -1
- package/dist/web/public/assets/dropdown-menu-BNH5SrVb.js +7 -0
- package/dist/web/public/assets/dropdown-menu-BNH5SrVb.js.map +1 -0
- package/dist/web/public/assets/{email-DwbfTUlV.js → email-YlI4MWLp.js} +3 -3
- package/dist/web/public/assets/{email-DwbfTUlV.js.map → email-YlI4MWLp.js.map} +1 -1
- package/dist/web/public/assets/{empty-state-CTwOQemt.js → empty-state-CuiqdZiB.js} +2 -2
- package/dist/web/public/assets/{empty-state-CTwOQemt.js.map → empty-state-CuiqdZiB.js.map} +1 -1
- package/dist/web/public/assets/{external-link-BY7Ye8yi.js → external-link-1WPpVvdu.js} +2 -2
- package/dist/web/public/assets/{external-link-BY7Ye8yi.js.map → external-link-1WPpVvdu.js.map} +1 -1
- package/dist/web/public/assets/{eye-6RUADoDS.js → eye-BfPyNFzk.js} +2 -2
- package/dist/web/public/assets/{eye-6RUADoDS.js.map → eye-BfPyNFzk.js.map} +1 -1
- package/dist/web/public/assets/{facts-DXE0aJmb.js → facts-xT_24pH8.js} +2 -2
- package/dist/web/public/assets/{facts-DXE0aJmb.js.map → facts-xT_24pH8.js.map} +1 -1
- package/dist/web/public/assets/file-text-BxfdLM0-.js +7 -0
- package/dist/web/public/assets/file-text-BxfdLM0-.js.map +1 -0
- package/dist/web/public/assets/{goals-C1LCm3qL.js → goals-C8ZQfbhj.js} +3 -3
- package/dist/web/public/assets/{goals-C1LCm3qL.js.map → goals-C8ZQfbhj.js.map} +1 -1
- package/dist/web/public/assets/health-A2StNEfn.js +2 -0
- package/dist/web/public/assets/{health-wqCp-K_o.js.map → health-A2StNEfn.js.map} +1 -1
- package/dist/web/public/assets/{heart-pulse-DfqI4GF7.js → heart-pulse-DXlE9oic.js} +2 -2
- package/dist/web/public/assets/{heart-pulse-DfqI4GF7.js.map → heart-pulse-DXlE9oic.js.map} +1 -1
- package/dist/web/public/assets/{heartbeat-Bumv4XtQ.js → heartbeat-ClO5gJrj.js} +3 -3
- package/dist/web/public/assets/{heartbeat-Bumv4XtQ.js.map → heartbeat-ClO5gJrj.js.map} +1 -1
- package/dist/web/public/assets/hot-bfTA-V_z.js +7 -0
- package/dist/web/public/assets/{hot-B-CMjQIr.js.map → hot-bfTA-V_z.js.map} +1 -1
- package/dist/web/public/assets/index-Bi2qWb-u.css +1 -0
- package/dist/web/public/assets/index-DCfdN5R7.js +244 -0
- package/dist/web/public/assets/index-DCfdN5R7.js.map +1 -0
- package/dist/web/public/assets/{injection-Dn_XqgLG.js → injection-omvCR6-p.js} +2 -2
- package/dist/web/public/assets/{injection-Dn_XqgLG.js.map → injection-omvCR6-p.js.map} +1 -1
- package/dist/web/public/assets/{installed-Cet-1M2Q.js → installed-DL6r3ktm.js} +4 -9
- package/dist/web/public/assets/installed-DL6r3ktm.js.map +1 -0
- package/dist/web/public/assets/jobs-Biy5lYd4.js +2 -0
- package/dist/web/public/assets/jobs-Biy5lYd4.js.map +1 -0
- package/dist/web/public/assets/layout-BLm6NJ3V.js +2 -0
- package/dist/web/public/assets/layout-BLm6NJ3V.js.map +1 -0
- package/dist/web/public/assets/layout-BTKafRVZ.js +2 -0
- package/dist/web/public/assets/layout-BTKafRVZ.js.map +1 -0
- package/dist/web/public/assets/layout-Bm-2s2fp.js +2 -0
- package/dist/web/public/assets/layout-Bm-2s2fp.js.map +1 -0
- package/dist/web/public/assets/layout-DsZ8eR4i.js +2 -0
- package/dist/web/public/assets/layout-DsZ8eR4i.js.map +1 -0
- package/dist/web/public/assets/{layout-D_3ZcVG7.js → layout-sxvovjEH.js} +2 -2
- package/dist/web/public/assets/{layout-D_3ZcVG7.js.map → layout-sxvovjEH.js.map} +1 -1
- package/dist/web/public/assets/llm-JjZDbBvJ.js +37 -0
- package/dist/web/public/assets/llm-JjZDbBvJ.js.map +1 -0
- package/dist/web/public/assets/loader-circle-DDdmcH0k.js +7 -0
- package/dist/web/public/assets/{loader-circle-DgdBWYl0.js.map → loader-circle-DDdmcH0k.js.map} +1 -1
- package/dist/web/public/assets/{map-pin-3QS1A0-I.js → map-pin-C_jAxukI.js} +2 -2
- package/dist/web/public/assets/{map-pin-3QS1A0-I.js.map → map-pin-C_jAxukI.js.map} +1 -1
- package/dist/web/public/assets/{mcp-DwKZULET.js → mcp-vKajK1F8.js} +3 -3
- package/dist/web/public/assets/{mcp-DwKZULET.js.map → mcp-vKajK1F8.js.map} +1 -1
- package/dist/web/public/assets/memos-DAt4k3DO.js +7 -0
- package/dist/web/public/assets/memos-DAt4k3DO.js.map +1 -0
- package/dist/web/public/assets/messengers-GYVTFlAj.js +2 -0
- package/dist/web/public/assets/messengers-GYVTFlAj.js.map +1 -0
- package/dist/web/public/assets/{mobile-Bq0FH9JV.js → mobile-VUyTo40E.js} +3 -3
- package/dist/web/public/assets/{mobile-Bq0FH9JV.js.map → mobile-VUyTo40E.js.map} +1 -1
- package/dist/web/public/assets/{network--s113Jkm.js → network-BUeWK3bs.js} +2 -2
- package/dist/web/public/assets/{network--s113Jkm.js.map → network-BUeWK3bs.js.map} +1 -1
- package/dist/web/public/assets/outbox-CEE0rwN3.js +2 -0
- package/dist/web/public/assets/outbox-CEE0rwN3.js.map +1 -0
- package/dist/web/public/assets/overview-BSOZ5gTD.js +12 -0
- package/dist/web/public/assets/overview-BSOZ5gTD.js.map +1 -0
- package/dist/web/public/assets/overview-COop5K2Y.js +12 -0
- package/dist/web/public/assets/overview-COop5K2Y.js.map +1 -0
- package/dist/web/public/assets/overview-DeH5ud6d.js +2 -0
- package/dist/web/public/assets/overview-DeH5ud6d.js.map +1 -0
- package/dist/web/public/assets/{pagination-DkdCTctJ.js → pagination-BBicLzXP.js} +3 -3
- package/dist/web/public/assets/{pagination-DkdCTctJ.js.map → pagination-BBicLzXP.js.map} +1 -1
- package/dist/web/public/assets/persona-CElXQZ4p.js +2 -0
- package/dist/web/public/assets/{persona-BvtcZh6G.js.map → persona-CElXQZ4p.js.map} +1 -1
- package/dist/web/public/assets/{plans-i3a6lrqF.js → plans-Bo5LlLeH.js} +3 -8
- package/dist/web/public/assets/plans-Bo5LlLeH.js.map +1 -0
- package/dist/web/public/assets/{play-CPoE_JnS.js → play-DX5wp4WH.js} +2 -2
- package/dist/web/public/assets/{play-CPoE_JnS.js.map → play-DX5wp4WH.js.map} +1 -1
- package/dist/web/public/assets/{plus-CfzKV_0u.js → plus-DH4J_YhN.js} +2 -2
- package/dist/web/public/assets/{plus-CfzKV_0u.js.map → plus-DH4J_YhN.js.map} +1 -1
- package/dist/web/public/assets/policy-BrgOuDt_.js +2 -0
- package/dist/web/public/assets/{policy-Cm88P8LO.js.map → policy-BrgOuDt_.js.map} +1 -1
- package/dist/web/public/assets/{qr-code-DMkV8nv2.js → qr-code-YrEuhMPC.js} +2 -2
- package/dist/web/public/assets/{qr-code-DMkV8nv2.js.map → qr-code-YrEuhMPC.js.map} +1 -1
- package/dist/web/public/assets/{refresh-ccw-nBMm5Xal.js → refresh-ccw-DlAd-eTQ.js} +2 -2
- package/dist/web/public/assets/{refresh-ccw-nBMm5Xal.js.map → refresh-ccw-DlAd-eTQ.js.map} +1 -1
- package/dist/web/public/assets/{reminders-DjEujanC.js → reminders-DBEE0zXG.js} +3 -3
- package/dist/web/public/assets/{reminders-DjEujanC.js.map → reminders-DBEE0zXG.js.map} +1 -1
- package/dist/web/public/assets/{save-DbrrCFDM.js → save-BDOtZrfp.js} +2 -2
- package/dist/web/public/assets/{save-DbrrCFDM.js.map → save-BDOtZrfp.js.map} +1 -1
- package/dist/web/public/assets/schedules-DAyhVI8-.js +2 -0
- package/dist/web/public/assets/schedules-DAyhVI8-.js.map +1 -0
- package/dist/web/public/assets/{search-5q3dkINm.js → search-55mtgHrB.js} +3 -3
- package/dist/web/public/assets/{search-5q3dkINm.js.map → search-55mtgHrB.js.map} +1 -1
- package/dist/web/public/assets/{search-DbE4VEm9.js → search-CAICU3aU.js} +2 -2
- package/dist/web/public/assets/{search-DbE4VEm9.js.map → search-CAICU3aU.js.map} +1 -1
- package/dist/web/public/assets/security-CbP4QgVp.js +2 -0
- package/dist/web/public/assets/security-CbP4QgVp.js.map +1 -0
- package/dist/web/public/assets/server-Dg4e8pvm.js +7 -0
- package/dist/web/public/assets/server-Dg4e8pvm.js.map +1 -0
- package/dist/web/public/assets/service-gWZa3sup.js +7 -0
- package/dist/web/public/assets/service-gWZa3sup.js.map +1 -0
- package/dist/web/public/assets/{shield-alert-WOa69jy3.js → shield-alert-DOKK9EnJ.js} +2 -2
- package/dist/web/public/assets/{shield-alert-WOa69jy3.js.map → shield-alert-DOKK9EnJ.js.map} +1 -1
- package/dist/web/public/assets/sparkles-G0QIs9nP.js +7 -0
- package/dist/web/public/assets/sparkles-G0QIs9nP.js.map +1 -0
- package/dist/web/public/assets/start-D-abhl3q.js +2 -0
- package/dist/web/public/assets/start-D-abhl3q.js.map +1 -0
- package/dist/web/public/assets/{status-badge-D5xhwquL.js → status-badge-CyLdpsXq.js} +2 -2
- package/dist/web/public/assets/{status-badge-D5xhwquL.js.map → status-badge-CyLdpsXq.js.map} +1 -1
- package/dist/web/public/assets/{subtasks-DMRyk6YS.js → subtasks-BnEjSGUR.js} +3 -3
- package/dist/web/public/assets/{subtasks-DMRyk6YS.js.map → subtasks-BnEjSGUR.js.map} +1 -1
- package/dist/web/public/assets/{table-Dx65w6V0.js → table-sCMZBe_Z.js} +2 -2
- package/dist/web/public/assets/{table-Dx65w6V0.js.map → table-sCMZBe_Z.js.map} +1 -1
- package/dist/web/public/assets/terminal-_pXeEjXG.js +7 -0
- package/dist/web/public/assets/terminal-_pXeEjXG.js.map +1 -0
- package/dist/web/public/assets/{topn-L7Juczp3.js → topn-D1B-gS1M.js} +3 -3
- package/dist/web/public/assets/{topn-L7Juczp3.js.map → topn-D1B-gS1M.js.map} +1 -1
- package/dist/web/public/assets/{trash-2-7xrfqd-v.js → trash-2-D2x2UPuZ.js} +2 -2
- package/dist/web/public/assets/{trash-2-7xrfqd-v.js.map → trash-2-D2x2UPuZ.js.map} +1 -1
- package/dist/web/public/assets/use-a2a-C98e2Via.js +2 -0
- package/dist/web/public/assets/use-a2a-C98e2Via.js.map +1 -0
- package/dist/web/public/assets/{use-agim-skills-pFjfgqMF.js → use-agim-skills-BbuJP3NT.js} +2 -2
- package/dist/web/public/assets/{use-agim-skills-pFjfgqMF.js.map → use-agim-skills-BbuJP3NT.js.map} +1 -1
- package/dist/web/public/assets/use-background-tasks-CwFmOokw.js +2 -0
- package/dist/web/public/assets/{use-background-tasks-D1--hHjp.js.map → use-background-tasks-CwFmOokw.js.map} +1 -1
- package/dist/web/public/assets/use-jobs-BJjeJ5lh.js +2 -0
- package/dist/web/public/assets/use-jobs-BJjeJ5lh.js.map +1 -0
- package/dist/web/public/assets/use-memory-CXDwKCco.js +2 -0
- package/dist/web/public/assets/{use-memory-Bz1Zao7g.js.map → use-memory-CXDwKCco.js.map} +1 -1
- package/dist/web/public/assets/use-observability-CY5ZUPrC.js +2 -0
- package/dist/web/public/assets/{use-observability-DtqSWVjM.js.map → use-observability-CY5ZUPrC.js.map} +1 -1
- package/dist/web/public/assets/use-outbox-DT_XWB_7.js +7 -0
- package/dist/web/public/assets/use-outbox-DT_XWB_7.js.map +1 -0
- package/dist/web/public/assets/use-schedules-D4W8fMwo.js +7 -0
- package/dist/web/public/assets/use-schedules-D4W8fMwo.js.map +1 -0
- package/dist/web/public/assets/use-settings-DGIjmUX0.js +2 -0
- package/dist/web/public/assets/use-settings-DGIjmUX0.js.map +1 -0
- package/dist/web/public/assets/use-skills-D2bMM580.js +7 -0
- package/dist/web/public/assets/use-skills-D2bMM580.js.map +1 -0
- package/dist/web/public/assets/use-vector-BYOFwjU0.js +2 -0
- package/dist/web/public/assets/use-vector-BYOFwjU0.js.map +1 -0
- package/dist/web/public/assets/use-workspace-CuytyHwb.js +2 -0
- package/dist/web/public/assets/{use-workspace-CConjEx0.js.map → use-workspace-CuytyHwb.js.map} +1 -1
- package/dist/web/public/assets/vector-CL8ezpSR.js +2 -0
- package/dist/web/public/assets/vector-CL8ezpSR.js.map +1 -0
- package/dist/web/public/assets/viewer-CD0iEfPU.js +7 -0
- package/dist/web/public/assets/viewer-CD0iEfPU.js.map +1 -0
- package/dist/web/public/assets/workspace-BA1_hso3.js +17 -0
- package/dist/web/public/assets/workspace-BA1_hso3.js.map +1 -0
- package/dist/web/public/assets/workspaces-DyGLJUgB.js +7 -0
- package/dist/web/public/assets/workspaces-DyGLJUgB.js.map +1 -0
- package/dist/web/public/index.html +2 -2
- package/dist/web/server.d.ts +0 -3
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +138 -3
- package/dist/web/server.js.map +1 -1
- package/package.json +1 -1
- package/dist/web/public/assets/a2a-D7MoJ1iT.js +0 -7
- package/dist/web/public/assets/a2a-D7MoJ1iT.js.map +0 -1
- package/dist/web/public/assets/agents-BXThDW6f.js +0 -7
- package/dist/web/public/assets/bgjobs-Rc05aEy9.js +0 -7
- package/dist/web/public/assets/bgjobs-Rc05aEy9.js.map +0 -1
- package/dist/web/public/assets/chat-DQpQLW9j.js +0 -17
- package/dist/web/public/assets/chat-DQpQLW9j.js.map +0 -1
- package/dist/web/public/assets/circle-check-DZnkaUdk.js +0 -7
- package/dist/web/public/assets/circle-check-DZnkaUdk.js.map +0 -1
- package/dist/web/public/assets/confirm-dialog-gPKJnvEW.js +0 -2
- package/dist/web/public/assets/health-wqCp-K_o.js +0 -2
- package/dist/web/public/assets/hot-B-CMjQIr.js +0 -12
- package/dist/web/public/assets/index-DHh1LYlA.js +0 -209
- package/dist/web/public/assets/index-DHh1LYlA.js.map +0 -1
- package/dist/web/public/assets/index-DknVjPYB.css +0 -1
- package/dist/web/public/assets/installed-Cet-1M2Q.js.map +0 -1
- package/dist/web/public/assets/jobs-CfEzOOAC.js +0 -2
- package/dist/web/public/assets/jobs-CfEzOOAC.js.map +0 -1
- package/dist/web/public/assets/layout-BX43KyXM.js +0 -2
- package/dist/web/public/assets/layout-BX43KyXM.js.map +0 -1
- package/dist/web/public/assets/layout-BcYZlaqf.js +0 -2
- package/dist/web/public/assets/layout-BcYZlaqf.js.map +0 -1
- package/dist/web/public/assets/layout-Cb7looUv.js +0 -2
- package/dist/web/public/assets/layout-Cb7looUv.js.map +0 -1
- package/dist/web/public/assets/layout-D7xH78OU.js +0 -2
- package/dist/web/public/assets/layout-D7xH78OU.js.map +0 -1
- package/dist/web/public/assets/llm-BZ9qqp-D.js +0 -27
- package/dist/web/public/assets/llm-BZ9qqp-D.js.map +0 -1
- package/dist/web/public/assets/loader-circle-DgdBWYl0.js +0 -7
- package/dist/web/public/assets/memos-BBtqFcoH.js +0 -12
- package/dist/web/public/assets/memos-BBtqFcoH.js.map +0 -1
- package/dist/web/public/assets/messengers-i7WvNT3o.js +0 -2
- package/dist/web/public/assets/messengers-i7WvNT3o.js.map +0 -1
- package/dist/web/public/assets/outbox-BbfC5kuG.js +0 -7
- package/dist/web/public/assets/outbox-BbfC5kuG.js.map +0 -1
- package/dist/web/public/assets/persona-BvtcZh6G.js +0 -2
- package/dist/web/public/assets/plans-i3a6lrqF.js.map +0 -1
- package/dist/web/public/assets/policy-Cm88P8LO.js +0 -2
- package/dist/web/public/assets/schedules-DzwDWykc.js +0 -7
- package/dist/web/public/assets/schedules-DzwDWykc.js.map +0 -1
- package/dist/web/public/assets/security-BIcnUrAs.js +0 -2
- package/dist/web/public/assets/security-BIcnUrAs.js.map +0 -1
- package/dist/web/public/assets/service-CnorFHzZ.js +0 -7
- package/dist/web/public/assets/service-CnorFHzZ.js.map +0 -1
- package/dist/web/public/assets/use-background-tasks-D1--hHjp.js +0 -2
- package/dist/web/public/assets/use-memory-Bz1Zao7g.js +0 -2
- package/dist/web/public/assets/use-observability-DtqSWVjM.js +0 -2
- package/dist/web/public/assets/use-settings-DKbDqCEJ.js +0 -2
- package/dist/web/public/assets/use-settings-DKbDqCEJ.js.map +0 -1
- package/dist/web/public/assets/use-workspace-CConjEx0.js +0 -2
- package/dist/web/public/assets/vector-D8sEa2W-.js +0 -2
- package/dist/web/public/assets/vector-D8sEa2W-.js.map +0 -1
- package/dist/web/public/assets/viewer-aSIjAKVA.js +0 -12
- package/dist/web/public/assets/viewer-aSIjAKVA.js.map +0 -1
- package/dist/web/public/assets/workspace-BqwWoinI.js +0 -17
- package/dist/web/public/assets/workspace-BqwWoinI.js.map +0 -1
- package/dist/web/public/assets/workspaces-ChsJcrav.js +0 -7
- package/dist/web/public/assets/workspaces-ChsJcrav.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network
|
|
1
|
+
{"version":3,"file":"network-BUeWK3bs.js","sources":["../../node_modules/lucide-react/dist/esm/icons/network.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Network = createLucideIcon(\"Network\", [\n [\"rect\", { x: \"16\", y: \"16\", width: \"6\", height: \"6\", rx: \"1\", key: \"4q2zg0\" }],\n [\"rect\", { x: \"2\", y: \"16\", width: \"6\", height: \"6\", rx: \"1\", key: \"8cvhb9\" }],\n [\"rect\", { x: \"9\", y: \"2\", width: \"6\", height: \"6\", rx: \"1\", key: \"1egb70\" }],\n [\"path\", { d: \"M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3\", key: \"1jsf9p\" }],\n [\"path\", { d: \"M12 12V8\", key: \"2874zd\" }]\n]);\n\nexport { Network as default };\n//# sourceMappingURL=network.js.map\n"],"names":["Network","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAUC,EAAiB,UAAW,CAC1C,CAAC,OAAQ,CAAE,EAAG,KAAM,EAAG,KAAM,MAAO,IAAK,OAAQ,IAAK,GAAI,IAAK,IAAK,QAAQ,CAAE,EAC9E,CAAC,OAAQ,CAAE,EAAG,IAAK,EAAG,KAAM,MAAO,IAAK,OAAQ,IAAK,GAAI,IAAK,IAAK,QAAQ,CAAE,EAC7E,CAAC,OAAQ,CAAE,EAAG,IAAK,EAAG,IAAK,MAAO,IAAK,OAAQ,IAAK,GAAI,IAAK,IAAK,QAAQ,CAAE,EAC5E,CAAC,OAAQ,CAAE,EAAG,4CAA6C,IAAK,QAAQ,CAAE,EAC1E,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,CAC3C,CAAC","x_google_ignoreList":[0]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{u as k,i as T,j as e,e as b,R as E,w as g,k as I,l as P,m as D,n as L,o as j,I as A,p as N,q as M,f as V}from"./index-DCfdN5R7.js";import{r as v}from"./react-DlP5eolq.js";import{D as F}from"./data-table-BkUshOZz.js";import{E as z}from"./empty-state-CuiqdZiB.js";import{S as B}from"./status-badge-CyLdpsXq.js";import{C as J}from"./confirm-dialog-BDb0NLny.js";import{a as Q,u as U,b as $,I as q}from"./use-outbox-DT_XWB_7.js";import{L as Y}from"./loader-circle-DDdmcH0k.js";import{R as G}from"./refresh-ccw-DlAd-eTQ.js";import"./table-sCMZBe_Z.js";import"./arrow-up-Dm0U4-6U.js";import"./arrow-down-7i0xwCI2.js";const H=["pending","delivered","giving_up"];function me(){const{t:s}=k(["tasks","common"]),[a,r]=T(),l=a.get("status")??null,o=a.get("thread")??"",{data:y,isLoading:C,isFetching:u,refetch:_}=Q({...l?{status:l}:{},...o?{thread:o}:{},limit:200}),S=y?.rows??[],n=U().data,c=$(),[d,h]=v.useState(null);function p(t){const i=new URLSearchParams(a);for(const[f,m]of Object.entries(t))m==null||m===""?i.delete(f):i.set(f,m);r(i,{replace:!0})}async function O(){if(d!=null)try{await c.mutateAsync(d),N.success(s("states.saved",{ns:"common"}))}catch(t){const{message:i}=M(t,s);throw N.error(i),t}}const R=v.useMemo(()=>[{id:"id",header:s("outbox.col.id"),cell:t=>e.jsxs("span",{className:"tabular-nums text-text-dim",children:["#",t.id]}),headClassName:"w-20"},{id:"status",header:s("outbox.col.status"),cell:t=>e.jsx(B,{status:t.status,children:s(`outbox.status.${t.status}`,{defaultValue:t.status})}),headClassName:"w-28"},{id:"platform",header:s("outbox.col.platform"),cell:t=>e.jsx("span",{className:"font-medium",children:t.platform}),headClassName:"w-28"},{id:"preview",header:s("outbox.col.preview"),cell:t=>e.jsx("span",{className:"line-clamp-2 text-text",title:t.payload,children:W(t.payload,t.kind)}),asCardTitle:!0},{id:"thread",header:s("outbox.col.thread"),cell:t=>e.jsx("span",{className:"font-mono text-xs text-text-dim line-clamp-1",title:t.thread_key,children:t.thread_key}),headClassName:"w-44",hideOnMobile:!0},{id:"kind",header:s("outbox.col.kind"),cell:t=>e.jsx("span",{className:"text-text-dim",children:t.kind}),headClassName:"w-20",hideOnMobile:!0},{id:"attempts",header:s("outbox.col.attempts"),cell:t=>e.jsx("span",{className:"tabular-nums",children:t.attempts}),headClassName:"w-20"},{id:"createdAt",header:s("outbox.col.createdAt"),cell:t=>e.jsx("span",{className:"text-text-dim",children:w(t.created_at)}),headClassName:"w-32",hideOnMobile:!0},{id:"lastError",header:s("outbox.col.lastError"),cell:t=>t.last_error?e.jsx("span",{className:"line-clamp-1 text-danger text-xs",title:t.last_error,children:t.last_error}):e.jsx("span",{className:"text-text-muted",children:"—"}),hideOnMobile:!1},{id:"actions",header:"",cell:t=>t.status==="giving_up"?e.jsxs(b,{variant:"outline",size:"sm",onClick:i=>{i.stopPropagation(),h(t.id)},disabled:c.isPending,children:[e.jsx(E,{className:"h-3 w-3"}),s("outbox.action.retry")]}):null,headClassName:"w-28"}],[s,c.isPending]);return e.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("outbox.title")}),e.jsxs(b,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>_(),disabled:u,"aria-label":s("actions.refresh",{ns:"common"}),children:[u?e.jsx(Y,{className:"h-4 w-4 animate-spin"}):e.jsx(G,{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("outbox.subtitle")})]}),n&&e.jsxs("div",{className:"grid grid-cols-2 gap-2 sm:grid-cols-4",children:[e.jsx(x,{label:s("outbox.stats.pending"),value:n.pending,tone:"info"}),e.jsx(x,{label:s("outbox.stats.giving_up"),value:n.giving_up,tone:"danger"}),e.jsx(x,{label:s("outbox.stats.delivered"),value:n.delivered,tone:"success"}),e.jsxs("div",{className:"rounded-md border border-border bg-surface px-3 py-2",children:[e.jsx("div",{className:"text-xs uppercase tracking-wide text-text-dim",children:s("outbox.stats.lastDelivered")}),e.jsx("div",{className:"text-sm font-medium tabular-nums",children:n.lastDeliveredAt?w(n.lastDeliveredAt):"—"})]})]}),e.jsxs("div",{className:"flex flex-wrap items-end gap-2",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(g,{htmlFor:"status-filter",className:"text-xs text-text-dim",children:s("outbox.filter.status")}),e.jsxs(I,{value:l??"__any__",onValueChange:t=>p({status:t==="__any__"?null:t}),children:[e.jsx(P,{id:"status-filter",className:"w-[160px]",children:e.jsx(D,{})}),e.jsxs(L,{children:[e.jsx(j,{value:"__any__",children:s("outbox.filter.statusAny")}),H.map(t=>e.jsx(j,{value:t,children:s(`outbox.status.${t}`,{defaultValue:t})},t))]})]})]}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(g,{htmlFor:"thread-filter",className:"text-xs text-text-dim",children:s("outbox.filter.thread")}),e.jsx(A,{id:"thread-filter",value:o,onChange:t=>p({thread:t.target.value}),placeholder:"wechat:room:...",className:"w-72 font-mono text-xs"})]})]}),e.jsx(F,{columns:R,rows:S,getRowId:t=>String(t.id),loading:C,emptyState:e.jsx(z,{icon:e.jsx(q,{}),title:s("outbox.empty.title"),description:s("outbox.empty.description")})}),e.jsx(J,{open:d!=null,onOpenChange:t=>{t||h(null)},title:s("outbox.action.confirmRetry"),description:s("outbox.action.confirmRetryDesc"),confirmLabel:s("outbox.action.retry"),onConfirm:O})]})}const K={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 x({label:s,value:a,tone:r}){return e.jsxs("div",{className:V("rounded-md border bg-surface px-3 py-2",K[r]),children:[e.jsx("div",{className:"text-xs uppercase tracking-wide text-text-dim",children:s}),e.jsx("div",{className:"text-2xl font-semibold tabular-nums",children:a})]})}function W(s,a){if(!s)return"—";if(a==="text")return s;try{const r=JSON.parse(s),l=r.text??r.message??r.title??r.body??null;return typeof l=="string"&&l.length>0?l:JSON.stringify(r)}catch{return s}}function w(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}}export{me as default};
|
|
2
|
+
//# sourceMappingURL=outbox-CEE0rwN3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbox-CEE0rwN3.js","sources":["../../src/routes/tasks/outbox.tsx"],"sourcesContent":["/**\n * /tasks/outbox — IM-platform delivery queue. Read-mostly; the one\n * mutation is \"retry\" on rows stuck in `giving_up`. Per-row action\n * routes through ConfirmDialog so an accidental click doesn't re-\n * fire a possibly-flaky delivery against the user's IM channel.\n */\n\nimport { useMemo, useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Inbox, Loader2, RefreshCcw, RotateCcw } from 'lucide-react'\n\nimport { DataTable, type DataTableColumn } from '@/components/common/data-table'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { StatusBadge } from '@/components/common/status-badge'\nimport { ConfirmDialog } from '@/components/common/confirm-dialog'\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 {\n useOutbox,\n useOutboxStats,\n useRetryOutbox,\n} from '@/hooks/use-outbox'\nimport type { OutboxRow, OutboxStatus } from '@/types/api'\nimport { describeError } from '@/lib/api/errors'\nimport { cn } from '@/lib/utils'\n\nconst STATUS_OPTIONS: OutboxStatus[] = ['pending', 'delivered', 'giving_up']\n\nexport default function OutboxRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const [params, setParams] = useSearchParams()\n const status = (params.get('status') as OutboxStatus | null) ?? null\n const thread = params.get('thread') ?? ''\n\n const { data, isLoading, isFetching, refetch } = useOutbox({\n ...(status ? { status } : {}),\n ...(thread ? { thread } : {}),\n limit: 200,\n })\n const rows = data?.rows ?? []\n const statsQuery = useOutboxStats()\n const stats = statsQuery.data\n\n const retryMut = useRetryOutbox()\n const [confirmRetryId, setConfirmRetryId] = useState<number | null>(null)\n\n function patchParams(patch: Record<string, string | null>): void {\n const next = new URLSearchParams(params)\n for (const [k, v] of Object.entries(patch)) {\n if (v == null || v === '') next.delete(k)\n else next.set(k, v)\n }\n setParams(next, { replace: true })\n }\n\n async function onConfirmRetry(): Promise<void> {\n if (confirmRetryId == null) return\n try {\n await retryMut.mutateAsync(confirmRetryId)\n toast.success(t('states.saved', { ns: 'common' }))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n throw err\n }\n }\n\n const columns: DataTableColumn<OutboxRow>[] = useMemo(\n () => [\n {\n id: 'id',\n header: t('outbox.col.id'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">#{r.id}</span>,\n headClassName: 'w-20',\n },\n {\n id: 'status',\n header: t('outbox.col.status'),\n cell: (r) => (\n <StatusBadge status={r.status}>\n {t(`outbox.status.${r.status}`, { defaultValue: r.status })}\n </StatusBadge>\n ),\n headClassName: 'w-28',\n },\n {\n id: 'platform',\n header: t('outbox.col.platform'),\n cell: (r) => <span className=\"font-medium\">{r.platform}</span>,\n headClassName: 'w-28',\n },\n {\n id: 'preview',\n header: t('outbox.col.preview'),\n cell: (r) => (\n <span\n className=\"line-clamp-2 text-text\"\n title={r.payload}\n >\n {previewPayload(r.payload, r.kind)}\n </span>\n ),\n asCardTitle: true,\n },\n {\n id: 'thread',\n header: t('outbox.col.thread'),\n cell: (r) => (\n <span\n className=\"font-mono text-xs text-text-dim line-clamp-1\"\n title={r.thread_key}\n >\n {r.thread_key}\n </span>\n ),\n headClassName: 'w-44',\n hideOnMobile: true,\n },\n {\n id: 'kind',\n header: t('outbox.col.kind'),\n cell: (r) => <span className=\"text-text-dim\">{r.kind}</span>,\n headClassName: 'w-20',\n hideOnMobile: true,\n },\n {\n id: 'attempts',\n header: t('outbox.col.attempts'),\n cell: (r) => <span className=\"tabular-nums\">{r.attempts}</span>,\n headClassName: 'w-20',\n },\n {\n id: 'createdAt',\n header: t('outbox.col.createdAt'),\n cell: (r) => <span className=\"text-text-dim\">{formatTime(r.created_at)}</span>,\n headClassName: 'w-32',\n hideOnMobile: true,\n },\n {\n id: 'lastError',\n header: t('outbox.col.lastError'),\n cell: (r) =>\n r.last_error ? (\n <span className=\"line-clamp-1 text-danger text-xs\" title={r.last_error}>\n {r.last_error}\n </span>\n ) : (\n <span className=\"text-text-muted\">—</span>\n ),\n hideOnMobile: false,\n },\n {\n id: 'actions',\n header: '',\n cell: (r) =>\n r.status === 'giving_up' ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation()\n setConfirmRetryId(r.id)\n }}\n disabled={retryMut.isPending}\n >\n <RotateCcw className=\"h-3 w-3\" />\n {t('outbox.action.retry')}\n </Button>\n ) : null,\n headClassName: 'w-28',\n },\n ],\n [t, retryMut.isPending],\n )\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('outbox.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('outbox.subtitle')}</p>\n </header>\n\n {/* Stats strip */}\n {stats && (\n <div className=\"grid grid-cols-2 gap-2 sm:grid-cols-4\">\n <StatCard label={t('outbox.stats.pending')} value={stats.pending} tone=\"info\" />\n <StatCard label={t('outbox.stats.giving_up')} value={stats.giving_up} tone=\"danger\" />\n <StatCard label={t('outbox.stats.delivered')} value={stats.delivered} tone=\"success\" />\n <div className=\"rounded-md border border-border bg-surface px-3 py-2\">\n <div className=\"text-xs uppercase tracking-wide text-text-dim\">\n {t('outbox.stats.lastDelivered')}\n </div>\n <div className=\"text-sm font-medium tabular-nums\">\n {stats.lastDeliveredAt ? formatTime(stats.lastDeliveredAt) : '—'}\n </div>\n </div>\n </div>\n )}\n\n {/* Filter row */}\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"status-filter\" className=\"text-xs text-text-dim\">\n {t('outbox.filter.status')}\n </Label>\n <Select\n value={status ?? '__any__'}\n onValueChange={(v) => patchParams({ status: v === '__any__' ? null : v })}\n >\n <SelectTrigger id=\"status-filter\" className=\"w-[160px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__any__\">{t('outbox.filter.statusAny')}</SelectItem>\n {STATUS_OPTIONS.map((s) => (\n <SelectItem key={s} value={s}>\n {t(`outbox.status.${s}`, { defaultValue: s })}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"thread-filter\" className=\"text-xs text-text-dim\">\n {t('outbox.filter.thread')}\n </Label>\n <Input\n id=\"thread-filter\"\n value={thread}\n onChange={(e) => patchParams({ thread: e.target.value })}\n placeholder=\"wechat:room:...\"\n className=\"w-72 font-mono text-xs\"\n />\n </div>\n </div>\n\n <DataTable\n columns={columns}\n rows={rows}\n getRowId={(r) => String(r.id)}\n loading={isLoading}\n emptyState={\n <EmptyState\n icon={<Inbox />}\n title={t('outbox.empty.title')}\n description={t('outbox.empty.description')}\n />\n }\n />\n\n <ConfirmDialog\n open={confirmRetryId != null}\n onOpenChange={(open) => {\n if (!open) setConfirmRetryId(null)\n }}\n title={t('outbox.action.confirmRetry')}\n description={t('outbox.action.confirmRetryDesc')}\n confirmLabel={t('outbox.action.retry')}\n onConfirm={onConfirmRetry}\n />\n </div>\n )\n}\n\ninterface StatCardProps {\n label: string\n value: number\n tone: 'info' | 'success' | 'warning' | 'danger'\n}\n\nconst TONE_STYLES: Record<StatCardProps['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 StatCard({ label, value, tone }: StatCardProps): JSX.Element {\n return (\n <div\n className={cn(\n 'rounded-md border bg-surface px-3 py-2',\n TONE_STYLES[tone],\n )}\n >\n <div className=\"text-xs uppercase tracking-wide text-text-dim\">{label}</div>\n <div className=\"text-2xl font-semibold tabular-nums\">{value}</div>\n </div>\n )\n}\n\n/** Render a one-line preview of an outbox row's payload.\n *\n * Card payloads are JSON encoded by the agent. We pluck the most\n * likely \"message\" field if we can parse it; otherwise we fall back\n * to the raw string. Text payloads are returned as-is, truncated\n * by the surrounding `line-clamp-2`. */\nfunction previewPayload(payload: string, kind: string): string {\n if (!payload) return '—'\n if (kind === 'text') return payload\n try {\n const parsed = JSON.parse(payload) as Record<string, unknown>\n const text = (parsed.text ?? parsed.message ?? parsed.title ?? parsed.body ?? null) as string | null\n if (typeof text === 'string' && text.length > 0) return text\n // Fallback: serialise the object compactly so the operator still\n // sees something useful.\n return JSON.stringify(parsed)\n } catch {\n return payload\n }\n}\n\nfunction formatTime(iso: string | null): string {\n if (iso == null) return '—'\n try {\n const d = new Date(iso)\n if (Number.isNaN(d.getTime())) return iso\n return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n } catch {\n return iso\n }\n}\n"],"names":["STATUS_OPTIONS","OutboxRoute","t","useTranslation","params","setParams","useSearchParams","status","thread","data","isLoading","isFetching","refetch","useOutbox","rows","stats","useOutboxStats","retryMut","useRetryOutbox","confirmRetryId","setConfirmRetryId","useState","patchParams","patch","next","k","v","onConfirmRetry","toast","err","message","describeError","columns","useMemo","r","jsxs","StatusBadge","jsx","previewPayload","formatTime","Button","e","RotateCcw","Loader2","RefreshCcw","StatCard","Label","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","s","Input","DataTable","EmptyState","Inbox","ConfirmDialog","open","TONE_STYLES","label","value","tone","cn","payload","kind","parsed","text","iso","d"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import{h as N,u as O,j as e,z as R,C as B,d as F,e as x,f as m,L as g}from"./index-DCfdN5R7.js";import{u as H,a as I}from"./use-agim-skills-BbuJP3NT.js";import{u as E,F as b}from"./use-skills-D2bMM580.js";import{B as p}from"./book-open-CSCq5cjL.js";import{R as T}from"./refresh-ccw-DlAd-eTQ.js";import{A as u}from"./arrow-right-A889Wof8.js";import"./react-DlP5eolq.js";/**
|
|
2
|
+
* @license lucide-react v0.469.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const _=N("Puzzle",[["path",{d:"M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z",key:"w46dr5"}]]);/**
|
|
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 Q=N("WandSparkles",[["path",{d:"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72",key:"ul74o6"}],["path",{d:"m14 7 3 3",key:"1r5n42"}],["path",{d:"M5 6v4",key:"ilb8ba"}],["path",{d:"M19 14v4",key:"blhpug"}],["path",{d:"M10 2v2",key:"7u0qdc"}],["path",{d:"M7 8H3",key:"zfb6yr"}],["path",{d:"M21 16h-4",key:"1cnmox"}],["path",{d:"M11 3H9",key:"1obp7u"}]]),S={success:"text-success",warning:"text-warning",danger:"text-danger",info:"text-info",default:"text-text-dim"},s="/settings/agim-skills";function X(){const{t:i}=O("settings"),a=H(),l=E(),n=I(),r=a.data?.skills??[],k=r.filter(t=>t.source==="workspace").length,y=r.filter(t=>t.source==="builtin").length,o=r.filter(t=>!t.available).length,C=r.filter(t=>t.always).length,c=l.data?.skills.length??0,w=!!l.data?.stale,j=l.isError||w,d=!!n.data?.overrideActive,L=n.data?.autoChars??n.data?.auto?.length??0,$=n.data?.overrideChars??n.data?.override?.length??0,f=a.isFetching||l.isFetching||n.isFetching,h=o+(j?1:0),v=D({t:i,skillCount:r.length,workspaceCount:k,unavailableCount:o,hotCount:c,overrideActive:d}),A=[{id:"installed",title:i("agimSkills.overview.cards.installed.title"),value:a.isLoading?"-":r.length,detail:i("agimSkills.overview.cards.installed.detail",{workspace:k,builtin:y}),to:`${s}/installed`,action:i("agimSkills.overview.cards.installed.action"),tone:r.length>0?"info":"default",icon:e.jsx(p,{})},{id:"availability",title:i("agimSkills.overview.cards.availability.title"),value:a.isLoading?"-":o,detail:o>0?i("agimSkills.overview.cards.availability.missing",{count:o}):i("agimSkills.overview.cards.availability.ready"),to:`${s}/installed`,action:i("agimSkills.overview.cards.availability.action"),tone:o>0?"danger":"success",icon:o>0?e.jsx(R,{}):e.jsx(B,{})},{id:"hot",title:i("agimSkills.overview.cards.hot.title"),value:l.isLoading?"-":c,detail:l.isError?i("agimSkills.overview.cards.hot.error"):w?i("agimSkills.overview.cards.hot.stale"):i("agimSkills.overview.cards.hot.ready",{count:c}),to:`${s}/hot`,action:i("agimSkills.overview.cards.hot.action"),tone:j?"warning":c>0?"info":"default",icon:e.jsx(b,{})},{id:"injection",title:i("agimSkills.overview.cards.injection.title"),value:i(d?"agimSkills.overview.cards.injection.overrideValue":"agimSkills.overview.cards.injection.autoValue"),detail:d?i("agimSkills.overview.cards.injection.overrideDetail",{chars:$.toLocaleString()}):i("agimSkills.overview.cards.injection.autoDetail",{chars:L.toLocaleString(),always:C}),to:`${s}/injection`,action:i("agimSkills.overview.cards.injection.action"),tone:d?"warning":"success",icon:e.jsx(Q,{})}];return e.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-3 border-b border-border pb-4 sm:flex-row sm:items-end",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("h1",{className:"text-xl font-semibold",children:i("agimSkills.overview.title")}),e.jsx(F,{variant:h>0?"warning":"success",children:h>0?i("agimSkills.overview.needsAttention",{count:h}):i("agimSkills.overview.ready")})]}),e.jsx("p",{className:"mt-1 max-w-2xl text-sm text-text-dim",children:i("agimSkills.overview.subtitle")})]}),e.jsxs(x,{type:"button",variant:"ghost",size:"sm",disabled:f,onClick:()=>{a.refetch(),l.refetch(),n.refetch()},children:[e.jsx(T,{className:m("h-4 w-4",f&&"animate-spin")}),e.jsx("span",{children:i("agimSkills.overview.refresh")})]})]}),e.jsx("section",{className:"grid gap-3 md:grid-cols-2 xl:grid-cols-4",children:A.map(t=>e.jsx(U,{card:t},t.id))}),e.jsxs("section",{className:"grid gap-4 lg:grid-cols-[minmax(0,1.1fr)_minmax(300px,0.9fr)]",children:[e.jsxs(g,{to:v.to,className:m("group flex min-h-24 items-center gap-3 rounded-md border border-accent bg-accent-bg/45 p-4 no-underline","hover:bg-accent-bg"),children:[e.jsx("span",{className:"flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-accent text-accent-fg",children:e.jsx(u,{className:"h-5 w-5"})}),e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsx("span",{className:"block text-sm font-semibold text-text",children:v.title}),e.jsx("span",{className:"mt-1 block text-sm text-text-dim",children:v.detail})]}),e.jsx(u,{className:"h-4 w-4 shrink-0 text-text-dim transition-transform group-hover:translate-x-0.5"})]}),e.jsxs("section",{className:"rounded-md border border-border bg-surface p-4",children:[e.jsx("h2",{className:"text-sm font-semibold",children:i("agimSkills.overview.views.title")}),e.jsx("div",{className:"mt-3 grid grid-cols-1 gap-2 sm:grid-cols-3 lg:grid-cols-1",children:[["installed",`${s}/installed`,e.jsx(p,{className:"h-4 w-4"})],["hot",`${s}/hot`,e.jsx(b,{className:"h-4 w-4"})],["injection",`${s}/injection`,e.jsx(_,{className:"h-4 w-4"})]].map(([t,z,M])=>e.jsx(x,{asChild:!0,variant:"secondary",size:"sm",children:e.jsxs(g,{to:z,children:[M,e.jsx("span",{children:i(`agimSkills.tab.${t}`)})]})},t))})]})]})]})}function U({card:i}){return e.jsxs("article",{className:"rounded-md border border-border bg-surface p-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsx("span",{className:m("flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-surface-2",S[i.tone],"[&_svg]:h-4 [&_svg]:w-4"),"aria-hidden":"true",children:i.icon}),e.jsx("span",{className:m("text-2xl font-semibold tabular-nums",S[i.tone]),children:i.value})]}),e.jsx("h2",{className:"mt-3 text-sm font-semibold",children:i.title}),e.jsx("p",{className:"mt-1 min-h-10 text-sm text-text-dim",children:i.detail}),e.jsx(x,{asChild:!0,variant:"ghost",size:"sm",className:"mt-2",children:e.jsxs(g,{to:i.to,children:[e.jsx("span",{children:i.action}),e.jsx(u,{className:"h-4 w-4"})]})})]})}function D(i){const a=i.unavailableCount>0?"fixUnavailable":i.skillCount===0?"createSkill":i.workspaceCount===0&&i.hotCount>0?"browseHot":i.overrideActive?"reviewOverride":"manageInstalled",l={fixUnavailable:`${s}/installed`,browseHot:`${s}/hot`,reviewOverride:`${s}/injection`,manageInstalled:`${s}/installed`,createSkill:`${s}/installed`};return{id:a,to:l[a],title:i.t(`agimSkills.overview.next.${a}.title`),detail:i.t(`agimSkills.overview.next.${a}.detail`)}}export{X as default};
|
|
12
|
+
//# sourceMappingURL=overview-BSOZ5gTD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overview-BSOZ5gTD.js","sources":["../../node_modules/lucide-react/dist/esm/icons/puzzle.js","../../node_modules/lucide-react/dist/esm/icons/wand-sparkles.js","../../src/routes/settings/agim-skills/overview.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 Puzzle = createLucideIcon(\"Puzzle\", [\n [\n \"path\",\n {\n d: \"M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z\",\n key: \"w46dr5\"\n }\n ]\n]);\n\nexport { Puzzle as default };\n//# sourceMappingURL=puzzle.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst WandSparkles = createLucideIcon(\"WandSparkles\", [\n [\n \"path\",\n {\n d: \"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72\",\n key: \"ul74o6\"\n }\n ],\n [\"path\", { d: \"m14 7 3 3\", key: \"1r5n42\" }],\n [\"path\", { d: \"M5 6v4\", key: \"ilb8ba\" }],\n [\"path\", { d: \"M19 14v4\", key: \"blhpug\" }],\n [\"path\", { d: \"M10 2v2\", key: \"7u0qdc\" }],\n [\"path\", { d: \"M7 8H3\", key: \"zfb6yr\" }],\n [\"path\", { d: \"M21 16h-4\", key: \"1cnmox\" }],\n [\"path\", { d: \"M11 3H9\", key: \"1obp7u\" }]\n]);\n\nexport { WandSparkles as default };\n//# sourceMappingURL=wand-sparkles.js.map\n","/**\n * /settings/agim-skills — overview surface.\n *\n * The installed / hot / injection pages stay as the source of truth.\n * This entry point answers the first operator question: \"is Skills\n * ready, and where should I click next?\"\n */\n\nimport { Link } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport {\n AlertTriangle,\n ArrowRight,\n BookOpen,\n CheckCircle2,\n Flame,\n Puzzle,\n RefreshCcw,\n Wand2,\n} from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { useAgimSkillsList, useSkillInjection } from '@/hooks/use-agim-skills'\nimport { useSkillsRemoteHot } from '@/hooks/use-skills'\nimport { cn } from '@/lib/utils'\n\ntype CardTone = 'success' | 'warning' | 'danger' | 'info' | 'default'\ntype NextActionId = 'fixUnavailable' | 'browseHot' | 'reviewOverride' | 'manageInstalled' | 'createSkill'\n\ninterface MetricCard {\n id: string\n title: string\n value: string | number\n detail: string\n to: string\n action: string\n tone: CardTone\n icon: JSX.Element\n}\n\ninterface NextAction {\n id: NextActionId\n to: string\n title: string\n detail: string\n}\n\nconst TONE_CLASS: Record<CardTone, string> = {\n success: 'text-success',\n warning: 'text-warning',\n danger: 'text-danger',\n info: 'text-info',\n default: 'text-text-dim',\n}\n\nconst ROOT = '/settings/agim-skills'\n\nexport default function AgimSkillsOverviewRoute(): JSX.Element {\n const { t } = useTranslation('settings')\n const skillsQuery = useAgimSkillsList()\n const hotQuery = useSkillsRemoteHot()\n const injectionQuery = useSkillInjection()\n\n const skills = skillsQuery.data?.skills ?? []\n const workspaceCount = skills.filter((s) => s.source === 'workspace').length\n const builtinCount = skills.filter((s) => s.source === 'builtin').length\n const unavailableCount = skills.filter((s) => !s.available).length\n const alwaysOnCount = skills.filter((s) => s.always).length\n const hotCount = hotQuery.data?.skills.length ?? 0\n const hotStale = Boolean(hotQuery.data?.stale)\n const hotUnavailable = hotQuery.isError || hotStale\n const overrideActive = Boolean(injectionQuery.data?.overrideActive)\n const autoChars = injectionQuery.data?.autoChars ?? injectionQuery.data?.auto?.length ?? 0\n const overrideChars = injectionQuery.data?.overrideChars ?? injectionQuery.data?.override?.length ?? 0\n const anyFetching = skillsQuery.isFetching || hotQuery.isFetching || injectionQuery.isFetching\n const needsAttention = unavailableCount + (hotUnavailable ? 1 : 0)\n\n const nextAction = pickNextAction({\n t,\n skillCount: skills.length,\n workspaceCount,\n unavailableCount,\n hotCount,\n overrideActive,\n })\n\n const cards: MetricCard[] = [\n {\n id: 'installed',\n title: t('agimSkills.overview.cards.installed.title'),\n value: skillsQuery.isLoading ? '-' : skills.length,\n detail: t('agimSkills.overview.cards.installed.detail', {\n workspace: workspaceCount,\n builtin: builtinCount,\n }),\n to: `${ROOT}/installed`,\n action: t('agimSkills.overview.cards.installed.action'),\n tone: skills.length > 0 ? 'info' : 'default',\n icon: <BookOpen />,\n },\n {\n id: 'availability',\n title: t('agimSkills.overview.cards.availability.title'),\n value: skillsQuery.isLoading ? '-' : unavailableCount,\n detail: unavailableCount > 0\n ? t('agimSkills.overview.cards.availability.missing', { count: unavailableCount })\n : t('agimSkills.overview.cards.availability.ready'),\n to: `${ROOT}/installed`,\n action: t('agimSkills.overview.cards.availability.action'),\n tone: unavailableCount > 0 ? 'danger' : 'success',\n icon: unavailableCount > 0 ? <AlertTriangle /> : <CheckCircle2 />,\n },\n {\n id: 'hot',\n title: t('agimSkills.overview.cards.hot.title'),\n value: hotQuery.isLoading ? '-' : hotCount,\n detail: hotQuery.isError\n ? t('agimSkills.overview.cards.hot.error')\n : hotStale\n ? t('agimSkills.overview.cards.hot.stale')\n : t('agimSkills.overview.cards.hot.ready', { count: hotCount }),\n to: `${ROOT}/hot`,\n action: t('agimSkills.overview.cards.hot.action'),\n tone: hotUnavailable ? 'warning' : hotCount > 0 ? 'info' : 'default',\n icon: <Flame />,\n },\n {\n id: 'injection',\n title: t('agimSkills.overview.cards.injection.title'),\n value: overrideActive\n ? t('agimSkills.overview.cards.injection.overrideValue')\n : t('agimSkills.overview.cards.injection.autoValue'),\n detail: overrideActive\n ? t('agimSkills.overview.cards.injection.overrideDetail', { chars: overrideChars.toLocaleString() })\n : t('agimSkills.overview.cards.injection.autoDetail', {\n chars: autoChars.toLocaleString(),\n always: alwaysOnCount,\n }),\n to: `${ROOT}/injection`,\n action: t('agimSkills.overview.cards.injection.action'),\n tone: overrideActive ? 'warning' : 'success',\n icon: <Wand2 />,\n },\n ]\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-3 border-b border-border pb-4 sm:flex-row sm:items-end\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h1 className=\"text-xl font-semibold\">{t('agimSkills.overview.title')}</h1>\n <Badge variant={needsAttention > 0 ? 'warning' : 'success'}>\n {needsAttention > 0\n ? t('agimSkills.overview.needsAttention', { count: needsAttention })\n : t('agimSkills.overview.ready')}\n </Badge>\n </div>\n <p className=\"mt-1 max-w-2xl text-sm text-text-dim\">{t('agimSkills.overview.subtitle')}</p>\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={anyFetching}\n onClick={() => {\n void skillsQuery.refetch()\n void hotQuery.refetch()\n void injectionQuery.refetch()\n }}\n >\n <RefreshCcw className={cn('h-4 w-4', anyFetching && 'animate-spin')} />\n <span>{t('agimSkills.overview.refresh')}</span>\n </Button>\n </header>\n\n <section className=\"grid gap-3 md:grid-cols-2 xl:grid-cols-4\">\n {cards.map((card) => (\n <MetricCardItem key={card.id} card={card} />\n ))}\n </section>\n\n <section className=\"grid gap-4 lg:grid-cols-[minmax(0,1.1fr)_minmax(300px,0.9fr)]\">\n <Link\n to={nextAction.to}\n className={cn(\n 'group flex min-h-24 items-center gap-3 rounded-md border border-accent bg-accent-bg/45 p-4 no-underline',\n 'hover:bg-accent-bg',\n )}\n >\n <span className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-accent text-accent-fg\">\n <ArrowRight className=\"h-5 w-5\" />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block text-sm font-semibold text-text\">{nextAction.title}</span>\n <span className=\"mt-1 block text-sm text-text-dim\">{nextAction.detail}</span>\n </span>\n <ArrowRight className=\"h-4 w-4 shrink-0 text-text-dim transition-transform group-hover:translate-x-0.5\" />\n </Link>\n\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <h2 className=\"text-sm font-semibold\">{t('agimSkills.overview.views.title')}</h2>\n <div className=\"mt-3 grid grid-cols-1 gap-2 sm:grid-cols-3 lg:grid-cols-1\">\n {([\n ['installed', `${ROOT}/installed`, <BookOpen className=\"h-4 w-4\" />],\n ['hot', `${ROOT}/hot`, <Flame className=\"h-4 w-4\" />],\n ['injection', `${ROOT}/injection`, <Puzzle className=\"h-4 w-4\" />],\n ] satisfies Array<[string, string, JSX.Element]>).map(([id, to, icon]) => (\n <Button key={id} asChild variant=\"secondary\" size=\"sm\">\n <Link to={to}>\n {icon}\n <span>{t(`agimSkills.tab.${id}`)}</span>\n </Link>\n </Button>\n ))}\n </div>\n </section>\n </section>\n </div>\n )\n}\n\nfunction MetricCardItem({ card }: { card: MetricCard }): JSX.Element {\n return (\n <article className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <span\n className={cn(\n 'flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-surface-2',\n TONE_CLASS[card.tone],\n '[&_svg]:h-4 [&_svg]:w-4',\n )}\n aria-hidden=\"true\"\n >\n {card.icon}\n </span>\n <span className={cn('text-2xl font-semibold tabular-nums', TONE_CLASS[card.tone])}>\n {card.value}\n </span>\n </div>\n <h2 className=\"mt-3 text-sm font-semibold\">{card.title}</h2>\n <p className=\"mt-1 min-h-10 text-sm text-text-dim\">{card.detail}</p>\n <Button asChild variant=\"ghost\" size=\"sm\" className=\"mt-2\">\n <Link to={card.to}>\n <span>{card.action}</span>\n <ArrowRight className=\"h-4 w-4\" />\n </Link>\n </Button>\n </article>\n )\n}\n\nfunction pickNextAction(opts: {\n t: ReturnType<typeof useTranslation>['t']\n skillCount: number\n workspaceCount: number\n unavailableCount: number\n hotCount: number\n overrideActive: boolean\n}): NextAction {\n const id: NextActionId = opts.unavailableCount > 0\n ? 'fixUnavailable'\n : opts.skillCount === 0\n ? 'createSkill'\n : opts.workspaceCount === 0 && opts.hotCount > 0\n ? 'browseHot'\n : opts.overrideActive\n ? 'reviewOverride'\n : 'manageInstalled'\n\n const to: Record<NextActionId, string> = {\n fixUnavailable: `${ROOT}/installed`,\n browseHot: `${ROOT}/hot`,\n reviewOverride: `${ROOT}/injection`,\n manageInstalled: `${ROOT}/installed`,\n createSkill: `${ROOT}/installed`,\n }\n return {\n id,\n to: to[id],\n title: opts.t(`agimSkills.overview.next.${id}.title`),\n detail: opts.t(`agimSkills.overview.next.${id}.detail`),\n }\n}\n"],"names":["Puzzle","createLucideIcon","WandSparkles","TONE_CLASS","ROOT","AgimSkillsOverviewRoute","t","useTranslation","skillsQuery","useAgimSkillsList","hotQuery","useSkillsRemoteHot","injectionQuery","useSkillInjection","skills","workspaceCount","s","builtinCount","unavailableCount","alwaysOnCount","hotCount","hotStale","hotUnavailable","overrideActive","autoChars","overrideChars","anyFetching","needsAttention","nextAction","pickNextAction","cards","BookOpen","AlertTriangle","CheckCircle2","Flame","Wand2","jsxs","jsx","Badge","Button","RefreshCcw","cn","card","MetricCardItem","Link","ArrowRight","id","to","icon","opts"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import{h as _,u as M,j as s,d as z,e as p,f as d,L as j,C as O}from"./index-DCfdN5R7.js";import{u as T}from"./use-a2a-C98e2Via.js";import{u as $,a as E,b as P}from"./use-background-tasks-CwFmOokw.js";import{u as U}from"./use-jobs-BJjeJ5lh.js";import{u as W,I as q}from"./use-outbox-DT_XWB_7.js";import{u as D,C as K}from"./use-schedules-D4W8fMwo.js";import{C as V}from"./clipboard-list-lnqdk2_J.js";import{R as X}from"./refresh-ccw-DlAd-eTQ.js";import{A as w}from"./arrow-right-A889Wof8.js";import"./react-DlP5eolq.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 Y=_("CircleHelp",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]]);/**
|
|
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 Z=_("Workflow",[["rect",{width:"8",height:"8",x:"3",y:"3",rx:"2",key:"by2w9f"}],["path",{d:"M7 11v4a2 2 0 0 0 2 2h4",key:"xkn7yn"}],["rect",{width:"8",height:"8",x:"13",y:"13",rx:"2",key:"1cgmvn"}]]),R={success:"text-success",warning:"text-warning",danger:"text-danger",info:"text-info",default:"text-text-dim"};function he(){const{t:e}=M("tasks"),a=U({limit:5,offset:0}),n=W(),u=D({}),x=T(),m=$(),r=E(),c=P(),h=a.data?.stats,g=a.data?.jobs??[],N=h?.running??g.filter(t=>t.status==="running").length,y=h?.pending??g.filter(t=>t.status==="pending").length,B=h?.failed??g.filter(t=>t.status==="failed").length,b=N+y,C=n.data,l=C?.pending??0,i=C?.giving_up??0,A=(u.data?.schedules??[]).filter(t=>t.enabled).length,S=(m.data?.bindings??[]).filter(t=>t.enabled).length,F=r.data?.count??r.data?.goals.length??0,o=c.data?.count??c.data?.pending.length??0,L=x.data?.recent24h??0,v=A+S+F,f=o+i+B,Q=a.isFetching||n.isFetching||u.isFetching||x.isFetching||m.isFetching||r.isFetching||c.isFetching,k=se({t:e,pendingAsks:o,outboxGivingUp:i,activeJobs:b,outboxPending:l,automationCount:v}),G=[{id:"work",title:e("overview.cards.work.title"),value:b,detail:e("overview.cards.work.detail",{running:N,pending:y}),to:"/tasks/jobs",action:e("overview.cards.work.action"),tone:b>0?"warning":"success",icon:s.jsx(V,{})},{id:"asks",title:e("overview.cards.asks.title"),value:o,detail:o>0?e("overview.cards.asks.waiting",{count:o}):e("overview.cards.asks.clear"),to:"/tasks/asks",action:e("overview.cards.asks.action"),tone:o>0?"danger":"success",icon:s.jsx(Y,{})},{id:"outbox",title:e("overview.cards.outbox.title"),value:i>0?i:l,detail:i>0?e("overview.cards.outbox.stuck",{count:i}):e("overview.cards.outbox.detail",{pending:l}),to:"/tasks/outbox",action:e("overview.cards.outbox.action"),tone:i>0?"danger":l>0?"warning":"success",icon:s.jsx(q,{})},{id:"automation",title:e("overview.cards.automation.title"),value:v,detail:e("overview.cards.automation.detail",{schedules:A,heartbeats:S,goals:F}),to:"/tasks/schedules",action:e("overview.cards.automation.action"),tone:v>0?"info":"default",icon:s.jsx(K,{})},{id:"a2a",title:e("overview.cards.a2a.title"),value:L,detail:e("overview.cards.a2a.detail"),to:"/tasks/a2a",action:e("overview.cards.a2a.action"),tone:L>0?"info":"default",icon:s.jsx(Z,{})}],H=[{title:e("overview.groups.work"),links:[["jobs","/tasks/jobs"],["subtasks","/tasks/subtasks"],["bgjobs","/tasks/bgjobs"],["outbox","/tasks/outbox"]]},{title:e("overview.groups.automation"),links:[["schedules","/tasks/schedules"],["heartbeat","/tasks/heartbeat"],["goals","/tasks/goals"],["asks","/tasks/asks"]]},{title:e("overview.groups.review"),links:[["a2a","/tasks/a2a"],["plans","/tasks/plans"]]}];return s.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[s.jsxs("header",{className:"flex flex-col gap-3 border-b border-border pb-4 sm:flex-row sm:items-end",children:[s.jsxs("div",{className:"min-w-0 flex-1",children:[s.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[s.jsx("h1",{className:"text-xl font-semibold",children:e("overview.title")}),s.jsx(z,{variant:f>0?"warning":"success",children:f>0?e("overview.needsAttention",{count:f}):e("overview.clear")})]}),s.jsx("p",{className:"mt-1 max-w-2xl text-sm text-text-dim",children:e("overview.subtitle")})]}),s.jsxs(p,{type:"button",variant:"ghost",size:"sm",disabled:Q,onClick:()=>{a.refetch(),n.refetch(),u.refetch(),x.refetch(),m.refetch(),r.refetch(),c.refetch()},children:[s.jsx(X,{className:d("h-4 w-4",Q&&"animate-spin")}),s.jsx("span",{children:e("overview.refresh")})]})]}),s.jsx("section",{className:"grid gap-3 md:grid-cols-2 xl:grid-cols-5",children:G.map(t=>s.jsx(ee,{card:t},t.id))}),s.jsxs("section",{className:"grid gap-4 lg:grid-cols-[minmax(0,1.1fr)_minmax(300px,0.9fr)]",children:[s.jsxs(j,{to:k.to,className:d("group flex min-h-24 items-center gap-3 rounded-md border border-accent bg-accent-bg/45 p-4 no-underline","hover:bg-accent-bg"),children:[s.jsx("span",{className:"flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-accent text-accent-fg",children:s.jsx(w,{className:"h-5 w-5"})}),s.jsxs("span",{className:"min-w-0 flex-1",children:[s.jsx("span",{className:"block text-sm font-semibold text-text",children:k.title}),s.jsx("span",{className:"mt-1 block text-sm text-text-dim",children:k.detail})]}),s.jsx(w,{className:"h-4 w-4 shrink-0 text-text-dim transition-transform group-hover:translate-x-0.5"})]}),s.jsxs("section",{className:"rounded-md border border-border bg-surface p-4",children:[s.jsx("h2",{className:"text-sm font-semibold",children:e("overview.groups.title")}),s.jsx("div",{className:"mt-3 grid gap-3 sm:grid-cols-3 lg:grid-cols-1",children:H.map(t=>s.jsxs("div",{children:[s.jsx("h3",{className:"text-[11px] font-semibold uppercase leading-5 text-text-muted",children:t.title}),s.jsx("div",{className:"mt-1 flex flex-wrap gap-2",children:t.links.map(([I,J])=>s.jsx(p,{asChild:!0,variant:"secondary",size:"sm",children:s.jsx(j,{to:J,children:s.jsx("span",{children:e(`subnav.${I}`)})})},J))})]},t.title))})]})]})]})}function ee({card:e}){return s.jsxs("article",{className:"rounded-md border border-border bg-surface p-4",children:[s.jsxs("div",{className:"flex items-start justify-between gap-3",children:[s.jsx("span",{className:d("flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-surface-2",R[e.tone],"[&_svg]:h-4 [&_svg]:w-4"),"aria-hidden":"true",children:e.tone==="success"?s.jsx(O,{}):e.icon}),s.jsx("span",{className:d("text-2xl font-semibold tabular-nums",R[e.tone]),children:e.value})]}),s.jsx("h2",{className:"mt-3 text-sm font-semibold",children:e.title}),s.jsx("p",{className:"mt-1 min-h-10 text-sm text-text-dim",children:e.detail}),s.jsx(p,{asChild:!0,variant:"ghost",size:"sm",className:"mt-2",children:s.jsxs(j,{to:e.to,children:[s.jsx("span",{children:e.action}),s.jsx(w,{className:"h-4 w-4"})]})})]})}function se(e){const a=e.pendingAsks>0?"asks":e.outboxGivingUp>0?"outboxStuck":e.activeJobs>0?"jobs":e.outboxPending>0?"outbox":e.automationCount>0?"automation":"idle";return{id:a,to:{asks:"/tasks/asks",outboxStuck:"/tasks/outbox",jobs:"/tasks/jobs",outbox:"/tasks/outbox",automation:"/tasks/schedules",idle:"/tasks/jobs"}[a],title:e.t(`overview.next.${a}.title`),detail:e.t(`overview.next.${a}.detail`)}}export{he as default};
|
|
12
|
+
//# sourceMappingURL=overview-COop5K2Y.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overview-COop5K2Y.js","sources":["../../node_modules/lucide-react/dist/esm/icons/circle-help.js","../../node_modules/lucide-react/dist/esm/icons/workflow.js","../../src/routes/tasks/overview.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 CircleHelp = createLucideIcon(\"CircleHelp\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\", key: \"1u773s\" }],\n [\"path\", { d: \"M12 17h.01\", key: \"p32p05\" }]\n]);\n\nexport { CircleHelp as default };\n//# sourceMappingURL=circle-help.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Workflow = createLucideIcon(\"Workflow\", [\n [\"rect\", { width: \"8\", height: \"8\", x: \"3\", y: \"3\", rx: \"2\", key: \"by2w9f\" }],\n [\"path\", { d: \"M7 11v4a2 2 0 0 0 2 2h4\", key: \"xkn7yn\" }],\n [\"rect\", { width: \"8\", height: \"8\", x: \"13\", y: \"13\", rx: \"2\", key: \"1cgmvn\" }]\n]);\n\nexport { Workflow as default };\n//# sourceMappingURL=workflow.js.map\n","/**\n * /tasks — overview surface.\n *\n * The detailed task pages are still the source of truth. This page\n * gives operators a small set of live signals and routes them to the\n * right table when something needs attention.\n */\n\nimport { Link } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport {\n ArrowRight,\n CalendarClock,\n CheckCircle2,\n ClipboardList,\n HelpCircle,\n Inbox,\n RefreshCcw,\n Workflow,\n} from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { useA2AStats } from '@/hooks/use-a2a'\nimport { useAsksList, useGoalsList, useHeartbeatList } from '@/hooks/use-background-tasks'\nimport { useJobs } from '@/hooks/use-jobs'\nimport { useOutboxStats } from '@/hooks/use-outbox'\nimport { useSchedules } from '@/hooks/use-schedules'\nimport { cn } from '@/lib/utils'\n\ntype CardTone = 'success' | 'warning' | 'danger' | 'info' | 'default'\ntype NextActionId = 'asks' | 'outboxStuck' | 'jobs' | 'outbox' | 'automation' | 'idle'\n\ninterface MetricCard {\n id: string\n title: string\n value: string | number\n detail: string\n to: string\n action: string\n tone: CardTone\n icon: JSX.Element\n}\n\ninterface NextAction {\n id: string\n to: string\n title: string\n detail: string\n}\n\nconst TONE_CLASS: Record<CardTone, string> = {\n success: 'text-success',\n warning: 'text-warning',\n danger: 'text-danger',\n info: 'text-info',\n default: 'text-text-dim',\n}\n\nexport default function TasksOverviewRoute(): JSX.Element {\n const { t } = useTranslation('tasks')\n const jobsQuery = useJobs({ limit: 5, offset: 0 })\n const outboxQuery = useOutboxStats()\n const schedulesQuery = useSchedules({})\n const a2aQuery = useA2AStats()\n const heartbeatQuery = useHeartbeatList()\n const goalsQuery = useGoalsList()\n const asksQuery = useAsksList()\n\n const jobStats = jobsQuery.data?.stats\n const jobs = jobsQuery.data?.jobs ?? []\n const runningJobs = jobStats?.running ?? jobs.filter((j) => j.status === 'running').length\n const pendingJobs = jobStats?.pending ?? jobs.filter((j) => j.status === 'pending').length\n const failedJobs = jobStats?.failed ?? jobs.filter((j) => j.status === 'failed').length\n const activeJobs = runningJobs + pendingJobs\n\n const outbox = outboxQuery.data\n const outboxPending = outbox?.pending ?? 0\n const outboxGivingUp = outbox?.giving_up ?? 0\n\n const schedules = schedulesQuery.data?.schedules ?? []\n const enabledSchedules = schedules.filter((s) => s.enabled).length\n const heartbeatBindings = heartbeatQuery.data?.bindings ?? []\n const enabledHeartbeats = heartbeatBindings.filter((b) => b.enabled).length\n const activeGoals = goalsQuery.data?.count ?? goalsQuery.data?.goals.length ?? 0\n const pendingAsks = asksQuery.data?.count ?? asksQuery.data?.pending.length ?? 0\n const a2aRecent = a2aQuery.data?.recent24h ?? 0\n const automationCount = enabledSchedules + enabledHeartbeats + activeGoals\n const needsAttention = pendingAsks + outboxGivingUp + failedJobs\n const anyFetching = jobsQuery.isFetching\n || outboxQuery.isFetching\n || schedulesQuery.isFetching\n || a2aQuery.isFetching\n || heartbeatQuery.isFetching\n || goalsQuery.isFetching\n || asksQuery.isFetching\n\n const nextAction = pickNextAction({\n t,\n pendingAsks,\n outboxGivingUp,\n activeJobs,\n outboxPending,\n automationCount,\n })\n\n const cards: MetricCard[] = [\n {\n id: 'work',\n title: t('overview.cards.work.title'),\n value: activeJobs,\n detail: t('overview.cards.work.detail', { running: runningJobs, pending: pendingJobs }),\n to: '/tasks/jobs',\n action: t('overview.cards.work.action'),\n tone: activeJobs > 0 ? 'warning' : 'success',\n icon: <ClipboardList />,\n },\n {\n id: 'asks',\n title: t('overview.cards.asks.title'),\n value: pendingAsks,\n detail: pendingAsks > 0\n ? t('overview.cards.asks.waiting', { count: pendingAsks })\n : t('overview.cards.asks.clear'),\n to: '/tasks/asks',\n action: t('overview.cards.asks.action'),\n tone: pendingAsks > 0 ? 'danger' : 'success',\n icon: <HelpCircle />,\n },\n {\n id: 'outbox',\n title: t('overview.cards.outbox.title'),\n value: outboxGivingUp > 0 ? outboxGivingUp : outboxPending,\n detail: outboxGivingUp > 0\n ? t('overview.cards.outbox.stuck', { count: outboxGivingUp })\n : t('overview.cards.outbox.detail', { pending: outboxPending }),\n to: '/tasks/outbox',\n action: t('overview.cards.outbox.action'),\n tone: outboxGivingUp > 0 ? 'danger' : outboxPending > 0 ? 'warning' : 'success',\n icon: <Inbox />,\n },\n {\n id: 'automation',\n title: t('overview.cards.automation.title'),\n value: automationCount,\n detail: t('overview.cards.automation.detail', {\n schedules: enabledSchedules,\n heartbeats: enabledHeartbeats,\n goals: activeGoals,\n }),\n to: '/tasks/schedules',\n action: t('overview.cards.automation.action'),\n tone: automationCount > 0 ? 'info' : 'default',\n icon: <CalendarClock />,\n },\n {\n id: 'a2a',\n title: t('overview.cards.a2a.title'),\n value: a2aRecent,\n detail: t('overview.cards.a2a.detail'),\n to: '/tasks/a2a',\n action: t('overview.cards.a2a.action'),\n tone: a2aRecent > 0 ? 'info' : 'default',\n icon: <Workflow />,\n },\n ]\n\n const groups = [\n {\n title: t('overview.groups.work'),\n links: [\n ['jobs', '/tasks/jobs'],\n ['subtasks', '/tasks/subtasks'],\n ['bgjobs', '/tasks/bgjobs'],\n ['outbox', '/tasks/outbox'],\n ],\n },\n {\n title: t('overview.groups.automation'),\n links: [\n ['schedules', '/tasks/schedules'],\n ['heartbeat', '/tasks/heartbeat'],\n ['goals', '/tasks/goals'],\n ['asks', '/tasks/asks'],\n ],\n },\n {\n title: t('overview.groups.review'),\n links: [\n ['a2a', '/tasks/a2a'],\n ['plans', '/tasks/plans'],\n ],\n },\n ] as const\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-3 border-b border-border pb-4 sm:flex-row sm:items-end\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h1 className=\"text-xl font-semibold\">{t('overview.title')}</h1>\n <Badge variant={needsAttention > 0 ? 'warning' : 'success'}>\n {needsAttention > 0\n ? t('overview.needsAttention', { count: needsAttention })\n : t('overview.clear')}\n </Badge>\n </div>\n <p className=\"mt-1 max-w-2xl text-sm text-text-dim\">{t('overview.subtitle')}</p>\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={anyFetching}\n onClick={() => {\n void jobsQuery.refetch()\n void outboxQuery.refetch()\n void schedulesQuery.refetch()\n void a2aQuery.refetch()\n void heartbeatQuery.refetch()\n void goalsQuery.refetch()\n void asksQuery.refetch()\n }}\n >\n <RefreshCcw className={cn('h-4 w-4', anyFetching && 'animate-spin')} />\n <span>{t('overview.refresh')}</span>\n </Button>\n </header>\n\n <section className=\"grid gap-3 md:grid-cols-2 xl:grid-cols-5\">\n {cards.map((card) => (\n <MetricCardItem key={card.id} card={card} />\n ))}\n </section>\n\n <section className=\"grid gap-4 lg:grid-cols-[minmax(0,1.1fr)_minmax(300px,0.9fr)]\">\n <Link\n to={nextAction.to}\n className={cn(\n 'group flex min-h-24 items-center gap-3 rounded-md border border-accent bg-accent-bg/45 p-4 no-underline',\n 'hover:bg-accent-bg',\n )}\n >\n <span className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-accent text-accent-fg\">\n <ArrowRight className=\"h-5 w-5\" />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block text-sm font-semibold text-text\">{nextAction.title}</span>\n <span className=\"mt-1 block text-sm text-text-dim\">{nextAction.detail}</span>\n </span>\n <ArrowRight className=\"h-4 w-4 shrink-0 text-text-dim transition-transform group-hover:translate-x-0.5\" />\n </Link>\n\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <h2 className=\"text-sm font-semibold\">{t('overview.groups.title')}</h2>\n <div className=\"mt-3 grid gap-3 sm:grid-cols-3 lg:grid-cols-1\">\n {groups.map((group) => (\n <div key={group.title}>\n <h3 className=\"text-[11px] font-semibold uppercase leading-5 text-text-muted\">\n {group.title}\n </h3>\n <div className=\"mt-1 flex flex-wrap gap-2\">\n {group.links.map(([id, to]) => (\n <Button key={to} asChild variant=\"secondary\" size=\"sm\">\n <Link to={to}>\n <span>{t(`subnav.${id}`)}</span>\n </Link>\n </Button>\n ))}\n </div>\n </div>\n ))}\n </div>\n </section>\n </section>\n </div>\n )\n}\n\nfunction MetricCardItem({ card }: { card: MetricCard }): JSX.Element {\n return (\n <article className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <span\n className={cn(\n 'flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-surface-2',\n TONE_CLASS[card.tone],\n '[&_svg]:h-4 [&_svg]:w-4',\n )}\n aria-hidden=\"true\"\n >\n {card.tone === 'success' ? <CheckCircle2 /> : card.icon}\n </span>\n <span className={cn('text-2xl font-semibold tabular-nums', TONE_CLASS[card.tone])}>\n {card.value}\n </span>\n </div>\n <h2 className=\"mt-3 text-sm font-semibold\">{card.title}</h2>\n <p className=\"mt-1 min-h-10 text-sm text-text-dim\">{card.detail}</p>\n <Button asChild variant=\"ghost\" size=\"sm\" className=\"mt-2\">\n <Link to={card.to}>\n <span>{card.action}</span>\n <ArrowRight className=\"h-4 w-4\" />\n </Link>\n </Button>\n </article>\n )\n}\n\nfunction pickNextAction(opts: {\n t: ReturnType<typeof useTranslation>['t']\n pendingAsks: number\n outboxGivingUp: number\n activeJobs: number\n outboxPending: number\n automationCount: number\n}): NextAction {\n const id: NextActionId = opts.pendingAsks > 0\n ? 'asks'\n : opts.outboxGivingUp > 0\n ? 'outboxStuck'\n : opts.activeJobs > 0\n ? 'jobs'\n : opts.outboxPending > 0\n ? 'outbox'\n : opts.automationCount > 0\n ? 'automation'\n : 'idle'\n const to: Record<NextActionId, string> = {\n asks: '/tasks/asks',\n outboxStuck: '/tasks/outbox',\n jobs: '/tasks/jobs',\n outbox: '/tasks/outbox',\n automation: '/tasks/schedules',\n idle: '/tasks/jobs',\n }\n return {\n id,\n to: to[id],\n title: opts.t(`overview.next.${id}.title`),\n detail: opts.t(`overview.next.${id}.detail`),\n }\n}\n"],"names":["CircleHelp","createLucideIcon","Workflow","TONE_CLASS","TasksOverviewRoute","t","useTranslation","jobsQuery","useJobs","outboxQuery","useOutboxStats","schedulesQuery","useSchedules","a2aQuery","useA2AStats","heartbeatQuery","useHeartbeatList","goalsQuery","useGoalsList","asksQuery","useAsksList","jobStats","jobs","runningJobs","j","pendingJobs","failedJobs","activeJobs","outbox","outboxPending","outboxGivingUp","enabledSchedules","s","enabledHeartbeats","b","activeGoals","pendingAsks","a2aRecent","automationCount","needsAttention","anyFetching","nextAction","pickNextAction","cards","ClipboardList","HelpCircle","Inbox","CalendarClock","groups","jsxs","jsx","Badge","Button","RefreshCcw","cn","card","MetricCardItem","Link","ArrowRight","group","id","to","CheckCircle2","opts"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{u as T,i as $,j as s,d as K,e as N,f as m,L as k}from"./index-DCfdN5R7.js";import{u as Q,a as z,b as D}from"./use-memory-CXDwKCco.js";import{u as I}from"./use-vector-BYOFwjU0.js";import{D as L}from"./database-lQzk64rV.js";import{B as O}from"./brain-Dl4DF5kX.js";import{S as H}from"./sparkles-G0QIs9nP.js";import{F as V}from"./file-text-BxfdLM0-.js";import{S as G}from"./search-CAICU3aU.js";import{R as J}from"./refresh-ccw-DlAd-eTQ.js";import{A as C}from"./arrow-right-A889Wof8.js";import"./react-DlP5eolq.js";const U={success:"text-success",warning:"text-warning",danger:"text-danger",info:"text-info",default:"text-text-dim"};function ce(){const{t:e}=T("memory"),[i]=$(),t=i.get("user")??"",v=Q(),x=z(),u=D(),f=I(t?{user_key:t}:{}),c=v.data?.users??[],F=t?c.find(r=>r.user_key===t):void 0,M=c.reduce((r,y)=>r+y.fact_count,0),d=c.filter(r=>r.has_persona).length,S=F?.fact_count??0,h=!!F?.has_persona,_=x.data?.jobs??[],B=_.some(r=>r.phase==="running"),g=_.some(r=>r.phase==="failed"),n=u.data,w=f.data,o=w?.coverage,E=!!w?.status.ready,l=w?.status.backend==="off",P=o&&o.total>0?Math.round(o.withEmbedding/o.total*100):0,p=o?Math.max(0,o.total-o.withEmbedding):0,b=[n?.lastError,g,!l&&p>0].filter(Boolean).length,R=v.isFetching||x.isFetching||u.isFetching||f.isFetching,j=W({t:e,userKey:t,hasUsers:c.length>0,selectedFacts:S,selectedHasPersona:h,distillPending:n?.pendingTotal??0,vectorNeedsBackfill:!l&&p>0}),A=[{id:"bank",title:e("overview.cards.bank.title"),value:c.length,detail:e("overview.cards.bank.detail",{facts:M,personas:d}),to:a("/memory/facts",t),action:e("overview.cards.bank.action"),tone:c.length>0?"info":"default",icon:s.jsx(L,{})},{id:"selected",title:e("overview.cards.selected.title"),value:t?S:"-",detail:t?h?e("overview.cards.selected.ready",{user:t}):e("overview.cards.selected.noPersona",{user:t}):e("overview.cards.selected.empty"),to:a("/memory/persona",t),action:e("overview.cards.selected.action"),tone:t?h?"success":"warning":"default",icon:s.jsx(O,{})},{id:"distill",title:e("overview.cards.distill.title"),value:n?.pendingTotal??0,detail:n?.running?e("overview.cards.distill.running"):n?.lastError?e("overview.cards.distill.error"):n?.enabled?e("overview.cards.distill.ready"):e("overview.cards.distill.off"),to:"/memory/distill",action:e("overview.cards.distill.action"),tone:n?.lastError?"danger":(n?.pendingTotal??0)>0?"warning":"success",icon:s.jsx(H,{})},{id:"consolidate",title:e("overview.cards.consolidate.title"),value:d,detail:B?e("overview.cards.consolidate.running"):g?e("overview.cards.consolidate.failed"):e("overview.cards.consolidate.detail",{count:d}),to:a("/memory/persona",t),action:e("overview.cards.consolidate.action"),tone:g?"danger":B?"warning":d>0?"success":"default",icon:s.jsx(V,{})},{id:"vector",title:e("overview.cards.vector.title"),value:l?e("overview.cards.vector.offValue"):`${P}%`,detail:l?e("overview.cards.vector.off"):E?e("overview.cards.vector.ready",{embedded:o?.withEmbedding??0,total:o?.total??0}):e("overview.cards.vector.notReady"),to:a("/memory/vector",t),action:e("overview.cards.vector.action"),tone:l?"default":E&&p===0?"success":"warning",icon:s.jsx(G,{})}];return s.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[s.jsxs("header",{className:"flex flex-col gap-3 border-b border-border pb-4 sm:flex-row sm:items-end",children:[s.jsxs("div",{className:"min-w-0 flex-1",children:[s.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[s.jsx("h1",{className:"text-xl font-semibold",children:e("overview.title")}),s.jsx(K,{variant:b>0?"warning":"success",children:b>0?e("overview.needsAttention",{count:b}):e("overview.clear")})]}),s.jsx("p",{className:"mt-1 max-w-2xl text-sm text-text-dim",children:e("overview.subtitle")})]}),s.jsxs(N,{type:"button",variant:"ghost",size:"sm",disabled:R,onClick:()=>{v.refetch(),x.refetch(),u.refetch(),f.refetch()},children:[s.jsx(J,{className:m("h-4 w-4",R&&"animate-spin")}),s.jsx("span",{children:e("overview.refresh")})]})]}),s.jsx("section",{className:"grid gap-3 md:grid-cols-2 xl:grid-cols-5",children:A.map(r=>s.jsx(q,{card:r},r.id))}),s.jsxs("section",{className:"grid gap-4 lg:grid-cols-[minmax(0,1.1fr)_minmax(300px,0.9fr)]",children:[s.jsxs(k,{to:j.to,className:m("group flex min-h-24 items-center gap-3 rounded-md border border-accent bg-accent-bg/45 p-4 no-underline","hover:bg-accent-bg"),children:[s.jsx("span",{className:"flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-accent text-accent-fg",children:s.jsx(C,{className:"h-5 w-5"})}),s.jsxs("span",{className:"min-w-0 flex-1",children:[s.jsx("span",{className:"block text-sm font-semibold text-text",children:j.title}),s.jsx("span",{className:"mt-1 block text-sm text-text-dim",children:j.detail})]}),s.jsx(C,{className:"h-4 w-4 shrink-0 text-text-dim transition-transform group-hover:translate-x-0.5"})]}),s.jsxs("section",{className:"rounded-md border border-border bg-surface p-4",children:[s.jsx("h2",{className:"text-sm font-semibold",children:e("overview.views.title")}),s.jsx("div",{className:"mt-3 grid grid-cols-2 gap-2",children:[["facts",a("/memory/facts",t)],["persona",a("/memory/persona",t)],["distill","/memory/distill"],["vector",a("/memory/vector",t)]].map(([r,y])=>s.jsx(N,{asChild:!0,variant:"secondary",size:"sm",children:s.jsx(k,{to:y,children:s.jsx("span",{children:e(`tabs.${r}`)})})},r))})]})]})]})}function q({card:e}){return s.jsxs("article",{className:"rounded-md border border-border bg-surface p-4",children:[s.jsxs("div",{className:"flex items-start justify-between gap-3",children:[s.jsx("span",{className:m("flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-surface-2",U[e.tone],"[&_svg]:h-4 [&_svg]:w-4"),"aria-hidden":"true",children:e.icon}),s.jsx("span",{className:m("text-2xl font-semibold tabular-nums",U[e.tone]),children:e.value})]}),s.jsx("h2",{className:"mt-3 text-sm font-semibold",children:e.title}),s.jsx("p",{className:"mt-1 min-h-10 text-sm text-text-dim",children:e.detail}),s.jsx(N,{asChild:!0,variant:"ghost",size:"sm",className:"mt-2",children:s.jsxs(k,{to:e.to,children:[s.jsx("span",{children:e.action}),s.jsx(C,{className:"h-4 w-4"})]})})]})}function W(e){const i=e.hasUsers?e.userKey?e.selectedFacts>0&&!e.selectedHasPersona?"persona":e.distillPending>0?"distill":e.vectorNeedsBackfill?"vector":"facts":"pickUser":"createMemory",t={pickUser:"/memory",createMemory:"/?welcome=1",persona:a("/memory/persona",e.userKey),distill:"/memory/distill",vector:a("/memory/vector",e.userKey),facts:a("/memory/facts",e.userKey)};return{id:i,to:t[i],title:e.t(`overview.next.${i}.title`),detail:e.t(`overview.next.${i}.detail`)}}function a(e,i){return i?`${e}?user=${encodeURIComponent(i)}`:e}export{ce as default};
|
|
2
|
+
//# sourceMappingURL=overview-DeH5ud6d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overview-DeH5ud6d.js","sources":["../../src/routes/memory/overview.tsx"],"sourcesContent":["/**\n * /memory — overview surface.\n *\n * The detailed memory tabs remain the source of truth. This page\n * summarizes the bank in human terms: users, facts, personas,\n * extraction backlog, and vector recall readiness.\n */\n\nimport { Link, useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport {\n ArrowRight,\n Brain,\n Database,\n FileText,\n RefreshCcw,\n Search,\n Sparkles,\n} from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n useConsolidateStatus,\n useDistillStatus,\n useMemoryUsers,\n} from '@/hooks/use-memory'\nimport { useVectorStatus } from '@/hooks/use-vector'\nimport { cn } from '@/lib/utils'\n\ntype CardTone = 'success' | 'warning' | 'danger' | 'info' | 'default'\ntype NextActionId = 'pickUser' | 'createMemory' | 'persona' | 'distill' | 'vector' | 'facts'\n\ninterface MetricCard {\n id: string\n title: string\n value: string | number\n detail: string\n to: string\n action: string\n tone: CardTone\n icon: JSX.Element\n}\n\ninterface NextAction {\n id: NextActionId\n to: string\n title: string\n detail: string\n}\n\nconst TONE_CLASS: Record<CardTone, string> = {\n success: 'text-success',\n warning: 'text-warning',\n danger: 'text-danger',\n info: 'text-info',\n default: 'text-text-dim',\n}\n\nexport default function MemoryOverviewRoute(): JSX.Element {\n const { t } = useTranslation('memory')\n const [params] = useSearchParams()\n const userKey = params.get('user') ?? ''\n\n const usersQuery = useMemoryUsers()\n const consolidateQuery = useConsolidateStatus()\n const distillQuery = useDistillStatus()\n const vectorQuery = useVectorStatus(userKey ? { user_key: userKey } : {})\n\n const users = usersQuery.data?.users ?? []\n const selectedUser = userKey ? users.find((u) => u.user_key === userKey) : undefined\n const totalFacts = users.reduce((sum, u) => sum + u.fact_count, 0)\n const personaCount = users.filter((u) => u.has_persona).length\n const selectedFacts = selectedUser?.fact_count ?? 0\n const selectedHasPersona = Boolean(selectedUser?.has_persona)\n\n const consolidateJobs = consolidateQuery.data?.jobs ?? []\n const runningConsolidate = consolidateJobs.some((j) => j.phase === 'running')\n const failedConsolidate = consolidateJobs.some((j) => j.phase === 'failed')\n const distill = distillQuery.data\n const vector = vectorQuery.data\n const coverage = vector?.coverage\n const vectorReady = Boolean(vector?.status.ready)\n const vectorOff = vector?.status.backend === 'off'\n const coveragePercent = coverage && coverage.total > 0\n ? Math.round((coverage.withEmbedding / coverage.total) * 100)\n : 0\n const coverageGap = coverage\n ? Math.max(0, coverage.total - coverage.withEmbedding)\n : 0\n\n const healthIssues = [\n distill?.lastError,\n failedConsolidate,\n !vectorOff && coverageGap > 0,\n ].filter(Boolean).length\n const anyFetching = usersQuery.isFetching\n || consolidateQuery.isFetching\n || distillQuery.isFetching\n || vectorQuery.isFetching\n\n const nextAction = pickNextAction({\n t,\n userKey,\n hasUsers: users.length > 0,\n selectedFacts,\n selectedHasPersona,\n distillPending: distill?.pendingTotal ?? 0,\n vectorNeedsBackfill: !vectorOff && coverageGap > 0,\n })\n\n const cards: MetricCard[] = [\n {\n id: 'bank',\n title: t('overview.cards.bank.title'),\n value: users.length,\n detail: t('overview.cards.bank.detail', { facts: totalFacts, personas: personaCount }),\n to: withUser('/memory/facts', userKey),\n action: t('overview.cards.bank.action'),\n tone: users.length > 0 ? 'info' : 'default',\n icon: <Database />,\n },\n {\n id: 'selected',\n title: t('overview.cards.selected.title'),\n value: userKey ? selectedFacts : '-',\n detail: userKey\n ? selectedHasPersona\n ? t('overview.cards.selected.ready', { user: userKey })\n : t('overview.cards.selected.noPersona', { user: userKey })\n : t('overview.cards.selected.empty'),\n to: withUser('/memory/persona', userKey),\n action: t('overview.cards.selected.action'),\n tone: userKey ? selectedHasPersona ? 'success' : 'warning' : 'default',\n icon: <Brain />,\n },\n {\n id: 'distill',\n title: t('overview.cards.distill.title'),\n value: distill?.pendingTotal ?? 0,\n detail: distill?.running\n ? t('overview.cards.distill.running')\n : distill?.lastError\n ? t('overview.cards.distill.error')\n : distill?.enabled\n ? t('overview.cards.distill.ready')\n : t('overview.cards.distill.off'),\n to: '/memory/distill',\n action: t('overview.cards.distill.action'),\n tone: distill?.lastError ? 'danger' : (distill?.pendingTotal ?? 0) > 0 ? 'warning' : 'success',\n icon: <Sparkles />,\n },\n {\n id: 'consolidate',\n title: t('overview.cards.consolidate.title'),\n value: personaCount,\n detail: runningConsolidate\n ? t('overview.cards.consolidate.running')\n : failedConsolidate\n ? t('overview.cards.consolidate.failed')\n : t('overview.cards.consolidate.detail', { count: personaCount }),\n to: withUser('/memory/persona', userKey),\n action: t('overview.cards.consolidate.action'),\n tone: failedConsolidate ? 'danger' : runningConsolidate ? 'warning' : personaCount > 0 ? 'success' : 'default',\n icon: <FileText />,\n },\n {\n id: 'vector',\n title: t('overview.cards.vector.title'),\n value: vectorOff ? t('overview.cards.vector.offValue') : `${coveragePercent}%`,\n detail: vectorOff\n ? t('overview.cards.vector.off')\n : vectorReady\n ? t('overview.cards.vector.ready', { embedded: coverage?.withEmbedding ?? 0, total: coverage?.total ?? 0 })\n : t('overview.cards.vector.notReady'),\n to: withUser('/memory/vector', userKey),\n action: t('overview.cards.vector.action'),\n tone: vectorOff ? 'default' : vectorReady && coverageGap === 0 ? 'success' : 'warning',\n icon: <Search />,\n },\n ]\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-3 border-b border-border pb-4 sm:flex-row sm:items-end\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h1 className=\"text-xl font-semibold\">{t('overview.title')}</h1>\n <Badge variant={healthIssues > 0 ? 'warning' : 'success'}>\n {healthIssues > 0\n ? t('overview.needsAttention', { count: healthIssues })\n : t('overview.clear')}\n </Badge>\n </div>\n <p className=\"mt-1 max-w-2xl text-sm text-text-dim\">{t('overview.subtitle')}</p>\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={anyFetching}\n onClick={() => {\n void usersQuery.refetch()\n void consolidateQuery.refetch()\n void distillQuery.refetch()\n void vectorQuery.refetch()\n }}\n >\n <RefreshCcw className={cn('h-4 w-4', anyFetching && 'animate-spin')} />\n <span>{t('overview.refresh')}</span>\n </Button>\n </header>\n\n <section className=\"grid gap-3 md:grid-cols-2 xl:grid-cols-5\">\n {cards.map((card) => (\n <MetricCardItem key={card.id} card={card} />\n ))}\n </section>\n\n <section className=\"grid gap-4 lg:grid-cols-[minmax(0,1.1fr)_minmax(300px,0.9fr)]\">\n <Link\n to={nextAction.to}\n className={cn(\n 'group flex min-h-24 items-center gap-3 rounded-md border border-accent bg-accent-bg/45 p-4 no-underline',\n 'hover:bg-accent-bg',\n )}\n >\n <span className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-accent text-accent-fg\">\n <ArrowRight className=\"h-5 w-5\" />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block text-sm font-semibold text-text\">{nextAction.title}</span>\n <span className=\"mt-1 block text-sm text-text-dim\">{nextAction.detail}</span>\n </span>\n <ArrowRight className=\"h-4 w-4 shrink-0 text-text-dim transition-transform group-hover:translate-x-0.5\" />\n </Link>\n\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <h2 className=\"text-sm font-semibold\">{t('overview.views.title')}</h2>\n <div className=\"mt-3 grid grid-cols-2 gap-2\">\n {([\n ['facts', withUser('/memory/facts', userKey)],\n ['persona', withUser('/memory/persona', userKey)],\n ['distill', '/memory/distill'],\n ['vector', withUser('/memory/vector', userKey)],\n ] satisfies Array<[string, string]>).map(([id, to]) => (\n <Button key={id} asChild variant=\"secondary\" size=\"sm\">\n <Link to={to}>\n <span>{t(`tabs.${id}`)}</span>\n </Link>\n </Button>\n ))}\n </div>\n </section>\n </section>\n </div>\n )\n}\n\nfunction MetricCardItem({ card }: { card: MetricCard }): JSX.Element {\n return (\n <article className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <span\n className={cn(\n 'flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-surface-2',\n TONE_CLASS[card.tone],\n '[&_svg]:h-4 [&_svg]:w-4',\n )}\n aria-hidden=\"true\"\n >\n {card.icon}\n </span>\n <span className={cn('text-2xl font-semibold tabular-nums', TONE_CLASS[card.tone])}>\n {card.value}\n </span>\n </div>\n <h2 className=\"mt-3 text-sm font-semibold\">{card.title}</h2>\n <p className=\"mt-1 min-h-10 text-sm text-text-dim\">{card.detail}</p>\n <Button asChild variant=\"ghost\" size=\"sm\" className=\"mt-2\">\n <Link to={card.to}>\n <span>{card.action}</span>\n <ArrowRight className=\"h-4 w-4\" />\n </Link>\n </Button>\n </article>\n )\n}\n\nfunction pickNextAction(opts: {\n t: ReturnType<typeof useTranslation>['t']\n userKey: string\n hasUsers: boolean\n selectedFacts: number\n selectedHasPersona: boolean\n distillPending: number\n vectorNeedsBackfill: boolean\n}): NextAction {\n const id: NextActionId = !opts.hasUsers\n ? 'createMemory'\n : !opts.userKey\n ? 'pickUser'\n : opts.selectedFacts > 0 && !opts.selectedHasPersona\n ? 'persona'\n : opts.distillPending > 0\n ? 'distill'\n : opts.vectorNeedsBackfill\n ? 'vector'\n : 'facts'\n const to: Record<NextActionId, string> = {\n pickUser: '/memory',\n createMemory: '/?welcome=1',\n persona: withUser('/memory/persona', opts.userKey),\n distill: '/memory/distill',\n vector: withUser('/memory/vector', opts.userKey),\n facts: withUser('/memory/facts', opts.userKey),\n }\n return {\n id,\n to: to[id],\n title: opts.t(`overview.next.${id}.title`),\n detail: opts.t(`overview.next.${id}.detail`),\n }\n}\n\nfunction withUser(path: string, userKey: string): string {\n return userKey ? `${path}?user=${encodeURIComponent(userKey)}` : path\n}\n"],"names":["TONE_CLASS","MemoryOverviewRoute","t","useTranslation","params","useSearchParams","userKey","usersQuery","useMemoryUsers","consolidateQuery","useConsolidateStatus","distillQuery","useDistillStatus","vectorQuery","useVectorStatus","users","selectedUser","u","totalFacts","sum","personaCount","selectedFacts","selectedHasPersona","consolidateJobs","runningConsolidate","j","failedConsolidate","distill","vector","coverage","vectorReady","vectorOff","coveragePercent","coverageGap","healthIssues","anyFetching","nextAction","pickNextAction","cards","withUser","Database","Brain","Sparkles","FileText","Search","jsxs","jsx","Badge","Button","RefreshCcw","cn","card","MetricCardItem","Link","ArrowRight","id","to","opts","path"],"mappings":"qgBAmDA,MAAMA,EAAuC,CAC3C,QAAS,eACT,QAAS,eACT,OAAS,cACT,KAAS,YACT,QAAS,eACX,EAEA,SAAwBC,IAAmC,CACzD,KAAM,CAAE,EAAAC,CAAA,EAAMC,EAAe,QAAQ,EAC/B,CAACC,CAAM,EAAIC,EAAA,EACXC,EAAUF,EAAO,IAAI,MAAM,GAAK,GAEhCG,EAAaC,EAAA,EACbC,EAAmBC,EAAA,EACnBC,EAAeC,EAAA,EACfC,EAAcC,EAAgBR,EAAU,CAAE,SAAUA,CAAA,EAAY,EAAE,EAElES,EAAQR,EAAW,MAAM,OAAS,CAAA,EAClCS,EAAeV,EAAUS,EAAM,KAAME,GAAMA,EAAE,WAAaX,CAAO,EAAI,OACrEY,EAAaH,EAAM,OAAO,CAACI,EAAKF,IAAME,EAAMF,EAAE,WAAY,CAAC,EAC3DG,EAAeL,EAAM,OAAQE,GAAMA,EAAE,WAAW,EAAE,OAClDI,EAAgBL,GAAc,YAAc,EAC5CM,EAAqB,EAAQN,GAAc,YAE3CO,EAAkBd,EAAiB,MAAM,MAAQ,CAAA,EACjDe,EAAqBD,EAAgB,KAAME,GAAMA,EAAE,QAAU,SAAS,EACtEC,EAAoBH,EAAgB,KAAME,GAAMA,EAAE,QAAU,QAAQ,EACpEE,EAAUhB,EAAa,KACvBiB,EAASf,EAAY,KACrBgB,EAAWD,GAAQ,SACnBE,EAAc,EAAQF,GAAQ,OAAO,MACrCG,EAAYH,GAAQ,OAAO,UAAY,MACvCI,EAAkBH,GAAYA,EAAS,MAAQ,EACjD,KAAK,MAAOA,EAAS,cAAgBA,EAAS,MAAS,GAAG,EAC1D,EACEI,EAAcJ,EAChB,KAAK,IAAI,EAAGA,EAAS,MAAQA,EAAS,aAAa,EACnD,EAEEK,EAAe,CACnBP,GAAS,UACTD,EACA,CAACK,GAAaE,EAAc,CAAA,EAC5B,OAAO,OAAO,EAAE,OACZE,EAAc5B,EAAW,YAC1BE,EAAiB,YACjBE,EAAa,YACbE,EAAY,WAEXuB,EAAaC,EAAe,CAChC,EAAAnC,EACA,QAAAI,EACA,SAAUS,EAAM,OAAS,EACzB,cAAAM,EACA,mBAAAC,EACA,eAAgBK,GAAS,cAAgB,EACzC,oBAAqB,CAACI,GAAaE,EAAc,CAAA,CAClD,EAEKK,EAAsB,CAC1B,CACE,GAAI,OACJ,MAAOpC,EAAE,2BAA2B,EACpC,MAAOa,EAAM,OACb,OAAQb,EAAE,6BAA8B,CAAE,MAAOgB,EAAY,SAAUE,EAAc,EACrF,GAAImB,EAAS,gBAAiBjC,CAAO,EACrC,OAAQJ,EAAE,4BAA4B,EACtC,KAAMa,EAAM,OAAS,EAAI,OAAS,UAClC,WAAOyB,EAAA,CAAA,CAAS,CAAA,EAElB,CACE,GAAI,WACJ,MAAOtC,EAAE,+BAA+B,EACxC,MAAOI,EAAUe,EAAgB,IACjC,OAAQf,EACJgB,EACEpB,EAAE,gCAAiC,CAAE,KAAMI,CAAA,CAAS,EACpDJ,EAAE,oCAAqC,CAAE,KAAMI,EAAS,EAC1DJ,EAAE,+BAA+B,EACrC,GAAIqC,EAAS,kBAAmBjC,CAAO,EACvC,OAAQJ,EAAE,gCAAgC,EAC1C,KAAMI,EAAUgB,EAAqB,UAAY,UAAY,UAC7D,WAAOmB,EAAA,CAAA,CAAM,CAAA,EAEf,CACE,GAAI,UACJ,MAAOvC,EAAE,8BAA8B,EACvC,MAAOyB,GAAS,cAAgB,EAChC,OAAQA,GAAS,QACbzB,EAAE,gCAAgC,EAClCyB,GAAS,UACPzB,EAAE,8BAA8B,EAChCyB,GAAS,QACPzB,EAAE,8BAA8B,EAChCA,EAAE,4BAA4B,EACtC,GAAI,kBACJ,OAAQA,EAAE,+BAA+B,EACzC,KAAMyB,GAAS,UAAY,UAAYA,GAAS,cAAgB,GAAK,EAAI,UAAY,UACrF,WAAOe,EAAA,CAAA,CAAS,CAAA,EAElB,CACE,GAAI,cACJ,MAAOxC,EAAE,kCAAkC,EAC3C,MAAOkB,EACP,OAAQI,EACJtB,EAAE,oCAAoC,EACtCwB,EACExB,EAAE,mCAAmC,EACrCA,EAAE,oCAAqC,CAAE,MAAOkB,EAAc,EACpE,GAAImB,EAAS,kBAAmBjC,CAAO,EACvC,OAAQJ,EAAE,mCAAmC,EAC7C,KAAMwB,EAAoB,SAAWF,EAAqB,UAAYJ,EAAe,EAAI,UAAY,UACrG,WAAOuB,EAAA,CAAA,CAAS,CAAA,EAElB,CACE,GAAI,SACJ,MAAOzC,EAAE,6BAA6B,EACtC,MAAO6B,EAAY7B,EAAE,gCAAgC,EAAI,GAAG8B,CAAe,IAC3E,OAAQD,EACJ7B,EAAE,2BAA2B,EAC7B4B,EACE5B,EAAE,8BAA+B,CAAE,SAAU2B,GAAU,eAAiB,EAAG,MAAOA,GAAU,OAAS,EAAG,EACxG3B,EAAE,gCAAgC,EACxC,GAAIqC,EAAS,iBAAkBjC,CAAO,EACtC,OAAQJ,EAAE,8BAA8B,EACxC,KAAM6B,EAAY,UAAYD,GAAeG,IAAgB,EAAI,UAAY,UAC7E,WAAOW,EAAA,CAAA,CAAO,CAAA,CAChB,EAGF,OACEC,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,2EAChB,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAC,MAAC,KAAA,CAAG,UAAU,wBAAyB,SAAA5C,EAAE,gBAAgB,EAAE,QAC1D6C,EAAA,CAAM,QAASb,EAAe,EAAI,UAAY,UAC5C,SAAAA,EAAe,EACZhC,EAAE,0BAA2B,CAAE,MAAOgC,CAAA,CAAc,EACpDhC,EAAE,gBAAgB,CAAA,CACxB,CAAA,EACF,QACC,IAAA,CAAE,UAAU,uCAAwC,SAAAA,EAAE,mBAAmB,CAAA,CAAE,CAAA,EAC9E,EACA2C,EAAAA,KAACG,EAAA,CACC,KAAK,SACL,QAAQ,QACR,KAAK,KACL,SAAUb,EACV,QAAS,IAAM,CACR5B,EAAW,QAAA,EACXE,EAAiB,QAAA,EACjBE,EAAa,QAAA,EACbE,EAAY,QAAA,CACnB,EAEA,SAAA,CAAAiC,MAACG,GAAW,UAAWC,EAAG,UAAWf,GAAe,cAAc,EAAG,EACrEW,EAAAA,IAAC,OAAA,CAAM,SAAA5C,EAAE,kBAAkB,CAAA,CAAE,CAAA,CAAA,CAAA,CAC/B,EACF,EAEA4C,EAAAA,IAAC,UAAA,CAAQ,UAAU,2CAChB,WAAM,IAAKK,GACVL,EAAAA,IAACM,EAAA,CAA6B,KAAAD,CAAA,EAATA,EAAK,EAAgB,CAC3C,EACH,EAEAN,EAAAA,KAAC,UAAA,CAAQ,UAAU,gEACjB,SAAA,CAAAA,EAAAA,KAACQ,EAAA,CACC,GAAIjB,EAAW,GACf,UAAWc,EACT,0GACA,oBAAA,EAGF,SAAA,CAAAJ,EAAAA,IAAC,QAAK,UAAU,4FACd,eAACQ,EAAA,CAAW,UAAU,UAAU,CAAA,CAClC,EACAT,EAAAA,KAAC,OAAA,CAAK,UAAU,iBACd,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAK,UAAU,wCAAyC,SAAAV,EAAW,MAAM,EAC1EU,EAAAA,IAAC,OAAA,CAAK,UAAU,mCAAoC,WAAW,MAAA,CAAO,CAAA,EACxE,EACAA,EAAAA,IAACQ,EAAA,CAAW,UAAU,iFAAA,CAAkF,CAAA,CAAA,CAAA,EAG1GT,EAAAA,KAAC,UAAA,CAAQ,UAAU,iDACjB,SAAA,CAAAC,MAAC,KAAA,CAAG,UAAU,wBAAyB,SAAA5C,EAAE,sBAAsB,EAAE,EACjE4C,EAAAA,IAAC,MAAA,CAAI,UAAU,8BACX,SAAA,CACA,CAAC,QAASP,EAAS,gBAAiBjC,CAAO,CAAC,EAC5C,CAAC,UAAWiC,EAAS,kBAAmBjC,CAAO,CAAC,EAChD,CAAC,UAAW,iBAAiB,EAC7B,CAAC,SAAUiC,EAAS,iBAAkBjC,CAAO,CAAC,CAAA,EACX,IAAI,CAAC,CAACiD,EAAIC,CAAE,IAC/CV,EAAAA,IAACE,EAAA,CAAgB,QAAO,GAAC,QAAQ,YAAY,KAAK,KAChD,SAAAF,EAAAA,IAACO,EAAA,CAAK,GAAAG,EACJ,SAAAV,EAAAA,IAAC,OAAA,CAAM,SAAA5C,EAAE,QAAQqD,CAAE,EAAE,CAAA,CAAE,CAAA,CACzB,CAAA,EAHWA,CAIb,CACD,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,EACF,CAEJ,CAEA,SAASH,EAAe,CAAE,KAAAD,GAA2C,CACnE,OACEN,EAAAA,KAAC,UAAA,CAAQ,UAAU,iDACjB,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAC,EAAAA,IAAC,OAAA,CACC,UAAWI,EACT,8EACAlD,EAAWmD,EAAK,IAAI,EACpB,yBAAA,EAEF,cAAY,OAEX,SAAAA,EAAK,IAAA,CAAA,EAERL,EAAAA,IAAC,OAAA,CAAK,UAAWI,EAAG,sCAAuClD,EAAWmD,EAAK,IAAI,CAAC,EAC7E,SAAAA,EAAK,KAAA,CACR,CAAA,EACF,EACAL,EAAAA,IAAC,KAAA,CAAG,UAAU,6BAA8B,WAAK,MAAM,EACvDA,EAAAA,IAAC,IAAA,CAAE,UAAU,sCAAuC,WAAK,OAAO,EAChEA,EAAAA,IAACE,EAAA,CAAO,QAAO,GAAC,QAAQ,QAAQ,KAAK,KAAK,UAAU,OAClD,SAAAH,EAAAA,KAACQ,EAAA,CAAK,GAAIF,EAAK,GACb,SAAA,CAAAL,EAAAA,IAAC,OAAA,CAAM,WAAK,MAAA,CAAO,EACnBA,EAAAA,IAACQ,EAAA,CAAW,UAAU,SAAA,CAAU,CAAA,CAAA,CAClC,CAAA,CACF,CAAA,EACF,CAEJ,CAEA,SAASjB,EAAeoB,EAQT,CACb,MAAMF,EAAoBE,EAAK,SAE1BA,EAAK,QAEJA,EAAK,cAAgB,GAAK,CAACA,EAAK,mBAC9B,UACAA,EAAK,eAAiB,EACpB,UACAA,EAAK,oBACH,SACA,QAPN,WAFF,eAUED,EAAmC,CACvC,SAAe,UACf,aAAc,cACd,QAAcjB,EAAS,kBAAmBkB,EAAK,OAAO,EACtD,QAAc,kBACd,OAAclB,EAAS,iBAAkBkB,EAAK,OAAO,EACrD,MAAclB,EAAS,gBAAiBkB,EAAK,OAAO,CAAA,EAEtD,MAAO,CACL,GAAAF,EACA,GAAIC,EAAGD,CAAE,EACT,MAAOE,EAAK,EAAE,iBAAiBF,CAAE,QAAQ,EACzC,OAAQE,EAAK,EAAE,iBAAiBF,CAAE,SAAS,CAAA,CAE/C,CAEA,SAAShB,EAASmB,EAAcpD,EAAyB,CACvD,OAAOA,EAAU,GAAGoD,CAAI,SAAS,mBAAmBpD,CAAO,CAAC,GAAKoD,CACnE"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{h as j,u as f,j as i,k as b,l as N,m as g,n as C,o as k,e as r,f as y}from"./index-DCfdN5R7.js";import{C as S}from"./chevron-left-01fAFVpo.js";import{C as z}from"./chevron-right-CFRb-SM_.js";/**
|
|
2
2
|
* @license lucide-react v0.469.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -8,5 +8,5 @@ import{o as j,u as f,j as i,S as b,g,h as N,i as C,k,B as r,c as y}from"./index-
|
|
|
8
8
|
*
|
|
9
9
|
* This source code is licensed under the ISC license.
|
|
10
10
|
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
-
*/const M=j("ChevronLast",[["path",{d:"m7 18 6-6-6-6",key:"lwmzdw"}],["path",{d:"M17 6v12",key:"1o0aio"}]]);function T({page:e,totalPages:c,totalRows:n,perPage:s,perPageOptions:o,onPageChange:l,onPerPageChange:d,className:u}){const{t:a}=f("common"),
|
|
12
|
-
//# sourceMappingURL=pagination-
|
|
11
|
+
*/const M=j("ChevronLast",[["path",{d:"m7 18 6-6-6-6",key:"lwmzdw"}],["path",{d:"M17 6v12",key:"1o0aio"}]]);function T({page:e,totalPages:c,totalRows:n,perPage:s,perPageOptions:o,onPageChange:l,onPerPageChange:d,className:u}){const{t:a}=f("common"),m=e>1,x=e<c,p=s!==void 0&&o&&o.length>0&&d,h=s?(e-1)*s+1:null,v=s&&n!==void 0?Math.min(e*s,n):null;return i.jsxs("div",{className:y("flex flex-wrap items-center justify-between gap-3 py-2",u),role:"navigation","aria-label":a("pagination.label"),children:[i.jsxs("div",{className:"flex items-center gap-2 text-sm text-text-dim",children:[p&&i.jsxs("div",{className:"hidden sm:flex items-center gap-2",children:[i.jsx("span",{children:a("pagination.perPage")}),i.jsxs(b,{value:String(s),onValueChange:t=>d?.(Number(t)),children:[i.jsx(N,{className:"h-8 w-[80px]",children:i.jsx(g,{})}),i.jsx(C,{children:o.map(t=>i.jsx(k,{value:String(t),children:t},t))})]})]}),n!==void 0&&h!==null&&v!==null&&i.jsx("span",{"aria-live":"polite",children:a("pagination.range",{from:n===0?0:h,to:v,total:n})})]}),i.jsxs("div",{className:"flex items-center gap-1",children:[i.jsx(r,{variant:"ghost",size:"icon","aria-label":a("pagination.firstPage"),disabled:!m,onClick:()=>l(1),className:"hidden sm:inline-flex",children:i.jsx(L,{})}),i.jsx(r,{variant:"ghost",size:"icon","aria-label":a("actions.previous"),disabled:!m,onClick:()=>l(e-1),children:i.jsx(S,{})}),i.jsx("span",{className:"px-2 text-sm tabular-nums","aria-live":"polite",children:a("pagination.pageOfTotal",{page:e,totalPages:Math.max(1,c)})}),i.jsx(r,{variant:"ghost",size:"icon","aria-label":a("actions.next"),disabled:!x,onClick:()=>l(e+1),children:i.jsx(z,{})}),i.jsx(r,{variant:"ghost",size:"icon","aria-label":a("pagination.lastPage"),disabled:!x,onClick:()=>l(c),className:"hidden sm:inline-flex",children:i.jsx(M,{})})]})]})}T.displayName="Pagination";export{T as P};
|
|
12
|
+
//# sourceMappingURL=pagination-BBicLzXP.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination-
|
|
1
|
+
{"version":3,"file":"pagination-BBicLzXP.js","sources":["../../node_modules/lucide-react/dist/esm/icons/chevron-first.js","../../node_modules/lucide-react/dist/esm/icons/chevron-last.js","../../src/components/common/pagination.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 ChevronFirst = createLucideIcon(\"ChevronFirst\", [\n [\"path\", { d: \"m17 18-6-6 6-6\", key: \"1yerx2\" }],\n [\"path\", { d: \"M7 6v12\", key: \"1p53r6\" }]\n]);\n\nexport { ChevronFirst as default };\n//# sourceMappingURL=chevron-first.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ChevronLast = createLucideIcon(\"ChevronLast\", [\n [\"path\", { d: \"m7 18 6-6-6-6\", key: \"lwmzdw\" }],\n [\"path\", { d: \"M17 6v12\", key: \"1o0aio\" }]\n]);\n\nexport { ChevronLast as default };\n//# sourceMappingURL=chevron-last.js.map\n","/**\n * Pagination — controlled page navigator. Drives the URL via the\n * `page` / `perPage` callbacks; the caller decides whether to write\n * useSearchParams (recommended), zustand, or just local state.\n *\n * Why controlled: each M2 page wants the page index in the URL so\n * deep-links work (\"here's row 42 — share it\"). Forcing the component\n * to manage its own state would either duplicate the search-params\n * read or trap callers into useEffect to sync. Controlled keeps the\n * data flow obvious.\n *\n * Mobile behavior:\n * - The page-size selector hides below sm (no room; default 20 is\n * fine on phone).\n * - The first / last buttons hide below sm (the page label keeps\n * the user oriented; prev / next is enough).\n * - All buttons have a 44×44 hit target via the `icon` size.\n *\n * Edge cases:\n * - page count of 0 / 1 → component still renders so the table\n * footer doesn't jump on the next page-flip; buttons are disabled.\n * - page > totalPages → clamp on the caller's side (we display the\n * label as-is so the caller sees the bug instead of us masking it).\n */\n\nimport { ChevronFirst, ChevronLast, ChevronLeft, ChevronRight } from 'lucide-react'\nimport { useTranslation } from 'react-i18next'\nimport { Button } from '@/components/ui/button'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { cn } from '@/lib/utils'\n\nexport interface PaginationProps {\n /** 1-based current page. */\n page: number\n /** Total number of pages. Pass `Math.max(1, Math.ceil(total / perPage))`. */\n totalPages: number\n /** Optional row count — when present, renders \"1–20 of 150\" alongside the page label. */\n totalRows?: number\n /** Optional rows-per-page slot. Pass `[10, 20, 50, 100]` to enable. */\n perPage?: number\n perPageOptions?: number[]\n onPageChange: (page: number) => void\n onPerPageChange?: (perPage: number) => void\n className?: string\n}\n\nfunction Pagination({\n page,\n totalPages,\n totalRows,\n perPage,\n perPageOptions,\n onPageChange,\n onPerPageChange,\n className,\n}: PaginationProps): JSX.Element {\n const { t } = useTranslation('common')\n const canPrev = page > 1\n const canNext = page < totalPages\n const showPerPage = perPage !== undefined && perPageOptions && perPageOptions.length > 0 && onPerPageChange\n\n const rangeFrom = perPage ? (page - 1) * perPage + 1 : null\n const rangeTo = perPage && totalRows !== undefined\n ? Math.min(page * perPage, totalRows)\n : null\n\n return (\n <div\n className={cn(\n 'flex flex-wrap items-center justify-between gap-3 py-2',\n className,\n )}\n role=\"navigation\"\n aria-label={t('pagination.label')}\n >\n <div className=\"flex items-center gap-2 text-sm text-text-dim\">\n {showPerPage && (\n <div className=\"hidden sm:flex items-center gap-2\">\n <span>{t('pagination.perPage')}</span>\n <Select\n value={String(perPage)}\n onValueChange={(v) => onPerPageChange?.(Number(v))}\n >\n <SelectTrigger className=\"h-8 w-[80px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {perPageOptions.map((n) => (\n <SelectItem key={n} value={String(n)}>\n {n}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n {totalRows !== undefined && rangeFrom !== null && rangeTo !== null && (\n <span aria-live=\"polite\">\n {t('pagination.range', {\n from: totalRows === 0 ? 0 : rangeFrom,\n to: rangeTo,\n total: totalRows,\n })}\n </span>\n )}\n </div>\n\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={t('pagination.firstPage')}\n disabled={!canPrev}\n onClick={() => onPageChange(1)}\n className=\"hidden sm:inline-flex\"\n >\n <ChevronFirst />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={t('actions.previous')}\n disabled={!canPrev}\n onClick={() => onPageChange(page - 1)}\n >\n <ChevronLeft />\n </Button>\n\n <span className=\"px-2 text-sm tabular-nums\" aria-live=\"polite\">\n {t('pagination.pageOfTotal', { page, totalPages: Math.max(1, totalPages) })}\n </span>\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={t('actions.next')}\n disabled={!canNext}\n onClick={() => onPageChange(page + 1)}\n >\n <ChevronRight />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={t('pagination.lastPage')}\n disabled={!canNext}\n onClick={() => onPageChange(totalPages)}\n className=\"hidden sm:inline-flex\"\n >\n <ChevronLast />\n </Button>\n </div>\n </div>\n )\n}\nPagination.displayName = 'Pagination'\n\nexport { Pagination }\n"],"names":["ChevronFirst","createLucideIcon","ChevronLast","Pagination","page","totalPages","totalRows","perPage","perPageOptions","onPageChange","onPerPageChange","className","t","useTranslation","canPrev","canNext","showPerPage","rangeFrom","rangeTo","jsxs","cn","jsx","Select","v","SelectTrigger","SelectValue","SelectContent","n","SelectItem","Button","ChevronLeft","ChevronRight"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{u as p,i as B,j as e,e as u,d as j,q as N,p as m,w as F,f as z}from"./index-DCfdN5R7.js";import{r as y}from"./react-DlP5eolq.js";import{E as P}from"./empty-state-CuiqdZiB.js";import{C as A}from"./confirm-dialog-BDb0NLny.js";import{f as R,g as U,a as _,h as M,i as q}from"./use-memory-CXDwKCco.js";import{B as D}from"./brain-Dl4DF5kX.js";import{L as x}from"./loader-circle-DDdmcH0k.js";import{R as J}from"./refresh-ccw-DlAd-eTQ.js";import{P as O}from"./play-DX5wp4WH.js";import{C as Q}from"./circle-check-big-DBg2BD6o.js";import{C as X}from"./circle-x-CqFMzO-x.js";import{T as G}from"./trash-2-D2x2UPuZ.js";function oe(){const{t}=p(["memory","common"]),[s]=B(),r=s.get("user")??"";return r?e.jsx(H,{userKey:r}):e.jsx("div",{className:"mx-auto max-w-3xl",children:e.jsx(P,{icon:e.jsx(D,{}),title:t("noUserSelected.title"),description:t("noUserSelected.description")})})}function H({userKey:t}){const{t:s}=p(["memory","common"]),r=R(t),n=r.data,o=U(),a=_().data?.jobs[0],i=M(),f=q(),[E,h]=y.useState(!1),[d,g]=y.useState(n?.summary??"");y.useEffect(()=>{g(n?.summary??"")},[n?.summary]);const b=d!==(n?.summary??"");async function w(){const c=d.trim();if(c)try{await i.mutateAsync({user_key:t,body:{summary:c}}),m.success(s("persona.saved"))}catch(l){const{message:k}=N(l,s);m.error(k)}}async function L(){try{await f.mutateAsync(t),m.success(s("common:actions.delete"))}catch(c){const{message:l}=N(c,s);throw m.error(l),c}}async function T(){try{await o.mutateAsync()}catch(c){const{message:l}=N(c,s);m.error(l)}}return e.jsxs("div",{className:"mx-auto flex max-w-4xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("persona.title")}),e.jsxs(u,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>r.refetch(),disabled:r.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[r.isFetching?e.jsx(x,{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("persona.subtitle")})]}),e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:"font-medium text-sm text-text",children:s("persona.consolidate.trigger")}),e.jsx(I,{job:a}),e.jsxs(u,{variant:"default",size:"sm",onClick:()=>void T(),disabled:o.isPending||a?.phase==="running",className:"ml-auto",children:[o.isPending?e.jsx(x,{className:"h-4 w-4 animate-spin"}):e.jsx(O,{className:"h-4 w-4"}),o.isPending?s("persona.consolidate.triggering"):s("persona.consolidate.trigger")]})]}),a?.phase==="done"&&(a.result.users!=null||a.result.updated!=null)&&e.jsx("p",{className:"mt-2 text-xs text-text-dim",children:s("persona.consolidate.result",{users:a.result.users??0,updated:a.result.updated??0})}),a?.phase==="failed"&&a.result.error&&e.jsx("p",{className:"mt-2 text-xs text-danger",children:a.result.error})]}),r.isLoading?e.jsx("div",{className:"h-48 w-full rounded-md bg-surface-2 animate-pulse"}):n?e.jsxs(e.Fragment,{children:[n.updated_at>0&&e.jsx("div",{className:"text-xs text-text-dim",children:s("persona.updated",{at:S(n.updated_at)})}),e.jsx(C,{draft:d,onChange:g,onSave:()=>void w(),saving:i.isPending,dirty:b,canDelete:!0,onDelete:()=>h(!0)})]}):e.jsxs(e.Fragment,{children:[e.jsx(P,{icon:e.jsx(D,{}),title:s("persona.empty.title"),description:s("persona.empty.description")}),e.jsx(C,{draft:d,onChange:g,onSave:()=>void w(),saving:i.isPending,dirty:b,canDelete:!1,onDelete:()=>h(!0)})]}),e.jsx(A,{open:E,onOpenChange:h,title:s("persona.confirmDelete"),description:s("persona.confirmDeleteDesc"),intent:"danger",confirmLabel:s("persona.delete"),onConfirm:L})]})}function C({draft:t,onChange:s,onSave:r,saving:n,dirty:o,canDelete:v,onDelete:a}){const{t:i}=p("memory");return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx(F,{htmlFor:"persona-editor",className:"text-sm text-text-dim",children:i("persona.editorLabel")}),e.jsx("textarea",{id:"persona-editor",value:t,onChange:f=>s(f.target.value),rows:12,className:z("w-full resize-y rounded-md border bg-bg px-3 py-2","font-mono text-sm leading-6","focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-1 focus:ring-offset-bg",o?"border-accent":"border-border")}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[v&&e.jsxs(u,{type:"button",variant:"outline",size:"sm",onClick:a,children:[e.jsx(G,{className:"h-3 w-3"}),i("persona.delete")]}),e.jsxs(u,{type:"button",size:"sm",className:"ml-auto",disabled:!o||n||t.trim().length===0,onClick:r,children:[n?e.jsx(x,{className:"h-4 w-4 animate-spin"}):null,i("persona.save")]})]})]})}function I({job:t}){const{t:s}=p("memory");return t?t.phase==="running"?e.jsxs(j,{variant:"info",children:[e.jsx(x,{className:"h-3 w-3 animate-spin"}),s("persona.consolidate.running")]}):t.phase==="done"?e.jsxs(j,{variant:"success",children:[e.jsx(Q,{className:"h-3 w-3"}),s("persona.consolidate.lastRun",{at:S(t.finishedAt??t.startedAt)})]}):e.jsxs(j,{variant:"danger",children:[e.jsx(X,{className:"h-3 w-3"}),s("persona.consolidate.doneFailed")]}):null}function S(t){try{const s=new Date(t);return Number.isNaN(s.getTime())?String(t):s.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(t)}}export{oe as default};
|
|
2
|
+
//# sourceMappingURL=persona-CElXQZ4p.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persona-BvtcZh6G.js","sources":["../../src/routes/memory/persona.tsx"],"sourcesContent":["/**\n * /memory/persona — view + edit the per-user persona summary +\n * trigger the consolidation pass.\n *\n * Layout: status strip (last consolidate run + button) on top, then\n * the persona editor (textarea + Save + Delete). The editor enters\n * an \"unsaved changes\" state when the textarea diverges from the\n * server-rendered summary; Save flips back to clean.\n *\n * Consolidate flow:\n * * Trigger button POSTs /api/memory/consolidate; the backend\n * replies 202 with a jobId.\n * * /api/memory/consolidate/status is polled every 3s by the\n * hook so the operator sees phase transitions live (running →\n * done / failed) without manual refresh.\n * * On `done`, the persona query is invalidated — the new\n * summary appears in the textarea automatically.\n */\n\nimport { useEffect, useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Brain, CheckCircle, Loader2, Play, RefreshCcw, Trash2, XCircle } from 'lucide-react'\n\nimport { EmptyState } from '@/components/common/empty-state'\nimport { ConfirmDialog } from '@/components/common/confirm-dialog'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Label } from '@/components/ui/label'\nimport {\n useMemoryPersona,\n useUpdatePersona,\n useDeletePersona,\n useConsolidateStatus,\n useTriggerConsolidate,\n} from '@/hooks/use-memory'\nimport { describeError } from '@/lib/api/errors'\nimport { cn } from '@/lib/utils'\nimport type { ConsolidateJob } from '@/types/api'\n\nexport default function MemoryPersonaRoute(): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n const [params] = useSearchParams()\n const userKey = params.get('user') ?? ''\n\n if (!userKey) {\n return (\n <div className=\"mx-auto max-w-3xl\">\n <EmptyState\n icon={<Brain />}\n title={t('noUserSelected.title')}\n description={t('noUserSelected.description')}\n />\n </div>\n )\n }\n\n return <PersonaEditor userKey={userKey} />\n}\n\ninterface PersonaEditorProps {\n userKey: string\n}\n\nfunction PersonaEditor({ userKey }: PersonaEditorProps): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n const personaQuery = useMemoryPersona(userKey)\n const persona = personaQuery.data\n\n const consolidate = useTriggerConsolidate()\n const status = useConsolidateStatus()\n const latestJob = status.data?.jobs[0]\n\n const updatePersona = useUpdatePersona()\n const deletePersona = useDeletePersona()\n const [confirmDelete, setConfirmDelete] = useState(false)\n\n /** Editor state — initialised from the server summary; tracks\n * dirtiness via reference comparison after each save. */\n const [draft, setDraft] = useState(persona?.summary ?? '')\n useEffect(() => {\n setDraft(persona?.summary ?? '')\n }, [persona?.summary])\n const dirty = draft !== (persona?.summary ?? '')\n\n async function onSave(): Promise<void> {\n const trimmed = draft.trim()\n if (!trimmed) return\n try {\n await updatePersona.mutateAsync({ user_key: userKey, body: { summary: trimmed } })\n toast.success(t('persona.saved'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n async function onConfirmDelete(): Promise<void> {\n try {\n await deletePersona.mutateAsync(userKey)\n toast.success(t('common:actions.delete'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n throw err\n }\n }\n\n async function onTrigger(): Promise<void> {\n try {\n await consolidate.mutateAsync()\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n return (\n <div className=\"mx-auto flex max-w-4xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('persona.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => personaQuery.refetch()}\n disabled={personaQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {personaQuery.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('persona.subtitle')}</p>\n </header>\n\n {/* Consolidate strip */}\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <span className=\"font-medium text-sm text-text\">{t('persona.consolidate.trigger')}</span>\n <ConsolidateBadge job={latestJob} />\n <Button\n variant=\"default\"\n size=\"sm\"\n onClick={() => void onTrigger()}\n disabled={consolidate.isPending || latestJob?.phase === 'running'}\n className=\"ml-auto\"\n >\n {consolidate.isPending\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <Play className=\"h-4 w-4\" />}\n {consolidate.isPending\n ? t('persona.consolidate.triggering')\n : t('persona.consolidate.trigger')}\n </Button>\n </div>\n {latestJob?.phase === 'done' && (latestJob.result.users != null || latestJob.result.updated != null) && (\n <p className=\"mt-2 text-xs text-text-dim\">\n {t('persona.consolidate.result', {\n users: latestJob.result.users ?? 0,\n updated: latestJob.result.updated ?? 0,\n })}\n </p>\n )}\n {latestJob?.phase === 'failed' && latestJob.result.error && (\n <p className=\"mt-2 text-xs text-danger\">{latestJob.result.error}</p>\n )}\n </div>\n\n {/* Editor */}\n {personaQuery.isLoading ? (\n <div className=\"h-48 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : !persona ? (\n <>\n <EmptyState\n icon={<Brain />}\n title={t('persona.empty.title')}\n description={t('persona.empty.description')}\n />\n {/* Even with no persona, the operator can still type one in\n and save — the upsert handler creates a new row. */}\n <PersonaTextarea\n draft={draft}\n onChange={setDraft}\n onSave={() => void onSave()}\n saving={updatePersona.isPending}\n dirty={dirty}\n canDelete={false}\n onDelete={() => setConfirmDelete(true)}\n />\n </>\n ) : (\n <>\n {persona.updated_at > 0 && (\n <div className=\"text-xs text-text-dim\">\n {t('persona.updated', { at: formatEpoch(persona.updated_at) })}\n </div>\n )}\n <PersonaTextarea\n draft={draft}\n onChange={setDraft}\n onSave={() => void onSave()}\n saving={updatePersona.isPending}\n dirty={dirty}\n canDelete\n onDelete={() => setConfirmDelete(true)}\n />\n </>\n )}\n\n <ConfirmDialog\n open={confirmDelete}\n onOpenChange={setConfirmDelete}\n title={t('persona.confirmDelete')}\n description={t('persona.confirmDeleteDesc')}\n intent=\"danger\"\n confirmLabel={t('persona.delete')}\n onConfirm={onConfirmDelete}\n />\n </div>\n )\n}\n\ninterface PersonaTextareaProps {\n draft: string\n onChange: (next: string) => void\n onSave: () => void\n saving: boolean\n dirty: boolean\n canDelete: boolean\n onDelete: () => void\n}\n\nfunction PersonaTextarea({\n draft, onChange, onSave, saving, dirty, canDelete, onDelete,\n}: PersonaTextareaProps): JSX.Element {\n const { t } = useTranslation('memory')\n return (\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"persona-editor\" className=\"text-sm text-text-dim\">\n {t('persona.editorLabel')}\n </Label>\n <textarea\n id=\"persona-editor\"\n value={draft}\n onChange={(e) => onChange(e.target.value)}\n rows={12}\n className={cn(\n 'w-full resize-y rounded-md border bg-bg px-3 py-2',\n 'font-mono text-sm leading-6',\n 'focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-1 focus:ring-offset-bg',\n dirty ? 'border-accent' : 'border-border',\n )}\n />\n <div className=\"flex flex-wrap items-center gap-2\">\n {canDelete && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={onDelete}\n >\n <Trash2 className=\"h-3 w-3\" />\n {t('persona.delete')}\n </Button>\n )}\n <Button\n type=\"button\"\n size=\"sm\"\n className=\"ml-auto\"\n disabled={!dirty || saving || draft.trim().length === 0}\n onClick={onSave}\n >\n {saving ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : null}\n {t('persona.save')}\n </Button>\n </div>\n </div>\n )\n}\n\ninterface ConsolidateBadgeProps {\n job: ConsolidateJob | undefined\n}\n\nfunction ConsolidateBadge({ job }: ConsolidateBadgeProps): JSX.Element | null {\n const { t } = useTranslation('memory')\n if (!job) return null\n if (job.phase === 'running') {\n return (\n <Badge variant=\"info\">\n <Loader2 className=\"h-3 w-3 animate-spin\" />\n {t('persona.consolidate.running')}\n </Badge>\n )\n }\n if (job.phase === 'done') {\n return (\n <Badge variant=\"success\">\n <CheckCircle className=\"h-3 w-3\" />\n {t('persona.consolidate.lastRun', { at: formatEpoch(job.finishedAt ?? job.startedAt) })}\n </Badge>\n )\n }\n return (\n <Badge variant=\"danger\">\n <XCircle className=\"h-3 w-3\" />\n {t('persona.consolidate.doneFailed')}\n </Badge>\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":["MemoryPersonaRoute","useTranslation","params","useSearchParams","userKey","jsx","PersonaEditor","EmptyState","Brain","t","personaQuery","useMemoryPersona","persona","consolidate","useTriggerConsolidate","latestJob","useConsolidateStatus","updatePersona","useUpdatePersona","deletePersona","useDeletePersona","confirmDelete","setConfirmDelete","useState","draft","setDraft","useEffect","dirty","onSave","trimmed","toast","err","message","describeError","onConfirmDelete","onTrigger","jsxs","Button","Loader2","RefreshCcw","ConsolidateBadge","Play","Fragment","formatEpoch","PersonaTextarea","ConfirmDialog","onChange","saving","canDelete","onDelete","Label","e","cn","Trash2","job","Badge","CheckCircle","XCircle","ms","d"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"persona-CElXQZ4p.js","sources":["../../src/routes/memory/persona.tsx"],"sourcesContent":["/**\n * /memory/persona — view + edit the per-user persona summary +\n * trigger the consolidation pass.\n *\n * Layout: status strip (last consolidate run + button) on top, then\n * the persona editor (textarea + Save + Delete). The editor enters\n * an \"unsaved changes\" state when the textarea diverges from the\n * server-rendered summary; Save flips back to clean.\n *\n * Consolidate flow:\n * * Trigger button POSTs /api/memory/consolidate; the backend\n * replies 202 with a jobId.\n * * /api/memory/consolidate/status is polled every 3s by the\n * hook so the operator sees phase transitions live (running →\n * done / failed) without manual refresh.\n * * On `done`, the persona query is invalidated — the new\n * summary appears in the textarea automatically.\n */\n\nimport { useEffect, useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Brain, CheckCircle, Loader2, Play, RefreshCcw, Trash2, XCircle } from 'lucide-react'\n\nimport { EmptyState } from '@/components/common/empty-state'\nimport { ConfirmDialog } from '@/components/common/confirm-dialog'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Label } from '@/components/ui/label'\nimport {\n useMemoryPersona,\n useUpdatePersona,\n useDeletePersona,\n useConsolidateStatus,\n useTriggerConsolidate,\n} from '@/hooks/use-memory'\nimport { describeError } from '@/lib/api/errors'\nimport { cn } from '@/lib/utils'\nimport type { ConsolidateJob } from '@/types/api'\n\nexport default function MemoryPersonaRoute(): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n const [params] = useSearchParams()\n const userKey = params.get('user') ?? ''\n\n if (!userKey) {\n return (\n <div className=\"mx-auto max-w-3xl\">\n <EmptyState\n icon={<Brain />}\n title={t('noUserSelected.title')}\n description={t('noUserSelected.description')}\n />\n </div>\n )\n }\n\n return <PersonaEditor userKey={userKey} />\n}\n\ninterface PersonaEditorProps {\n userKey: string\n}\n\nfunction PersonaEditor({ userKey }: PersonaEditorProps): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n const personaQuery = useMemoryPersona(userKey)\n const persona = personaQuery.data\n\n const consolidate = useTriggerConsolidate()\n const status = useConsolidateStatus()\n const latestJob = status.data?.jobs[0]\n\n const updatePersona = useUpdatePersona()\n const deletePersona = useDeletePersona()\n const [confirmDelete, setConfirmDelete] = useState(false)\n\n /** Editor state — initialised from the server summary; tracks\n * dirtiness via reference comparison after each save. */\n const [draft, setDraft] = useState(persona?.summary ?? '')\n useEffect(() => {\n setDraft(persona?.summary ?? '')\n }, [persona?.summary])\n const dirty = draft !== (persona?.summary ?? '')\n\n async function onSave(): Promise<void> {\n const trimmed = draft.trim()\n if (!trimmed) return\n try {\n await updatePersona.mutateAsync({ user_key: userKey, body: { summary: trimmed } })\n toast.success(t('persona.saved'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n async function onConfirmDelete(): Promise<void> {\n try {\n await deletePersona.mutateAsync(userKey)\n toast.success(t('common:actions.delete'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n throw err\n }\n }\n\n async function onTrigger(): Promise<void> {\n try {\n await consolidate.mutateAsync()\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n return (\n <div className=\"mx-auto flex max-w-4xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('persona.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => personaQuery.refetch()}\n disabled={personaQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {personaQuery.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('persona.subtitle')}</p>\n </header>\n\n {/* Consolidate strip */}\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <span className=\"font-medium text-sm text-text\">{t('persona.consolidate.trigger')}</span>\n <ConsolidateBadge job={latestJob} />\n <Button\n variant=\"default\"\n size=\"sm\"\n onClick={() => void onTrigger()}\n disabled={consolidate.isPending || latestJob?.phase === 'running'}\n className=\"ml-auto\"\n >\n {consolidate.isPending\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <Play className=\"h-4 w-4\" />}\n {consolidate.isPending\n ? t('persona.consolidate.triggering')\n : t('persona.consolidate.trigger')}\n </Button>\n </div>\n {latestJob?.phase === 'done' && (latestJob.result.users != null || latestJob.result.updated != null) && (\n <p className=\"mt-2 text-xs text-text-dim\">\n {t('persona.consolidate.result', {\n users: latestJob.result.users ?? 0,\n updated: latestJob.result.updated ?? 0,\n })}\n </p>\n )}\n {latestJob?.phase === 'failed' && latestJob.result.error && (\n <p className=\"mt-2 text-xs text-danger\">{latestJob.result.error}</p>\n )}\n </div>\n\n {/* Editor */}\n {personaQuery.isLoading ? (\n <div className=\"h-48 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : !persona ? (\n <>\n <EmptyState\n icon={<Brain />}\n title={t('persona.empty.title')}\n description={t('persona.empty.description')}\n />\n {/* Even with no persona, the operator can still type one in\n and save — the upsert handler creates a new row. */}\n <PersonaTextarea\n draft={draft}\n onChange={setDraft}\n onSave={() => void onSave()}\n saving={updatePersona.isPending}\n dirty={dirty}\n canDelete={false}\n onDelete={() => setConfirmDelete(true)}\n />\n </>\n ) : (\n <>\n {persona.updated_at > 0 && (\n <div className=\"text-xs text-text-dim\">\n {t('persona.updated', { at: formatEpoch(persona.updated_at) })}\n </div>\n )}\n <PersonaTextarea\n draft={draft}\n onChange={setDraft}\n onSave={() => void onSave()}\n saving={updatePersona.isPending}\n dirty={dirty}\n canDelete\n onDelete={() => setConfirmDelete(true)}\n />\n </>\n )}\n\n <ConfirmDialog\n open={confirmDelete}\n onOpenChange={setConfirmDelete}\n title={t('persona.confirmDelete')}\n description={t('persona.confirmDeleteDesc')}\n intent=\"danger\"\n confirmLabel={t('persona.delete')}\n onConfirm={onConfirmDelete}\n />\n </div>\n )\n}\n\ninterface PersonaTextareaProps {\n draft: string\n onChange: (next: string) => void\n onSave: () => void\n saving: boolean\n dirty: boolean\n canDelete: boolean\n onDelete: () => void\n}\n\nfunction PersonaTextarea({\n draft, onChange, onSave, saving, dirty, canDelete, onDelete,\n}: PersonaTextareaProps): JSX.Element {\n const { t } = useTranslation('memory')\n return (\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"persona-editor\" className=\"text-sm text-text-dim\">\n {t('persona.editorLabel')}\n </Label>\n <textarea\n id=\"persona-editor\"\n value={draft}\n onChange={(e) => onChange(e.target.value)}\n rows={12}\n className={cn(\n 'w-full resize-y rounded-md border bg-bg px-3 py-2',\n 'font-mono text-sm leading-6',\n 'focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-1 focus:ring-offset-bg',\n dirty ? 'border-accent' : 'border-border',\n )}\n />\n <div className=\"flex flex-wrap items-center gap-2\">\n {canDelete && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={onDelete}\n >\n <Trash2 className=\"h-3 w-3\" />\n {t('persona.delete')}\n </Button>\n )}\n <Button\n type=\"button\"\n size=\"sm\"\n className=\"ml-auto\"\n disabled={!dirty || saving || draft.trim().length === 0}\n onClick={onSave}\n >\n {saving ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : null}\n {t('persona.save')}\n </Button>\n </div>\n </div>\n )\n}\n\ninterface ConsolidateBadgeProps {\n job: ConsolidateJob | undefined\n}\n\nfunction ConsolidateBadge({ job }: ConsolidateBadgeProps): JSX.Element | null {\n const { t } = useTranslation('memory')\n if (!job) return null\n if (job.phase === 'running') {\n return (\n <Badge variant=\"info\">\n <Loader2 className=\"h-3 w-3 animate-spin\" />\n {t('persona.consolidate.running')}\n </Badge>\n )\n }\n if (job.phase === 'done') {\n return (\n <Badge variant=\"success\">\n <CheckCircle className=\"h-3 w-3\" />\n {t('persona.consolidate.lastRun', { at: formatEpoch(job.finishedAt ?? job.startedAt) })}\n </Badge>\n )\n }\n return (\n <Badge variant=\"danger\">\n <XCircle className=\"h-3 w-3\" />\n {t('persona.consolidate.doneFailed')}\n </Badge>\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":["MemoryPersonaRoute","useTranslation","params","useSearchParams","userKey","jsx","PersonaEditor","EmptyState","Brain","t","personaQuery","useMemoryPersona","persona","consolidate","useTriggerConsolidate","latestJob","useConsolidateStatus","updatePersona","useUpdatePersona","deletePersona","useDeletePersona","confirmDelete","setConfirmDelete","useState","draft","setDraft","useEffect","dirty","onSave","trimmed","toast","err","message","describeError","onConfirmDelete","onTrigger","jsxs","Button","Loader2","RefreshCcw","ConsolidateBadge","Play","Fragment","formatEpoch","PersonaTextarea","ConfirmDialog","onChange","saving","canDelete","onDelete","Label","e","cn","Trash2","job","Badge","CheckCircle","XCircle","ms","d"],"mappings":"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"}
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{h as f,u as j,j as e,d as u,e as m,w as N,I as g,x as b,C}from"./index-DCfdN5R7.js";import{r as o}from"./react-DlP5eolq.js";import{T as v,a as y,b as p,c as i,d as k,e as l}from"./table-sCMZBe_Z.js";import{f as F}from"./use-background-tasks-CwFmOokw.js";import{C as w}from"./clipboard-list-lnqdk2_J.js";import{L}from"./loader-circle-DDdmcH0k.js";import{R as T}from"./refresh-ccw-DlAd-eTQ.js";import{C as M}from"./chevron-right-CFRb-SM_.js";import{C as R}from"./clock-4hd1joQe.js";import{C as O}from"./circle-x-CqFMzO-x.js";/**
|
|
2
2
|
* @license lucide-react v0.469.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const
|
|
7
|
-
|
|
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 P=j("PenLine",[["path",{d:"M12 20h9",key:"t2du7b"}],["path",{d:"M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z",key:"1ykcvy"}]]),z={approved:e.jsx(R,{className:"h-3 w-3"}),rejected:e.jsx(T,{className:"h-3 w-3"}),edited:e.jsx(P,{className:"h-3 w-3"}),expired:e.jsx(M,{className:"h-3 w-3"})},A={approved:"success",rejected:"warning",edited:"info",expired:"outline"};function E(s){if(s==null)return"—";if(s<1e3)return`${s}ms`;const a=s/1e3;return a<60?`${a.toFixed(1)}s`:`${(a/60).toFixed(1)}min`}function X(){const{t:s}=u(["tasks","common"]),[a,r]=o.useState(""),[c,d]=o.useState(""),t=k({threadKey:c||void 0,limit:200}),x=o.useMemo(()=>t.data?.plans??[],[t.data]);function h(){d(a.trim())}return e.jsxs("div",{className:"mx-auto flex max-w-6xl flex-col gap-4 p-4",children:[e.jsxs("header",{className:"flex items-center gap-3",children:[e.jsx(O,{className:"h-5 w-5 text-text-dim"}),e.jsx("h1",{className:"text-xl font-semibold",children:s("plans.title")}),e.jsx(f,{variant:"info",children:x.length}),e.jsxs(m,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>void t.refetch(),disabled:t.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[t.isFetching?e.jsx(L,{className:"h-4 w-4 animate-spin"}):e.jsx(w,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("plans.refresh")})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("plans.subtitle")}),e.jsxs("section",{className:"flex items-end gap-2 rounded-md border border-border bg-surface p-3",children:[e.jsxs("div",{className:"flex flex-1 flex-col gap-1",children:[e.jsx(g,{className:"text-xs font-medium",children:s("plans.filterLabel")}),e.jsx(N,{value:a,onChange:n=>r(n.target.value),onKeyDown:n=>{n.key==="Enter"&&h()},placeholder:"tg:8754479311:default",className:"font-mono text-xs"})]}),e.jsx(m,{size:"sm",onClick:h,disabled:t.isFetching,children:s("plans.applyFilter")}),c&&e.jsx(m,{size:"sm",variant:"ghost",onClick:()=>{r(""),d("")},children:s("plans.clearFilter")})]}),t.isLoading?e.jsx("div",{className:"h-32 rounded-md bg-surface-2 animate-pulse"}):x.length===0?e.jsx("section",{className:"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim",children:s(c?"plans.emptyFiltered":"plans.empty")}):e.jsxs(C,{children:[e.jsx(v,{children:e.jsxs(p,{children:[e.jsx(i,{className:"w-8"}),e.jsx(i,{children:s("plans.col.outcome")}),e.jsx(i,{children:s("plans.col.thread")}),e.jsx(i,{children:s("plans.col.resolvedAt")}),e.jsx(i,{children:s("plans.col.pending")}),e.jsx(i,{children:s("plans.col.detail")})]})}),e.jsx(y,{children:x.map(n=>e.jsx(I,{row:n},n.id))})]})]})}function I({row:s}){const{t:a}=u(["tasks"]),[r,c]=o.useState(!1);return e.jsxs(e.Fragment,{children:[e.jsxs(p,{className:"cursor-pointer hover:bg-surface-hover",onClick:()=>c(d=>!d),children:[e.jsx(l,{className:"p-1 align-top text-text-dim",children:r?e.jsx(b,{className:"h-4 w-4"}):e.jsx(F,{className:"h-4 w-4"})}),e.jsx(l,{className:"align-top",children:e.jsxs(f,{variant:A[s.outcome],children:[z[s.outcome],e.jsx("span",{className:"ml-1",children:a(`plans.outcome.${s.outcome}`,{defaultValue:s.outcome})})]})}),e.jsx(l,{className:"align-top",children:e.jsx("code",{className:"text-[11px]",children:s.threadKey})}),e.jsx(l,{className:"align-top text-[11px] text-text-dim",children:s.resolvedAt}),e.jsx(l,{className:"align-top text-[11px] text-text-dim",children:E(s.pendingMs)}),e.jsx(l,{className:"align-top text-xs",children:s.detail?e.jsxs("span",{title:s.detail,children:[s.detail.slice(0,80),s.detail.length>80?"…":""]}):e.jsx("span",{className:"text-text-dim",children:"—"})})]}),r&&e.jsx(p,{children:e.jsxs(l,{colSpan:6,className:"bg-surface-2 p-3",children:[e.jsx("div",{className:"text-[11px] text-text-dim",children:a("plans.planMdLabel")}),e.jsx("pre",{className:"mt-1 max-h-96 overflow-y-auto whitespace-pre-wrap rounded border border-border bg-surface p-3 text-[12px]",children:s.planMd})]})})]})}export{X as default};
|
|
12
|
-
//# sourceMappingURL=plans-i3a6lrqF.js.map
|
|
6
|
+
*/const P=f("PenLine",[["path",{d:"M12 20h9",key:"t2du7b"}],["path",{d:"M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z",key:"1ykcvy"}]]),A={approved:e.jsx(C,{className:"h-3 w-3"}),rejected:e.jsx(O,{className:"h-3 w-3"}),edited:e.jsx(P,{className:"h-3 w-3"}),expired:e.jsx(R,{className:"h-3 w-3"})},E={approved:"success",rejected:"warning",edited:"info",expired:"outline"};function I(s){if(s==null)return"—";if(s<1e3)return`${s}ms`;const a=s/1e3;return a<60?`${a.toFixed(1)}s`:`${(a/60).toFixed(1)}min`}function X(){const{t:s}=j(["tasks","common"]),[a,r]=o.useState(""),[c,d]=o.useState(""),t=F({threadKey:c||void 0,limit:200}),x=o.useMemo(()=>t.data?.plans??[],[t.data]);function h(){d(a.trim())}return e.jsxs("div",{className:"mx-auto flex max-w-6xl flex-col gap-4 p-4",children:[e.jsxs("header",{className:"flex items-center gap-3",children:[e.jsx(w,{className:"h-5 w-5 text-text-dim"}),e.jsx("h1",{className:"text-xl font-semibold",children:s("plans.title")}),e.jsx(u,{variant:"info",children:x.length}),e.jsxs(m,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>void t.refetch(),disabled:t.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[t.isFetching?e.jsx(L,{className:"h-4 w-4 animate-spin"}):e.jsx(T,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("plans.refresh")})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("plans.subtitle")}),e.jsxs("section",{className:"flex items-end gap-2 rounded-md border border-border bg-surface p-3",children:[e.jsxs("div",{className:"flex flex-1 flex-col gap-1",children:[e.jsx(N,{className:"text-xs font-medium",children:s("plans.filterLabel")}),e.jsx(g,{value:a,onChange:n=>r(n.target.value),onKeyDown:n=>{n.key==="Enter"&&h()},placeholder:"tg:8754479311:default",className:"font-mono text-xs"})]}),e.jsx(m,{size:"sm",onClick:h,disabled:t.isFetching,children:s("plans.applyFilter")}),c&&e.jsx(m,{size:"sm",variant:"ghost",onClick:()=>{r(""),d("")},children:s("plans.clearFilter")})]}),t.isLoading?e.jsx("div",{className:"h-32 rounded-md bg-surface-2 animate-pulse"}):x.length===0?e.jsx("section",{className:"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim",children:s(c?"plans.emptyFiltered":"plans.empty")}):e.jsxs(v,{children:[e.jsx(y,{children:e.jsxs(p,{children:[e.jsx(i,{className:"w-8"}),e.jsx(i,{children:s("plans.col.outcome")}),e.jsx(i,{children:s("plans.col.thread")}),e.jsx(i,{children:s("plans.col.resolvedAt")}),e.jsx(i,{children:s("plans.col.pending")}),e.jsx(i,{children:s("plans.col.detail")})]})}),e.jsx(k,{children:x.map(n=>e.jsx(S,{row:n},n.id))})]})]})}function S({row:s}){const{t:a}=j(["tasks"]),[r,c]=o.useState(!1);return e.jsxs(e.Fragment,{children:[e.jsxs(p,{className:"cursor-pointer hover:bg-surface-hover",onClick:()=>c(d=>!d),children:[e.jsx(l,{className:"p-1 align-top text-text-dim",children:r?e.jsx(b,{className:"h-4 w-4"}):e.jsx(M,{className:"h-4 w-4"})}),e.jsx(l,{className:"align-top",children:e.jsxs(u,{variant:E[s.outcome],children:[A[s.outcome],e.jsx("span",{className:"ml-1",children:a(`plans.outcome.${s.outcome}`,{defaultValue:s.outcome})})]})}),e.jsx(l,{className:"align-top",children:e.jsx("code",{className:"text-[11px]",children:s.threadKey})}),e.jsx(l,{className:"align-top text-[11px] text-text-dim",children:s.resolvedAt}),e.jsx(l,{className:"align-top text-[11px] text-text-dim",children:I(s.pendingMs)}),e.jsx(l,{className:"align-top text-xs",children:s.detail?e.jsxs("span",{title:s.detail,children:[s.detail.slice(0,80),s.detail.length>80?"…":""]}):e.jsx("span",{className:"text-text-dim",children:"—"})})]}),r&&e.jsx(p,{children:e.jsxs(l,{colSpan:6,className:"bg-surface-2 p-3",children:[e.jsx("div",{className:"text-[11px] text-text-dim",children:a("plans.planMdLabel")}),e.jsx("pre",{className:"mt-1 max-h-96 overflow-y-auto whitespace-pre-wrap rounded border border-border bg-surface p-3 text-[12px]",children:s.planMd})]})})]})}export{X as default};
|
|
7
|
+
//# sourceMappingURL=plans-Bo5LlLeH.js.map
|