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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-CG3WiG7h.js","sources":["../../src/routes/dashboard.tsx"],"sourcesContent":["/**\n * /dashboard — operator home.\n *\n * Keep this page as a routing surface, not a second settings page: it\n * summarizes the minimum path and links to the detailed owner pages.\n */\n\nimport { Link } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport {\n AlertCircle,\n ArrowRight,\n Bot,\n CheckCircle2,\n ClipboardList,\n Database,\n Loader2,\n MessageSquare,\n Plug,\n RefreshCcw,\n Server,\n Settings,\n ShieldCheck,\n} from 'lucide-react'\n\nimport { Topbar } from '@/components/shell/topbar'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { useLlmList } from '@/hooks/use-llm-admin'\nimport { useConfig, useServiceStatus } from '@/hooks/use-settings'\nimport { useAgentsStatus } from '@/hooks/use-workspace'\nimport { agentDisplayName } from '@/lib/agent-label'\nimport { cn } from '@/lib/utils'\n\ntype StatusState = 'done' | 'todo' | 'warn' | 'loading'\ntype BadgeVariant = 'success' | 'warning' | 'info' | 'outline'\n\ninterface StatusCard {\n id: string\n state: StatusState\n icon: JSX.Element\n title: string\n detail: string\n meta?: string\n action: string\n to: string\n}\n\ninterface DashboardAction {\n id: string\n title: string\n detail: string\n to: string\n primary?: boolean\n}\n\nconst STATE_BADGE: Record<StatusState, BadgeVariant> = {\n done: 'success',\n todo: 'outline',\n warn: 'warning',\n loading: 'info',\n}\n\nexport default function DashboardRoute(): JSX.Element {\n const { t } = useTranslation()\n const cfgQuery = useConfig()\n const serviceQuery = useServiceStatus()\n const agentsQuery = useAgentsStatus()\n const llmQuery = useLlmList()\n\n const cfg = cfgQuery.data\n const defaultAgent = cfg?.defaultAgent || cfg?.agents?.[0] || ''\n const agentName = defaultAgent ? agentDisplayName(defaultAgent) : t('dashboard.unknown')\n const nativeAgentSelected = defaultAgent === 'native'\n const agentStatus = defaultAgent ? agentsQuery.data?.[defaultAgent] : undefined\n const agentLoading = cfgQuery.isLoading || agentsQuery.isLoading\n const service = serviceQuery.data\n const serviceRunning = Boolean(service && service.mode !== 'none')\n const usableBackends = (llmQuery.data?.backends ?? []).filter((b) => b.secret.source !== 'none')\n const llmReady = usableBackends.length > 0\n const messengers = cfg?.messengers ?? []\n const imReady = messengers.length > 0\n\n const webState: StatusState = serviceQuery.isLoading ? 'loading' : serviceRunning ? 'done' : 'warn'\n const agentState: StatusState = agentLoading\n ? 'loading'\n : agentStatus === true\n ? 'done'\n : agentStatus === false\n ? 'warn'\n : defaultAgent\n ? 'todo'\n : 'warn'\n const llmState: StatusState = llmQuery.isLoading\n ? 'loading'\n : llmReady\n ? 'done'\n : nativeAgentSelected\n ? 'warn'\n : 'todo'\n const imState: StatusState = cfgQuery.isLoading ? 'loading' : imReady ? 'done' : 'todo'\n const coreReadyCount = [webState, agentState, imState].filter((s) => s === 'done').length\n const anyFetching = cfgQuery.isFetching\n || serviceQuery.isFetching\n || agentsQuery.isFetching\n || llmQuery.isFetching\n\n const cards: StatusCard[] = [\n {\n id: 'web',\n state: webState,\n icon: <MessageSquare />,\n title: t('dashboard.cards.web.title'),\n detail: serviceRunning\n ? t('dashboard.cards.web.ready', { mode: service?.mode ?? '' })\n : t('dashboard.cards.web.needsStart'),\n meta: service?.web ? `${service.web.bind}:${service.web.port}` : undefined,\n action: serviceRunning\n ? t('dashboard.cards.web.open')\n : t('dashboard.cards.web.action'),\n to: serviceRunning ? '/?welcome=1' : '/settings/service',\n },\n {\n id: 'agent',\n state: agentState,\n icon: <Bot />,\n title: t('dashboard.cards.agent.title'),\n detail: agentStatus === true\n ? t('dashboard.cards.agent.ready', { agent: agentName })\n : agentStatus === false\n ? t('dashboard.cards.agent.offline', { agent: agentName })\n : defaultAgent\n ? t('dashboard.cards.agent.selected', { agent: agentName })\n : t('dashboard.cards.agent.empty'),\n meta: defaultAgent ? t('dashboard.cards.agent.default') : undefined,\n action: t('dashboard.cards.agent.action'),\n to: '/settings/agents',\n },\n {\n id: 'llm',\n state: llmState,\n icon: <Bot />,\n title: t('dashboard.cards.llm.title'),\n detail: llmReady\n ? t('dashboard.cards.llm.ready', { count: usableBackends.length })\n : nativeAgentSelected\n ? t('dashboard.cards.llm.required')\n : t('dashboard.cards.llm.optional'),\n meta: nativeAgentSelected\n ? t('dashboard.cards.llm.core')\n : t('dashboard.cards.llm.meta'),\n action: t('dashboard.cards.llm.action'),\n to: '/settings/llm',\n },\n {\n id: 'im',\n state: imState,\n icon: <Plug />,\n title: t('dashboard.cards.im.title'),\n detail: imReady\n ? t('dashboard.cards.im.ready', { platforms: messengers.map((m) => platformLabel(m, t)).join(', ') })\n : t('dashboard.cards.im.empty'),\n meta: imReady ? t('dashboard.cards.im.metaReady', { count: messengers.length }) : undefined,\n action: t('dashboard.cards.im.action'),\n to: '/settings/messengers',\n },\n ]\n\n const nextActions = makeNextActions({\n t,\n serviceRunning,\n agentReady: agentState === 'done',\n imReady,\n llmReady,\n nativeAgentSelected,\n })\n\n const quickLinks = [\n { to: '/?welcome=1', icon: <MessageSquare />, title: t('dashboard.quick.chat') },\n { to: '/settings/start', icon: <Settings />, title: t('dashboard.quick.start') },\n { to: '/workspace', icon: <Database />, title: t('dashboard.quick.workspace') },\n { to: '/settings/service', icon: <Server />, title: t('dashboard.quick.service') },\n ]\n const advancedLinks = [\n { to: '/tasks', icon: <ClipboardList />, title: t('dashboard.advanced.tasks') },\n { to: '/memory', icon: <Database />, title: t('dashboard.advanced.memory') },\n { to: '/settings/agim-skills/installed', icon: <ShieldCheck />, title: t('dashboard.advanced.skills') },\n { to: '/observability', icon: <Server />, title: t('dashboard.advanced.observability') },\n ]\n\n return (\n <div className=\"min-h-dvh bg-bg\">\n <Topbar />\n <main className=\"mx-auto flex max-w-6xl flex-col gap-4 px-4 py-4 sm:px-6\">\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('dashboard.title')}</h1>\n <Badge variant={coreReadyCount >= 3 ? 'success' : 'info'}>\n {t('dashboard.coreReady', { count: coreReadyCount })}\n </Badge>\n </div>\n <p className=\"mt-1 max-w-2xl text-sm text-text-dim\">{t('dashboard.subtitle')}</p>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <Button asChild size=\"sm\">\n <Link to=\"/?welcome=1\">\n <MessageSquare className=\"h-4 w-4\" />\n <span>{t('dashboard.actions.chat')}</span>\n </Link>\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={anyFetching}\n onClick={() => {\n void cfgQuery.refetch()\n void serviceQuery.refetch()\n void agentsQuery.refetch()\n void llmQuery.refetch()\n }}\n >\n <RefreshCcw className={cn('h-4 w-4', anyFetching && 'animate-spin')} />\n <span>{t('actions.refresh')}</span>\n </Button>\n </div>\n </header>\n\n <section className=\"grid gap-3 md:grid-cols-2 xl:grid-cols-4\">\n {cards.map((card) => (\n <StatusCardItem key={card.id} card={card} />\n ))}\n </section>\n\n <section className=\"grid gap-4 lg:grid-cols-[minmax(0,1.25fr)_minmax(280px,0.75fr)]\">\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"mb-3 flex items-center justify-between gap-3\">\n <h2 className=\"text-sm font-semibold\">{t('dashboard.next.title')}</h2>\n <Badge variant={coreReadyCount >= 3 ? 'success' : 'secondary'}>\n {t(coreReadyCount >= 3 ? 'dashboard.next.ready' : 'dashboard.next.pending')}\n </Badge>\n </div>\n <div className=\"grid gap-2\">\n {nextActions.map((action) => (\n <Link\n key={action.id}\n to={action.to}\n className={cn(\n 'group flex min-h-16 items-center gap-3 rounded-md border border-border p-3 no-underline',\n 'hover:border-border-strong hover:bg-surface-hover',\n action.primary && 'border-accent bg-accent-bg/45',\n )}\n >\n <span\n className={cn(\n 'flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-surface-2 text-text-dim',\n action.primary && 'bg-accent text-accent-fg',\n )}\n aria-hidden=\"true\"\n >\n <ArrowRight className=\"h-4 w-4\" />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block text-sm font-medium text-text\">{action.title}</span>\n <span className=\"mt-0.5 block text-sm text-text-dim\">{action.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 </div>\n </section>\n\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <h2 className=\"text-sm font-semibold\">{t('dashboard.quick.title')}</h2>\n <div className=\"mt-3 grid grid-cols-2 gap-2\">\n {quickLinks.map((link) => (\n <DashboardLink key={link.to} {...link} />\n ))}\n </div>\n <h2 className=\"mt-4 text-sm font-semibold\">{t('dashboard.advanced.title')}</h2>\n <div className=\"mt-3 grid grid-cols-2 gap-2\">\n {advancedLinks.map((link) => (\n <DashboardLink key={link.to} {...link} />\n ))}\n </div>\n </section>\n </section>\n </main>\n </div>\n )\n}\n\nfunction StatusCardItem({ card }: { card: StatusCard }): JSX.Element {\n const { t } = useTranslation()\n const done = card.state === 'done'\n return (\n <article className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex items-start gap-3\">\n <span\n className={cn(\n 'flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-surface-2',\n card.state === 'done' && 'text-success',\n card.state === 'warn' && 'text-warning',\n card.state === 'todo' && 'text-text-dim',\n card.state === 'loading' && 'text-info',\n '[&_svg]:h-4 [&_svg]:w-4',\n )}\n aria-hidden=\"true\"\n >\n {card.state === 'done'\n ? <CheckCircle2 />\n : card.state === 'warn'\n ? <AlertCircle />\n : card.state === 'loading'\n ? <Loader2 className=\"animate-spin\" />\n : card.icon}\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h2 className=\"text-sm font-semibold\">{card.title}</h2>\n <Badge variant={STATE_BADGE[card.state]}>{t(`dashboard.state.${card.state}`)}</Badge>\n </div>\n <p className=\"mt-1 text-sm text-text-dim\">{card.detail}</p>\n {card.meta && <p className=\"mt-1 truncate text-xs text-text-muted\">{card.meta}</p>}\n <Button asChild variant={done ? 'ghost' : 'secondary'} size=\"sm\" className=\"mt-3\">\n <Link to={card.to}>\n <span>{card.action}</span>\n <ArrowRight className=\"h-4 w-4\" />\n </Link>\n </Button>\n </div>\n </div>\n </article>\n )\n}\n\nfunction DashboardLink({\n to,\n icon,\n title,\n}: {\n to: string\n icon: JSX.Element\n title: string\n}): JSX.Element {\n return (\n <Link\n to={to}\n className={cn(\n 'flex min-h-12 items-center gap-2 rounded-md border border-border bg-surface-2 px-3 py-2 no-underline',\n 'text-sm font-medium text-text hover:bg-surface-hover',\n '[&_svg]:h-4 [&_svg]:w-4 [&_svg]:shrink-0',\n )}\n >\n {icon}\n <span className=\"min-w-0 truncate\">{title}</span>\n </Link>\n )\n}\n\nfunction makeNextActions(opts: {\n t: ReturnType<typeof useTranslation>['t']\n serviceRunning: boolean\n agentReady: boolean\n imReady: boolean\n llmReady: boolean\n nativeAgentSelected: boolean\n}): DashboardAction[] {\n const actions: DashboardAction[] = []\n const add = (id: string, to: string, primary = false) => {\n actions.push({\n id,\n to,\n primary,\n title: opts.t(`dashboard.next.items.${id}.title`),\n detail: opts.t(`dashboard.next.items.${id}.detail`),\n })\n }\n\n if (!opts.serviceRunning) {\n add('service', '/settings/service', true)\n add('agent', '/settings/agents')\n add('chat', '/?welcome=1')\n } else if (!opts.agentReady) {\n if (opts.nativeAgentSelected && !opts.llmReady) {\n add('llm', '/settings/llm', true)\n add('agent', '/settings/agents')\n } else {\n add('agent', '/settings/agents', true)\n add('llm', '/settings/llm')\n }\n add('chat', '/?welcome=1')\n } else {\n add('chat', '/?welcome=1', true)\n if (!opts.imReady) add('im', '/settings/messengers')\n if (!opts.llmReady) add('llmOptional', '/settings/llm')\n }\n\n if (opts.imReady && opts.serviceRunning && opts.agentReady) {\n add('operate', '/tasks')\n } else if (!opts.imReady && !actions.some((a) => a.id === 'im')) {\n add('im', '/settings/messengers')\n }\n\n return actions.slice(0, 4)\n}\n\nfunction platformLabel(id: string, t: ReturnType<typeof useTranslation>['t']): string {\n const labels: Record<string, string> = {\n 'wechat-ilink': t('dashboard.platform.wechat'),\n telegram: t('dashboard.platform.telegram'),\n feishu: t('dashboard.platform.feishu'),\n dingtalk: t('dashboard.platform.dingtalk'),\n discord: t('dashboard.platform.discord'),\n email: t('dashboard.platform.email'),\n }\n return labels[id] ?? id\n}\n"],"names":["STATE_BADGE","DashboardRoute","t","useTranslation","cfgQuery","useConfig","serviceQuery","useServiceStatus","agentsQuery","useAgentsStatus","llmQuery","useLlmList","cfg","defaultAgent","agentName","agentDisplayName","nativeAgentSelected","agentStatus","agentLoading","service","serviceRunning","usableBackends","b","llmReady","messengers","imReady","webState","agentState","llmState","imState","coreReadyCount","s","anyFetching","cards","MessageSquare","Bot","Plug","m","platformLabel","nextActions","makeNextActions","quickLinks","jsx","Settings","Database","Server","advancedLinks","ClipboardList","ShieldCheck","jsxs","Topbar","Badge","Button","Link","RefreshCcw","cn","card","StatusCardItem","action","ArrowRight","link","DashboardLink","done","CheckCircle2","AlertCircle","Loader2","to","icon","title","opts","actions","add","id","primary","a"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{h as _,u as H,j as e,f as g}from"./index-DCfdN5R7.js";import{r as P}from"./react-DlP5eolq.js";import{T as $,a as q,b as u,c as D,d as B,e as b}from"./table-sCMZBe_Z.js";import{E}from"./empty-state-CuiqdZiB.js";import{A as F}from"./arrow-up-Dm0U4-6U.js";import{A as L}from"./arrow-down-7i0xwCI2.js";/**
|
|
2
2
|
* @license lucide-react v0.469.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/const O=_("ArrowUpDown",[["path",{d:"m21 16-4 4-4-4",key:"f6ql7i"}],["path",{d:"M17 20V4",key:"1ejh1v"}],["path",{d:"m3 8 4-4 4 4",key:"11wl7u"}],["path",{d:"M7 4v16",key:"1glfcx"}]]);function V({columns:i,rows:r,getRowId:m,loading:N=!1,loadingRows:k=5,emptyState:y,onRowClick:h,selection:n,onSelectionChange:v,sort:x,onSortChange:p,className:M}){const{t:f}=H("common"),t=n!==void 0&&v!==void 0,j=t&&r.length>0&&r.every(a=>n.has(m(a))),T=t&&r.some(a=>n.has(m(a)))&&!j;function w(){if(!t)return;const a=new Set(n);if(j)for(const s of r)a.delete(m(s));else for(const s of r)a.add(m(s));v(a)}function A(a){if(!t)return;const s=new Set(n);s.has(a)?s.delete(a):s.add(a),v(s)}function U(a){p&&(!x||x.id!==a?p({id:a,dir:"asc"}):x.dir==="asc"?p({id:a,dir:"desc"}):p(null))}return e.jsxs("div",{className:g("w-full",M),children:[e.jsx("div",{className:"hidden md:block",children:e.jsxs($,{children:[e.jsx(q,{children:e.jsxs(u,{children:[t&&e.jsx(D,{className:"w-10",children:e.jsx("input",{type:"checkbox",role:"checkbox","aria-label":f("table.selectAll"),"aria-checked":T?"mixed":j,checked:j,ref:a=>{a&&(a.indeterminate=T)},onChange:w,disabled:N||r.length===0,className:"h-4 w-4 accent-accent cursor-pointer"})}),i.map(a=>e.jsx(D,{className:a.headClassName,children:a.sortable&&p?e.jsxs("button",{type:"button",onClick:()=>U(a.id),className:g("inline-flex items-center gap-1","uppercase tracking-wide","hover:text-text transition-colors"),children:[a.header,x?.id===a.id?x.dir==="asc"?e.jsx(F,{className:"h-3 w-3"}):e.jsx(L,{className:"h-3 w-3"}):e.jsx(O,{className:"h-3 w-3 opacity-50"})]}):a.header},a.id))]})}),e.jsx(B,{children:N?Array.from({length:k}).map((a,s)=>e.jsxs(u,{children:[t&&e.jsx(b,{}),i.map(c=>e.jsx(b,{className:c.cellClassName,children:e.jsx("div",{className:"h-4 w-3/4 rounded bg-surface-2 animate-pulse"})},c.id))]},`skeleton-${s}`)):r.length===0?e.jsx(u,{children:e.jsx(b,{colSpan:i.length+(t?1:0),className:"p-0",children:y??e.jsx(E,{title:f("states.empty")})})}):r.map((a,s)=>{const c=m(a),o=t&&n.has(c);return e.jsxs(u,{"data-state":o?"selected":void 0,onClick:h?()=>h(a):void 0,className:h?"cursor-pointer":void 0,children:[t&&e.jsx(b,{onClick:d=>d.stopPropagation(),children:e.jsx("input",{type:"checkbox",role:"checkbox","aria-label":f("table.selectRow"),checked:o,onChange:()=>A(c),className:"h-4 w-4 accent-accent cursor-pointer"})}),i.map(d=>e.jsx(b,{className:d.cellClassName,children:d.cell(a,s)},d.id))]},c)})})]})}),e.jsx("div",{className:"md:hidden flex flex-col gap-2",children:N?Array.from({length:Math.min(3,k)}).map((a,s)=>e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3 space-y-2",children:[e.jsx("div",{className:"h-4 w-1/2 rounded bg-surface-2 animate-pulse"}),e.jsx("div",{className:"h-3 w-3/4 rounded bg-surface-2 animate-pulse"}),e.jsx("div",{className:"h-3 w-2/3 rounded bg-surface-2 animate-pulse"})]},`mskel-${s}`)):r.length===0?y??e.jsx(E,{title:f("states.empty")}):r.map((a,s)=>{const c=m(a),o=t&&n.has(c),d=i.find(l=>l.asCardTitle)??i[0],C=i.filter(l=>!l.asCardTitle&&!l.hideOnMobile&&l.id!==d?.id);return e.jsxs("div",{"data-state":o?"selected":void 0,onClick:h?()=>h(a):void 0,className:g("rounded-md border bg-surface p-3",o?"border-accent":"border-border",h&&"cursor-pointer active:bg-surface-hover"),children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[d&&e.jsx("div",{className:"font-medium text-text",children:d.cell(a,s)}),t&&e.jsx("input",{type:"checkbox",role:"checkbox","aria-label":f("table.selectRow"),checked:!!o,onChange:()=>A(c),onClick:l=>l.stopPropagation(),className:"h-4 w-4 accent-accent cursor-pointer mt-0.5"})]}),C.length>0&&e.jsx("dl",{className:"mt-2 grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-sm",children:C.map(l=>e.jsxs(P.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:l.header}),e.jsx("dd",{className:"text-text",children:l.cell(a,s)})]},l.id))})]},c)})})]})}V.displayName="DataTable";export{V as D};
|
|
7
|
-
//# sourceMappingURL=data-table-
|
|
7
|
+
//# sourceMappingURL=data-table-BkUshOZz.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-DOKUic1J.js","sources":["../../node_modules/lucide-react/dist/esm/icons/arrow-up-down.js","../../src/components/common/data-table.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 ArrowUpDown = createLucideIcon(\"ArrowUpDown\", [\n [\"path\", { d: \"m21 16-4 4-4-4\", key: \"f6ql7i\" }],\n [\"path\", { d: \"M17 20V4\", key: \"1ejh1v\" }],\n [\"path\", { d: \"m3 8 4-4 4 4\", key: \"11wl7u\" }],\n [\"path\", { d: \"M7 4v16\", key: \"1glfcx\" }]\n]);\n\nexport { ArrowUpDown as default };\n//# sourceMappingURL=arrow-up-down.js.map\n","/**\n * DataTable<T> — generic table for the M2 list pages (jobs /\n * approvals / reminders / memos). Wraps the primitive Table with:\n *\n * * Type-safe `columns` definition — header label, cell renderer,\n * optional sortable flag, optional className for both header / cell.\n * * Loading state — N skeleton rows so layout doesn't jump.\n * * Empty state — drops in <EmptyState> below the header.\n * * Row selection (optional) — `selection` + `onSelectionChange`;\n * caller manages the Set so it can be URL-state or zustand.\n * * Sort — controlled `sort: { id, dir }` + `onSortChange`. Same\n * rationale as Pagination: the URL is the source of truth.\n * * Mobile fallback — below `md` the table swaps to a vertical card\n * list. Card view uses the same column definitions but stacks\n * label / value pairs instead of a row.\n *\n * What this deliberately does NOT do:\n * * No virtualization. Expected row counts at M2 are ≤ 200; if a\n * page outgrows that, swap the render to react-window from inside\n * here without changing callers.\n * * No column resizing / hiding UX. shadcn columns are static.\n * * No filters. Filters live above the table in a dedicated\n * FilterBar (next-PR concern).\n *\n * Why hand-rolled instead of @tanstack/table-core:\n * For the M2 surface area (4 flat-data pages, ≤ 200 rows each),\n * pulling in a 13 KB head-table dep would add abstraction we don't\n * use. If virtualisation or column-pinning becomes a need, the\n * columns prop here maps 1:1 to tanstack's ColumnDef and we can\n * migrate without changing call sites.\n */\n\nimport * as React from 'react'\nimport { ArrowDown, ArrowUp, ArrowUpDown } from 'lucide-react'\nimport { useTranslation } from 'react-i18next'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { cn } from '@/lib/utils'\n\nexport type SortDir = 'asc' | 'desc'\n\nexport interface SortState {\n id: string\n dir: SortDir\n}\n\nexport interface DataTableColumn<T> {\n /** Stable id for sort + selection. Usually matches the row key. */\n id: string\n /** Header label. ReactNode so callers can pass <Tooltip> etc. */\n header: React.ReactNode\n /** Cell renderer. Receives the row and its index. */\n cell: (row: T, index: number) => React.ReactNode\n /** When true, the header becomes a sort button. */\n sortable?: boolean\n /** Optional className applied to the <th>. */\n headClassName?: string\n /** Optional className applied to every <td> in this column. */\n cellClassName?: string\n /** Mobile-card variant: when set, this column's value renders\n * prominently as the card's title row. Only one column should\n * use this; the rest become label/value pairs. */\n asCardTitle?: boolean\n /** Hide this column on the mobile card view. */\n hideOnMobile?: boolean\n}\n\nexport interface DataTableProps<T> {\n columns: DataTableColumn<T>[]\n rows: T[]\n /** Stable per-row id. Used for selection + React keys. */\n getRowId: (row: T) => string\n loading?: boolean\n /** Number of skeleton rows to show during loading. Default 5. */\n loadingRows?: number\n /** Empty-state slot. When omitted a default EmptyState renders. */\n emptyState?: React.ReactNode\n /** Click handler for the whole row — opens detail drawer, navigates, etc. */\n onRowClick?: (row: T) => void\n /** Controlled selection. When defined, a checkbox column auto-renders. */\n selection?: Set<string>\n onSelectionChange?: (next: Set<string>) => void\n /** Controlled sort. When omitted, sortable headers stay inert. */\n sort?: SortState | null\n onSortChange?: (next: SortState | null) => void\n className?: string\n}\n\nfunction DataTable<T>({\n columns,\n rows,\n getRowId,\n loading = false,\n loadingRows = 5,\n emptyState,\n onRowClick,\n selection,\n onSelectionChange,\n sort,\n onSortChange,\n className,\n}: DataTableProps<T>): JSX.Element {\n const { t } = useTranslation('common')\n const selectable = selection !== undefined && onSelectionChange !== undefined\n\n const allChecked = selectable && rows.length > 0 && rows.every((r) => selection.has(getRowId(r)))\n const someChecked = selectable && rows.some((r) => selection.has(getRowId(r))) && !allChecked\n\n function toggleAll(): void {\n if (!selectable) return\n const next = new Set(selection)\n if (allChecked) {\n for (const r of rows) next.delete(getRowId(r))\n } else {\n for (const r of rows) next.add(getRowId(r))\n }\n onSelectionChange(next)\n }\n\n function toggleRow(id: string): void {\n if (!selectable) return\n const next = new Set(selection)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n onSelectionChange(next)\n }\n\n function toggleSort(colId: string): void {\n if (!onSortChange) return\n if (!sort || sort.id !== colId) {\n onSortChange({ id: colId, dir: 'asc' })\n } else if (sort.dir === 'asc') {\n onSortChange({ id: colId, dir: 'desc' })\n } else {\n onSortChange(null)\n }\n }\n\n return (\n <div className={cn('w-full', className)}>\n {/* Desktop / tablet — table view */}\n <div className=\"hidden md:block\">\n <Table>\n <TableHeader>\n <TableRow>\n {selectable && (\n <TableHead className=\"w-10\">\n <input\n type=\"checkbox\"\n role=\"checkbox\"\n aria-label={t('table.selectAll')}\n aria-checked={someChecked ? 'mixed' : allChecked}\n checked={allChecked}\n ref={(el) => {\n if (el) el.indeterminate = someChecked\n }}\n onChange={toggleAll}\n disabled={loading || rows.length === 0}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n </TableHead>\n )}\n {columns.map((c) => (\n <TableHead key={c.id} className={c.headClassName}>\n {c.sortable && onSortChange ? (\n <button\n type=\"button\"\n onClick={() => toggleSort(c.id)}\n className={cn(\n 'inline-flex items-center gap-1',\n 'uppercase tracking-wide',\n 'hover:text-text transition-colors',\n )}\n >\n {c.header}\n {sort?.id === c.id ? (\n sort.dir === 'asc' ? <ArrowUp className=\"h-3 w-3\" /> : <ArrowDown className=\"h-3 w-3\" />\n ) : (\n <ArrowUpDown className=\"h-3 w-3 opacity-50\" />\n )}\n </button>\n ) : (\n c.header\n )}\n </TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {loading\n ? Array.from({ length: loadingRows }).map((_, i) => (\n <TableRow key={`skeleton-${i}`}>\n {selectable && <TableCell />}\n {columns.map((c) => (\n <TableCell key={c.id} className={c.cellClassName}>\n <div className=\"h-4 w-3/4 rounded bg-surface-2 animate-pulse\" />\n </TableCell>\n ))}\n </TableRow>\n ))\n : rows.length === 0\n ? (\n <TableRow>\n <TableCell\n colSpan={columns.length + (selectable ? 1 : 0)}\n className=\"p-0\"\n >\n {emptyState ?? <EmptyState title={t('states.empty')} />}\n </TableCell>\n </TableRow>\n )\n : rows.map((row, i) => {\n const id = getRowId(row)\n const isSelected = selectable && selection.has(id)\n return (\n <TableRow\n key={id}\n data-state={isSelected ? 'selected' : undefined}\n onClick={onRowClick ? () => onRowClick(row) : undefined}\n className={onRowClick ? 'cursor-pointer' : undefined}\n >\n {selectable && (\n <TableCell onClick={(e) => e.stopPropagation()}>\n <input\n type=\"checkbox\"\n role=\"checkbox\"\n aria-label={t('table.selectRow')}\n checked={isSelected}\n onChange={() => toggleRow(id)}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n </TableCell>\n )}\n {columns.map((c) => (\n <TableCell key={c.id} className={c.cellClassName}>\n {c.cell(row, i)}\n </TableCell>\n ))}\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </div>\n\n {/* Mobile — card view */}\n <div className=\"md:hidden flex flex-col gap-2\">\n {loading\n ? Array.from({ length: Math.min(3, loadingRows) }).map((_, i) => (\n <div\n key={`mskel-${i}`}\n className=\"rounded-md border border-border bg-surface p-3 space-y-2\"\n >\n <div className=\"h-4 w-1/2 rounded bg-surface-2 animate-pulse\" />\n <div className=\"h-3 w-3/4 rounded bg-surface-2 animate-pulse\" />\n <div className=\"h-3 w-2/3 rounded bg-surface-2 animate-pulse\" />\n </div>\n ))\n : rows.length === 0\n ? (emptyState ?? <EmptyState title={t('states.empty')} />)\n : rows.map((row, i) => {\n const id = getRowId(row)\n const isSelected = selectable && selection.has(id)\n const titleCol = columns.find((c) => c.asCardTitle) ?? columns[0]\n const fieldCols = columns.filter((c) => !c.asCardTitle && !c.hideOnMobile && c.id !== titleCol?.id)\n return (\n <div\n key={id}\n data-state={isSelected ? 'selected' : undefined}\n onClick={onRowClick ? () => onRowClick(row) : undefined}\n className={cn(\n 'rounded-md border bg-surface p-3',\n isSelected ? 'border-accent' : 'border-border',\n onRowClick && 'cursor-pointer active:bg-surface-hover',\n )}\n >\n <div className=\"flex items-start justify-between gap-2\">\n {titleCol && (\n <div className=\"font-medium text-text\">{titleCol.cell(row, i)}</div>\n )}\n {selectable && (\n <input\n type=\"checkbox\"\n role=\"checkbox\"\n aria-label={t('table.selectRow')}\n checked={!!isSelected}\n onChange={() => toggleRow(id)}\n onClick={(e) => e.stopPropagation()}\n className=\"h-4 w-4 accent-accent cursor-pointer mt-0.5\"\n />\n )}\n </div>\n {fieldCols.length > 0 && (\n <dl className=\"mt-2 grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-sm\">\n {fieldCols.map((c) => (\n <React.Fragment key={c.id}>\n <dt className=\"text-text-dim\">{c.header}</dt>\n <dd className=\"text-text\">{c.cell(row, i)}</dd>\n </React.Fragment>\n ))}\n </dl>\n )}\n </div>\n )\n })}\n </div>\n </div>\n )\n}\nDataTable.displayName = 'DataTable'\n\nexport { DataTable }\n"],"names":["ArrowUpDown","createLucideIcon","DataTable","columns","rows","getRowId","loading","loadingRows","emptyState","onRowClick","selection","onSelectionChange","sort","onSortChange","className","t","useTranslation","selectable","allChecked","r","someChecked","toggleAll","next","toggleRow","id","toggleSort","colId","cn","jsx","jsxs","Table","TableHeader","TableRow","TableHead","el","c","ArrowUp","ArrowDown","TableBody","_","i","TableCell","EmptyState","row","isSelected","e","titleCol","fieldCols","React.Fragment"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"data-table-BkUshOZz.js","sources":["../../node_modules/lucide-react/dist/esm/icons/arrow-up-down.js","../../src/components/common/data-table.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 ArrowUpDown = createLucideIcon(\"ArrowUpDown\", [\n [\"path\", { d: \"m21 16-4 4-4-4\", key: \"f6ql7i\" }],\n [\"path\", { d: \"M17 20V4\", key: \"1ejh1v\" }],\n [\"path\", { d: \"m3 8 4-4 4 4\", key: \"11wl7u\" }],\n [\"path\", { d: \"M7 4v16\", key: \"1glfcx\" }]\n]);\n\nexport { ArrowUpDown as default };\n//# sourceMappingURL=arrow-up-down.js.map\n","/**\n * DataTable<T> — generic table for the M2 list pages (jobs /\n * approvals / reminders / memos). Wraps the primitive Table with:\n *\n * * Type-safe `columns` definition — header label, cell renderer,\n * optional sortable flag, optional className for both header / cell.\n * * Loading state — N skeleton rows so layout doesn't jump.\n * * Empty state — drops in <EmptyState> below the header.\n * * Row selection (optional) — `selection` + `onSelectionChange`;\n * caller manages the Set so it can be URL-state or zustand.\n * * Sort — controlled `sort: { id, dir }` + `onSortChange`. Same\n * rationale as Pagination: the URL is the source of truth.\n * * Mobile fallback — below `md` the table swaps to a vertical card\n * list. Card view uses the same column definitions but stacks\n * label / value pairs instead of a row.\n *\n * What this deliberately does NOT do:\n * * No virtualization. Expected row counts at M2 are ≤ 200; if a\n * page outgrows that, swap the render to react-window from inside\n * here without changing callers.\n * * No column resizing / hiding UX. shadcn columns are static.\n * * No filters. Filters live above the table in a dedicated\n * FilterBar (next-PR concern).\n *\n * Why hand-rolled instead of @tanstack/table-core:\n * For the M2 surface area (4 flat-data pages, ≤ 200 rows each),\n * pulling in a 13 KB head-table dep would add abstraction we don't\n * use. If virtualisation or column-pinning becomes a need, the\n * columns prop here maps 1:1 to tanstack's ColumnDef and we can\n * migrate without changing call sites.\n */\n\nimport * as React from 'react'\nimport { ArrowDown, ArrowUp, ArrowUpDown } from 'lucide-react'\nimport { useTranslation } from 'react-i18next'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { cn } from '@/lib/utils'\n\nexport type SortDir = 'asc' | 'desc'\n\nexport interface SortState {\n id: string\n dir: SortDir\n}\n\nexport interface DataTableColumn<T> {\n /** Stable id for sort + selection. Usually matches the row key. */\n id: string\n /** Header label. ReactNode so callers can pass <Tooltip> etc. */\n header: React.ReactNode\n /** Cell renderer. Receives the row and its index. */\n cell: (row: T, index: number) => React.ReactNode\n /** When true, the header becomes a sort button. */\n sortable?: boolean\n /** Optional className applied to the <th>. */\n headClassName?: string\n /** Optional className applied to every <td> in this column. */\n cellClassName?: string\n /** Mobile-card variant: when set, this column's value renders\n * prominently as the card's title row. Only one column should\n * use this; the rest become label/value pairs. */\n asCardTitle?: boolean\n /** Hide this column on the mobile card view. */\n hideOnMobile?: boolean\n}\n\nexport interface DataTableProps<T> {\n columns: DataTableColumn<T>[]\n rows: T[]\n /** Stable per-row id. Used for selection + React keys. */\n getRowId: (row: T) => string\n loading?: boolean\n /** Number of skeleton rows to show during loading. Default 5. */\n loadingRows?: number\n /** Empty-state slot. When omitted a default EmptyState renders. */\n emptyState?: React.ReactNode\n /** Click handler for the whole row — opens detail drawer, navigates, etc. */\n onRowClick?: (row: T) => void\n /** Controlled selection. When defined, a checkbox column auto-renders. */\n selection?: Set<string>\n onSelectionChange?: (next: Set<string>) => void\n /** Controlled sort. When omitted, sortable headers stay inert. */\n sort?: SortState | null\n onSortChange?: (next: SortState | null) => void\n className?: string\n}\n\nfunction DataTable<T>({\n columns,\n rows,\n getRowId,\n loading = false,\n loadingRows = 5,\n emptyState,\n onRowClick,\n selection,\n onSelectionChange,\n sort,\n onSortChange,\n className,\n}: DataTableProps<T>): JSX.Element {\n const { t } = useTranslation('common')\n const selectable = selection !== undefined && onSelectionChange !== undefined\n\n const allChecked = selectable && rows.length > 0 && rows.every((r) => selection.has(getRowId(r)))\n const someChecked = selectable && rows.some((r) => selection.has(getRowId(r))) && !allChecked\n\n function toggleAll(): void {\n if (!selectable) return\n const next = new Set(selection)\n if (allChecked) {\n for (const r of rows) next.delete(getRowId(r))\n } else {\n for (const r of rows) next.add(getRowId(r))\n }\n onSelectionChange(next)\n }\n\n function toggleRow(id: string): void {\n if (!selectable) return\n const next = new Set(selection)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n onSelectionChange(next)\n }\n\n function toggleSort(colId: string): void {\n if (!onSortChange) return\n if (!sort || sort.id !== colId) {\n onSortChange({ id: colId, dir: 'asc' })\n } else if (sort.dir === 'asc') {\n onSortChange({ id: colId, dir: 'desc' })\n } else {\n onSortChange(null)\n }\n }\n\n return (\n <div className={cn('w-full', className)}>\n {/* Desktop / tablet — table view */}\n <div className=\"hidden md:block\">\n <Table>\n <TableHeader>\n <TableRow>\n {selectable && (\n <TableHead className=\"w-10\">\n <input\n type=\"checkbox\"\n role=\"checkbox\"\n aria-label={t('table.selectAll')}\n aria-checked={someChecked ? 'mixed' : allChecked}\n checked={allChecked}\n ref={(el) => {\n if (el) el.indeterminate = someChecked\n }}\n onChange={toggleAll}\n disabled={loading || rows.length === 0}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n </TableHead>\n )}\n {columns.map((c) => (\n <TableHead key={c.id} className={c.headClassName}>\n {c.sortable && onSortChange ? (\n <button\n type=\"button\"\n onClick={() => toggleSort(c.id)}\n className={cn(\n 'inline-flex items-center gap-1',\n 'uppercase tracking-wide',\n 'hover:text-text transition-colors',\n )}\n >\n {c.header}\n {sort?.id === c.id ? (\n sort.dir === 'asc' ? <ArrowUp className=\"h-3 w-3\" /> : <ArrowDown className=\"h-3 w-3\" />\n ) : (\n <ArrowUpDown className=\"h-3 w-3 opacity-50\" />\n )}\n </button>\n ) : (\n c.header\n )}\n </TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {loading\n ? Array.from({ length: loadingRows }).map((_, i) => (\n <TableRow key={`skeleton-${i}`}>\n {selectable && <TableCell />}\n {columns.map((c) => (\n <TableCell key={c.id} className={c.cellClassName}>\n <div className=\"h-4 w-3/4 rounded bg-surface-2 animate-pulse\" />\n </TableCell>\n ))}\n </TableRow>\n ))\n : rows.length === 0\n ? (\n <TableRow>\n <TableCell\n colSpan={columns.length + (selectable ? 1 : 0)}\n className=\"p-0\"\n >\n {emptyState ?? <EmptyState title={t('states.empty')} />}\n </TableCell>\n </TableRow>\n )\n : rows.map((row, i) => {\n const id = getRowId(row)\n const isSelected = selectable && selection.has(id)\n return (\n <TableRow\n key={id}\n data-state={isSelected ? 'selected' : undefined}\n onClick={onRowClick ? () => onRowClick(row) : undefined}\n className={onRowClick ? 'cursor-pointer' : undefined}\n >\n {selectable && (\n <TableCell onClick={(e) => e.stopPropagation()}>\n <input\n type=\"checkbox\"\n role=\"checkbox\"\n aria-label={t('table.selectRow')}\n checked={isSelected}\n onChange={() => toggleRow(id)}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n </TableCell>\n )}\n {columns.map((c) => (\n <TableCell key={c.id} className={c.cellClassName}>\n {c.cell(row, i)}\n </TableCell>\n ))}\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </div>\n\n {/* Mobile — card view */}\n <div className=\"md:hidden flex flex-col gap-2\">\n {loading\n ? Array.from({ length: Math.min(3, loadingRows) }).map((_, i) => (\n <div\n key={`mskel-${i}`}\n className=\"rounded-md border border-border bg-surface p-3 space-y-2\"\n >\n <div className=\"h-4 w-1/2 rounded bg-surface-2 animate-pulse\" />\n <div className=\"h-3 w-3/4 rounded bg-surface-2 animate-pulse\" />\n <div className=\"h-3 w-2/3 rounded bg-surface-2 animate-pulse\" />\n </div>\n ))\n : rows.length === 0\n ? (emptyState ?? <EmptyState title={t('states.empty')} />)\n : rows.map((row, i) => {\n const id = getRowId(row)\n const isSelected = selectable && selection.has(id)\n const titleCol = columns.find((c) => c.asCardTitle) ?? columns[0]\n const fieldCols = columns.filter((c) => !c.asCardTitle && !c.hideOnMobile && c.id !== titleCol?.id)\n return (\n <div\n key={id}\n data-state={isSelected ? 'selected' : undefined}\n onClick={onRowClick ? () => onRowClick(row) : undefined}\n className={cn(\n 'rounded-md border bg-surface p-3',\n isSelected ? 'border-accent' : 'border-border',\n onRowClick && 'cursor-pointer active:bg-surface-hover',\n )}\n >\n <div className=\"flex items-start justify-between gap-2\">\n {titleCol && (\n <div className=\"font-medium text-text\">{titleCol.cell(row, i)}</div>\n )}\n {selectable && (\n <input\n type=\"checkbox\"\n role=\"checkbox\"\n aria-label={t('table.selectRow')}\n checked={!!isSelected}\n onChange={() => toggleRow(id)}\n onClick={(e) => e.stopPropagation()}\n className=\"h-4 w-4 accent-accent cursor-pointer mt-0.5\"\n />\n )}\n </div>\n {fieldCols.length > 0 && (\n <dl className=\"mt-2 grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-sm\">\n {fieldCols.map((c) => (\n <React.Fragment key={c.id}>\n <dt className=\"text-text-dim\">{c.header}</dt>\n <dd className=\"text-text\">{c.cell(row, i)}</dd>\n </React.Fragment>\n ))}\n </dl>\n )}\n </div>\n )\n })}\n </div>\n </div>\n )\n}\nDataTable.displayName = 'DataTable'\n\nexport { DataTable }\n"],"names":["ArrowUpDown","createLucideIcon","DataTable","columns","rows","getRowId","loading","loadingRows","emptyState","onRowClick","selection","onSelectionChange","sort","onSortChange","className","t","useTranslation","selectable","allChecked","r","someChecked","toggleAll","next","toggleRow","id","toggleSort","colId","cn","jsx","jsxs","Table","TableHeader","TableRow","TableHead","el","c","ArrowUp","ArrowDown","TableBody","_","i","TableCell","EmptyState","row","isSelected","e","titleCol","fieldCols","React.Fragment"],"mappings":"iTAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,EAAcC,EAAiB,cAAe,CAClD,CAAC,OAAQ,CAAE,EAAG,iBAAkB,IAAK,QAAQ,CAAE,EAC/C,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CAAC,OAAQ,CAAE,EAAG,eAAgB,IAAK,QAAQ,CAAE,EAC7C,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAQ,CAAE,CAC1C,CAAC,ECiFD,SAASC,EAAa,CACpB,QAAAC,EACA,KAAAC,EACA,SAAAC,EACA,QAAAC,EAAU,GACV,YAAAC,EAAc,EACd,WAAAC,EACA,WAAAC,EACA,UAAAC,EACA,kBAAAC,EACA,KAAAC,EACA,aAAAC,EACA,UAAAC,CACF,EAAmC,CACjC,KAAM,CAAE,EAAAC,CAAA,EAAMC,EAAe,QAAQ,EAC/BC,EAAaP,IAAc,QAAaC,IAAsB,OAE9DO,EAAaD,GAAcb,EAAK,OAAS,GAAKA,EAAK,MAAOe,GAAMT,EAAU,IAAIL,EAASc,CAAC,CAAC,CAAC,EAC1FC,EAAcH,GAAcb,EAAK,KAAMe,GAAMT,EAAU,IAAIL,EAASc,CAAC,CAAC,CAAC,GAAK,CAACD,EAEnF,SAASG,GAAkB,CACzB,GAAI,CAACJ,EAAY,OACjB,MAAMK,EAAO,IAAI,IAAIZ,CAAS,EAC9B,GAAIQ,EACF,UAAWC,KAAKf,EAAMkB,EAAK,OAAOjB,EAASc,CAAC,CAAC,MAE7C,WAAWA,KAAKf,EAAMkB,EAAK,IAAIjB,EAASc,CAAC,CAAC,EAE5CR,EAAkBW,CAAI,CACxB,CAEA,SAASC,EAAUC,EAAkB,CACnC,GAAI,CAACP,EAAY,OACjB,MAAMK,EAAO,IAAI,IAAIZ,CAAS,EAC1BY,EAAK,IAAIE,CAAE,EAAGF,EAAK,OAAOE,CAAE,EAC3BF,EAAK,IAAIE,CAAE,EAChBb,EAAkBW,CAAI,CACxB,CAEA,SAASG,EAAWC,EAAqB,CAClCb,IACD,CAACD,GAAQA,EAAK,KAAOc,EACvBb,EAAa,CAAE,GAAIa,EAAO,IAAK,MAAO,EAC7Bd,EAAK,MAAQ,MACtBC,EAAa,CAAE,GAAIa,EAAO,IAAK,OAAQ,EAEvCb,EAAa,IAAI,EAErB,CAEA,cACG,MAAA,CAAI,UAAWc,EAAG,SAAUb,CAAS,EAEpC,SAAA,CAAAc,MAAC,MAAA,CAAI,UAAU,kBACb,SAAAC,EAAAA,KAACC,EAAA,CACC,SAAA,CAAAF,EAAAA,IAACG,EAAA,CACC,gBAACC,EAAA,CACE,SAAA,CAAAf,GACCW,EAAAA,IAACK,EAAA,CAAU,UAAU,OACnB,SAAAL,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,KAAK,WACL,aAAYb,EAAE,iBAAiB,EAC/B,eAAcK,EAAc,QAAUF,EACtC,QAASA,EACT,IAAMgB,GAAO,CACPA,MAAO,cAAgBd,EAC7B,EACA,SAAUC,EACV,SAAUf,GAAWF,EAAK,SAAW,EACrC,UAAU,sCAAA,CAAA,EAEd,EAEDD,EAAQ,IAAKgC,GACZP,EAAAA,IAACK,EAAA,CAAqB,UAAWE,EAAE,cAChC,SAAAA,EAAE,UAAYtB,EACbgB,EAAAA,KAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMJ,EAAWU,EAAE,EAAE,EAC9B,UAAWR,EACT,iCACA,0BACA,mCAAA,EAGD,SAAA,CAAAQ,EAAE,OACFvB,GAAM,KAAOuB,EAAE,GACdvB,EAAK,MAAQ,YAASwB,EAAA,CAAQ,UAAU,UAAU,EAAKR,MAACS,GAAU,UAAU,SAAA,CAAU,EAEtFT,EAAAA,IAAC5B,EAAA,CAAY,UAAU,oBAAA,CAAqB,CAAA,CAAA,CAAA,EAIhDmC,EAAE,QAnBUA,EAAE,EAqBlB,CACD,CAAA,CAAA,CACH,CAAA,CACF,EACAP,EAAAA,IAACU,EAAA,CACE,SAAAhC,EACG,MAAM,KAAK,CAAE,OAAQC,CAAA,CAAa,EAAE,IAAI,CAACgC,EAAGC,WACzCR,EAAA,CACE,SAAA,CAAAf,SAAewB,EAAA,EAAU,EACzBtC,EAAQ,IAAK,GACZyB,EAAAA,IAACa,GAAqB,UAAW,EAAE,cACjC,SAAAb,EAAAA,IAAC,OAAI,UAAU,8CAAA,CAA+C,CAAA,EADhD,EAAE,EAElB,CACD,CAAA,CAAA,EANY,YAAYY,CAAC,EAO5B,CACD,EACDpC,EAAK,SAAW,EAEdwB,EAAAA,IAACI,EAAA,CACC,SAAAJ,EAAAA,IAACa,EAAA,CACC,QAAStC,EAAQ,QAAUc,EAAa,EAAI,GAC5C,UAAU,MAET,YAAcW,MAACc,EAAA,CAAW,MAAO3B,EAAE,cAAc,CAAA,CAAG,CAAA,CAAA,EAEzD,EAEAX,EAAK,IAAI,CAACuC,EAAKH,IAAM,CACnB,MAAMhB,EAAKnB,EAASsC,CAAG,EACjBC,EAAa3B,GAAcP,EAAU,IAAIc,CAAE,EACjD,OACEK,EAAAA,KAACG,EAAA,CAEC,aAAYY,EAAa,WAAa,OACtC,QAASnC,EAAa,IAAMA,EAAWkC,CAAG,EAAI,OAC9C,UAAWlC,EAAa,iBAAmB,OAE1C,SAAA,CAAAQ,SACEwB,EAAA,CAAU,QAAUI,GAAMA,EAAE,kBAC3B,SAAAjB,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,KAAK,WACL,aAAYb,EAAE,iBAAiB,EAC/B,QAAS6B,EACT,SAAU,IAAMrB,EAAUC,CAAE,EAC5B,UAAU,sCAAA,CAAA,EAEd,EAEDrB,EAAQ,IAAKgC,GACZP,EAAAA,IAACa,GAAqB,UAAWN,EAAE,cAChC,SAAAA,EAAE,KAAKQ,EAAKH,CAAC,CAAA,EADAL,EAAE,EAElB,CACD,CAAA,CAAA,EArBIX,CAAA,CAwBX,CAAC,CAAA,CACT,CAAA,CAAA,CACF,CAAA,CACF,QAGC,MAAA,CAAI,UAAU,gCACZ,SAAAlB,EACG,MAAM,KAAK,CAAE,OAAQ,KAAK,IAAI,EAAGC,CAAW,CAAA,CAAG,EAAE,IAAI,CAACgC,EAAGC,IACvDX,EAAAA,KAAC,MAAA,CAEC,UAAU,2DAEV,SAAA,CAAAD,EAAAA,IAAC,MAAA,CAAI,UAAU,8CAAA,CAA+C,EAC9DA,EAAAA,IAAC,MAAA,CAAI,UAAU,8CAAA,CAA+C,EAC9DA,EAAAA,IAAC,MAAA,CAAI,UAAU,8CAAA,CAA+C,CAAA,CAAA,EALzD,SAASY,CAAC,EAAA,CAOlB,EACDpC,EAAK,SAAW,EACbI,GAAcoB,EAAAA,IAACc,EAAA,CAAW,MAAO3B,EAAE,cAAc,CAAA,CAAG,EACrDX,EAAK,IAAI,CAACuC,EAAKH,IAAM,CACnB,MAAMhB,EAAKnB,EAASsC,CAAG,EACjBC,EAAa3B,GAAcP,EAAU,IAAIc,CAAE,EAC3CsB,EAAW3C,EAAQ,KAAMgC,GAAMA,EAAE,WAAW,GAAKhC,EAAQ,CAAC,EAC1D4C,EAAY5C,EAAQ,OAAQgC,GAAM,CAACA,EAAE,aAAe,CAACA,EAAE,cAAgBA,EAAE,KAAOW,GAAU,EAAE,EAClG,OACEjB,EAAAA,KAAC,MAAA,CAEC,aAAYe,EAAa,WAAa,OACtC,QAASnC,EAAa,IAAMA,EAAWkC,CAAG,EAAI,OAC9C,UAAWhB,EACT,mCACAiB,EAAa,gBAAkB,gBAC/BnC,GAAc,wCAAA,EAGhB,SAAA,CAAAoB,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACZ,SAAA,CAAAiB,GACClB,EAAAA,IAAC,OAAI,UAAU,wBAAyB,WAAS,KAAKe,EAAKH,CAAC,CAAA,CAAE,EAE/DvB,GACCW,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,KAAK,WACL,aAAYb,EAAE,iBAAiB,EAC/B,QAAS,CAAC,CAAC6B,EACX,SAAU,IAAMrB,EAAUC,CAAE,EAC5B,QAAUqB,GAAMA,EAAE,gBAAA,EAClB,UAAU,6CAAA,CAAA,CACZ,EAEJ,EACCE,EAAU,OAAS,GAClBnB,EAAAA,IAAC,MAAG,UAAU,gEACX,SAAAmB,EAAU,IAAKZ,GACdN,EAAAA,KAACmB,EAAAA,SAAA,CACC,SAAA,CAAApB,EAAAA,IAAC,KAAA,CAAG,UAAU,gBAAiB,SAAAO,EAAE,OAAO,EACxCP,MAAC,MAAG,UAAU,YAAa,WAAE,KAAKe,EAAKH,CAAC,CAAA,CAAE,CAAA,GAFvBL,EAAE,EAGvB,CACD,CAAA,CACH,CAAA,CAAA,EAjCGX,CAAA,CAqCX,CAAC,CAAA,CACT,CAAA,EACF,CAEJ,CACAtB,EAAU,YAAc","x_google_ignoreList":[0]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{h as e}from"./index-DCfdN5R7.js";/**
|
|
2
|
+
* @license lucide-react v0.469.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const s=e("Database",[["ellipse",{cx:"12",cy:"5",rx:"9",ry:"3",key:"msslwz"}],["path",{d:"M3 5V19A9 3 0 0 0 21 19V5",key:"1wlel7"}],["path",{d:"M3 12A9 3 0 0 0 21 12",key:"mv7ke4"}]]);export{s as D};
|
|
7
|
+
//# sourceMappingURL=database-lQzk64rV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-lQzk64rV.js","sources":["../../node_modules/lucide-react/dist/esm/icons/database.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 Database = createLucideIcon(\"Database\", [\n [\"ellipse\", { cx: \"12\", cy: \"5\", rx: \"9\", ry: \"3\", key: \"msslwz\" }],\n [\"path\", { d: \"M3 5V19A9 3 0 0 0 21 19V5\", key: \"1wlel7\" }],\n [\"path\", { d: \"M3 12A9 3 0 0 0 21 12\", key: \"mv7ke4\" }]\n]);\n\nexport { Database as default };\n//# sourceMappingURL=database.js.map\n"],"names":["Database","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAWC,EAAiB,WAAY,CAC5C,CAAC,UAAW,CAAE,GAAI,KAAM,GAAI,IAAK,GAAI,IAAK,GAAI,IAAK,IAAK,QAAQ,CAAE,EAClE,CAAC,OAAQ,CAAE,EAAG,4BAA6B,IAAK,QAAQ,CAAE,EAC1D,CAAC,OAAQ,CAAE,EAAG,wBAAyB,IAAK,QAAQ,CAAE,CACxD,CAAC","x_google_ignoreList":[0]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{h as K,u as Y,a as J,K as W,j as e,d as O,e as k,k as _,l as L,m as E,n as A,o as x,b as Z,p,q as F,w as $,I as ee,f as se}from"./index-DCfdN5R7.js";import{r as f}from"./react-DlP5eolq.js";import{b as te,u as le,c as ne}from"./use-settings-DGIjmUX0.js";import{L as R}from"./loader-circle-DDdmcH0k.js";import{S as ae}from"./save-BDOtZrfp.js";import{b as ie,j as re}from"./use-memory-CXDwKCco.js";import{R as de}from"./refresh-ccw-DlAd-eTQ.js";import{P as oe}from"./play-DX5wp4WH.js";/**
|
|
2
2
|
* @license lucide-react v0.469.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const ce=J("AlarmClockCheck",[["circle",{cx:"12",cy:"13",r:"8",key:"3y4lt7"}],["path",{d:"M5 3 2 6",key:"18tl5t"}],["path",{d:"m22 6-3-3",key:"1opdir"}],["path",{d:"M6.38 18.7 4 21",key:"17xu3x"}],["path",{d:"M17.64 18.67 20 21",key:"kv2oe2"}],["path",{d:"m9 13 2 2 4-4",key:"6343dt"}]]),A={intervalMs:"300000",floorMin:"30",batchMax:"20",maxPending:"200"};function me(n){const s=(n??"1").trim().toLowerCase();return s!=="0"&&s!=="false"&&s!=="no"&&s!=="off"}function ue(n){const s=(n||"auto").toLowerCase();return s==="agent"||s==="llm"?s:"auto"}function xe({onSaved:n}){const{t:s}=Y(["memory","common"]),a=te({reveal:!1}),r=f.useMemo(()=>a.data?.env??{},[a.data?.env]),j=le(),d=K(),c=j.data?.agents??[],h=d.data?.backends??[],v=d.data?.roles?.distill??"",T=f.useMemo(()=>()=>({source:ue(r.AGIM_MEMORY_DISTILL_SOURCE),agent:r.AGIM_MEMORY_DISTILL_AGENT||"",llmBackend:v,enabled:me(r.AGIM_MEMORY_DISTILL_ENABLED),intervalMs:r.AGIM_MEMORY_DISTILL_INTERVAL_MS||"",floorMin:r.AGIM_MEMORY_DISTILL_FLOOR_MIN||"",batchMax:r.AGIM_MEMORY_DISTILL_BATCH_MAX||"",maxPending:r.AGIM_MEMORY_DISTILL_MAX_PENDING||""}),[r,v]),[l,N]=f.useState(T),g=f.useRef(l),P=f.useRef(!1);f.useEffect(()=>{if(P.current||!a.data||!d.data)return;const t=T();N(t),g.current=t,P.current=!0},[a.data,d.data,T]);const B=ne(),G=W(),w=f.useMemo(()=>{const t=g.current;return Object.keys(l).some(i=>l[i]!==t[i])},[l]);function m(t,i){N(o=>({...o,[t]:i}))}function I(t,i,o){if(!t.trim())return null;const u=Number(t);return!Number.isFinite(u)||u<i?s("distill.form.errors.numRange",{field:o,min:i}):null}function H(){return l.source==="agent"&&!l.agent.trim()?s("distill.form.errors.agentRequired"):l.source==="llm"&&!l.llmBackend.trim()?s("distill.form.errors.llmRequired"):I(l.intervalMs,1e4,s("distill.form.intervalMs"))??I(l.floorMin,0,s("distill.form.floorMin"))??I(l.batchMax,1,s("distill.form.batchMax"))??I(l.maxPending,1,s("distill.form.maxPending"))}function V(){const t=g.current,i={},o=(u,M,q)=>{M!==q&&(i[u]=M.trim()===""?null:M.trim())};return l.source!==t.source&&(i.AGIM_MEMORY_DISTILL_SOURCE=l.source==="auto"?null:l.source),l.enabled!==t.enabled&&(i.AGIM_MEMORY_DISTILL_ENABLED=l.enabled?"1":"0"),l.source==="agent"?o("AGIM_MEMORY_DISTILL_AGENT",l.agent,t.agent):t.agent&&(i.AGIM_MEMORY_DISTILL_AGENT=null),o("AGIM_MEMORY_DISTILL_INTERVAL_MS",l.intervalMs,t.intervalMs),o("AGIM_MEMORY_DISTILL_FLOOR_MIN",l.floorMin,t.floorMin),o("AGIM_MEMORY_DISTILL_BATCH_MAX",l.batchMax,t.batchMax),o("AGIM_MEMORY_DISTILL_MAX_PENDING",l.maxPending,t.maxPending),i}async function U(){const t=H();if(t){p.error(t);return}const i=V(),o=l.source==="llm"&&l.llmBackend.trim()!==""&&l.llmBackend!==g.current.llmBackend;if(Object.keys(i).length===0&&!o){p.info(s("distill.form.nothingChanged"));return}try{Object.keys(i).length>0&&await B.mutateAsync({updates:i}),o&&await G.mutateAsync({distill:l.llmBackend.trim()}),p.success(s("distill.form.savedToast")),g.current={...l},N(u=>({...u})),n?.()}catch(u){const{message:M}=F(u,s);p.error(M)}}function z(){N(g.current)}const C=B.isPending||G.isPending,Q=h.length===0,X=c.length===0;return e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("h2",{className:"text-sm font-medium",children:s("distill.form.title")}),w&&e.jsx(O,{variant:"info",children:s("distill.form.dirty")}),e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[w&&e.jsx(k,{type:"button",variant:"secondary",size:"sm",onClick:z,disabled:C,children:s("distill.form.discard")}),e.jsxs(k,{type:"button",size:"sm",onClick:()=>void U(),disabled:!w||C,children:[C?e.jsx(R,{className:"h-4 w-4 animate-spin"}):e.jsx(ae,{className:"h-4 w-4"}),s("distill.form.save")]})]})]}),e.jsx("p",{className:"mt-1 text-xs text-text-dim",children:s("distill.form.hint")}),a.isLoading?e.jsx("div",{className:"mt-3 h-32 w-full rounded-md bg-surface-2 animate-pulse"}):e.jsxs("div",{className:"mt-3 flex flex-col gap-4",children:[e.jsxs("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2",children:[e.jsx(b,{label:s("distill.form.source"),help:s("distill.form.sourceHelp"),children:e.jsxs(_,{value:l.source,onValueChange:t=>m("source",t),children:[e.jsx(L,{children:e.jsx(E,{})}),e.jsxs(S,{children:[e.jsx(x,{value:"auto",children:s("distill.form.sourceAuto")}),e.jsx(x,{value:"agent",children:s("distill.form.sourceAgent")}),e.jsx(x,{value:"llm",children:s("distill.form.sourceLlm")})]})]})}),l.source==="auto"&&e.jsx("div",{className:"flex items-end",children:e.jsx("p",{className:"text-[11px] text-text-muted",children:s("distill.form.autoNote")})}),l.source==="agent"&&e.jsx(b,{label:s("distill.form.agent"),help:s("distill.form.agentHelp"),children:X?e.jsx("p",{className:"text-[11px] text-warning",children:s("distill.form.noAgents")}):e.jsxs(_,{value:l.agent,onValueChange:t=>m("agent",t),children:[e.jsx(L,{children:e.jsx(E,{placeholder:s("distill.form.agentPlaceholder")})}),e.jsx(S,{children:c.map(t=>e.jsx(x,{value:t,children:Z(t)},t))})]})}),l.source==="llm"&&e.jsx(b,{label:s("distill.form.llmBackend"),help:s("distill.form.llmBackendHelp"),children:Q?e.jsx("p",{className:"text-[11px] text-warning",children:s("distill.form.noBackends")}):e.jsxs(_,{value:l.llmBackend,onValueChange:t=>m("llmBackend",t),children:[e.jsx(L,{children:e.jsx(E,{placeholder:s("distill.form.llmPlaceholder")})}),e.jsx(S,{children:h.map(t=>e.jsxs(x,{value:t.name,children:[t.name," ",e.jsxs("span",{className:"text-text-muted",children:["· ",t.model]})]},t.name))})]})})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-medium text-text-dim",children:s("distill.form.scheduleTitle")}),e.jsxs("div",{className:"mt-2 grid grid-cols-1 gap-3 sm:grid-cols-2",children:[e.jsx(b,{label:s("distill.form.enabled"),help:s("distill.form.enabledHelp"),children:e.jsxs(_,{value:l.enabled?"on":"off",onValueChange:t=>m("enabled",t==="on"),children:[e.jsx(L,{children:e.jsx(E,{})}),e.jsxs(S,{children:[e.jsx(x,{value:"on",children:s("distill.form.enabledOn")}),e.jsx(x,{value:"off",children:s("distill.form.enabledOff")})]})]})}),e.jsx(y,{label:s("distill.form.intervalMs"),help:s("distill.form.intervalMsHelp"),value:l.intervalMs,placeholder:A.intervalMs,min:1e4,step:1e4,onChange:t=>m("intervalMs",t)}),e.jsx(y,{label:s("distill.form.floorMin"),help:s("distill.form.floorMinHelp"),value:l.floorMin,placeholder:A.floorMin,min:0,step:5,onChange:t=>m("floorMin",t)}),e.jsx(y,{label:s("distill.form.batchMax"),help:s("distill.form.batchMaxHelp"),value:l.batchMax,placeholder:A.batchMax,min:1,step:1,onChange:t=>m("batchMax",t)}),e.jsx(y,{label:s("distill.form.maxPending"),help:s("distill.form.maxPendingHelp"),value:l.maxPending,placeholder:A.maxPending,min:1,step:10,onChange:t=>m("maxPending",t)})]})]})]})]})}function b({label:n,help:s,children:a}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx($,{className:"text-xs text-text-dim",children:n}),a,s&&e.jsx("p",{className:"text-[11px] text-text-muted",children:s})]})}function y({label:n,help:s,value:a,placeholder:r,min:j,step:d,onChange:c}){return e.jsx(b,{label:n,help:s,children:e.jsx(ee,{type:"number",min:j,step:d,value:a,placeholder:r,onChange:h=>c(h.target.value),className:"font-mono text-xs"})})}function _e(){const{t:n}=Y(["memory","common"]),s=ie(),a=s.data,r=re();async function j(){try{await r.mutateAsync(),p.success(n("distill.actions.runStarted"))}catch(h){const{message:v}=F(h,n);p.error(v)}}const d=!!a?.running,c=a?.pendingTotal??0;return e.jsxs("div",{className:"mx-auto flex max-w-5xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:n("distill.title")}),e.jsxs(k,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>s.refetch(),disabled:s.isFetching,"aria-label":n("actions.refresh",{ns:"common"}),children:[s.isFetching?e.jsx(R,{className:"h-4 w-4 animate-spin"}):e.jsx(oe,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:n("actions.refresh",{ns:"common"})})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:n("distill.subtitle")})]}),e.jsx(xe,{onSaved:()=>void s.refetch()}),e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[e.jsx("span",{className:"font-medium",children:n("distill.status.title")}),e.jsx(O,{variant:a?.enabled?"success":"secondary",children:a?.enabled?n("distill.status.enabledTrue"):n("distill.status.enabledFalse")}),d&&e.jsxs(O,{variant:"info",children:[e.jsx(R,{className:"mr-1 inline h-3 w-3 animate-spin"}),n("distill.status.running")]}),e.jsx("div",{className:"ml-auto",children:e.jsxs(k,{variant:"default",size:"sm",onClick:()=>void j(),disabled:r.isPending||d||!a?.enabled,children:[r.isPending?e.jsx(R,{className:"h-4 w-4 animate-spin"}):e.jsx(de,{className:"h-4 w-4"}),n("distill.actions.runNow")]})})]}),s.isLoading?e.jsx("div",{className:"mt-3 h-20 w-full rounded-md bg-surface-2 animate-pulse"}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-2 sm:grid-cols-3",children:[e.jsx(D,{label:n("distill.status.pending"),value:c,tone:c>0?"warning":"success"}),e.jsx(D,{label:n("distill.status.lastProcessed"),value:a?.lastProcessed??0,tone:"info"}),e.jsx(D,{label:n("distill.status.lastRun"),value:he(a?.lastRunAt),tone:"info"})]}),c===0&&e.jsxs("p",{className:"mt-2 flex items-center gap-1 text-xs text-text-muted",children:[e.jsx(ce,{className:"h-3 w-3"}),n("distill.status.bufferEmpty")]}),a?.lastError&&e.jsxs("p",{className:"mt-2 text-xs text-danger break-all",children:[n("distill.status.lastError"),": ",a.lastError]})]})]})]})}const fe={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 D({label:n,value:s,tone:a}){return e.jsxs("div",{className:se("rounded-md border bg-bg px-2 py-2",fe[a]),children:[e.jsx("div",{className:"text-[10px] uppercase tracking-wide text-text-dim",children:n}),e.jsx("div",{className:"text-xl font-semibold tabular-nums",children:s})]})}function he(n){if(!n)return"—";try{const s=new Date(n);return Number.isNaN(s.getTime())?String(n):s.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(n)}}export{_e as default};
|
|
7
|
-
//# sourceMappingURL=distill-
|
|
6
|
+
*/const ce=K("AlarmClockCheck",[["circle",{cx:"12",cy:"13",r:"8",key:"3y4lt7"}],["path",{d:"M5 3 2 6",key:"18tl5t"}],["path",{d:"m22 6-3-3",key:"1opdir"}],["path",{d:"M6.38 18.7 4 21",key:"17xu3x"}],["path",{d:"M17.64 18.67 20 21",key:"kv2oe2"}],["path",{d:"m9 13 2 2 4-4",key:"6343dt"}]]),S={intervalMs:"300000",floorMin:"30",batchMax:"20",maxPending:"200"};function me(n){const s=(n??"1").trim().toLowerCase();return s!=="0"&&s!=="false"&&s!=="no"&&s!=="off"}function ue(n){const s=(n||"auto").toLowerCase();return s==="agent"||s==="llm"?s:"auto"}function xe({onSaved:n}){const{t:s}=Y(["memory","common"]),a=te({reveal:!1}),r=f.useMemo(()=>a.data?.env??{},[a.data?.env]),j=le(),o=J(),c=j.data?.agents??[],h=o.data?.backends??[],v=o.data?.roles?.distill??"",T=f.useMemo(()=>()=>({source:ue(r.AGIM_MEMORY_DISTILL_SOURCE),agent:r.AGIM_MEMORY_DISTILL_AGENT||"",llmBackend:v,enabled:me(r.AGIM_MEMORY_DISTILL_ENABLED),intervalMs:r.AGIM_MEMORY_DISTILL_INTERVAL_MS||"",floorMin:r.AGIM_MEMORY_DISTILL_FLOOR_MIN||"",batchMax:r.AGIM_MEMORY_DISTILL_BATCH_MAX||"",maxPending:r.AGIM_MEMORY_DISTILL_MAX_PENDING||""}),[r,v]),[l,N]=f.useState(T),g=f.useRef(l),P=f.useRef(!1);f.useEffect(()=>{if(P.current||!a.data||!o.data)return;const t=T();N(t),g.current=t,P.current=!0},[a.data,o.data,T]);const G=ne(),B=W(),w=f.useMemo(()=>{const t=g.current;return Object.keys(l).some(i=>l[i]!==t[i])},[l]);function m(t,i){N(d=>({...d,[t]:i}))}function I(t,i,d){if(!t.trim())return null;const u=Number(t);return!Number.isFinite(u)||u<i?s("distill.form.errors.numRange",{field:d,min:i}):null}function H(){return l.source==="agent"&&!l.agent.trim()?s("distill.form.errors.agentRequired"):l.source==="llm"&&!l.llmBackend.trim()?s("distill.form.errors.llmRequired"):I(l.intervalMs,1e4,s("distill.form.intervalMs"))??I(l.floorMin,0,s("distill.form.floorMin"))??I(l.batchMax,1,s("distill.form.batchMax"))??I(l.maxPending,1,s("distill.form.maxPending"))}function V(){const t=g.current,i={},d=(u,M,q)=>{M!==q&&(i[u]=M.trim()===""?null:M.trim())};return l.source!==t.source&&(i.AGIM_MEMORY_DISTILL_SOURCE=l.source==="auto"?null:l.source),l.enabled!==t.enabled&&(i.AGIM_MEMORY_DISTILL_ENABLED=l.enabled?"1":"0"),l.source==="agent"?d("AGIM_MEMORY_DISTILL_AGENT",l.agent,t.agent):t.agent&&(i.AGIM_MEMORY_DISTILL_AGENT=null),d("AGIM_MEMORY_DISTILL_INTERVAL_MS",l.intervalMs,t.intervalMs),d("AGIM_MEMORY_DISTILL_FLOOR_MIN",l.floorMin,t.floorMin),d("AGIM_MEMORY_DISTILL_BATCH_MAX",l.batchMax,t.batchMax),d("AGIM_MEMORY_DISTILL_MAX_PENDING",l.maxPending,t.maxPending),i}async function U(){const t=H();if(t){p.error(t);return}const i=V(),d=l.source==="llm"&&l.llmBackend.trim()!==""&&l.llmBackend!==g.current.llmBackend;if(Object.keys(i).length===0&&!d){p.info(s("distill.form.nothingChanged"));return}try{Object.keys(i).length>0&&await G.mutateAsync({updates:i}),d&&await B.mutateAsync({distill:l.llmBackend.trim()}),p.success(s("distill.form.savedToast")),g.current={...l},N(u=>({...u})),n?.()}catch(u){const{message:M}=F(u,s);p.error(M)}}function z(){N(g.current)}const C=G.isPending||B.isPending,Q=h.length===0,X=c.length===0;return e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("h2",{className:"text-sm font-medium",children:s("distill.form.title")}),w&&e.jsx(O,{variant:"info",children:s("distill.form.dirty")}),e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[w&&e.jsx(k,{type:"button",variant:"secondary",size:"sm",onClick:z,disabled:C,children:s("distill.form.discard")}),e.jsxs(k,{type:"button",size:"sm",onClick:()=>void U(),disabled:!w||C,children:[C?e.jsx(R,{className:"h-4 w-4 animate-spin"}):e.jsx(ae,{className:"h-4 w-4"}),s("distill.form.save")]})]})]}),e.jsx("p",{className:"mt-1 text-xs text-text-dim",children:s("distill.form.hint")}),a.isLoading?e.jsx("div",{className:"mt-3 h-32 w-full rounded-md bg-surface-2 animate-pulse"}):e.jsxs("div",{className:"mt-3 flex flex-col gap-4",children:[e.jsxs("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2",children:[e.jsx(b,{label:s("distill.form.source"),help:s("distill.form.sourceHelp"),children:e.jsxs(_,{value:l.source,onValueChange:t=>m("source",t),children:[e.jsx(L,{children:e.jsx(E,{})}),e.jsxs(A,{children:[e.jsx(x,{value:"auto",children:s("distill.form.sourceAuto")}),e.jsx(x,{value:"agent",children:s("distill.form.sourceAgent")}),e.jsx(x,{value:"llm",children:s("distill.form.sourceLlm")})]})]})}),l.source==="auto"&&e.jsx("div",{className:"flex items-end",children:e.jsx("p",{className:"text-[11px] text-text-muted",children:s("distill.form.autoNote")})}),l.source==="agent"&&e.jsx(b,{label:s("distill.form.agent"),help:s("distill.form.agentHelp"),children:X?e.jsx("p",{className:"text-[11px] text-warning",children:s("distill.form.noAgents")}):e.jsxs(_,{value:l.agent,onValueChange:t=>m("agent",t),children:[e.jsx(L,{children:e.jsx(E,{placeholder:s("distill.form.agentPlaceholder")})}),e.jsx(A,{children:c.map(t=>e.jsx(x,{value:t,children:Z(t)},t))})]})}),l.source==="llm"&&e.jsx(b,{label:s("distill.form.llmBackend"),help:s("distill.form.llmBackendHelp"),children:Q?e.jsx("p",{className:"text-[11px] text-warning",children:s("distill.form.noBackends")}):e.jsxs(_,{value:l.llmBackend,onValueChange:t=>m("llmBackend",t),children:[e.jsx(L,{children:e.jsx(E,{placeholder:s("distill.form.llmPlaceholder")})}),e.jsx(A,{children:h.map(t=>e.jsxs(x,{value:t.name,children:[t.name," ",e.jsxs("span",{className:"text-text-muted",children:["· ",t.model]})]},t.name))})]})})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-medium text-text-dim",children:s("distill.form.scheduleTitle")}),e.jsxs("div",{className:"mt-2 grid grid-cols-1 gap-3 sm:grid-cols-2",children:[e.jsx(b,{label:s("distill.form.enabled"),help:s("distill.form.enabledHelp"),children:e.jsxs(_,{value:l.enabled?"on":"off",onValueChange:t=>m("enabled",t==="on"),children:[e.jsx(L,{children:e.jsx(E,{})}),e.jsxs(A,{children:[e.jsx(x,{value:"on",children:s("distill.form.enabledOn")}),e.jsx(x,{value:"off",children:s("distill.form.enabledOff")})]})]})}),e.jsx(y,{label:s("distill.form.intervalMs"),help:s("distill.form.intervalMsHelp"),value:l.intervalMs,placeholder:S.intervalMs,min:1e4,step:1e4,onChange:t=>m("intervalMs",t)}),e.jsx(y,{label:s("distill.form.floorMin"),help:s("distill.form.floorMinHelp"),value:l.floorMin,placeholder:S.floorMin,min:0,step:5,onChange:t=>m("floorMin",t)}),e.jsx(y,{label:s("distill.form.batchMax"),help:s("distill.form.batchMaxHelp"),value:l.batchMax,placeholder:S.batchMax,min:1,step:1,onChange:t=>m("batchMax",t)}),e.jsx(y,{label:s("distill.form.maxPending"),help:s("distill.form.maxPendingHelp"),value:l.maxPending,placeholder:S.maxPending,min:1,step:10,onChange:t=>m("maxPending",t)})]})]})]})]})}function b({label:n,help:s,children:a}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx($,{className:"text-xs text-text-dim",children:n}),a,s&&e.jsx("p",{className:"text-[11px] text-text-muted",children:s})]})}function y({label:n,help:s,value:a,placeholder:r,min:j,step:o,onChange:c}){return e.jsx(b,{label:n,help:s,children:e.jsx(ee,{type:"number",min:j,step:o,value:a,placeholder:r,onChange:h=>c(h.target.value),className:"font-mono text-xs"})})}function _e(){const{t:n}=Y(["memory","common"]),s=ie(),a=s.data,r=re();async function j(){try{await r.mutateAsync(),p.success(n("distill.actions.runStarted"))}catch(h){const{message:v}=F(h,n);p.error(v)}}const o=!!a?.running,c=a?.pendingTotal??0;return e.jsxs("div",{className:"mx-auto flex max-w-5xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:n("distill.title")}),e.jsxs(k,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>s.refetch(),disabled:s.isFetching,"aria-label":n("actions.refresh",{ns:"common"}),children:[s.isFetching?e.jsx(R,{className:"h-4 w-4 animate-spin"}):e.jsx(de,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:n("actions.refresh",{ns:"common"})})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:n("distill.subtitle")})]}),e.jsx(xe,{onSaved:()=>void s.refetch()}),e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[e.jsx("span",{className:"font-medium",children:n("distill.status.title")}),e.jsx(O,{variant:a?.enabled?"success":"secondary",children:a?.enabled?n("distill.status.enabledTrue"):n("distill.status.enabledFalse")}),o&&e.jsxs(O,{variant:"info",children:[e.jsx(R,{className:"mr-1 inline h-3 w-3 animate-spin"}),n("distill.status.running")]}),e.jsx("div",{className:"ml-auto",children:e.jsxs(k,{variant:"default",size:"sm",onClick:()=>void j(),disabled:r.isPending||o||!a?.enabled,children:[r.isPending?e.jsx(R,{className:"h-4 w-4 animate-spin"}):e.jsx(oe,{className:"h-4 w-4"}),n("distill.actions.runNow")]})})]}),s.isLoading?e.jsx("div",{className:"mt-3 h-20 w-full rounded-md bg-surface-2 animate-pulse"}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-2 sm:grid-cols-3",children:[e.jsx(D,{label:n("distill.status.pending"),value:c,tone:c>0?"warning":"success"}),e.jsx(D,{label:n("distill.status.lastProcessed"),value:a?.lastProcessed??0,tone:"info"}),e.jsx(D,{label:n("distill.status.lastRun"),value:he(a?.lastRunAt),tone:"info"})]}),c===0&&e.jsxs("p",{className:"mt-2 flex items-center gap-1 text-xs text-text-muted",children:[e.jsx(ce,{className:"h-3 w-3"}),n("distill.status.bufferEmpty")]}),a?.lastError&&e.jsxs("p",{className:"mt-2 text-xs text-danger break-all",children:[n("distill.status.lastError"),": ",a.lastError]})]})]})]})}const fe={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 D({label:n,value:s,tone:a}){return e.jsxs("div",{className:se("rounded-md border bg-bg px-2 py-2",fe[a]),children:[e.jsx("div",{className:"text-[10px] uppercase tracking-wide text-text-dim",children:n}),e.jsx("div",{className:"text-xl font-semibold tabular-nums",children:s})]})}function he(n){if(!n)return"—";try{const s=new Date(n);return Number.isNaN(s.getTime())?String(n):s.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(n)}}export{_e as default};
|
|
7
|
+
//# sourceMappingURL=distill-CPurVW3v.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distill-p6P7-1UR.js","sources":["../../node_modules/lucide-react/dist/esm/icons/alarm-clock-check.js","../../src/routes/memory/distill-config-form.tsx","../../src/routes/memory/distill.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 AlarmClockCheck = createLucideIcon(\"AlarmClockCheck\", [\n [\"circle\", { cx: \"12\", cy: \"13\", r: \"8\", key: \"3y4lt7\" }],\n [\"path\", { d: \"M5 3 2 6\", key: \"18tl5t\" }],\n [\"path\", { d: \"m22 6-3-3\", key: \"1opdir\" }],\n [\"path\", { d: \"M6.38 18.7 4 21\", key: \"17xu3x\" }],\n [\"path\", { d: \"M17.64 18.67 20 21\", key: \"kv2oe2\" }],\n [\"path\", { d: \"m9 13 2 2 4-4\", key: \"6343dt\" }]\n]);\n\nexport { AlarmClockCheck as default };\n//# sourceMappingURL=alarm-clock-check.js.map\n","/**\n * DistillConfigForm — inline editor for the \"dream distillation\"\n * scheduler (memory-distiller.ts + memory-distill.ts).\n *\n * Two things the operator configures here:\n *\n * 1. SOURCE — which LLM extracts facts from buffered turns:\n * auto → the turn's own agent (zero-config default; nothing else\n * to set). Recommended for most installs.\n * agent → a specific, already-enabled agent CLI\n * (AGIM_MEMORY_DISTILL_AGENT).\n * llm → a standalone LLM backend bound to the `distill` role,\n * configured exactly like the native agent's LLM\n * (PUT /api/llm/roles { distill }). No CLI spawn.\n *\n * 2. SCHEDULE — the cadence knobs (enabled / interval / staleness\n * floor / batch size / per-user buffer cap), all AGIM_MEMORY_DISTILL_*\n * env keys behind the server allowlist.\n *\n * Save flow mirrors vector-backend-form: diff against the last-loaded\n * values, PUT /api/env for the env keys, and — only when source=llm and\n * the chosen backend changed — PUT /api/llm/roles to (re)bind the\n * distill role. Empty agent / backend selections are validated before\n * save so we never persist a half-configured source.\n */\n\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Loader2, Save } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport { useEnv, useUpdateEnv, useConfig } from '@/hooks/use-settings'\nimport { useLlmList, useLlmPutRoles } from '@/hooks/use-llm-admin'\nimport { describeError } from '@/lib/api/errors'\nimport { agentDisplayName } from '@/lib/agent-label'\n\ntype DistillSource = 'auto' | 'agent' | 'llm'\n\ninterface FormState {\n source: DistillSource\n agent: string // AGIM_MEMORY_DISTILL_AGENT (source=agent)\n llmBackend: string // llmRoles.distill backend name (source=llm)\n enabled: boolean // AGIM_MEMORY_DISTILL_ENABLED\n intervalMs: string // AGIM_MEMORY_DISTILL_INTERVAL_MS\n floorMin: string // AGIM_MEMORY_DISTILL_FLOOR_MIN\n batchMax: string // AGIM_MEMORY_DISTILL_BATCH_MAX\n maxPending: string // AGIM_MEMORY_DISTILL_MAX_PENDING\n}\n\n// Mirror of the memory-distiller.ts defaults so placeholders match the\n// runtime fallbacks when a key is unset.\nconst DEFAULTS = {\n intervalMs: '300000',\n floorMin: '30',\n batchMax: '20',\n maxPending: '200',\n} as const\n\nfunction readEnabled(raw: string | undefined): boolean {\n const v = (raw ?? '1').trim().toLowerCase()\n return v !== '0' && v !== 'false' && v !== 'no' && v !== 'off'\n}\n\nfunction readSource(raw: string | undefined): DistillSource {\n const v = (raw || 'auto').toLowerCase()\n return v === 'agent' || v === 'llm' ? v : 'auto'\n}\n\nexport interface DistillConfigFormProps {\n /** Called after a successful save so the parent can refresh status. */\n onSaved?: () => void\n}\n\nexport function DistillConfigForm({ onSaved }: DistillConfigFormProps): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n\n const envQuery = useEnv({ reveal: false })\n const env = useMemo(() => envQuery.data?.env ?? {}, [envQuery.data?.env])\n const cfgQuery = useConfig()\n const llmQuery = useLlmList()\n\n const enabledAgents = cfgQuery.data?.agents ?? []\n const llmBackends = llmQuery.data?.backends ?? []\n const currentDistillRole = llmQuery.data?.roles?.distill ?? ''\n\n const readForm = useMemo<() => FormState>(() => () => ({\n source: readSource(env.AGIM_MEMORY_DISTILL_SOURCE),\n agent: env.AGIM_MEMORY_DISTILL_AGENT || '',\n llmBackend: currentDistillRole,\n enabled: readEnabled(env.AGIM_MEMORY_DISTILL_ENABLED),\n intervalMs: env.AGIM_MEMORY_DISTILL_INTERVAL_MS || '',\n floorMin: env.AGIM_MEMORY_DISTILL_FLOOR_MIN || '',\n batchMax: env.AGIM_MEMORY_DISTILL_BATCH_MAX || '',\n maxPending: env.AGIM_MEMORY_DISTILL_MAX_PENDING || '',\n }), [env, currentDistillRole])\n\n const [form, setForm] = useState<FormState>(readForm)\n const initialRef = useRef<FormState>(form)\n const seededRef = useRef(false)\n\n // Seed from the server exactly once, after BOTH env and the llm roles have\n // loaded (llmBackend is derived from llmQuery). Seeding once — rather than on\n // every refetch — is deliberate: readForm's identity changes whenever the\n // env object or currentDistillRole changes, so a re-seed-on-refetch effect\n // would stomp the operator's unsaved edits the moment an unrelated llmQuery\n // or env refetch fires (window focus, or role invalidation from a different\n // save). The post-save baseline is committed directly in onSave instead.\n useEffect(() => {\n if (seededRef.current) return\n if (!envQuery.data || !llmQuery.data) return\n const next = readForm()\n setForm(next)\n initialRef.current = next\n seededRef.current = true\n }, [envQuery.data, llmQuery.data, readForm])\n\n const updateEnv = useUpdateEnv()\n const putRoles = useLlmPutRoles()\n\n const dirty = useMemo(() => {\n const initial = initialRef.current\n return (Object.keys(form) as Array<keyof FormState>).some((k) => form[k] !== initial[k])\n }, [form])\n\n function set<K extends keyof FormState>(k: K, v: FormState[K]): void {\n setForm((prev) => ({ ...prev, [k]: v }))\n }\n\n function numField(value: string, min: number, label: string): string | null {\n if (!value.trim()) return null\n const n = Number(value)\n if (!Number.isFinite(n) || n < min) return t('distill.form.errors.numRange', { field: label, min })\n return null\n }\n\n function validate(): string | null {\n if (form.source === 'agent' && !form.agent.trim()) {\n return t('distill.form.errors.agentRequired')\n }\n if (form.source === 'llm' && !form.llmBackend.trim()) {\n return t('distill.form.errors.llmRequired')\n }\n return (\n numField(form.intervalMs, 10000, t('distill.form.intervalMs'))\n ?? numField(form.floorMin, 0, t('distill.form.floorMin'))\n ?? numField(form.batchMax, 1, t('distill.form.batchMax'))\n ?? numField(form.maxPending, 1, t('distill.form.maxPending'))\n )\n }\n\n function buildEnvUpdates(): Record<string, string | null> {\n const initial = initialRef.current\n const out: Record<string, string | null> = {}\n const diffStr = (key: string, cur: string, prev: string): void => {\n if (cur === prev) return\n out[key] = cur.trim() === '' ? null : cur.trim()\n }\n if (form.source !== initial.source) {\n // 'auto' is the runtime default → store null to keep env tidy.\n out.AGIM_MEMORY_DISTILL_SOURCE = form.source === 'auto' ? null : form.source\n }\n if (form.enabled !== initial.enabled) {\n out.AGIM_MEMORY_DISTILL_ENABLED = form.enabled ? '1' : '0'\n }\n // Only persist the agent name when the chosen source actually uses it,\n // so flipping away from 'agent' doesn't leave a stale key behind.\n if (form.source === 'agent') {\n diffStr('AGIM_MEMORY_DISTILL_AGENT', form.agent, initial.agent)\n } else if (initial.agent) {\n out.AGIM_MEMORY_DISTILL_AGENT = null\n }\n diffStr('AGIM_MEMORY_DISTILL_INTERVAL_MS', form.intervalMs, initial.intervalMs)\n diffStr('AGIM_MEMORY_DISTILL_FLOOR_MIN', form.floorMin, initial.floorMin)\n diffStr('AGIM_MEMORY_DISTILL_BATCH_MAX', form.batchMax, initial.batchMax)\n diffStr('AGIM_MEMORY_DISTILL_MAX_PENDING', form.maxPending, initial.maxPending)\n return out\n }\n\n async function onSave(): Promise<void> {\n const err = validate()\n if (err) { toast.error(err); return }\n\n const envUpdates = buildEnvUpdates()\n const roleChanged = form.source === 'llm'\n && form.llmBackend.trim() !== ''\n && form.llmBackend !== initialRef.current.llmBackend\n\n if (Object.keys(envUpdates).length === 0 && !roleChanged) {\n toast.info(t('distill.form.nothingChanged'))\n return\n }\n\n try {\n if (Object.keys(envUpdates).length > 0) {\n await updateEnv.mutateAsync({ updates: envUpdates })\n }\n if (roleChanged) {\n await putRoles.mutateAsync({ distill: form.llmBackend.trim() })\n }\n toast.success(t('distill.form.savedToast'))\n // Commit the saved values as the new baseline so the form settles to\n // non-dirty. We seed from the server only once (see the effect above),\n // so there's no refetch round-trip to reset it for us; the shallow copy\n // re-triggers the `dirty` memo against the updated baseline.\n initialRef.current = { ...form }\n setForm((f) => ({ ...f }))\n onSaved?.()\n } catch (serr) {\n const { message } = describeError(serr, t)\n toast.error(message)\n }\n }\n\n function onDiscard(): void {\n setForm(initialRef.current)\n }\n\n const busy = updateEnv.isPending || putRoles.isPending\n const noBackends = llmBackends.length === 0\n const noAgents = enabledAgents.length === 0\n\n return (\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h2 className=\"text-sm font-medium\">{t('distill.form.title')}</h2>\n {dirty && <Badge variant=\"info\">{t('distill.form.dirty')}</Badge>}\n <div className=\"ml-auto flex items-center gap-2\">\n {dirty && (\n <Button type=\"button\" variant=\"secondary\" size=\"sm\" onClick={onDiscard} disabled={busy}>\n {t('distill.form.discard')}\n </Button>\n )}\n <Button type=\"button\" size=\"sm\" onClick={() => void onSave()} disabled={!dirty || busy}>\n {busy ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Save className=\"h-4 w-4\" />}\n {t('distill.form.save')}\n </Button>\n </div>\n </div>\n <p className=\"mt-1 text-xs text-text-dim\">{t('distill.form.hint')}</p>\n\n {envQuery.isLoading ? (\n <div className=\"mt-3 h-32 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <div className=\"mt-3 flex flex-col gap-4\">\n {/* ── Source ── */}\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <Field label={t('distill.form.source')} help={t('distill.form.sourceHelp')}>\n <Select value={form.source} onValueChange={(v) => set('source', v as DistillSource)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"auto\">{t('distill.form.sourceAuto')}</SelectItem>\n <SelectItem value=\"agent\">{t('distill.form.sourceAgent')}</SelectItem>\n <SelectItem value=\"llm\">{t('distill.form.sourceLlm')}</SelectItem>\n </SelectContent>\n </Select>\n </Field>\n\n {form.source === 'auto' && (\n <div className=\"flex items-end\">\n <p className=\"text-[11px] text-text-muted\">{t('distill.form.autoNote')}</p>\n </div>\n )}\n\n {form.source === 'agent' && (\n <Field label={t('distill.form.agent')} help={t('distill.form.agentHelp')}>\n {noAgents ? (\n <p className=\"text-[11px] text-warning\">{t('distill.form.noAgents')}</p>\n ) : (\n <Select value={form.agent} onValueChange={(v) => set('agent', v)}>\n <SelectTrigger>\n <SelectValue placeholder={t('distill.form.agentPlaceholder')} />\n </SelectTrigger>\n <SelectContent>\n {enabledAgents.map((name) => (\n <SelectItem key={name} value={name}>{agentDisplayName(name)}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n </Field>\n )}\n\n {form.source === 'llm' && (\n <Field label={t('distill.form.llmBackend')} help={t('distill.form.llmBackendHelp')}>\n {noBackends ? (\n <p className=\"text-[11px] text-warning\">{t('distill.form.noBackends')}</p>\n ) : (\n <Select value={form.llmBackend} onValueChange={(v) => set('llmBackend', v)}>\n <SelectTrigger>\n <SelectValue placeholder={t('distill.form.llmPlaceholder')} />\n </SelectTrigger>\n <SelectContent>\n {llmBackends.map((b) => (\n <SelectItem key={b.name} value={b.name}>\n {b.name} <span className=\"text-text-muted\">· {b.model}</span>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n </Field>\n )}\n </div>\n\n {/* ── Schedule ── */}\n <div>\n <div className=\"text-xs font-medium text-text-dim\">{t('distill.form.scheduleTitle')}</div>\n <div className=\"mt-2 grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <Field label={t('distill.form.enabled')} help={t('distill.form.enabledHelp')}>\n <Select\n value={form.enabled ? 'on' : 'off'}\n onValueChange={(v) => set('enabled', v === 'on')}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"on\">{t('distill.form.enabledOn')}</SelectItem>\n <SelectItem value=\"off\">{t('distill.form.enabledOff')}</SelectItem>\n </SelectContent>\n </Select>\n </Field>\n <NumberField\n label={t('distill.form.intervalMs')}\n help={t('distill.form.intervalMsHelp')}\n value={form.intervalMs}\n placeholder={DEFAULTS.intervalMs}\n min={10000}\n step={10000}\n onChange={(v) => set('intervalMs', v)}\n />\n <NumberField\n label={t('distill.form.floorMin')}\n help={t('distill.form.floorMinHelp')}\n value={form.floorMin}\n placeholder={DEFAULTS.floorMin}\n min={0}\n step={5}\n onChange={(v) => set('floorMin', v)}\n />\n <NumberField\n label={t('distill.form.batchMax')}\n help={t('distill.form.batchMaxHelp')}\n value={form.batchMax}\n placeholder={DEFAULTS.batchMax}\n min={1}\n step={1}\n onChange={(v) => set('batchMax', v)}\n />\n <NumberField\n label={t('distill.form.maxPending')}\n help={t('distill.form.maxPendingHelp')}\n value={form.maxPending}\n placeholder={DEFAULTS.maxPending}\n min={1}\n step={10}\n onChange={(v) => set('maxPending', v)}\n />\n </div>\n </div>\n </div>\n )}\n </div>\n )\n}\n\nfunction Field({\n label,\n help,\n children,\n}: {\n label: string\n help?: string\n children: React.ReactNode\n}): JSX.Element {\n return (\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs text-text-dim\">{label}</Label>\n {children}\n {help && <p className=\"text-[11px] text-text-muted\">{help}</p>}\n </div>\n )\n}\n\nfunction NumberField({\n label,\n help,\n value,\n placeholder,\n min,\n step,\n onChange,\n}: {\n label: string\n help?: string\n value: string\n placeholder: string\n min: number\n step: number\n onChange: (v: string) => void\n}): JSX.Element {\n return (\n <Field label={label} help={help}>\n <Input\n type=\"number\"\n min={min}\n step={step}\n value={value}\n placeholder={placeholder}\n onChange={(e) => onChange(e.target.value)}\n className=\"font-mono text-xs\"\n />\n </Field>\n )\n}\n","/**\n * /memory/distill — \"dream distillation\" control surface.\n *\n * Dream distillation buffers every chat turn into pending_distill and\n * batch-extracts facts in the background when the system is idle (or\n * once a user's oldest buffered turn passes the staleness floor). This\n * tab lets the operator:\n *\n * - configure the extraction SOURCE + SCHEDULE (DistillConfigForm)\n * - watch the live buffer depth + last-run telemetry (status tiles)\n * - force a pass now (\"Run now\" → POST /api/memory/distill)\n *\n * Status polls every 3s (useDistillStatus) so a manual run visibly\n * drains `pendingTotal` to zero without a refresh. This view is global\n * (not per-user) — the buffer spans every user — so it ignores the\n * layout's ?user= filter.\n */\n\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { AlarmClockCheck, Loader2, Play, RefreshCcw } from 'lucide-react'\n\nimport { DistillConfigForm } from './distill-config-form'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { useDistillStatus, useTriggerDistill } from '@/hooks/use-memory'\nimport { describeError } from '@/lib/api/errors'\nimport { cn } from '@/lib/utils'\n\nexport default function MemoryDistillRoute(): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n const statusQuery = useDistillStatus()\n const status = statusQuery.data\n const trigger = useTriggerDistill()\n\n async function onRunNow(): Promise<void> {\n try {\n await trigger.mutateAsync()\n toast.success(t('distill.actions.runStarted'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n const running = !!status?.running\n const pending = status?.pendingTotal ?? 0\n\n return (\n <div className=\"mx-auto flex max-w-5xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('distill.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => statusQuery.refetch()}\n disabled={statusQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {statusQuery.isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('distill.subtitle')}</p>\n </header>\n\n {/* Configuration */}\n <DistillConfigForm onSaved={() => void statusQuery.refetch()} />\n\n {/* Status + actions */}\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"flex flex-wrap items-center gap-2 text-sm\">\n <span className=\"font-medium\">{t('distill.status.title')}</span>\n <Badge variant={status?.enabled ? 'success' : 'secondary'}>\n {status?.enabled ? t('distill.status.enabledTrue') : t('distill.status.enabledFalse')}\n </Badge>\n {running && (\n <Badge variant=\"info\">\n <Loader2 className=\"mr-1 inline h-3 w-3 animate-spin\" />\n {t('distill.status.running')}\n </Badge>\n )}\n <div className=\"ml-auto\">\n <Button\n variant=\"default\"\n size=\"sm\"\n onClick={() => void onRunNow()}\n disabled={trigger.isPending || running || !status?.enabled}\n >\n {trigger.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Play className=\"h-4 w-4\" />}\n {t('distill.actions.runNow')}\n </Button>\n </div>\n </div>\n\n {statusQuery.isLoading ? (\n <div className=\"mt-3 h-20 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <>\n <div className=\"mt-3 grid grid-cols-2 gap-2 sm:grid-cols-3\">\n <StatTile label={t('distill.status.pending')} value={pending} tone={pending > 0 ? 'warning' : 'success'} />\n <StatTile label={t('distill.status.lastProcessed')} value={status?.lastProcessed ?? 0} tone=\"info\" />\n <StatTile label={t('distill.status.lastRun')} value={formatEpoch(status?.lastRunAt)} tone=\"info\" />\n </div>\n {pending === 0 && (\n <p className=\"mt-2 flex items-center gap-1 text-xs text-text-muted\">\n <AlarmClockCheck className=\"h-3 w-3\" />\n {t('distill.status.bufferEmpty')}\n </p>\n )}\n {status?.lastError && (\n <p className=\"mt-2 text-xs text-danger break-all\">\n {t('distill.status.lastError')}: {status.lastError}\n </p>\n )}\n </>\n )}\n </div>\n </div>\n )\n}\n\ninterface StatTileProps {\n label: string\n value: number | string\n tone: 'info' | 'success' | 'warning' | 'danger'\n}\n\nconst TONE_STYLES: Record<StatTileProps['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 StatTile({ label, value, tone }: StatTileProps): JSX.Element {\n return (\n <div className={cn('rounded-md border bg-bg px-2 py-2', TONE_STYLES[tone])}>\n <div className=\"text-[10px] uppercase tracking-wide text-text-dim\">{label}</div>\n <div className=\"text-xl font-semibold tabular-nums\">{value}</div>\n </div>\n )\n}\n\nfunction formatEpoch(ms: number | null | undefined): string {\n if (!ms) return '—'\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":["AlarmClockCheck","createLucideIcon","DEFAULTS","readEnabled","raw","v","readSource","DistillConfigForm","onSaved","t","useTranslation","envQuery","useEnv","env","useMemo","cfgQuery","useConfig","llmQuery","useLlmList","enabledAgents","llmBackends","currentDistillRole","readForm","form","setForm","useState","initialRef","useRef","seededRef","useEffect","next","updateEnv","useUpdateEnv","putRoles","useLlmPutRoles","dirty","initial","k","set","prev","numField","value","min","label","n","validate","buildEnvUpdates","out","diffStr","key","cur","onSave","err","toast","envUpdates","roleChanged","f","serr","message","describeError","onDiscard","busy","noBackends","noAgents","jsxs","jsx","Badge","Button","Loader2","Save","Field","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","name","agentDisplayName","b","NumberField","help","children","Label","placeholder","step","onChange","Input","e","MemoryDistillRoute","statusQuery","useDistillStatus","status","trigger","useTriggerDistill","onRunNow","running","pending","RefreshCcw","Play","Fragment","StatTile","formatEpoch","TONE_STYLES","tone","cn","ms","d"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"distill-CPurVW3v.js","sources":["../../node_modules/lucide-react/dist/esm/icons/alarm-clock-check.js","../../src/routes/memory/distill-config-form.tsx","../../src/routes/memory/distill.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 AlarmClockCheck = createLucideIcon(\"AlarmClockCheck\", [\n [\"circle\", { cx: \"12\", cy: \"13\", r: \"8\", key: \"3y4lt7\" }],\n [\"path\", { d: \"M5 3 2 6\", key: \"18tl5t\" }],\n [\"path\", { d: \"m22 6-3-3\", key: \"1opdir\" }],\n [\"path\", { d: \"M6.38 18.7 4 21\", key: \"17xu3x\" }],\n [\"path\", { d: \"M17.64 18.67 20 21\", key: \"kv2oe2\" }],\n [\"path\", { d: \"m9 13 2 2 4-4\", key: \"6343dt\" }]\n]);\n\nexport { AlarmClockCheck as default };\n//# sourceMappingURL=alarm-clock-check.js.map\n","/**\n * DistillConfigForm — inline editor for the \"dream distillation\"\n * scheduler (memory-distiller.ts + memory-distill.ts).\n *\n * Two things the operator configures here:\n *\n * 1. SOURCE — which LLM extracts facts from buffered turns:\n * auto → the turn's own agent (zero-config default; nothing else\n * to set). Recommended for most installs.\n * agent → a specific, already-enabled agent CLI\n * (AGIM_MEMORY_DISTILL_AGENT).\n * llm → a standalone LLM backend bound to the `distill` role,\n * configured exactly like the native agent's LLM\n * (PUT /api/llm/roles { distill }). No CLI spawn.\n *\n * 2. SCHEDULE — the cadence knobs (enabled / interval / staleness\n * floor / batch size / per-user buffer cap), all AGIM_MEMORY_DISTILL_*\n * env keys behind the server allowlist.\n *\n * Save flow mirrors vector-backend-form: diff against the last-loaded\n * values, PUT /api/env for the env keys, and — only when source=llm and\n * the chosen backend changed — PUT /api/llm/roles to (re)bind the\n * distill role. Empty agent / backend selections are validated before\n * save so we never persist a half-configured source.\n */\n\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Loader2, Save } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport { useEnv, useUpdateEnv, useConfig } from '@/hooks/use-settings'\nimport { useLlmList, useLlmPutRoles } from '@/hooks/use-llm-admin'\nimport { describeError } from '@/lib/api/errors'\nimport { agentDisplayName } from '@/lib/agent-label'\n\ntype DistillSource = 'auto' | 'agent' | 'llm'\n\ninterface FormState {\n source: DistillSource\n agent: string // AGIM_MEMORY_DISTILL_AGENT (source=agent)\n llmBackend: string // llmRoles.distill backend name (source=llm)\n enabled: boolean // AGIM_MEMORY_DISTILL_ENABLED\n intervalMs: string // AGIM_MEMORY_DISTILL_INTERVAL_MS\n floorMin: string // AGIM_MEMORY_DISTILL_FLOOR_MIN\n batchMax: string // AGIM_MEMORY_DISTILL_BATCH_MAX\n maxPending: string // AGIM_MEMORY_DISTILL_MAX_PENDING\n}\n\n// Mirror of the memory-distiller.ts defaults so placeholders match the\n// runtime fallbacks when a key is unset.\nconst DEFAULTS = {\n intervalMs: '300000',\n floorMin: '30',\n batchMax: '20',\n maxPending: '200',\n} as const\n\nfunction readEnabled(raw: string | undefined): boolean {\n const v = (raw ?? '1').trim().toLowerCase()\n return v !== '0' && v !== 'false' && v !== 'no' && v !== 'off'\n}\n\nfunction readSource(raw: string | undefined): DistillSource {\n const v = (raw || 'auto').toLowerCase()\n return v === 'agent' || v === 'llm' ? v : 'auto'\n}\n\nexport interface DistillConfigFormProps {\n /** Called after a successful save so the parent can refresh status. */\n onSaved?: () => void\n}\n\nexport function DistillConfigForm({ onSaved }: DistillConfigFormProps): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n\n const envQuery = useEnv({ reveal: false })\n const env = useMemo(() => envQuery.data?.env ?? {}, [envQuery.data?.env])\n const cfgQuery = useConfig()\n const llmQuery = useLlmList()\n\n const enabledAgents = cfgQuery.data?.agents ?? []\n const llmBackends = llmQuery.data?.backends ?? []\n const currentDistillRole = llmQuery.data?.roles?.distill ?? ''\n\n const readForm = useMemo<() => FormState>(() => () => ({\n source: readSource(env.AGIM_MEMORY_DISTILL_SOURCE),\n agent: env.AGIM_MEMORY_DISTILL_AGENT || '',\n llmBackend: currentDistillRole,\n enabled: readEnabled(env.AGIM_MEMORY_DISTILL_ENABLED),\n intervalMs: env.AGIM_MEMORY_DISTILL_INTERVAL_MS || '',\n floorMin: env.AGIM_MEMORY_DISTILL_FLOOR_MIN || '',\n batchMax: env.AGIM_MEMORY_DISTILL_BATCH_MAX || '',\n maxPending: env.AGIM_MEMORY_DISTILL_MAX_PENDING || '',\n }), [env, currentDistillRole])\n\n const [form, setForm] = useState<FormState>(readForm)\n const initialRef = useRef<FormState>(form)\n const seededRef = useRef(false)\n\n // Seed from the server exactly once, after BOTH env and the llm roles have\n // loaded (llmBackend is derived from llmQuery). Seeding once — rather than on\n // every refetch — is deliberate: readForm's identity changes whenever the\n // env object or currentDistillRole changes, so a re-seed-on-refetch effect\n // would stomp the operator's unsaved edits the moment an unrelated llmQuery\n // or env refetch fires (window focus, or role invalidation from a different\n // save). The post-save baseline is committed directly in onSave instead.\n useEffect(() => {\n if (seededRef.current) return\n if (!envQuery.data || !llmQuery.data) return\n const next = readForm()\n setForm(next)\n initialRef.current = next\n seededRef.current = true\n }, [envQuery.data, llmQuery.data, readForm])\n\n const updateEnv = useUpdateEnv()\n const putRoles = useLlmPutRoles()\n\n const dirty = useMemo(() => {\n const initial = initialRef.current\n return (Object.keys(form) as Array<keyof FormState>).some((k) => form[k] !== initial[k])\n }, [form])\n\n function set<K extends keyof FormState>(k: K, v: FormState[K]): void {\n setForm((prev) => ({ ...prev, [k]: v }))\n }\n\n function numField(value: string, min: number, label: string): string | null {\n if (!value.trim()) return null\n const n = Number(value)\n if (!Number.isFinite(n) || n < min) return t('distill.form.errors.numRange', { field: label, min })\n return null\n }\n\n function validate(): string | null {\n if (form.source === 'agent' && !form.agent.trim()) {\n return t('distill.form.errors.agentRequired')\n }\n if (form.source === 'llm' && !form.llmBackend.trim()) {\n return t('distill.form.errors.llmRequired')\n }\n return (\n numField(form.intervalMs, 10000, t('distill.form.intervalMs'))\n ?? numField(form.floorMin, 0, t('distill.form.floorMin'))\n ?? numField(form.batchMax, 1, t('distill.form.batchMax'))\n ?? numField(form.maxPending, 1, t('distill.form.maxPending'))\n )\n }\n\n function buildEnvUpdates(): Record<string, string | null> {\n const initial = initialRef.current\n const out: Record<string, string | null> = {}\n const diffStr = (key: string, cur: string, prev: string): void => {\n if (cur === prev) return\n out[key] = cur.trim() === '' ? null : cur.trim()\n }\n if (form.source !== initial.source) {\n // 'auto' is the runtime default → store null to keep env tidy.\n out.AGIM_MEMORY_DISTILL_SOURCE = form.source === 'auto' ? null : form.source\n }\n if (form.enabled !== initial.enabled) {\n out.AGIM_MEMORY_DISTILL_ENABLED = form.enabled ? '1' : '0'\n }\n // Only persist the agent name when the chosen source actually uses it,\n // so flipping away from 'agent' doesn't leave a stale key behind.\n if (form.source === 'agent') {\n diffStr('AGIM_MEMORY_DISTILL_AGENT', form.agent, initial.agent)\n } else if (initial.agent) {\n out.AGIM_MEMORY_DISTILL_AGENT = null\n }\n diffStr('AGIM_MEMORY_DISTILL_INTERVAL_MS', form.intervalMs, initial.intervalMs)\n diffStr('AGIM_MEMORY_DISTILL_FLOOR_MIN', form.floorMin, initial.floorMin)\n diffStr('AGIM_MEMORY_DISTILL_BATCH_MAX', form.batchMax, initial.batchMax)\n diffStr('AGIM_MEMORY_DISTILL_MAX_PENDING', form.maxPending, initial.maxPending)\n return out\n }\n\n async function onSave(): Promise<void> {\n const err = validate()\n if (err) { toast.error(err); return }\n\n const envUpdates = buildEnvUpdates()\n const roleChanged = form.source === 'llm'\n && form.llmBackend.trim() !== ''\n && form.llmBackend !== initialRef.current.llmBackend\n\n if (Object.keys(envUpdates).length === 0 && !roleChanged) {\n toast.info(t('distill.form.nothingChanged'))\n return\n }\n\n try {\n if (Object.keys(envUpdates).length > 0) {\n await updateEnv.mutateAsync({ updates: envUpdates })\n }\n if (roleChanged) {\n await putRoles.mutateAsync({ distill: form.llmBackend.trim() })\n }\n toast.success(t('distill.form.savedToast'))\n // Commit the saved values as the new baseline so the form settles to\n // non-dirty. We seed from the server only once (see the effect above),\n // so there's no refetch round-trip to reset it for us; the shallow copy\n // re-triggers the `dirty` memo against the updated baseline.\n initialRef.current = { ...form }\n setForm((f) => ({ ...f }))\n onSaved?.()\n } catch (serr) {\n const { message } = describeError(serr, t)\n toast.error(message)\n }\n }\n\n function onDiscard(): void {\n setForm(initialRef.current)\n }\n\n const busy = updateEnv.isPending || putRoles.isPending\n const noBackends = llmBackends.length === 0\n const noAgents = enabledAgents.length === 0\n\n return (\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h2 className=\"text-sm font-medium\">{t('distill.form.title')}</h2>\n {dirty && <Badge variant=\"info\">{t('distill.form.dirty')}</Badge>}\n <div className=\"ml-auto flex items-center gap-2\">\n {dirty && (\n <Button type=\"button\" variant=\"secondary\" size=\"sm\" onClick={onDiscard} disabled={busy}>\n {t('distill.form.discard')}\n </Button>\n )}\n <Button type=\"button\" size=\"sm\" onClick={() => void onSave()} disabled={!dirty || busy}>\n {busy ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Save className=\"h-4 w-4\" />}\n {t('distill.form.save')}\n </Button>\n </div>\n </div>\n <p className=\"mt-1 text-xs text-text-dim\">{t('distill.form.hint')}</p>\n\n {envQuery.isLoading ? (\n <div className=\"mt-3 h-32 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <div className=\"mt-3 flex flex-col gap-4\">\n {/* ── Source ── */}\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <Field label={t('distill.form.source')} help={t('distill.form.sourceHelp')}>\n <Select value={form.source} onValueChange={(v) => set('source', v as DistillSource)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"auto\">{t('distill.form.sourceAuto')}</SelectItem>\n <SelectItem value=\"agent\">{t('distill.form.sourceAgent')}</SelectItem>\n <SelectItem value=\"llm\">{t('distill.form.sourceLlm')}</SelectItem>\n </SelectContent>\n </Select>\n </Field>\n\n {form.source === 'auto' && (\n <div className=\"flex items-end\">\n <p className=\"text-[11px] text-text-muted\">{t('distill.form.autoNote')}</p>\n </div>\n )}\n\n {form.source === 'agent' && (\n <Field label={t('distill.form.agent')} help={t('distill.form.agentHelp')}>\n {noAgents ? (\n <p className=\"text-[11px] text-warning\">{t('distill.form.noAgents')}</p>\n ) : (\n <Select value={form.agent} onValueChange={(v) => set('agent', v)}>\n <SelectTrigger>\n <SelectValue placeholder={t('distill.form.agentPlaceholder')} />\n </SelectTrigger>\n <SelectContent>\n {enabledAgents.map((name) => (\n <SelectItem key={name} value={name}>{agentDisplayName(name)}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n </Field>\n )}\n\n {form.source === 'llm' && (\n <Field label={t('distill.form.llmBackend')} help={t('distill.form.llmBackendHelp')}>\n {noBackends ? (\n <p className=\"text-[11px] text-warning\">{t('distill.form.noBackends')}</p>\n ) : (\n <Select value={form.llmBackend} onValueChange={(v) => set('llmBackend', v)}>\n <SelectTrigger>\n <SelectValue placeholder={t('distill.form.llmPlaceholder')} />\n </SelectTrigger>\n <SelectContent>\n {llmBackends.map((b) => (\n <SelectItem key={b.name} value={b.name}>\n {b.name} <span className=\"text-text-muted\">· {b.model}</span>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n </Field>\n )}\n </div>\n\n {/* ── Schedule ── */}\n <div>\n <div className=\"text-xs font-medium text-text-dim\">{t('distill.form.scheduleTitle')}</div>\n <div className=\"mt-2 grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <Field label={t('distill.form.enabled')} help={t('distill.form.enabledHelp')}>\n <Select\n value={form.enabled ? 'on' : 'off'}\n onValueChange={(v) => set('enabled', v === 'on')}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"on\">{t('distill.form.enabledOn')}</SelectItem>\n <SelectItem value=\"off\">{t('distill.form.enabledOff')}</SelectItem>\n </SelectContent>\n </Select>\n </Field>\n <NumberField\n label={t('distill.form.intervalMs')}\n help={t('distill.form.intervalMsHelp')}\n value={form.intervalMs}\n placeholder={DEFAULTS.intervalMs}\n min={10000}\n step={10000}\n onChange={(v) => set('intervalMs', v)}\n />\n <NumberField\n label={t('distill.form.floorMin')}\n help={t('distill.form.floorMinHelp')}\n value={form.floorMin}\n placeholder={DEFAULTS.floorMin}\n min={0}\n step={5}\n onChange={(v) => set('floorMin', v)}\n />\n <NumberField\n label={t('distill.form.batchMax')}\n help={t('distill.form.batchMaxHelp')}\n value={form.batchMax}\n placeholder={DEFAULTS.batchMax}\n min={1}\n step={1}\n onChange={(v) => set('batchMax', v)}\n />\n <NumberField\n label={t('distill.form.maxPending')}\n help={t('distill.form.maxPendingHelp')}\n value={form.maxPending}\n placeholder={DEFAULTS.maxPending}\n min={1}\n step={10}\n onChange={(v) => set('maxPending', v)}\n />\n </div>\n </div>\n </div>\n )}\n </div>\n )\n}\n\nfunction Field({\n label,\n help,\n children,\n}: {\n label: string\n help?: string\n children: React.ReactNode\n}): JSX.Element {\n return (\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs text-text-dim\">{label}</Label>\n {children}\n {help && <p className=\"text-[11px] text-text-muted\">{help}</p>}\n </div>\n )\n}\n\nfunction NumberField({\n label,\n help,\n value,\n placeholder,\n min,\n step,\n onChange,\n}: {\n label: string\n help?: string\n value: string\n placeholder: string\n min: number\n step: number\n onChange: (v: string) => void\n}): JSX.Element {\n return (\n <Field label={label} help={help}>\n <Input\n type=\"number\"\n min={min}\n step={step}\n value={value}\n placeholder={placeholder}\n onChange={(e) => onChange(e.target.value)}\n className=\"font-mono text-xs\"\n />\n </Field>\n )\n}\n","/**\n * /memory/distill — \"dream distillation\" control surface.\n *\n * Dream distillation buffers every chat turn into pending_distill and\n * batch-extracts facts in the background when the system is idle (or\n * once a user's oldest buffered turn passes the staleness floor). This\n * tab lets the operator:\n *\n * - configure the extraction SOURCE + SCHEDULE (DistillConfigForm)\n * - watch the live buffer depth + last-run telemetry (status tiles)\n * - force a pass now (\"Run now\" → POST /api/memory/distill)\n *\n * Status polls every 3s (useDistillStatus) so a manual run visibly\n * drains `pendingTotal` to zero without a refresh. This view is global\n * (not per-user) — the buffer spans every user — so it ignores the\n * layout's ?user= filter.\n */\n\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { AlarmClockCheck, Loader2, Play, RefreshCcw } from 'lucide-react'\n\nimport { DistillConfigForm } from './distill-config-form'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { useDistillStatus, useTriggerDistill } from '@/hooks/use-memory'\nimport { describeError } from '@/lib/api/errors'\nimport { cn } from '@/lib/utils'\n\nexport default function MemoryDistillRoute(): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n const statusQuery = useDistillStatus()\n const status = statusQuery.data\n const trigger = useTriggerDistill()\n\n async function onRunNow(): Promise<void> {\n try {\n await trigger.mutateAsync()\n toast.success(t('distill.actions.runStarted'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n const running = !!status?.running\n const pending = status?.pendingTotal ?? 0\n\n return (\n <div className=\"mx-auto flex max-w-5xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('distill.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => statusQuery.refetch()}\n disabled={statusQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {statusQuery.isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('distill.subtitle')}</p>\n </header>\n\n {/* Configuration */}\n <DistillConfigForm onSaved={() => void statusQuery.refetch()} />\n\n {/* Status + actions */}\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"flex flex-wrap items-center gap-2 text-sm\">\n <span className=\"font-medium\">{t('distill.status.title')}</span>\n <Badge variant={status?.enabled ? 'success' : 'secondary'}>\n {status?.enabled ? t('distill.status.enabledTrue') : t('distill.status.enabledFalse')}\n </Badge>\n {running && (\n <Badge variant=\"info\">\n <Loader2 className=\"mr-1 inline h-3 w-3 animate-spin\" />\n {t('distill.status.running')}\n </Badge>\n )}\n <div className=\"ml-auto\">\n <Button\n variant=\"default\"\n size=\"sm\"\n onClick={() => void onRunNow()}\n disabled={trigger.isPending || running || !status?.enabled}\n >\n {trigger.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Play className=\"h-4 w-4\" />}\n {t('distill.actions.runNow')}\n </Button>\n </div>\n </div>\n\n {statusQuery.isLoading ? (\n <div className=\"mt-3 h-20 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <>\n <div className=\"mt-3 grid grid-cols-2 gap-2 sm:grid-cols-3\">\n <StatTile label={t('distill.status.pending')} value={pending} tone={pending > 0 ? 'warning' : 'success'} />\n <StatTile label={t('distill.status.lastProcessed')} value={status?.lastProcessed ?? 0} tone=\"info\" />\n <StatTile label={t('distill.status.lastRun')} value={formatEpoch(status?.lastRunAt)} tone=\"info\" />\n </div>\n {pending === 0 && (\n <p className=\"mt-2 flex items-center gap-1 text-xs text-text-muted\">\n <AlarmClockCheck className=\"h-3 w-3\" />\n {t('distill.status.bufferEmpty')}\n </p>\n )}\n {status?.lastError && (\n <p className=\"mt-2 text-xs text-danger break-all\">\n {t('distill.status.lastError')}: {status.lastError}\n </p>\n )}\n </>\n )}\n </div>\n </div>\n )\n}\n\ninterface StatTileProps {\n label: string\n value: number | string\n tone: 'info' | 'success' | 'warning' | 'danger'\n}\n\nconst TONE_STYLES: Record<StatTileProps['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 StatTile({ label, value, tone }: StatTileProps): JSX.Element {\n return (\n <div className={cn('rounded-md border bg-bg px-2 py-2', TONE_STYLES[tone])}>\n <div className=\"text-[10px] uppercase tracking-wide text-text-dim\">{label}</div>\n <div className=\"text-xl font-semibold tabular-nums\">{value}</div>\n </div>\n )\n}\n\nfunction formatEpoch(ms: number | null | undefined): string {\n if (!ms) return '—'\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":["AlarmClockCheck","createLucideIcon","DEFAULTS","readEnabled","raw","v","readSource","DistillConfigForm","onSaved","t","useTranslation","envQuery","useEnv","env","useMemo","cfgQuery","useConfig","llmQuery","useLlmList","enabledAgents","llmBackends","currentDistillRole","readForm","form","setForm","useState","initialRef","useRef","seededRef","useEffect","next","updateEnv","useUpdateEnv","putRoles","useLlmPutRoles","dirty","initial","k","set","prev","numField","value","min","label","n","validate","buildEnvUpdates","out","diffStr","key","cur","onSave","err","toast","envUpdates","roleChanged","f","serr","message","describeError","onDiscard","busy","noBackends","noAgents","jsxs","jsx","Badge","Button","Loader2","Save","Field","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","name","agentDisplayName","b","NumberField","help","children","Label","placeholder","step","onChange","Input","e","MemoryDistillRoute","statusQuery","useDistillStatus","status","trigger","useTriggerDistill","onRunNow","running","pending","RefreshCcw","Play","Fragment","StatTile","formatEpoch","TONE_STYLES","tone","cn","ms","d"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{o}from"./index-
|
|
1
|
+
import{h as o}from"./index-DCfdN5R7.js";/**
|
|
2
2
|
* @license lucide-react v0.469.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/const a=o("Download",[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"7 10 12 15 17 10",key:"2ggqvy"}],["line",{x1:"12",x2:"12",y1:"15",y2:"3",key:"1vk2je"}]]);export{a as D};
|
|
7
|
-
//# sourceMappingURL=download-
|
|
7
|
+
//# sourceMappingURL=download-CVZnHcwj.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download-
|
|
1
|
+
{"version":3,"file":"download-CVZnHcwj.js","sources":["../../node_modules/lucide-react/dist/esm/icons/download.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 Download = createLucideIcon(\"Download\", [\n [\"path\", { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\", key: \"ih7n3h\" }],\n [\"polyline\", { points: \"7 10 12 15 17 10\", key: \"2ggqvy\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"15\", y2: \"3\", key: \"1vk2je\" }]\n]);\n\nexport { Download as default };\n//# sourceMappingURL=download.js.map\n"],"names":["Download","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAWC,EAAiB,WAAY,CAC5C,CAAC,OAAQ,CAAE,EAAG,4CAA6C,IAAK,QAAQ,CAAE,EAC1E,CAAC,WAAY,CAAE,OAAQ,mBAAoB,IAAK,QAAQ,CAAE,EAC1D,CAAC,OAAQ,CAAE,GAAI,KAAM,GAAI,KAAM,GAAI,KAAM,GAAI,IAAK,IAAK,QAAQ,CAAE,CACnE,CAAC","x_google_ignoreList":[0]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{h as Nn,V as me,W as ye,Y as le,j as a,Z as P,_ as w,$ as N,a0 as Ee,a1 as Se,a2 as ve,a3 as Tn,a4 as An,a5 as De,a6 as te,a7 as jn,a8 as On,a9 as Fn,aa as kn,ab as Ln,ac as Gn,ad as Kn,ae as $n,af as Un,ag as Bn,f as T,A as Vn}from"./index-DCfdN5R7.js";import{r}from"./react-DlP5eolq.js";import{C as Yn}from"./chevron-right-CFRb-SM_.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 zn=Nn("Circle",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]]);var de="rovingFocusGroup.onEntryFocus",Xn={bubbles:!1,cancelable:!0},W="RovingFocusGroup",[fe,Pe,Hn]=ye(W),[Wn,Ne]=me(W,[Hn]),[Zn,qn]=Wn(W),Te=r.forwardRef((e,o)=>a.jsx(fe.Provider,{scope:e.__scopeRovingFocusGroup,children:a.jsx(fe.Slot,{scope:e.__scopeRovingFocusGroup,children:a.jsx(Jn,{...e,ref:o})})}));Te.displayName=W;var Jn=r.forwardRef((e,o)=>{const{__scopeRovingFocusGroup:n,orientation:t,loop:s=!1,dir:c,currentTabStopId:i,defaultCurrentTabStopId:m,onCurrentTabStopIdChange:d,onEntryFocus:v,preventScrollOnEntryFocus:p=!1,...u}=e,l=r.useRef(null),g=N(o,l),h=Ee(c),[R,M]=Se({prop:i,defaultProp:m??null,onChange:d,caller:W}),[x,D]=r.useState(!1),b=ve(v),E=Pe(n),$=r.useRef(!1),[J,A]=r.useState(0);return r.useEffect(()=>{const C=l.current;if(C)return C.addEventListener(de,b),()=>C.removeEventListener(de,b)},[b]),a.jsx(Zn,{scope:n,orientation:t,dir:h,loop:s,currentTabStopId:R,onItemFocus:r.useCallback(C=>M(C),[M]),onItemShiftTab:r.useCallback(()=>D(!0),[]),onFocusableItemAdd:r.useCallback(()=>A(C=>C+1),[]),onFocusableItemRemove:r.useCallback(()=>A(C=>C-1),[]),children:a.jsx(P.div,{tabIndex:x||J===0?-1:0,"data-orientation":t,...u,ref:g,style:{outline:"none",...e.style},onMouseDown:w(e.onMouseDown,()=>{$.current=!0}),onFocus:w(e.onFocus,C=>{const L=!$.current;if(C.target===C.currentTarget&&L&&!x){const j=new CustomEvent(de,Xn);if(C.currentTarget.dispatchEvent(j),!j.defaultPrevented){const U=E().filter(S=>S.focusable),B=U.find(S=>S.active),Q=U.find(S=>S.id===R),ce=[B,Q,...U].filter(Boolean).map(S=>S.ref.current);Oe(ce,p)}}$.current=!1}),onBlur:w(e.onBlur,()=>D(!1))})})}),Ae="RovingFocusGroupItem",je=r.forwardRef((e,o)=>{const{__scopeRovingFocusGroup:n,focusable:t=!0,active:s=!1,tabStopId:c,children:i,...m}=e,d=le(),v=c||d,p=qn(Ae,n),u=p.currentTabStopId===v,l=Pe(n),{onFocusableItemAdd:g,onFocusableItemRemove:h,currentTabStopId:R}=p;return r.useEffect(()=>{if(t)return g(),()=>h()},[t,g,h]),a.jsx(fe.ItemSlot,{scope:n,id:v,focusable:t,active:s,children:a.jsx(P.span,{tabIndex:u?0:-1,"data-orientation":p.orientation,...m,ref:o,onMouseDown:w(e.onMouseDown,M=>{t?p.onItemFocus(v):M.preventDefault()}),onFocus:w(e.onFocus,()=>p.onItemFocus(v)),onKeyDown:w(e.onKeyDown,M=>{if(M.key==="Tab"&&M.shiftKey){p.onItemShiftTab();return}if(M.target!==M.currentTarget)return;const x=no(M,p.orientation,p.dir);if(x!==void 0){if(M.metaKey||M.ctrlKey||M.altKey||M.shiftKey)return;M.preventDefault();let b=l().filter(E=>E.focusable).map(E=>E.ref.current);if(x==="last")b.reverse();else if(x==="prev"||x==="next"){x==="prev"&&b.reverse();const E=b.indexOf(M.currentTarget);b=p.loop?oo(b,E+1):b.slice(E+1)}setTimeout(()=>Oe(b))}}),children:typeof i=="function"?i({isCurrentTabStop:u,hasTabStop:R!=null}):i})})});je.displayName=Ae;var Qn={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function eo(e,o){return o!=="rtl"?e:e==="ArrowLeft"?"ArrowRight":e==="ArrowRight"?"ArrowLeft":e}function no(e,o,n){const t=eo(e.key,n);if(!(o==="vertical"&&["ArrowLeft","ArrowRight"].includes(t))&&!(o==="horizontal"&&["ArrowUp","ArrowDown"].includes(t)))return Qn[t]}function Oe(e,o=!1){const n=document.activeElement;for(const t of e)if(t===n||(t.focus({preventScroll:o}),document.activeElement!==n))return}function oo(e,o){return e.map((n,t)=>e[(o+t)%e.length])}var to=Te,ro=je,pe=["Enter"," "],ao=["ArrowDown","PageUp","Home"],Fe=["ArrowUp","PageDown","End"],so=[...ao,...Fe],co={ltr:[...pe,"ArrowRight"],rtl:[...pe,"ArrowLeft"]},uo={ltr:["ArrowLeft"],rtl:["ArrowRight"]},Z="Menu",[X,io,lo]=ye(Z),[F,ke]=me(Z,[lo,De,Ne]),re=De(),Le=Ne(),[fo,k]=F(Z),[po,q]=F(Z),Ge=e=>{const{__scopeMenu:o,open:n=!1,children:t,dir:s,onOpenChange:c,modal:i=!0}=e,m=re(o),[d,v]=r.useState(null),p=r.useRef(!1),u=ve(c),l=Ee(s);return r.useEffect(()=>{const g=()=>{p.current=!0,document.addEventListener("pointerdown",h,{capture:!0,once:!0}),document.addEventListener("pointermove",h,{capture:!0,once:!0})},h=()=>p.current=!1;return document.addEventListener("keydown",g,{capture:!0}),()=>{document.removeEventListener("keydown",g,{capture:!0}),document.removeEventListener("pointerdown",h,{capture:!0}),document.removeEventListener("pointermove",h,{capture:!0})}},[]),r.useEffect(()=>{if(!n)return;const g=()=>u(!1);return window.addEventListener("blur",g),()=>window.removeEventListener("blur",g)},[n,u]),a.jsx(Tn,{...m,children:a.jsx(fo,{scope:o,open:n,onOpenChange:u,content:d,onContentChange:v,children:a.jsx(po,{scope:o,onClose:r.useCallback(()=>u(!1),[u]),isUsingKeyboardRef:p,dir:l,modal:i,children:t})})})};Ge.displayName=Z;var mo="MenuAnchor",we=r.forwardRef((e,o)=>{const{__scopeMenu:n,...t}=e,s=re(n);return a.jsx(An,{...s,...t,ref:o})});we.displayName=mo;var ge="MenuPortal",[vo,Ke]=F(ge,{forceMount:void 0}),$e=e=>{const{__scopeMenu:o,forceMount:n,children:t,container:s}=e,c=k(ge,o);return a.jsx(vo,{scope:o,forceMount:n,children:a.jsx(te,{present:n||c.open,children:a.jsx(jn,{asChild:!0,container:s,children:t})})})};$e.displayName=ge;var y="MenuContent",[wo,he]=F(y),Ue=r.forwardRef((e,o)=>{const n=Ke(y,e.__scopeMenu),{forceMount:t=n.forceMount,...s}=e,c=k(y,e.__scopeMenu),i=q(y,e.__scopeMenu);return a.jsx(X.Provider,{scope:e.__scopeMenu,children:a.jsx(te,{present:t||c.open,children:a.jsx(X.Slot,{scope:e.__scopeMenu,children:i.modal?a.jsx(go,{...s,ref:o}):a.jsx(ho,{...s,ref:o})})})})}),go=r.forwardRef((e,o)=>{const n=k(y,e.__scopeMenu),t=r.useRef(null),s=N(o,t);return r.useEffect(()=>{const c=t.current;if(c)return On(c)},[]),a.jsx(Me,{...e,ref:s,trapFocus:n.open,disableOutsidePointerEvents:n.open,disableOutsideScroll:!0,onFocusOutside:w(e.onFocusOutside,c=>c.preventDefault(),{checkForDefaultPrevented:!1}),onDismiss:()=>n.onOpenChange(!1)})}),ho=r.forwardRef((e,o)=>{const n=k(y,e.__scopeMenu);return a.jsx(Me,{...e,ref:o,trapFocus:!1,disableOutsidePointerEvents:!1,disableOutsideScroll:!1,onDismiss:()=>n.onOpenChange(!1)})}),Mo=Un("MenuContent.ScrollLock"),Me=r.forwardRef((e,o)=>{const{__scopeMenu:n,loop:t=!1,trapFocus:s,onOpenAutoFocus:c,onCloseAutoFocus:i,disableOutsidePointerEvents:m,onEntryFocus:d,onEscapeKeyDown:v,onPointerDownOutside:p,onFocusOutside:u,onInteractOutside:l,onDismiss:g,disableOutsideScroll:h,...R}=e,M=k(y,n),x=q(y,n),D=re(n),b=Le(n),E=io(n),[$,J]=r.useState(null),A=r.useRef(null),C=N(o,A,M.onContentChange),L=r.useRef(0),j=r.useRef(""),U=r.useRef(0),B=r.useRef(null),Q=r.useRef("right"),ee=r.useRef(0),ce=h?Ln:r.Fragment,S=h?{as:Mo,allowPinchZoom:!0}:void 0,Pn=f=>{const K=j.current+f,O=E().filter(I=>!I.disabled),V=document.activeElement,ue=O.find(I=>I.ref.current===V)?.textValue,ie=O.map(I=>I.textValue),Re=No(ie,K,ue),Y=O.find(I=>I.textValue===Re)?.ref.current;(function I(be){j.current=be,window.clearTimeout(L.current),be!==""&&(L.current=window.setTimeout(()=>I(""),1e3))})(K),Y&&setTimeout(()=>Y.focus())};r.useEffect(()=>()=>window.clearTimeout(L.current),[]),kn();const G=r.useCallback(f=>Q.current===B.current?.side&&Ao(f,B.current?.area),[]);return a.jsx(wo,{scope:n,searchRef:j,onItemEnter:r.useCallback(f=>{G(f)&&f.preventDefault()},[G]),onItemLeave:r.useCallback(f=>{G(f)||(A.current?.focus(),J(null))},[G]),onTriggerLeave:r.useCallback(f=>{G(f)&&f.preventDefault()},[G]),pointerGraceTimerRef:U,onPointerGraceIntentChange:r.useCallback(f=>{B.current=f},[]),children:a.jsx(ce,{...S,children:a.jsx(Gn,{asChild:!0,trapped:s,onMountAutoFocus:w(c,f=>{f.preventDefault(),A.current?.focus({preventScroll:!0})}),onUnmountAutoFocus:i,children:a.jsx(Kn,{asChild:!0,disableOutsidePointerEvents:m,onEscapeKeyDown:v,onPointerDownOutside:p,onFocusOutside:u,onInteractOutside:l,onDismiss:g,children:a.jsx(to,{asChild:!0,...b,dir:x.dir,orientation:"vertical",loop:t,currentTabStopId:$,onCurrentTabStopIdChange:J,onEntryFocus:w(d,f=>{x.isUsingKeyboardRef.current||f.preventDefault()}),preventScrollOnEntryFocus:!0,children:a.jsx($n,{role:"menu","aria-orientation":"vertical","data-state":rn(M.open),"data-radix-menu-content":"",dir:x.dir,...D,...R,ref:C,style:{outline:"none",...R.style},onKeyDown:w(R.onKeyDown,f=>{const O=f.target.closest("[data-radix-menu-content]")===f.currentTarget,V=f.ctrlKey||f.altKey||f.metaKey,ue=f.key.length===1;O&&(f.key==="Tab"&&f.preventDefault(),!V&&ue&&Pn(f.key));const ie=A.current;if(f.target!==ie||!so.includes(f.key))return;f.preventDefault();const Y=E().filter(I=>!I.disabled).map(I=>I.ref.current);Fe.includes(f.key)&&Y.reverse(),Do(Y)}),onBlur:w(e.onBlur,f=>{f.currentTarget.contains(f.target)||(window.clearTimeout(L.current),j.current="")}),onPointerMove:w(e.onPointerMove,H(f=>{const K=f.target,O=ee.current!==f.clientX;if(f.currentTarget.contains(K)&&O){const V=f.clientX>ee.current?"right":"left";Q.current=V,ee.current=f.clientX}}))})})})})})})});Ue.displayName=y;var xo="MenuGroup",xe=r.forwardRef((e,o)=>{const{__scopeMenu:n,...t}=e;return a.jsx(P.div,{role:"group",...t,ref:o})});xe.displayName=xo;var Co="MenuLabel",Be=r.forwardRef((e,o)=>{const{__scopeMenu:n,...t}=e;return a.jsx(P.div,{...t,ref:o})});Be.displayName=Co;var ne="MenuItem",Ie="menu.itemSelect",ae=r.forwardRef((e,o)=>{const{disabled:n=!1,onSelect:t,...s}=e,c=r.useRef(null),i=q(ne,e.__scopeMenu),m=he(ne,e.__scopeMenu),d=N(o,c),v=r.useRef(!1),p=()=>{const u=c.current;if(!n&&u){const l=new CustomEvent(Ie,{bubbles:!0,cancelable:!0});u.addEventListener(Ie,g=>t?.(g),{once:!0}),Fn(u,l),l.defaultPrevented?v.current=!1:i.onClose()}};return a.jsx(Ve,{...s,ref:d,disabled:n,onClick:w(e.onClick,p),onPointerDown:u=>{e.onPointerDown?.(u),v.current=!0},onPointerUp:w(e.onPointerUp,u=>{v.current||u.currentTarget?.click()}),onKeyDown:w(e.onKeyDown,u=>{const l=m.searchRef.current!=="";n||l&&u.key===" "||pe.includes(u.key)&&(u.currentTarget.click(),u.preventDefault())})})});ae.displayName=ne;var Ve=r.forwardRef((e,o)=>{const{__scopeMenu:n,disabled:t=!1,textValue:s,...c}=e,i=he(ne,n),m=Le(n),d=r.useRef(null),v=N(o,d),[p,u]=r.useState(!1),[l,g]=r.useState("");return r.useEffect(()=>{const h=d.current;h&&g((h.textContent??"").trim())},[c.children]),a.jsx(X.ItemSlot,{scope:n,disabled:t,textValue:s??l,children:a.jsx(ro,{asChild:!0,...m,focusable:!t,children:a.jsx(P.div,{role:"menuitem","data-highlighted":p?"":void 0,"aria-disabled":t||void 0,"data-disabled":t?"":void 0,...c,ref:v,onPointerMove:w(e.onPointerMove,H(h=>{t?i.onItemLeave(h):(i.onItemEnter(h),h.defaultPrevented||h.currentTarget.focus({preventScroll:!0}))})),onPointerLeave:w(e.onPointerLeave,H(h=>i.onItemLeave(h))),onFocus:w(e.onFocus,()=>u(!0)),onBlur:w(e.onBlur,()=>u(!1))})})})}),_o="MenuCheckboxItem",Ye=r.forwardRef((e,o)=>{const{checked:n=!1,onCheckedChange:t,...s}=e;return a.jsx(Ze,{scope:e.__scopeMenu,checked:n,children:a.jsx(ae,{role:"menuitemcheckbox","aria-checked":oe(n)?"mixed":n,...s,ref:o,"data-state":_e(n),onSelect:w(s.onSelect,()=>t?.(oe(n)?!0:!n),{checkForDefaultPrevented:!1})})})});Ye.displayName=_o;var ze="MenuRadioGroup",[Ro,bo]=F(ze,{value:void 0,onValueChange:()=>{}}),Xe=r.forwardRef((e,o)=>{const{value:n,onValueChange:t,...s}=e,c=ve(t);return a.jsx(Ro,{scope:e.__scopeMenu,value:n,onValueChange:c,children:a.jsx(xe,{...s,ref:o})})});Xe.displayName=ze;var He="MenuRadioItem",We=r.forwardRef((e,o)=>{const{value:n,...t}=e,s=bo(He,e.__scopeMenu),c=n===s.value;return a.jsx(Ze,{scope:e.__scopeMenu,checked:c,children:a.jsx(ae,{role:"menuitemradio","aria-checked":c,...t,ref:o,"data-state":_e(c),onSelect:w(t.onSelect,()=>s.onValueChange?.(n),{checkForDefaultPrevented:!1})})})});We.displayName=He;var Ce="MenuItemIndicator",[Ze,Io]=F(Ce,{checked:!1}),qe=r.forwardRef((e,o)=>{const{__scopeMenu:n,forceMount:t,...s}=e,c=Io(Ce,n);return a.jsx(te,{present:t||oe(c.checked)||c.checked===!0,children:a.jsx(P.span,{...s,ref:o,"data-state":_e(c.checked)})})});qe.displayName=Ce;var yo="MenuSeparator",Je=r.forwardRef((e,o)=>{const{__scopeMenu:n,...t}=e;return a.jsx(P.div,{role:"separator","aria-orientation":"horizontal",...t,ref:o})});Je.displayName=yo;var Eo="MenuArrow",Qe=r.forwardRef((e,o)=>{const{__scopeMenu:n,...t}=e,s=re(n);return a.jsx(Bn,{...s,...t,ref:o})});Qe.displayName=Eo;var So="MenuSub",[yt,en]=F(So),z="MenuSubTrigger",nn=r.forwardRef((e,o)=>{const n=k(z,e.__scopeMenu),t=q(z,e.__scopeMenu),s=en(z,e.__scopeMenu),c=he(z,e.__scopeMenu),i=r.useRef(null),{pointerGraceTimerRef:m,onPointerGraceIntentChange:d}=c,v={__scopeMenu:e.__scopeMenu},p=r.useCallback(()=>{i.current&&window.clearTimeout(i.current),i.current=null},[]);r.useEffect(()=>p,[p]),r.useEffect(()=>{const l=m.current;return()=>{window.clearTimeout(l),d(null)}},[m,d]);const u=N(o,s.onTriggerChange);return a.jsx(we,{asChild:!0,...v,children:a.jsx(Ve,{id:s.triggerId,"aria-haspopup":"menu","aria-expanded":n.open,"aria-controls":n.open?s.contentId:void 0,"data-state":rn(n.open),...e,ref:u,onClick:l=>{e.onClick?.(l),!(e.disabled||l.defaultPrevented)&&(l.currentTarget.focus(),n.open||n.onOpenChange(!0))},onPointerMove:w(e.onPointerMove,H(l=>{c.onItemEnter(l),!l.defaultPrevented&&!e.disabled&&!n.open&&!i.current&&(c.onPointerGraceIntentChange(null),i.current=window.setTimeout(()=>{n.onOpenChange(!0),p()},100))})),onPointerLeave:w(e.onPointerLeave,H(l=>{p();const g=n.content?.getBoundingClientRect();if(g){const h=n.content?.dataset.side,R=h==="right",M=R?-5:5,x=g[R?"left":"right"],D=g[R?"right":"left"];c.onPointerGraceIntentChange({area:[{x:l.clientX+M,y:l.clientY},{x,y:g.top},{x:D,y:g.top},{x:D,y:g.bottom},{x,y:g.bottom}],side:h}),window.clearTimeout(m.current),m.current=window.setTimeout(()=>c.onPointerGraceIntentChange(null),300)}else{if(c.onTriggerLeave(l),l.defaultPrevented)return;c.onPointerGraceIntentChange(null)}})),onKeyDown:w(e.onKeyDown,l=>{const g=c.searchRef.current!=="";e.disabled||g&&l.key===" "||co[t.dir].includes(l.key)&&(n.onOpenChange(!0),n.content?.focus(),l.preventDefault())})})})});nn.displayName=z;var on="MenuSubContent",tn=r.forwardRef((e,o)=>{const n=Ke(y,e.__scopeMenu),{forceMount:t=n.forceMount,align:s="start",...c}=e,i=k(y,e.__scopeMenu),m=q(y,e.__scopeMenu),d=en(on,e.__scopeMenu),v=r.useRef(null),p=N(o,v);return a.jsx(X.Provider,{scope:e.__scopeMenu,children:a.jsx(te,{present:t||i.open,children:a.jsx(X.Slot,{scope:e.__scopeMenu,children:a.jsx(Me,{id:d.contentId,"aria-labelledby":d.triggerId,...c,ref:p,align:s,side:m.dir==="rtl"?"left":"right",disableOutsidePointerEvents:!1,disableOutsideScroll:!1,trapFocus:!1,onOpenAutoFocus:u=>{m.isUsingKeyboardRef.current&&v.current?.focus(),u.preventDefault()},onCloseAutoFocus:u=>u.preventDefault(),onFocusOutside:w(e.onFocusOutside,u=>{u.target!==d.trigger&&i.onOpenChange(!1)}),onEscapeKeyDown:w(e.onEscapeKeyDown,u=>{m.onClose(),u.preventDefault()}),onKeyDown:w(e.onKeyDown,u=>{const l=u.currentTarget.contains(u.target),g=uo[m.dir].includes(u.key);l&&g&&(i.onOpenChange(!1),d.trigger?.focus(),u.preventDefault())})})})})})});tn.displayName=on;function rn(e){return e?"open":"closed"}function oe(e){return e==="indeterminate"}function _e(e){return oe(e)?"indeterminate":e?"checked":"unchecked"}function Do(e){const o=document.activeElement;for(const n of e)if(n===o||(n.focus(),document.activeElement!==o))return}function Po(e,o){return e.map((n,t)=>e[(o+t)%e.length])}function No(e,o,n){const s=o.length>1&&Array.from(o).every(v=>v===o[0])?o[0]:o,c=n?e.indexOf(n):-1;let i=Po(e,Math.max(c,0));s.length===1&&(i=i.filter(v=>v!==n));const d=i.find(v=>v.toLowerCase().startsWith(s.toLowerCase()));return d!==n?d:void 0}function To(e,o){const{x:n,y:t}=e;let s=!1;for(let c=0,i=o.length-1;c<o.length;i=c++){const m=o[c],d=o[i],v=m.x,p=m.y,u=d.x,l=d.y;p>t!=l>t&&n<(u-v)*(t-p)/(l-p)+v&&(s=!s)}return s}function Ao(e,o){if(!o)return!1;const n={x:e.clientX,y:e.clientY};return To(n,o)}function H(e){return o=>o.pointerType==="mouse"?e(o):void 0}var jo=Ge,Oo=we,Fo=$e,ko=Ue,Lo=xe,Go=Be,Ko=ae,$o=Ye,Uo=Xe,Bo=We,Vo=qe,Yo=Je,zo=Qe,Xo=nn,Ho=tn,se="DropdownMenu",[Wo]=me(se,[ke]),_=ke(),[Zo,an]=Wo(se),sn=e=>{const{__scopeDropdownMenu:o,children:n,dir:t,open:s,defaultOpen:c,onOpenChange:i,modal:m=!0}=e,d=_(o),v=r.useRef(null),[p,u]=Se({prop:s,defaultProp:c??!1,onChange:i,caller:se});return a.jsx(Zo,{scope:o,triggerId:le(),triggerRef:v,contentId:le(),open:p,onOpenChange:u,onOpenToggle:r.useCallback(()=>u(l=>!l),[u]),modal:m,children:a.jsx(jo,{...d,open:p,onOpenChange:u,dir:t,modal:m,children:n})})};sn.displayName=se;var cn="DropdownMenuTrigger",un=r.forwardRef((e,o)=>{const{__scopeDropdownMenu:n,disabled:t=!1,...s}=e,c=an(cn,n),i=_(n),m=N(o,c.triggerRef);return a.jsx(Oo,{asChild:!0,...i,children:a.jsx(P.button,{type:"button",id:c.triggerId,"aria-haspopup":"menu","aria-expanded":c.open,"aria-controls":c.open?c.contentId:void 0,"data-state":c.open?"open":"closed","data-disabled":t?"":void 0,disabled:t,...s,ref:m,onPointerDown:w(e.onPointerDown,d=>{!t&&d.button===0&&d.ctrlKey===!1&&(c.onOpenToggle(),c.open||d.preventDefault())}),onKeyDown:w(e.onKeyDown,d=>{t||(["Enter"," "].includes(d.key)&&c.onOpenToggle(),d.key==="ArrowDown"&&c.onOpenChange(!0),["Enter"," ","ArrowDown"].includes(d.key)&&d.preventDefault())})})})});un.displayName=cn;var qo="DropdownMenuPortal",dn=e=>{const{__scopeDropdownMenu:o,...n}=e,t=_(o);return a.jsx(Fo,{...t,...n})};dn.displayName=qo;var ln="DropdownMenuContent",fn=r.forwardRef((e,o)=>{const{__scopeDropdownMenu:n,...t}=e,s=an(ln,n),c=_(n),i=r.useRef(!1);return a.jsx(ko,{id:s.contentId,"aria-labelledby":s.triggerId,...c,...t,ref:o,onCloseAutoFocus:w(e.onCloseAutoFocus,m=>{i.current||s.triggerRef.current?.focus(),i.current=!1,m.preventDefault()}),onInteractOutside:w(e.onInteractOutside,m=>{const d=m.detail.originalEvent,v=d.button===0&&d.ctrlKey===!0,p=d.button===2||v;(!s.modal||p)&&(i.current=!0)}),style:{...e.style,"--radix-dropdown-menu-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-dropdown-menu-content-available-width":"var(--radix-popper-available-width)","--radix-dropdown-menu-content-available-height":"var(--radix-popper-available-height)","--radix-dropdown-menu-trigger-width":"var(--radix-popper-anchor-width)","--radix-dropdown-menu-trigger-height":"var(--radix-popper-anchor-height)"}})});fn.displayName=ln;var Jo="DropdownMenuGroup",Qo=r.forwardRef((e,o)=>{const{__scopeDropdownMenu:n,...t}=e,s=_(n);return a.jsx(Lo,{...s,...t,ref:o})});Qo.displayName=Jo;var et="DropdownMenuLabel",pn=r.forwardRef((e,o)=>{const{__scopeDropdownMenu:n,...t}=e,s=_(n);return a.jsx(Go,{...s,...t,ref:o})});pn.displayName=et;var nt="DropdownMenuItem",mn=r.forwardRef((e,o)=>{const{__scopeDropdownMenu:n,...t}=e,s=_(n);return a.jsx(Ko,{...s,...t,ref:o})});mn.displayName=nt;var ot="DropdownMenuCheckboxItem",vn=r.forwardRef((e,o)=>{const{__scopeDropdownMenu:n,...t}=e,s=_(n);return a.jsx($o,{...s,...t,ref:o})});vn.displayName=ot;var tt="DropdownMenuRadioGroup",rt=r.forwardRef((e,o)=>{const{__scopeDropdownMenu:n,...t}=e,s=_(n);return a.jsx(Uo,{...s,...t,ref:o})});rt.displayName=tt;var at="DropdownMenuRadioItem",wn=r.forwardRef((e,o)=>{const{__scopeDropdownMenu:n,...t}=e,s=_(n);return a.jsx(Bo,{...s,...t,ref:o})});wn.displayName=at;var st="DropdownMenuItemIndicator",gn=r.forwardRef((e,o)=>{const{__scopeDropdownMenu:n,...t}=e,s=_(n);return a.jsx(Vo,{...s,...t,ref:o})});gn.displayName=st;var ct="DropdownMenuSeparator",hn=r.forwardRef((e,o)=>{const{__scopeDropdownMenu:n,...t}=e,s=_(n);return a.jsx(Yo,{...s,...t,ref:o})});hn.displayName=ct;var ut="DropdownMenuArrow",it=r.forwardRef((e,o)=>{const{__scopeDropdownMenu:n,...t}=e,s=_(n);return a.jsx(zo,{...s,...t,ref:o})});it.displayName=ut;var dt="DropdownMenuSubTrigger",Mn=r.forwardRef((e,o)=>{const{__scopeDropdownMenu:n,...t}=e,s=_(n);return a.jsx(Xo,{...s,...t,ref:o})});Mn.displayName=dt;var lt="DropdownMenuSubContent",xn=r.forwardRef((e,o)=>{const{__scopeDropdownMenu:n,...t}=e,s=_(n);return a.jsx(Ho,{...s,...t,ref:o,style:{...e.style,"--radix-dropdown-menu-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-dropdown-menu-content-available-width":"var(--radix-popper-available-width)","--radix-dropdown-menu-content-available-height":"var(--radix-popper-available-height)","--radix-dropdown-menu-trigger-width":"var(--radix-popper-anchor-width)","--radix-dropdown-menu-trigger-height":"var(--radix-popper-anchor-height)"}})});xn.displayName=lt;var ft=sn,pt=un,mt=dn,Cn=fn,_n=pn,Rn=mn,bn=vn,In=wn,yn=gn,En=hn,Sn=Mn,Dn=xn;const Et=ft,St=pt,vt=r.forwardRef(({className:e,inset:o,children:n,...t},s)=>a.jsxs(Sn,{ref:s,className:T("flex cursor-default select-none items-center gap-2 rounded px-2 py-1.5 text-sm outline-none","focus:bg-surface-hover data-[state=open]:bg-surface-hover",o&&"pl-8",e),...t,children:[n,a.jsx(Yn,{className:"ml-auto h-4 w-4"})]}));vt.displayName=Sn.displayName;const wt=r.forwardRef(({className:e,...o},n)=>a.jsx(Dn,{ref:n,className:T("z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-surface p-1 shadow-md","data-[state=open]:animate-in data-[state=closed]:animate-out","data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0","data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",e),...o}));wt.displayName=Dn.displayName;const gt=r.forwardRef(({className:e,sideOffset:o=4,...n},t)=>a.jsx(mt,{children:a.jsx(Cn,{ref:t,sideOffset:o,className:T("z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-surface p-1 shadow-md","data-[state=open]:animate-in data-[state=closed]:animate-out","data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0","data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",e),...n})}));gt.displayName=Cn.displayName;const ht=r.forwardRef(({className:e,inset:o,...n},t)=>a.jsx(Rn,{ref:t,className:T("relative flex cursor-default select-none items-center gap-2 rounded px-2 py-1.5 text-sm outline-none","focus:bg-surface-hover focus:text-text","data-[disabled]:pointer-events-none data-[disabled]:opacity-50",o&&"pl-8",e),...n}));ht.displayName=Rn.displayName;const Mt=r.forwardRef(({className:e,children:o,checked:n,...t},s)=>a.jsxs(bn,{ref:s,className:T("relative flex cursor-default select-none items-center rounded py-1.5 pl-8 pr-2 text-sm outline-none","focus:bg-surface-hover","data-[disabled]:pointer-events-none data-[disabled]:opacity-50",e),checked:n,...t,children:[a.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:a.jsx(yn,{children:a.jsx(Vn,{className:"h-4 w-4"})})}),o]}));Mt.displayName=bn.displayName;const xt=r.forwardRef(({className:e,children:o,...n},t)=>a.jsxs(In,{ref:t,className:T("relative flex cursor-default select-none items-center rounded py-1.5 pl-8 pr-2 text-sm outline-none","focus:bg-surface-hover","data-[disabled]:pointer-events-none data-[disabled]:opacity-50",e),...n,children:[a.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:a.jsx(yn,{children:a.jsx(zn,{className:"h-2 w-2 fill-current"})})}),o]}));xt.displayName=In.displayName;const Ct=r.forwardRef(({className:e,inset:o,...n},t)=>a.jsx(_n,{ref:t,className:T("px-2 py-1.5 text-xs font-semibold uppercase tracking-wide text-text-muted",o&&"pl-8",e),...n}));Ct.displayName=_n.displayName;const _t=r.forwardRef(({className:e,...o},n)=>a.jsx(En,{ref:n,className:T("-mx-1 my-1 h-px bg-border",e),...o}));_t.displayName=En.displayName;export{Et as D,St as a,gt as b,ht as c,Ct as d,_t as e,Mt as f};
|
|
7
|
+
//# sourceMappingURL=dropdown-menu-BNH5SrVb.js.map
|