agim-cli 1.2.158 → 1.3.0
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 +39 -0
- package/README.md +9 -8
- package/README.zh-CN.md +9 -8
- package/dist/cli-ui/cmd-handlers.d.ts.map +1 -1
- package/dist/cli-ui/cmd-handlers.js +1 -0
- package/dist/cli-ui/cmd-handlers.js.map +1 -1
- package/dist/cli-ui/entry-menu.d.ts +0 -2
- package/dist/cli-ui/entry-menu.d.ts.map +1 -1
- package/dist/cli-ui/entry-menu.js +0 -1
- package/dist/cli-ui/entry-menu.js.map +1 -1
- package/dist/cli-ui/i18n.d.ts +3 -8
- package/dist/cli-ui/i18n.d.ts.map +1 -1
- package/dist/cli-ui/i18n.js +6 -16
- package/dist/cli-ui/i18n.js.map +1 -1
- package/dist/cli.js +39 -70
- package/dist/cli.js.map +1 -1
- package/dist/core/acp-server.d.ts.map +1 -1
- package/dist/core/acp-server.js +23 -44
- package/dist/core/acp-server.js.map +1 -1
- package/dist/core/admin-allowlist.d.ts +26 -15
- package/dist/core/admin-allowlist.d.ts.map +1 -1
- package/dist/core/admin-allowlist.js +213 -179
- package/dist/core/admin-allowlist.js.map +1 -1
- package/dist/core/approval-router.d.ts.map +1 -1
- package/dist/core/approval-router.js +23 -0
- package/dist/core/approval-router.js.map +1 -1
- package/dist/core/ask-user-rpc.d.ts.map +1 -1
- package/dist/core/ask-user-rpc.js +2 -3
- package/dist/core/ask-user-rpc.js.map +1 -1
- package/dist/core/commands/builtin.js +2 -2
- package/dist/core/commands/builtin.js.map +1 -1
- package/dist/core/commands/outbox.d.ts +1 -1
- package/dist/core/commands/outbox.d.ts.map +1 -1
- package/dist/core/commands/outbox.js +5 -1
- package/dist/core/commands/outbox.js.map +1 -1
- package/dist/core/commands/service.js +2 -2
- package/dist/core/commands/service.js.map +1 -1
- package/dist/core/commands/setup.d.ts.map +1 -1
- package/dist/core/commands/setup.js +11 -60
- package/dist/core/commands/setup.js.map +1 -1
- package/dist/core/llm/index.d.ts +1 -1
- package/dist/core/llm/index.d.ts.map +1 -1
- package/dist/core/llm/index.js +1 -1
- package/dist/core/llm/index.js.map +1 -1
- package/dist/core/llm/model-catalog.d.ts +18 -0
- package/dist/core/llm/model-catalog.d.ts.map +1 -0
- package/dist/core/llm/model-catalog.js +67 -0
- package/dist/core/llm/model-catalog.js.map +1 -0
- package/dist/core/llm/provider-base.d.ts +4 -0
- package/dist/core/llm/provider-base.d.ts.map +1 -1
- package/dist/core/llm/provider-base.js +18 -3
- package/dist/core/llm/provider-base.js.map +1 -1
- package/dist/core/llm/registry.d.ts +6 -0
- package/dist/core/llm/registry.d.ts.map +1 -1
- package/dist/core/llm/registry.js +12 -0
- package/dist/core/llm/registry.js.map +1 -1
- package/dist/core/llm/secrets.js +2 -2
- package/dist/core/llm/secrets.js.map +1 -1
- package/dist/core/onboarding.js +1 -1
- package/dist/core/onboarding.js.map +1 -1
- package/dist/core/registry.js +3 -3
- package/dist/core/registry.js.map +1 -1
- package/dist/core/router.js +2 -2
- package/dist/core/router.js.map +1 -1
- package/dist/core/sender-allowlist.js +1 -1
- package/dist/core/sender-allowlist.js.map +1 -1
- package/dist/plugins/agents/native/index.d.ts.map +1 -1
- package/dist/plugins/agents/native/index.js +17 -4
- 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 +9 -3
- package/dist/plugins/agents/pi-native/factory.js.map +1 -1
- package/dist/plugins/agents/pi-native/index.js +1 -1
- 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 +6 -1
- package/dist/plugins/agents/pi-native/provider-resolver.js.map +1 -1
- package/dist/web/llm-api.d.ts.map +1 -1
- package/dist/web/llm-api.js +12 -0
- package/dist/web/llm-api.js.map +1 -1
- package/dist/web/public/assets/{a2a-CK_McNBZ.js → a2a-Dtc6AKjx.js} +3 -3
- package/dist/web/public/assets/{a2a-CK_McNBZ.js.map → a2a-Dtc6AKjx.js.map} +1 -1
- package/dist/web/public/assets/{activity-SXgxjjhd.js → activity-CWFI_ke7.js} +2 -2
- package/dist/web/public/assets/{activity-SXgxjjhd.js.map → activity-CWFI_ke7.js.map} +1 -1
- package/dist/web/public/assets/admins-CeQorJdU.js +17 -0
- package/dist/web/public/assets/admins-CeQorJdU.js.map +1 -0
- package/dist/web/public/assets/{agents-BhuZPnjf.js → agents-DnJruPrS.js} +3 -3
- package/dist/web/public/assets/{agents-BhuZPnjf.js.map → agents-DnJruPrS.js.map} +1 -1
- package/dist/web/public/assets/{approvals-CUsF6htp.js → approvals-BEPKSyrL.js} +3 -3
- package/dist/web/public/assets/{approvals-CUsF6htp.js.map → approvals-BEPKSyrL.js.map} +1 -1
- package/dist/web/public/assets/{arrow-down-Dhsj-A0i.js → arrow-down-CzWGZc48.js} +2 -2
- package/dist/web/public/assets/{arrow-down-Dhsj-A0i.js.map → arrow-down-CzWGZc48.js.map} +1 -1
- package/dist/web/public/assets/{arrow-up-Byeo8HHt.js → arrow-up-CXy94NPi.js} +2 -2
- package/dist/web/public/assets/{arrow-up-Byeo8HHt.js.map → arrow-up-CXy94NPi.js.map} +1 -1
- package/dist/web/public/assets/{asks-BkwfCOfj.js → asks-BszsbhPn.js} +3 -3
- package/dist/web/public/assets/{asks-BkwfCOfj.js.map → asks-BszsbhPn.js.map} +1 -1
- package/dist/web/public/assets/audit-ACrwMizd.js +2 -0
- package/dist/web/public/assets/{audit-DshxCHuP.js.map → audit-ACrwMizd.js.map} +1 -1
- package/dist/web/public/assets/{bell-CgQQygG1.js → bell-BLwNOhXO.js} +2 -2
- package/dist/web/public/assets/{bell-CgQQygG1.js.map → bell-BLwNOhXO.js.map} +1 -1
- package/dist/web/public/assets/{bgjobs-qYRbEcQY.js → bgjobs-Cwp0PmTF.js} +3 -3
- package/dist/web/public/assets/{bgjobs-qYRbEcQY.js.map → bgjobs-Cwp0PmTF.js.map} +1 -1
- package/dist/web/public/assets/{brain-V9r2NcZc.js → brain-5AJBYzXX.js} +2 -2
- package/dist/web/public/assets/{brain-V9r2NcZc.js.map → brain-5AJBYzXX.js.map} +1 -1
- package/dist/web/public/assets/{briefcase-CC-yM9eZ.js → briefcase-BTDurkZz.js} +2 -2
- package/dist/web/public/assets/{briefcase-CC-yM9eZ.js.map → briefcase-BTDurkZz.js.map} +1 -1
- package/dist/web/public/assets/chat-D7jjr-Rn.js +17 -0
- package/dist/web/public/assets/chat-D7jjr-Rn.js.map +1 -0
- package/dist/web/public/assets/{chevron-left-CTwCYqyt.js → chevron-left-CnLOhWHE.js} +2 -2
- package/dist/web/public/assets/{chevron-left-CTwCYqyt.js.map → chevron-left-CnLOhWHE.js.map} +1 -1
- package/dist/web/public/assets/chevron-right-CpWYrqTa.js +7 -0
- package/dist/web/public/assets/{chevron-right-CDiFYKGo.js.map → chevron-right-CpWYrqTa.js.map} +1 -1
- package/dist/web/public/assets/{circle-check-CWttT2Af.js → circle-check-DhcTh_uP.js} +2 -2
- package/dist/web/public/assets/{circle-check-CWttT2Af.js.map → circle-check-DhcTh_uP.js.map} +1 -1
- package/dist/web/public/assets/{circle-check-big-Cf2odn4o.js → circle-check-big-CcknUEHz.js} +2 -2
- package/dist/web/public/assets/{circle-check-big-Cf2odn4o.js.map → circle-check-big-CcknUEHz.js.map} +1 -1
- package/dist/web/public/assets/{circle-x-CMJqo4Pi.js → circle-x-QODE2UcL.js} +2 -2
- package/dist/web/public/assets/{circle-x-CMJqo4Pi.js.map → circle-x-QODE2UcL.js.map} +1 -1
- package/dist/web/public/assets/{clock-DUKggKlF.js → clock-BPBx4QWT.js} +3 -3
- package/dist/web/public/assets/{clock-DUKggKlF.js.map → clock-BPBx4QWT.js.map} +1 -1
- package/dist/web/public/assets/confirm-dialog-HsyBgWxC.js +2 -0
- package/dist/web/public/assets/{confirm-dialog-CMWuyC3w.js.map → confirm-dialog-HsyBgWxC.js.map} +1 -1
- package/dist/web/public/assets/{copy-D8mIKuYJ.js → copy-VJNELMp7.js} +3 -3
- package/dist/web/public/assets/{copy-D8mIKuYJ.js.map → copy-VJNELMp7.js.map} +1 -1
- package/dist/web/public/assets/{data-table-CHGndGOY.js → data-table-C0yaCeSS.js} +2 -2
- package/dist/web/public/assets/{data-table-CHGndGOY.js.map → data-table-C0yaCeSS.js.map} +1 -1
- package/dist/web/public/assets/{download-CgEI28s6.js → download-EUh-RXv5.js} +3 -3
- package/dist/web/public/assets/{download-CgEI28s6.js.map → download-EUh-RXv5.js.map} +1 -1
- package/dist/web/public/assets/{email-BLZQOZnx.js → email-YUzrp4Tf.js} +3 -3
- package/dist/web/public/assets/{email-BLZQOZnx.js.map → email-YUzrp4Tf.js.map} +1 -1
- package/dist/web/public/assets/{empty-state-D8kx-FwO.js → empty-state-DoiBKL4l.js} +2 -2
- package/dist/web/public/assets/{empty-state-D8kx-FwO.js.map → empty-state-DoiBKL4l.js.map} +1 -1
- package/dist/web/public/assets/{external-link-BM6n9mwt.js → external-link-Bf2430Ji.js} +2 -2
- package/dist/web/public/assets/{external-link-BM6n9mwt.js.map → external-link-Bf2430Ji.js.map} +1 -1
- package/dist/web/public/assets/{eye-Dk27zHD5.js → eye-vE4k-Us-.js} +2 -2
- package/dist/web/public/assets/{eye-Dk27zHD5.js.map → eye-vE4k-Us-.js.map} +1 -1
- package/dist/web/public/assets/facts-BPVTGzM4.js +2 -0
- package/dist/web/public/assets/{facts-CoWF4O82.js.map → facts-BPVTGzM4.js.map} +1 -1
- package/dist/web/public/assets/{goals-CuiFswaR.js → goals-HsKzf-PG.js} +3 -3
- package/dist/web/public/assets/{goals-CuiFswaR.js.map → goals-HsKzf-PG.js.map} +1 -1
- package/dist/web/public/assets/health-CSMAArAj.js +2 -0
- package/dist/web/public/assets/{health-C3lSUr_r.js.map → health-CSMAArAj.js.map} +1 -1
- package/dist/web/public/assets/{heart-pulse-D34iW_OF.js → heart-pulse-8RDC8GWv.js} +2 -2
- package/dist/web/public/assets/{heart-pulse-D34iW_OF.js.map → heart-pulse-8RDC8GWv.js.map} +1 -1
- package/dist/web/public/assets/{heartbeat-Z5gPGZhm.js → heartbeat-BzHZy7Mx.js} +3 -3
- package/dist/web/public/assets/{heartbeat-Z5gPGZhm.js.map → heartbeat-BzHZy7Mx.js.map} +1 -1
- package/dist/web/public/assets/{hot-CZJeO9Mj.js → hot-DkFvD3H4.js} +3 -3
- package/dist/web/public/assets/{hot-CZJeO9Mj.js.map → hot-DkFvD3H4.js.map} +1 -1
- package/dist/web/public/assets/index-Bc0H0I1S.css +1 -0
- package/dist/web/public/assets/index-D7BuMEIr.js +204 -0
- package/dist/web/public/assets/index-D7BuMEIr.js.map +1 -0
- package/dist/web/public/assets/injection-a2kkgRbT.js +2 -0
- package/dist/web/public/assets/{injection-BTDjIbkn.js.map → injection-a2kkgRbT.js.map} +1 -1
- package/dist/web/public/assets/{installed-B5IGYO0m.js → installed-XQQEPKh8.js} +3 -3
- package/dist/web/public/assets/{installed-B5IGYO0m.js.map → installed-XQQEPKh8.js.map} +1 -1
- package/dist/web/public/assets/jobs-Cby1Eq4o.js +2 -0
- package/dist/web/public/assets/{jobs-9YLeiSVG.js.map → jobs-Cby1Eq4o.js.map} +1 -1
- package/dist/web/public/assets/{layout-5cLpIeb4.js → layout-0rDvqHCV.js} +2 -2
- package/dist/web/public/assets/{layout-5cLpIeb4.js.map → layout-0rDvqHCV.js.map} +1 -1
- package/dist/web/public/assets/{layout-BdCXtDqk.js → layout-BRnEPnky.js} +2 -2
- package/dist/web/public/assets/{layout-BdCXtDqk.js.map → layout-BRnEPnky.js.map} +1 -1
- package/dist/web/public/assets/layout-BdtJtlu5.js +2 -0
- package/dist/web/public/assets/{layout-CgeijAPB.js.map → layout-BdtJtlu5.js.map} +1 -1
- package/dist/web/public/assets/{layout-DLtODZx_.js → layout-CbqldDRj.js} +2 -2
- package/dist/web/public/assets/{layout-DLtODZx_.js.map → layout-CbqldDRj.js.map} +1 -1
- package/dist/web/public/assets/layout-Gh29ouFO.js +2 -0
- package/dist/web/public/assets/{layout-DviZj3TJ.js.map → layout-Gh29ouFO.js.map} +1 -1
- package/dist/web/public/assets/{llm-BXhp_nmW.js → llm-COWnMdB9.js} +3 -3
- package/dist/web/public/assets/llm-COWnMdB9.js.map +1 -0
- package/dist/web/public/assets/loader-circle-DO3Ni2RJ.js +7 -0
- package/dist/web/public/assets/{loader-circle-Bgi0H_iI.js.map → loader-circle-DO3Ni2RJ.js.map} +1 -1
- package/dist/web/public/assets/{map-pin-o5p1iOoH.js → map-pin-BsL35E1s.js} +2 -2
- package/dist/web/public/assets/{map-pin-o5p1iOoH.js.map → map-pin-BsL35E1s.js.map} +1 -1
- package/dist/web/public/assets/{mcp-kSwFcRcU.js → mcp-CWMdxcBf.js} +3 -3
- package/dist/web/public/assets/{mcp-kSwFcRcU.js.map → mcp-CWMdxcBf.js.map} +1 -1
- package/dist/web/public/assets/{memos-uAcJzXoQ.js → memos-BYQa4d2t.js} +3 -3
- package/dist/web/public/assets/{memos-uAcJzXoQ.js.map → memos-BYQa4d2t.js.map} +1 -1
- package/dist/web/public/assets/messengers-CebazAJ1.js +2 -0
- package/dist/web/public/assets/{messengers-CkfyROty.js.map → messengers-CebazAJ1.js.map} +1 -1
- package/dist/web/public/assets/{mobile-ClKdRpd9.js → mobile-CMJRNHs2.js} +3 -3
- package/dist/web/public/assets/{mobile-ClKdRpd9.js.map → mobile-CMJRNHs2.js.map} +1 -1
- package/dist/web/public/assets/{native-agent-yfdrcTaK.js → native-agent-MGgMeTHN.js} +3 -3
- package/dist/web/public/assets/{native-agent-yfdrcTaK.js.map → native-agent-MGgMeTHN.js.map} +1 -1
- package/dist/web/public/assets/{network-BlQWIsIc.js → network-pNcx_slv.js} +2 -2
- package/dist/web/public/assets/{network-BlQWIsIc.js.map → network-pNcx_slv.js.map} +1 -1
- package/dist/web/public/assets/{outbox-CYwJu6AR.js → outbox-87hzZQLn.js} +3 -3
- package/dist/web/public/assets/{outbox-CYwJu6AR.js.map → outbox-87hzZQLn.js.map} +1 -1
- package/dist/web/public/assets/{pagination-C6qu72mB.js → pagination-C4edFAqf.js} +2 -2
- package/dist/web/public/assets/{pagination-C6qu72mB.js.map → pagination-C4edFAqf.js.map} +1 -1
- package/dist/web/public/assets/persona-BcOT3Wms.js +2 -0
- package/dist/web/public/assets/{persona-DnuFOp64.js.map → persona-BcOT3Wms.js.map} +1 -1
- package/dist/web/public/assets/{plans-DUg3JDwQ.js → plans-Ddz5qwqp.js} +3 -3
- package/dist/web/public/assets/{plans-DUg3JDwQ.js.map → plans-Ddz5qwqp.js.map} +1 -1
- package/dist/web/public/assets/{play-BGXpdCxa.js → play-Bzdymasn.js} +2 -2
- package/dist/web/public/assets/{play-BGXpdCxa.js.map → play-Bzdymasn.js.map} +1 -1
- package/dist/web/public/assets/{plus-2MZ7TkP3.js → plus-BxjzY9Wh.js} +2 -2
- package/dist/web/public/assets/{plus-2MZ7TkP3.js.map → plus-BxjzY9Wh.js.map} +1 -1
- package/dist/web/public/assets/policy-Be-tMZZc.js +2 -0
- package/dist/web/public/assets/{policy-C4xe2rWm.js.map → policy-Be-tMZZc.js.map} +1 -1
- package/dist/web/public/assets/{qr-code-BVHNR5Zs.js → qr-code-D1V5cA_X.js} +2 -2
- package/dist/web/public/assets/{qr-code-BVHNR5Zs.js.map → qr-code-D1V5cA_X.js.map} +1 -1
- package/dist/web/public/assets/{refresh-ccw-MHrCmmSv.js → refresh-ccw-BhPAzZAa.js} +2 -2
- package/dist/web/public/assets/{refresh-ccw-MHrCmmSv.js.map → refresh-ccw-BhPAzZAa.js.map} +1 -1
- package/dist/web/public/assets/{reminders-CmV_JNt5.js → reminders-DEWtrlH_.js} +3 -3
- package/dist/web/public/assets/{reminders-CmV_JNt5.js.map → reminders-DEWtrlH_.js.map} +1 -1
- package/dist/web/public/assets/{save-DhFewuZL.js → save-Cye8Vlu5.js} +2 -2
- package/dist/web/public/assets/{save-DhFewuZL.js.map → save-Cye8Vlu5.js.map} +1 -1
- package/dist/web/public/assets/{schedules-Cp63TJGf.js → schedules-CuqRy3t8.js} +3 -3
- package/dist/web/public/assets/{schedules-Cp63TJGf.js.map → schedules-CuqRy3t8.js.map} +1 -1
- package/dist/web/public/assets/{search-wZEXSmcX.js → search-BQqVArrW.js} +2 -2
- package/dist/web/public/assets/{search-wZEXSmcX.js.map → search-BQqVArrW.js.map} +1 -1
- package/dist/web/public/assets/{search-wUAqWxXK.js → search-Dot_W5Eu.js} +3 -3
- package/dist/web/public/assets/{search-wUAqWxXK.js.map → search-Dot_W5Eu.js.map} +1 -1
- package/dist/web/public/assets/security-BB-YnetQ.js +2 -0
- package/dist/web/public/assets/{security-BoMdDyCY.js.map → security-BB-YnetQ.js.map} +1 -1
- package/dist/web/public/assets/{service-C_KqtWwn.js → service-DgkqlAtM.js} +3 -3
- package/dist/web/public/assets/{service-C_KqtWwn.js.map → service-DgkqlAtM.js.map} +1 -1
- package/dist/web/public/assets/{shield-alert-CplKlUGS.js → shield-alert-CBOmgn9W.js} +2 -2
- package/dist/web/public/assets/{shield-alert-CplKlUGS.js.map → shield-alert-CBOmgn9W.js.map} +1 -1
- package/dist/web/public/assets/{status-badge-q2WooCma.js → status-badge-9sMFH4uP.js} +2 -2
- package/dist/web/public/assets/{status-badge-q2WooCma.js.map → status-badge-9sMFH4uP.js.map} +1 -1
- package/dist/web/public/assets/{subtasks-CBi4c6FD.js → subtasks-BrqdQxw_.js} +3 -3
- package/dist/web/public/assets/{subtasks-CBi4c6FD.js.map → subtasks-BrqdQxw_.js.map} +1 -1
- package/dist/web/public/assets/{table-Bmwe7n4n.js → table-CSHCu7pz.js} +2 -2
- package/dist/web/public/assets/{table-Bmwe7n4n.js.map → table-CSHCu7pz.js.map} +1 -1
- package/dist/web/public/assets/{topn-CMRS4ApA.js → topn-DZWbwDge.js} +3 -3
- package/dist/web/public/assets/{topn-CMRS4ApA.js.map → topn-DZWbwDge.js.map} +1 -1
- package/dist/web/public/assets/{trash-2-CT_B0mSH.js → trash-2-Cco09tAA.js} +2 -2
- package/dist/web/public/assets/{trash-2-CT_B0mSH.js.map → trash-2-Cco09tAA.js.map} +1 -1
- package/dist/web/public/assets/use-agim-skills-CJOJKeOZ.js +2 -0
- package/dist/web/public/assets/{use-agim-skills-C0HdvMQj.js.map → use-agim-skills-CJOJKeOZ.js.map} +1 -1
- package/dist/web/public/assets/use-background-tasks-D77bcfrq.js +2 -0
- package/dist/web/public/assets/{use-background-tasks-Co9CtmcD.js.map → use-background-tasks-D77bcfrq.js.map} +1 -1
- package/dist/web/public/assets/use-memory-CX4B1SYC.js +2 -0
- package/dist/web/public/assets/{use-memory-BHYuPOc9.js.map → use-memory-CX4B1SYC.js.map} +1 -1
- package/dist/web/public/assets/use-observability-rcc7fRmj.js +2 -0
- package/dist/web/public/assets/{use-observability-CHv6H0zQ.js.map → use-observability-rcc7fRmj.js.map} +1 -1
- package/dist/web/public/assets/use-settings-DQnJkPXp.js +2 -0
- package/dist/web/public/assets/{use-settings-Bx0ZTOsd.js.map → use-settings-DQnJkPXp.js.map} +1 -1
- package/dist/web/public/assets/use-workspace-J5eeVxw9.js +2 -0
- package/dist/web/public/assets/{use-workspace-zFEfqUCo.js.map → use-workspace-J5eeVxw9.js.map} +1 -1
- package/dist/web/public/assets/vector-xRphJ8hW.js +2 -0
- package/dist/web/public/assets/{vector-B9v7zTvA.js.map → vector-xRphJ8hW.js.map} +1 -1
- package/dist/web/public/assets/{viewer-CeD55ZLu.js → viewer-Bq7l2kE8.js} +3 -3
- package/dist/web/public/assets/{viewer-CeD55ZLu.js.map → viewer-Bq7l2kE8.js.map} +1 -1
- package/dist/web/public/assets/{workspace-Ci21xBqp.js → workspace-BqMuxPFF.js} +3 -3
- package/dist/web/public/assets/{workspace-Ci21xBqp.js.map → workspace-BqMuxPFF.js.map} +1 -1
- package/dist/web/public/assets/{workspaces-C8mT-jmj.js → workspaces-D0pYJfxI.js} +3 -3
- package/dist/web/public/assets/{workspaces-C8mT-jmj.js.map → workspaces-D0pYJfxI.js.map} +1 -1
- package/dist/web/public/index.html +2 -2
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +85 -54
- package/dist/web/server.js.map +1 -1
- package/package.json +1 -1
- package/dist/core/admin-bootstrap.d.ts +0 -42
- package/dist/core/admin-bootstrap.d.ts.map +0 -1
- package/dist/core/admin-bootstrap.js +0 -156
- package/dist/core/admin-bootstrap.js.map +0 -1
- package/dist/web/public/assets/admins-aofsuukT.js +0 -12
- package/dist/web/public/assets/admins-aofsuukT.js.map +0 -1
- package/dist/web/public/assets/audit-DshxCHuP.js +0 -2
- package/dist/web/public/assets/chat-CY4JriM5.js +0 -7
- package/dist/web/public/assets/chat-CY4JriM5.js.map +0 -1
- package/dist/web/public/assets/chevron-right-CDiFYKGo.js +0 -7
- package/dist/web/public/assets/confirm-dialog-CMWuyC3w.js +0 -2
- package/dist/web/public/assets/dialog-xeyu8dCf.js +0 -2
- package/dist/web/public/assets/dialog-xeyu8dCf.js.map +0 -1
- package/dist/web/public/assets/facts-CoWF4O82.js +0 -2
- package/dist/web/public/assets/health-C3lSUr_r.js +0 -2
- package/dist/web/public/assets/index-D1ulN_24.js +0 -199
- package/dist/web/public/assets/index-D1ulN_24.js.map +0 -1
- package/dist/web/public/assets/index-uKzGZ_Df.css +0 -1
- package/dist/web/public/assets/injection-BTDjIbkn.js +0 -2
- package/dist/web/public/assets/jobs-9YLeiSVG.js +0 -2
- package/dist/web/public/assets/layout-CgeijAPB.js +0 -2
- package/dist/web/public/assets/layout-DviZj3TJ.js +0 -2
- package/dist/web/public/assets/llm-BXhp_nmW.js.map +0 -1
- package/dist/web/public/assets/loader-circle-Bgi0H_iI.js +0 -7
- package/dist/web/public/assets/messengers-CkfyROty.js +0 -2
- package/dist/web/public/assets/persona-DnuFOp64.js +0 -2
- package/dist/web/public/assets/policy-C4xe2rWm.js +0 -2
- package/dist/web/public/assets/security-BoMdDyCY.js +0 -2
- package/dist/web/public/assets/use-agim-skills-C0HdvMQj.js +0 -2
- package/dist/web/public/assets/use-background-tasks-Co9CtmcD.js +0 -2
- package/dist/web/public/assets/use-llm-admin-Bd0XAQpx.js +0 -2
- package/dist/web/public/assets/use-llm-admin-Bd0XAQpx.js.map +0 -1
- package/dist/web/public/assets/use-memory-BHYuPOc9.js +0 -2
- package/dist/web/public/assets/use-observability-CHv6H0zQ.js +0 -2
- package/dist/web/public/assets/use-settings-Bx0ZTOsd.js +0 -2
- package/dist/web/public/assets/use-workspace-zFEfqUCo.js +0 -2
- package/dist/web/public/assets/useQuery-Bt7Ty7IO.js +0 -2
- package/dist/web/public/assets/useQuery-Bt7Ty7IO.js.map +0 -1
- package/dist/web/public/assets/vector-B9v7zTvA.js +0 -2
- package/dist/web/public/assets/x-DXACg96C.js +0 -7
- package/dist/web/public/assets/x-DXACg96C.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agim-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Agim (阿吉姆) — universal messenger-to-agent bridge. Connect WeChat / Feishu / DingTalk / Email to Claude Code / Codex / OpenCode, or any custom agent via ACP. Installs the `agim` command.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
export declare const BOOTSTRAP_TOKEN_FILE: string;
|
|
2
|
-
/**
|
|
3
|
-
* Called once at process startup. If no admin is configured (env empty,
|
|
4
|
-
* no runtime additions), regenerates a fresh token file and logs the
|
|
5
|
-
* onboarding instruction. Idempotent on already-admin'd boxes — does
|
|
6
|
-
* nothing.
|
|
7
|
-
*
|
|
8
|
-
* Returns the token on first-run boxes (so callers can echo it to
|
|
9
|
-
* stdout in addition to the structured log), null on already-configured
|
|
10
|
-
* boxes.
|
|
11
|
-
*/
|
|
12
|
-
export declare function ensureBootstrapTokenIfNeeded(): string | null;
|
|
13
|
-
/**
|
|
14
|
-
* v1.2.2 — generate an admin INVITE token unconditionally (even when an
|
|
15
|
-
* admin already exists). Reuses the same bootstrap-token file + the same
|
|
16
|
-
* `/setup admin <token>` IM flow. Overwrites any existing unconsumed
|
|
17
|
-
* token so only the latest invite is valid at any time.
|
|
18
|
-
*
|
|
19
|
-
* Intended for an existing admin to onboard additional admins without
|
|
20
|
-
* SSH'ing into the server to look up the autogen bootstrap token.
|
|
21
|
-
* Triggered by `agim admin invite` CLI / the entry-menu option.
|
|
22
|
-
*/
|
|
23
|
-
export declare function generateAdminInviteToken(): {
|
|
24
|
-
token: string;
|
|
25
|
-
file: string;
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Verify a candidate token + promote the caller to admin on success.
|
|
29
|
-
* Returns the outcome so the slash-command handler can craft the right
|
|
30
|
-
* reply. On success, the token file is unlinked (single-use).
|
|
31
|
-
*/
|
|
32
|
-
export declare function consumeBootstrapToken(candidate: string, platform: string, userId: string): Promise<{
|
|
33
|
-
ok: true;
|
|
34
|
-
alreadyAdmin: false;
|
|
35
|
-
} | {
|
|
36
|
-
ok: true;
|
|
37
|
-
alreadyAdmin: true;
|
|
38
|
-
} | {
|
|
39
|
-
ok: false;
|
|
40
|
-
reason: 'no_token_file' | 'mismatch' | 'missing_user_id';
|
|
41
|
-
}>;
|
|
42
|
-
//# sourceMappingURL=admin-bootstrap.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"admin-bootstrap.d.ts","sourceRoot":"","sources":["../../src/core/admin-bootstrap.ts"],"names":[],"mappings":"AAqCA,eAAO,MAAM,oBAAoB,QAA2C,CAAA;AAgB5E;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,GAAG,IAAI,CAoC5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,IAAI;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAU1E;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CACN;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,YAAY,EAAE,KAAK,CAAA;CAAE,GACjC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,YAAY,EAAE,IAAI,CAAA;CAAE,GAChC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,eAAe,GAAG,UAAU,GAAG,iBAAiB,CAAA;CAAE,CAC1E,CA+BA"}
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
// Admin bootstrap — first-run admin onboarding.
|
|
2
|
-
//
|
|
3
|
-
// Problem this solves: a fresh deploy has IMHUB_ADMIN_USERS empty, so the
|
|
4
|
-
// service-management commands (/restart, /stop) are blanket denied. The
|
|
5
|
-
// operator can't onboard themselves via IM because they're not yet
|
|
6
|
-
// admin. Telling them "edit env + restart" is friction they may not
|
|
7
|
-
// know how to do.
|
|
8
|
-
//
|
|
9
|
-
// Flow:
|
|
10
|
-
// 1. cli.ts at startup checks isAllowlistConfigured(). If FALSE,
|
|
11
|
-
// generates a one-time 12-char base32 token, writes it to
|
|
12
|
-
// ~/.agim/admin-bootstrap-token (chmod 600), and logs:
|
|
13
|
-
// "⚙️ 未配置管理员。在 IM 里发 /setup admin <TOKEN> 把自己设为 admin。"
|
|
14
|
-
// 2. The operator pulls the token from journalctl / the file, and
|
|
15
|
-
// sends `/setup admin <token>` to their bot.
|
|
16
|
-
// 3. consumeBootstrapToken() verifies the token, calls promoteAdmin()
|
|
17
|
-
// (which persists to ~/.agim/env), and unlinks the token file.
|
|
18
|
-
// 4. The slash-command handler replies "✅ 你 (platform:userId) 已设
|
|
19
|
-
// 为管理员,token 已作废。"
|
|
20
|
-
//
|
|
21
|
-
// Security:
|
|
22
|
-
// - Token is 60 bits of entropy (12 base32 chars). Brute-force is
|
|
23
|
-
// impossible at IM message rate.
|
|
24
|
-
// - File is chmod 600 — only the agim process owner can read.
|
|
25
|
-
// - Single-use: consumeBootstrapToken() unlinks the file on success.
|
|
26
|
-
// - Each process restart regenerates (only if no admins). So if the
|
|
27
|
-
// operator forgets the old token, a restart gives them a new one.
|
|
28
|
-
import { existsSync, readFileSync, writeFileSync, unlinkSync, chmodSync, mkdirSync } from 'node:fs';
|
|
29
|
-
import { randomBytes } from 'node:crypto';
|
|
30
|
-
import { join, dirname } from 'node:path';
|
|
31
|
-
import { AGIM_HOME } from './agim-paths.js';
|
|
32
|
-
import { isAllowlistConfigured, promoteAdmin } from './admin-allowlist.js';
|
|
33
|
-
import { logger as rootLogger } from './logger.js';
|
|
34
|
-
const log = rootLogger.child({ component: 'admin-bootstrap' });
|
|
35
|
-
export const BOOTSTRAP_TOKEN_FILE = join(AGIM_HOME, 'admin-bootstrap-token');
|
|
36
|
-
/** Base32 alphabet — Crockford-style, excludes I/L/O/U for legibility. */
|
|
37
|
-
const ALPHABET = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
|
|
38
|
-
function generateToken() {
|
|
39
|
-
const bytes = randomBytes(8);
|
|
40
|
-
let out = '';
|
|
41
|
-
for (let i = 0; i < 12; i++) {
|
|
42
|
-
out += ALPHABET[bytes[i % bytes.length] % ALPHABET.length];
|
|
43
|
-
// Insert hyphens for readability: 4-4-4.
|
|
44
|
-
if (i === 3 || i === 7)
|
|
45
|
-
out += '-';
|
|
46
|
-
}
|
|
47
|
-
return out;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Called once at process startup. If no admin is configured (env empty,
|
|
51
|
-
* no runtime additions), regenerates a fresh token file and logs the
|
|
52
|
-
* onboarding instruction. Idempotent on already-admin'd boxes — does
|
|
53
|
-
* nothing.
|
|
54
|
-
*
|
|
55
|
-
* Returns the token on first-run boxes (so callers can echo it to
|
|
56
|
-
* stdout in addition to the structured log), null on already-configured
|
|
57
|
-
* boxes.
|
|
58
|
-
*/
|
|
59
|
-
export function ensureBootstrapTokenIfNeeded() {
|
|
60
|
-
if (isAllowlistConfigured()) {
|
|
61
|
-
// Clean up any stale token file from a previous unconfigured state.
|
|
62
|
-
if (existsSync(BOOTSTRAP_TOKEN_FILE)) {
|
|
63
|
-
try {
|
|
64
|
-
unlinkSync(BOOTSTRAP_TOKEN_FILE);
|
|
65
|
-
}
|
|
66
|
-
catch { /* ignore */ }
|
|
67
|
-
}
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
const token = generateToken();
|
|
71
|
-
try {
|
|
72
|
-
mkdirSync(dirname(BOOTSTRAP_TOKEN_FILE), { recursive: true });
|
|
73
|
-
writeFileSync(BOOTSTRAP_TOKEN_FILE, token + '\n');
|
|
74
|
-
chmodSync(BOOTSTRAP_TOKEN_FILE, 0o600);
|
|
75
|
-
}
|
|
76
|
-
catch (err) {
|
|
77
|
-
log.error({
|
|
78
|
-
event: 'admin-bootstrap.write_failed',
|
|
79
|
-
err: err instanceof Error ? err.message : String(err),
|
|
80
|
-
}, 'failed to write bootstrap token; admins cannot self-onboard via /setup');
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
// Compliance (R13 A3): never put the raw token in the pino log or
|
|
84
|
-
// unconditionally on stdout — both go to journald and would let any
|
|
85
|
-
// journal reader race the operator. We log only the file path; the
|
|
86
|
-
// token lives in 0o600 on disk and operators retrieve it via
|
|
87
|
-
// `cat ~/.agim/admin-bootstrap-token`.
|
|
88
|
-
log.info({ event: 'admin-bootstrap.ready', file: BOOTSTRAP_TOKEN_FILE }, 'admin-bootstrap token written; retrieve from file on the host');
|
|
89
|
-
console.log();
|
|
90
|
-
console.log('⚙️ No admin configured. To onboard yourself:');
|
|
91
|
-
console.log(` 1. On the host, run: cat ${BOOTSTRAP_TOKEN_FILE}`);
|
|
92
|
-
console.log(' 2. In IM, send: /setup admin <paste-token-here>');
|
|
93
|
-
console.log(' · Token regenerates on every restart while no admin is set.');
|
|
94
|
-
console.log();
|
|
95
|
-
return token;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* v1.2.2 — generate an admin INVITE token unconditionally (even when an
|
|
99
|
-
* admin already exists). Reuses the same bootstrap-token file + the same
|
|
100
|
-
* `/setup admin <token>` IM flow. Overwrites any existing unconsumed
|
|
101
|
-
* token so only the latest invite is valid at any time.
|
|
102
|
-
*
|
|
103
|
-
* Intended for an existing admin to onboard additional admins without
|
|
104
|
-
* SSH'ing into the server to look up the autogen bootstrap token.
|
|
105
|
-
* Triggered by `agim admin invite` CLI / the entry-menu option.
|
|
106
|
-
*/
|
|
107
|
-
export function generateAdminInviteToken() {
|
|
108
|
-
const token = generateToken();
|
|
109
|
-
mkdirSync(dirname(BOOTSTRAP_TOKEN_FILE), { recursive: true });
|
|
110
|
-
writeFileSync(BOOTSTRAP_TOKEN_FILE, token + '\n');
|
|
111
|
-
chmodSync(BOOTSTRAP_TOKEN_FILE, 0o600);
|
|
112
|
-
log.info({
|
|
113
|
-
event: 'admin-bootstrap.invite_generated',
|
|
114
|
-
file: BOOTSTRAP_TOKEN_FILE,
|
|
115
|
-
}, 'admin invite token generated (existing admin invoked invite flow)');
|
|
116
|
-
return { token, file: BOOTSTRAP_TOKEN_FILE };
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Verify a candidate token + promote the caller to admin on success.
|
|
120
|
-
* Returns the outcome so the slash-command handler can craft the right
|
|
121
|
-
* reply. On success, the token file is unlinked (single-use).
|
|
122
|
-
*/
|
|
123
|
-
export async function consumeBootstrapToken(candidate, platform, userId) {
|
|
124
|
-
if (!userId)
|
|
125
|
-
return { ok: false, reason: 'missing_user_id' };
|
|
126
|
-
if (!existsSync(BOOTSTRAP_TOKEN_FILE)) {
|
|
127
|
-
return { ok: false, reason: 'no_token_file' };
|
|
128
|
-
}
|
|
129
|
-
let stored = '';
|
|
130
|
-
try {
|
|
131
|
-
stored = readFileSync(BOOTSTRAP_TOKEN_FILE, 'utf-8').trim();
|
|
132
|
-
}
|
|
133
|
-
catch {
|
|
134
|
-
return { ok: false, reason: 'no_token_file' };
|
|
135
|
-
}
|
|
136
|
-
// Constant-time-ish compare; we have no timing attacker over IM, but
|
|
137
|
-
// matching the project's existing safeEqual hygiene.
|
|
138
|
-
if (stored.length !== candidate.length || stored !== candidate) {
|
|
139
|
-
return { ok: false, reason: 'mismatch' };
|
|
140
|
-
}
|
|
141
|
-
const promoted = await promoteAdmin(platform, userId);
|
|
142
|
-
// Unlink whether we added a new entry or the caller was already admin
|
|
143
|
-
// via some other path — the token is consumed regardless.
|
|
144
|
-
try {
|
|
145
|
-
unlinkSync(BOOTSTRAP_TOKEN_FILE);
|
|
146
|
-
}
|
|
147
|
-
catch { /* ignore */ }
|
|
148
|
-
log.info({
|
|
149
|
-
event: 'admin-bootstrap.consumed',
|
|
150
|
-
platform: platform.toLowerCase(),
|
|
151
|
-
userId,
|
|
152
|
-
newPromotion: promoted,
|
|
153
|
-
});
|
|
154
|
-
return { ok: true, alreadyAdmin: !promoted };
|
|
155
|
-
}
|
|
156
|
-
//# sourceMappingURL=admin-bootstrap.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"admin-bootstrap.js","sourceRoot":"","sources":["../../src/core/admin-bootstrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import{n as A,u as S,j as s,B as d,k as c,L as N,I as y,l as n,m as w}from"./index-D1ulN_24.js";import{r as x}from"./react-DlP5eolq.js";import{C as L}from"./confirm-dialog-CMWuyC3w.js";import{E as P}from"./empty-state-D8kx-FwO.js";import{T as E,a as z,b as C,c as h,d as B,e as u}from"./table-Bmwe7n4n.js";import{n as F,o as D,p as H}from"./use-settings-Bx0ZTOsd.js";import{L as T}from"./loader-circle-Bgi0H_iI.js";import{R as U}from"./refresh-ccw-MHrCmmSv.js";import{T as _}from"./trash-2-CT_B0mSH.js";import"./dialog-xeyu8dCf.js";import"./x-DXACg96C.js";import"./useQuery-Bt7Ty7IO.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 M=A("Shield",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}]]);/**
|
|
7
|
-
* @license lucide-react v0.469.0 - ISC
|
|
8
|
-
*
|
|
9
|
-
* This source code is licensed under the ISC license.
|
|
10
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
-
*/const $=A("UserPlus",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]]);function es(){const{t:e}=S(["settings","common"]),i=F(),t=i.data,r=D(),f=H(),[l,p]=x.useState(""),[m,j]=x.useState(""),[o,g]=x.useState(null);async function k(a){a.preventDefault();const b=l.trim(),v=m.trim();if(!(!b||!v))try{await r.mutateAsync({platform:b,userId:v}),n.success(e("admins.toast.added")),p(""),j("")}catch(R){n.error(w(R,e).message)}}async function I(){if(o)try{await f.mutateAsync(o),n.success(e("admins.toast.removed"))}catch(a){throw n.error(w(a,e).message),a}}return s.jsxs("div",{className:"mx-auto flex max-w-4xl flex-col gap-4",children:[s.jsxs("header",{className:"flex flex-col gap-1",children:[s.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[s.jsx("h1",{className:"text-xl font-semibold",children:e("admins.title")}),s.jsxs(d,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>i.refetch(),disabled:i.isFetching,"aria-label":e("actions.refresh",{ns:"common"}),children:[i.isFetching?s.jsx(T,{className:"h-4 w-4 animate-spin"}):s.jsx(U,{className:"h-4 w-4"}),s.jsx("span",{className:"hidden sm:inline",children:e("actions.refresh",{ns:"common"})})]})]}),s.jsx("p",{className:"text-sm text-text-dim",children:e("admins.subtitle")})]}),t&&s.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[t.configured?s.jsx(c,{variant:"success",children:e("admins.configured")}):s.jsx(c,{variant:"warning",children:e("admins.notConfigured")}),t.bootstrapAvailable&&s.jsx(c,{variant:"info",title:t.bootstrapTokenPath,children:e("admins.bootstrapAvailable")})]}),i.isLoading?s.jsx("div",{className:"h-32 rounded-md bg-surface-2 animate-pulse"}):t&&t.admins.length===0?s.jsx(P,{icon:s.jsx(M,{}),title:e("admins.empty")}):t?s.jsxs(E,{children:[s.jsx(z,{children:s.jsxs(C,{children:[s.jsx(h,{className:"w-40",children:e("admins.col.platform")}),s.jsx(h,{children:e("admins.col.userId")}),s.jsx(h,{className:"w-24"})]})}),s.jsx(B,{children:t.admins.map(a=>s.jsxs(C,{children:[s.jsx(u,{className:"font-mono",children:a.platform}),s.jsx(u,{className:"font-mono text-xs",children:a.userId}),s.jsx(u,{children:s.jsxs(d,{variant:"ghost",size:"sm",onClick:()=>g(a),disabled:f.isPending,"aria-label":e("admins.remove.label"),children:[s.jsx(_,{className:"h-3 w-3"}),s.jsx("span",{className:"sr-only sm:not-sr-only sm:ml-1",children:e("admins.remove.label")})]})})]},`${a.platform}:${a.userId}`))})]}):null,s.jsxs("form",{onSubmit:a=>void k(a),className:"rounded-md border border-border bg-surface p-4",children:[s.jsx("div",{className:"mb-3 text-sm font-medium",children:e("admins.add.title")}),s.jsxs("div",{className:"grid grid-cols-1 gap-2 sm:grid-cols-[180px_1fr_auto] sm:items-end",children:[s.jsxs("div",{className:"flex flex-col gap-1",children:[s.jsx(N,{htmlFor:"admin-platform",className:"text-xs text-text-dim",children:e("admins.add.platform")}),s.jsx(y,{id:"admin-platform",value:l,onChange:a=>p(a.target.value),placeholder:"wechat",className:"font-mono text-xs"})]}),s.jsxs("div",{className:"flex flex-col gap-1",children:[s.jsx(N,{htmlFor:"admin-user",className:"text-xs text-text-dim",children:e("admins.add.userId")}),s.jsx(y,{id:"admin-user",value:m,onChange:a=>j(a.target.value),placeholder:"wxid_abc123",className:"font-mono text-xs"})]}),s.jsxs(d,{type:"submit",size:"sm",disabled:r.isPending||!l.trim()||!m.trim(),children:[r.isPending?s.jsx(T,{className:"h-4 w-4 animate-spin"}):s.jsx($,{className:"h-4 w-4"}),e("admins.add.submit")]})]})]}),s.jsx(L,{open:o!=null,onOpenChange:a=>{a||g(null)},title:e("admins.remove.confirmTitle"),description:e("admins.remove.confirmDescription"),intent:"danger",confirmLabel:e("admins.remove.label"),onConfirm:I})]})}export{es as default};
|
|
12
|
-
//# sourceMappingURL=admins-aofsuukT.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"admins-aofsuukT.js","sources":["../../node_modules/lucide-react/dist/esm/icons/shield.js","../../node_modules/lucide-react/dist/esm/icons/user-plus.js","../../src/routes/settings/admins.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 Shield = createLucideIcon(\"Shield\", [\n [\n \"path\",\n {\n d: \"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\",\n key: \"oel41y\"\n }\n ]\n]);\n\nexport { Shield as default };\n//# sourceMappingURL=shield.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst UserPlus = createLucideIcon(\"UserPlus\", [\n [\"path\", { d: \"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2\", key: \"1yyitq\" }],\n [\"circle\", { cx: \"9\", cy: \"7\", r: \"4\", key: \"nufk8\" }],\n [\"line\", { x1: \"19\", x2: \"19\", y1: \"8\", y2: \"14\", key: \"1bvyxn\" }],\n [\"line\", { x1: \"22\", x2: \"16\", y1: \"11\", y2: \"11\", key: \"1shjgl\" }]\n]);\n\nexport { UserPlus as default };\n//# sourceMappingURL=user-plus.js.map\n","/**\n * /settings/admins — manage `IMHUB_ADMIN_USERS` entries.\n *\n * Each entry is a `(platform, userId)` pair (e.g. `wechat:wxid_abc`).\n * Add via the inline form at the bottom; remove via per-row trash\n * button → ConfirmDialog. The backend's POST/DELETE handlers gate\n * on isLocalBind — if the operator is hitting agim from another\n * host the mutations 403; we surface that toast verbatim.\n */\n\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Loader2, RefreshCcw, Shield, Trash2, UserPlus } from 'lucide-react'\n\nimport { ConfirmDialog } from '@/components/common/confirm-dialog'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table'\nimport {\n useAddAdmin,\n useAdminAllowlist,\n useRemoveAdmin,\n} from '@/hooks/use-settings'\nimport { describeError } from '@/lib/api/errors'\nimport type { AdminEntry } from '@/types/api'\n\nexport default function SettingsAdminsRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const listQuery = useAdminAllowlist()\n const data = listQuery.data\n\n const addAdmin = useAddAdmin()\n const removeAdmin = useRemoveAdmin()\n\n const [platform, setPlatform] = useState('')\n const [userId, setUserId] = useState('')\n const [removeTarget, setRemoveTarget] = useState<AdminEntry | null>(null)\n\n async function onAdd(e: React.FormEvent): Promise<void> {\n e.preventDefault()\n const p = platform.trim()\n const u = userId.trim()\n if (!p || !u) return\n try {\n await addAdmin.mutateAsync({ platform: p, userId: u })\n toast.success(t('admins.toast.added'))\n setPlatform('')\n setUserId('')\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n async function onConfirmRemove(): Promise<void> {\n if (!removeTarget) return\n try {\n await removeAdmin.mutateAsync(removeTarget)\n toast.success(t('admins.toast.removed'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n throw err\n }\n }\n\n return (\n <div className=\"mx-auto flex max-w-4xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('admins.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.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('admins.subtitle')}</p>\n </header>\n\n {data && (\n <div className=\"flex flex-wrap items-center gap-2\">\n {data.configured ? (\n <Badge variant=\"success\">{t('admins.configured')}</Badge>\n ) : (\n <Badge variant=\"warning\">{t('admins.notConfigured')}</Badge>\n )}\n {data.bootstrapAvailable && (\n <Badge variant=\"info\" title={data.bootstrapTokenPath}>\n {t('admins.bootstrapAvailable')}\n </Badge>\n )}\n </div>\n )}\n\n {listQuery.isLoading ? (\n <div className=\"h-32 rounded-md bg-surface-2 animate-pulse\" />\n ) : data && data.admins.length === 0 ? (\n <EmptyState icon={<Shield />} title={t('admins.empty')} />\n ) : data ? (\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-40\">{t('admins.col.platform')}</TableHead>\n <TableHead>{t('admins.col.userId')}</TableHead>\n <TableHead className=\"w-24\" />\n </TableRow>\n </TableHeader>\n <TableBody>\n {data.admins.map((a) => (\n <TableRow key={`${a.platform}:${a.userId}`}>\n <TableCell className=\"font-mono\">{a.platform}</TableCell>\n <TableCell className=\"font-mono text-xs\">{a.userId}</TableCell>\n <TableCell>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setRemoveTarget(a)}\n disabled={removeAdmin.isPending}\n aria-label={t('admins.remove.label')}\n >\n <Trash2 className=\"h-3 w-3\" />\n <span className=\"sr-only sm:not-sr-only sm:ml-1\">{t('admins.remove.label')}</span>\n </Button>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n ) : null}\n\n {/* Add form */}\n <form\n onSubmit={(e) => void onAdd(e)}\n className=\"rounded-md border border-border bg-surface p-4\"\n >\n <div className=\"mb-3 text-sm font-medium\">{t('admins.add.title')}</div>\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-[180px_1fr_auto] sm:items-end\">\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"admin-platform\" className=\"text-xs text-text-dim\">\n {t('admins.add.platform')}\n </Label>\n <Input\n id=\"admin-platform\"\n value={platform}\n onChange={(e) => setPlatform(e.target.value)}\n placeholder=\"wechat\"\n className=\"font-mono text-xs\"\n />\n </div>\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"admin-user\" className=\"text-xs text-text-dim\">\n {t('admins.add.userId')}\n </Label>\n <Input\n id=\"admin-user\"\n value={userId}\n onChange={(e) => setUserId(e.target.value)}\n placeholder=\"wxid_abc123\"\n className=\"font-mono text-xs\"\n />\n </div>\n <Button\n type=\"submit\"\n size=\"sm\"\n disabled={addAdmin.isPending || !platform.trim() || !userId.trim()}\n >\n {addAdmin.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <UserPlus className=\"h-4 w-4\" />}\n {t('admins.add.submit')}\n </Button>\n </div>\n </form>\n\n <ConfirmDialog\n open={removeTarget != null}\n onOpenChange={(open) => { if (!open) setRemoveTarget(null) }}\n title={t('admins.remove.confirmTitle')}\n description={t('admins.remove.confirmDescription')}\n intent=\"danger\"\n confirmLabel={t('admins.remove.label')}\n onConfirm={onConfirmRemove}\n />\n </div>\n )\n}\n"],"names":["Shield","createLucideIcon","UserPlus","SettingsAdminsRoute","t","useTranslation","listQuery","useAdminAllowlist","data","addAdmin","useAddAdmin","removeAdmin","useRemoveAdmin","platform","setPlatform","useState","userId","setUserId","removeTarget","setRemoveTarget","onAdd","e","p","u","toast","err","describeError","onConfirmRemove","jsxs","jsx","Button","Loader2","RefreshCcw","Badge","EmptyState","Table","TableHeader","TableRow","TableHead","TableBody","TableCell","Trash2","Label","Input","ConfirmDialog","open"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{u as A,e as O,j as t,k as F,B as I,L as P,I as k,c as B}from"./index-D1ulN_24.js";import{r as i}from"./react-DlP5eolq.js";import{D as _}from"./data-table-CHGndGOY.js";import{E as U}from"./empty-state-D8kx-FwO.js";import{b as $}from"./use-observability-CHv6H0zQ.js";import{L as q}from"./loader-circle-Bgi0H_iI.js";import{R as z}from"./refresh-ccw-MHrCmmSv.js";import{A as H}from"./activity-SXgxjjhd.js";import"./table-Bmwe7n4n.js";import"./arrow-up-Byeo8HHt.js";import"./arrow-down-Dhsj-A0i.js";import"./useQuery-Bt7Ty7IO.js";const G=300;function nt(){const{t:e}=A(["observability","common"]),[s,d]=O(),c=Math.max(1,Number(s.get("days"))||7),n=s.get("agent")??"",l=s.get("platform")??"",r=s.get("user")??"",o=s.get("intent")??"",[u,j]=i.useState(n),[x,b]=i.useState(l),[f,w]=i.useState(r),[h,C]=i.useState(o);i.useEffect(()=>{j(n)},[n]),i.useEffect(()=>{b(l)},[l]),i.useEffect(()=>{w(r)},[r]),i.useEffect(()=>{C(o)},[o]),i.useEffect(()=>{const a=window.setTimeout(()=>{R({agent:u||null,platform:x||null,user:f||null,intent:h||null})},G);return()=>window.clearTimeout(a)},[u,x,f,h]);const E=i.useMemo(()=>({days:c,limit:200,...n?{agent:n}:{},...l?{platform:l}:{},...r?{user:r}:{},...o?{intent:o}:{}}),[c,n,l,r,o]),{data:v,isLoading:S,isFetching:y,refetch:M}=$(E),L=v?.invocations??[],p=v?.stats;function R(a){const g=new URLSearchParams(s);for(const[D,N]of Object.entries(a))N==null||N===""?g.delete(D):g.set(D,N);d(g,{replace:!0})}const T=i.useMemo(()=>[{id:"ts",header:e("audit.col.ts"),cell:a=>t.jsx("span",{className:"text-text-dim text-xs tabular-nums",children:J(a.ts)}),headClassName:"w-32"},{id:"agent",header:e("audit.col.agent"),cell:a=>t.jsx("span",{className:"font-medium",children:a.agent}),headClassName:"w-32"},{id:"platform",header:e("audit.col.platform"),cell:a=>t.jsx("span",{className:"text-text-dim",children:a.platform}),headClassName:"w-24",hideOnMobile:!0},{id:"user",header:e("audit.col.user"),cell:a=>t.jsx("span",{className:"font-mono text-xs text-text-dim line-clamp-1",children:a.user_id}),headClassName:"w-32",hideOnMobile:!0},{id:"intent",header:e("audit.col.intent"),cell:a=>t.jsx("span",{className:"text-text-dim line-clamp-1",children:a.intent||"—"}),asCardTitle:!0},{id:"duration",header:e("audit.col.duration"),cell:a=>t.jsxs("span",{className:"tabular-nums text-text-dim",children:[Math.round(a.duration_ms),"ms"]}),headClassName:"w-20"},{id:"cost",header:e("audit.col.cost"),cell:a=>t.jsxs("span",{className:"tabular-nums text-text-dim",children:["$",a.cost.toFixed(4)]}),headClassName:"w-24",hideOnMobile:!0},{id:"outcome",header:e("audit.col.outcome"),cell:a=>t.jsx(F,{variant:a.success?"success":"danger",title:a.error??"",children:a.success?e("audit.outcome.ok"):e("audit.outcome.fail")}),headClassName:"w-20"}],[e]);return t.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[t.jsx("header",{className:"flex flex-col gap-1",children:t.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[t.jsx("h1",{className:"text-xl font-semibold",children:e("audit.title")}),t.jsxs(I,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>M(),disabled:y,"aria-label":e("actions.refresh",{ns:"common"}),children:[y?t.jsx(q,{className:"h-4 w-4 animate-spin"}):t.jsx(z,{className:"h-4 w-4"}),t.jsx("span",{className:"hidden sm:inline",children:e("actions.refresh",{ns:"common"})})]})]})}),p&&t.jsxs("div",{className:"flex flex-wrap items-center gap-3 text-sm",children:[t.jsxs("span",{className:"text-text-dim",children:[e("audit.stats.total"),": ",t.jsx("span",{className:"tabular-nums font-medium text-text",children:p.total})]}),t.jsxs("span",{className:"text-text-dim",children:[e("audit.stats.totalCost"),": ",t.jsxs("span",{className:"tabular-nums font-medium text-text",children:["$",p.totalCost.toFixed(4)]})]})]}),t.jsxs("div",{className:"grid grid-cols-2 gap-2 sm:grid-cols-4",children:[t.jsx(m,{id:"agent",label:e("audit.filter.agent"),value:u,onChange:j}),t.jsx(m,{id:"platform",label:e("audit.filter.platform"),value:x,onChange:b}),t.jsx(m,{id:"user",label:e("audit.filter.user"),value:f,onChange:w}),t.jsx(m,{id:"intent",label:e("audit.filter.intent"),value:h,onChange:C})]}),t.jsx(_,{columns:T,rows:L,getRowId:a=>String(a.id),loading:S,emptyState:t.jsx(U,{icon:t.jsx(H,{}),title:e("audit.empty.title"),description:e("audit.empty.description")})})]})}function m({id:e,label:s,value:d,onChange:c}){return t.jsxs("div",{className:"flex flex-col gap-1",children:[t.jsx(P,{htmlFor:e,className:"text-xs text-text-dim",children:s}),t.jsx(k,{id:e,value:d,onChange:n=>c(n.target.value),className:B("h-9")})]})}function J(e){try{const s=new Date(e);return Number.isNaN(s.getTime())?e:s.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return e}}export{nt as default};
|
|
2
|
-
//# sourceMappingURL=audit-DshxCHuP.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import{n as E,u as R,ah as A,l as d,j as e,B as m,c as p,ai as B,aj as D,ak as M,a0 as H,k as L}from"./index-D1ulN_24.js";import{r as l}from"./react-DlP5eolq.js";import{C as z}from"./chevron-left-CTwCYqyt.js";import{A as I}from"./arrow-down-Dhsj-A0i.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 F=E("EllipsisVertical",[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"12",cy:"5",r:"1",key:"gxeob9"}],["circle",{cx:"12",cy:"19",r:"1",key:"lyex9k"}]]),O={open:"bg-success",connecting:"bg-warning animate-pulse",closed:"bg-text-muted",error:"bg-danger"};function U(){const{t:a}=R(["chat","common"]),{state:s,send:g,switchAgent:b,approvalClick:f,newConversation:v,clearError:h}=A(),[o,x]=l.useState(""),[j,c]=l.useState(!1),[w,y]=l.useState(!1),i=l.useRef(null),u=l.useRef(null),N=l.useRef(null);l.useEffect(()=>{const t=i.current;!t||t.scrollHeight-t.scrollTop-t.clientHeight>200&&s.currentReplyId==null||requestAnimationFrame(()=>{t.scrollTop=t.scrollHeight})},[s.messages,s.currentReplyId]),l.useEffect(()=>{const t=i.current;if(!t)return;const n=()=>{const r=t.scrollHeight-t.scrollTop-t.clientHeight;y(r>200)};return t.addEventListener("scroll",n,{passive:!0}),n(),()=>t.removeEventListener("scroll",n)},[]),l.useEffect(()=>{s.error&&(d.error(s.error),h())},[s.error,h]),l.useEffect(()=>{const t=u.current;t&&(t.style.height="auto",t.style.height=`${Math.min(t.scrollHeight,24*6+16)}px`)},[o]);function k(t){t?.preventDefault();const n=o.trim();if(n){if(s.status!=="open"){d.error(a("chat.notConnected",{defaultValue:"Not connected. Reconnecting…"}));return}g(n),x(""),requestAnimationFrame(()=>u.current?.focus())}}function S(t){t.nativeEvent.isComposing||t.keyCode}function C(){const t=i.current;t&&t.scrollTo({top:t.scrollHeight,behavior:"smooth"})}function V(){fetch("/api/auth/logout",{method:"POST"}).finally(()=>{try{localStorage.removeItem("agim_token")}catch{}window.location.replace("/login")})}return e.jsxs("div",{className:"flex h-dvh flex-col bg-bg",children:[e.jsxs("header",{className:"flex items-center gap-2 border-b border-border bg-surface px-3 py-2",style:{paddingTop:"calc(env(safe-area-inset-top) + 0.5rem)"},children:[e.jsx(m,{variant:"ghost",size:"sm","aria-label":a("chat.back",{defaultValue:"Back"}),onClick:()=>window.history.length>1?window.history.back():window.location.assign("/"),className:"h-9 w-9 p-0",children:e.jsx(z,{className:"h-5 w-5"})}),e.jsxs("div",{className:"flex min-w-0 flex-1 flex-col items-center",children:[e.jsx("span",{className:"truncate text-sm font-semibold",children:a("chat.mobileTitle",{defaultValue:"agim chat"})}),e.jsxs("span",{className:"flex items-center gap-1.5 text-[11px] text-text-dim",children:[e.jsx("span",{className:p("inline-block h-1.5 w-1.5 rounded-full",O[s.status])}),e.jsx("span",{children:s.agent}),e.jsx("span",{children:"·"}),e.jsx("span",{children:s.status})]})]}),e.jsxs("div",{className:"relative",children:[e.jsx(m,{variant:"ghost",size:"sm","aria-label":a("chat.menu",{defaultValue:"Menu"}),onClick:()=>c(t=>!t),className:"h-9 w-9 p-0",children:e.jsx(F,{className:"h-5 w-5"})}),j&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"fixed inset-0 z-30",onClick:()=>c(!1),"aria-hidden":!0}),e.jsxs("div",{className:"absolute right-0 top-10 z-40 w-56 rounded-md border border-border bg-surface p-2 shadow-lg",role:"menu",children:[e.jsx("div",{className:"px-2 py-1 text-[11px] uppercase text-text-dim",children:a("chat.agent",{defaultValue:"Agent"})}),e.jsx("div",{className:"px-1 pb-2",children:e.jsx(B,{agents:s.agents,value:s.agent,onChange:t=>{b(t),c(!1)}})}),e.jsx("button",{type:"button",className:"block w-full rounded px-2 py-2 text-left text-sm hover:bg-surface-hover disabled:opacity-50",disabled:s.status!=="open",onClick:()=>{v(),c(!1),d.success(a("chat.newConvToast",{defaultValue:"Started a new conversation"}))},children:a("chat.newConv",{defaultValue:"New conversation"})}),e.jsx("button",{type:"button",className:"block w-full rounded px-2 py-2 text-left text-sm hover:bg-surface-hover",onClick:V,children:a("chat.logout",{defaultValue:"Log out"})})]})]})]})]}),e.jsx("div",{ref:i,className:"flex-1 overflow-y-auto",children:e.jsxs("div",{className:"flex flex-col gap-2 px-3 py-3",children:[s.messages.length===0&&s.status==="open"&&e.jsxs("div",{className:"flex flex-col items-center gap-2 py-16 text-center",children:[e.jsx("div",{className:"flex h-12 w-12 items-center justify-center rounded-full bg-surface-2 text-2xl",children:"💬"}),e.jsx("h2",{className:"text-base font-semibold",children:a("chat.welcomeTitle",{defaultValue:"Start a conversation"})}),e.jsx("p",{className:"max-w-xs text-sm text-text-dim",children:a("chat.welcomeBodyMobile",{defaultValue:"Type a message below. Switch agent or start over from the ⋯ menu."})})]}),s.messages.length===0&&s.status!=="open"&&e.jsx("div",{className:"grid place-items-center py-16 text-center",children:e.jsx("p",{className:"text-sm text-text-dim",children:s.status==="connecting"?a("chat.connecting",{defaultValue:"Connecting to agim…"}):a("chat.disconnected",{defaultValue:"Disconnected. Reconnecting automatically."})})}),s.messages.filter(t=>!t.approval).map(t=>e.jsx(D,{msg:t,onApprove:(n,r,T)=>f(n,r,T)},t.id))]})}),w&&e.jsx("button",{type:"button",onClick:C,className:"absolute bottom-24 left-1/2 z-20 -translate-x-1/2 rounded-full border border-border bg-surface p-2 shadow-md","aria-label":a("chat.scrollDown",{defaultValue:"Scroll to bottom"}),children:e.jsx(I,{className:"h-4 w-4"})}),e.jsx(M,{approvals:s.pendingApprovals,onApprove:(t,n,r)=>f(t,n,r)}),e.jsxs("form",{onSubmit:k,className:"sticky bottom-0 border-t border-border bg-surface px-3 py-2",style:{paddingBottom:"calc(env(safe-area-inset-bottom) + 0.5rem)"},children:[e.jsxs("div",{ref:N,className:"flex items-end gap-2",children:[e.jsx("textarea",{ref:u,value:o,onChange:t=>x(t.target.value),onKeyDown:S,placeholder:a("chat.inputPlaceholderMobile",{defaultValue:"Message…"}),rows:1,className:p("flex-1 resize-none rounded-2xl border border-border bg-bg","px-3 py-2 text-[15px] leading-6","focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-1 focus:ring-offset-bg")}),e.jsx(m,{type:"submit",disabled:!o.trim()||s.status!=="open","aria-label":a("chat.send",{defaultValue:"Send"}),className:"h-10 w-10 shrink-0 rounded-full p-0",children:e.jsx(H,{className:"h-4 w-4"})})]}),s.currentReplyId&&e.jsx("div",{className:"mt-2 flex items-center gap-2",children:e.jsx(L,{variant:"info",children:a("chat.streaming",{defaultValue:"… streaming"})})})]})]})}export{U as default};
|
|
7
|
-
//# sourceMappingURL=chat-CY4JriM5.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"chat-CY4JriM5.js","sources":["../../node_modules/lucide-react/dist/esm/icons/ellipsis-vertical.js","../../src/routes/m/chat.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst EllipsisVertical = createLucideIcon(\"EllipsisVertical\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"1\", key: \"41hilf\" }],\n [\"circle\", { cx: \"12\", cy: \"5\", r: \"1\", key: \"gxeob9\" }],\n [\"circle\", { cx: \"12\", cy: \"19\", r: \"1\", key: \"lyex9k\" }]\n]);\n\nexport { EllipsisVertical as default };\n//# sourceMappingURL=ellipsis-vertical.js.map\n","/**\n * /m/chat — agim mobile chat surface (v1.2.129).\n *\n * Reuses the desktop useChat() hook + MessageBubble + ApprovalDock so\n * the feature matrix matches /chat exactly (send, stream, switch agent,\n * approvals, new conversation, status indicator). Only the chrome\n * changes — the page lives OUTSIDE the admin shell, has a single\n * mobile-tuned topbar, and the input bar uses pb-safe to clear the\n * iOS home indicator + the soft keyboard.\n *\n * Layout reference: Claude Code mobile (the screenshot shared with the\n * v1.2.129 spec). Five elements: back chevron + thread title with\n * subtitle + ⋯ action menu, scroll list with auto-scroll-to-bottom,\n * floating \"↓\" when the user scrolled up, approval dock above input,\n * bottom input with pb-safe.\n */\n\nimport { useEffect, useRef, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { ArrowDown, ChevronLeft, MoreVertical, Send } from 'lucide-react'\nimport { toast } from 'sonner'\n\nimport { useChat } from '@/hooks/use-chat'\nimport { Button } from '@/components/ui/button'\nimport { Badge } from '@/components/ui/badge'\nimport { MessageBubble } from '@/components/chat/message-bubble'\nimport { ApprovalDock } from '@/components/chat/approval-dock'\nimport { AgentPicker } from '@/components/chat/agent-picker'\nimport { cn } from '@/lib/utils'\n\nconst STATUS_STYLES: Record<string, string> = {\n open: 'bg-success',\n connecting: 'bg-warning animate-pulse',\n closed: 'bg-text-muted',\n error: 'bg-danger',\n}\n\nexport default function MobileChatRoute(): JSX.Element {\n const { t } = useTranslation(['chat', 'common'])\n const {\n state, send, switchAgent, approvalClick, newConversation, clearError,\n } = useChat()\n const [input, setInput] = useState('')\n const [menuOpen, setMenuOpen] = useState(false)\n const [showScrollDown, setShowScrollDown] = useState(false)\n const listRef = useRef<HTMLDivElement>(null)\n const inputRef = useRef<HTMLTextAreaElement>(null)\n const textareaWrapperRef = useRef<HTMLDivElement>(null)\n\n // Auto-scroll to bottom on new messages OR streaming chunk. Same\n // pinch-tolerance as the desktop route: if the user scrolled up\n // more than 200px we hold position (until they tap the ↓ button).\n useEffect(() => {\n const el = listRef.current\n if (!el) return\n const distFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight\n if (distFromBottom > 200 && state.currentReplyId == null) return\n requestAnimationFrame(() => {\n el.scrollTop = el.scrollHeight\n })\n }, [state.messages, state.currentReplyId])\n\n // Floating \"scroll to bottom\" pill — show iff the user is more than\n // 200px above the bottom. Re-evaluate on scroll + on every list\n // mutation (covered by the auto-scroll effect above).\n useEffect(() => {\n const el = listRef.current\n if (!el) return\n const onScroll = (): void => {\n const dist = el.scrollHeight - el.scrollTop - el.clientHeight\n setShowScrollDown(dist > 200)\n }\n el.addEventListener('scroll', onScroll, { passive: true })\n onScroll()\n return () => el.removeEventListener('scroll', onScroll)\n }, [])\n\n // Surface WS errors as toasts (and clear so they don't re-fire on\n // every render). Same pattern as the desktop route.\n useEffect(() => {\n if (!state.error) return\n toast.error(state.error)\n clearError()\n }, [state.error, clearError])\n\n // Auto-grow the textarea up to 6 lines, then scroll.\n useEffect(() => {\n const ta = inputRef.current\n if (!ta) return\n ta.style.height = 'auto'\n ta.style.height = `${Math.min(ta.scrollHeight, 24 * 6 + 16)}px`\n }, [input])\n\n function onSubmit(e?: React.FormEvent): void {\n e?.preventDefault()\n const v = input.trim()\n if (!v) return\n if (state.status !== 'open') {\n toast.error(t('chat.notConnected', { defaultValue: 'Not connected. Reconnecting…' }))\n return\n }\n send(v)\n setInput('')\n requestAnimationFrame(() => inputRef.current?.focus())\n }\n\n function onKeyDown(e: React.KeyboardEvent<HTMLTextAreaElement>): void {\n // IME-safe: never submit while a Chinese / Japanese / Korean\n // composition span is active. Same guard as /chat — see comments\n // there for the keyCode === 229 legacy fallback rationale.\n const ne = e.nativeEvent as KeyboardEvent & { isComposing?: boolean }\n if (ne.isComposing || e.keyCode === 229) return\n // Mobile: Enter inserts newline, send is the explicit button.\n // Most mobile keyboards expose a separate Send key only via the\n // virtual keyboard's submit action — which already triggers our\n // form submit on iOS Safari. Don't hijack Enter.\n }\n\n function onScrollToBottom(): void {\n const el = listRef.current\n if (!el) return\n el.scrollTo({ top: el.scrollHeight, behavior: 'smooth' })\n }\n\n function onLogout(): void {\n void fetch('/api/auth/logout', { method: 'POST' }).finally(() => {\n try { localStorage.removeItem('agim_token') } catch { /* noop */ }\n // Cookie was cleared by the server, but force a fresh load too.\n window.location.replace('/login')\n })\n }\n\n return (\n <div className=\"flex h-dvh flex-col bg-bg\">\n {/* Topbar — flat, single row. Left: back chevron. Center: title\n + subtitle. Right: actions menu. Topbar is bg-surface to give\n it a paper-feel vs. the bg behind messages. */}\n <header\n className=\"flex items-center gap-2 border-b border-border bg-surface px-3 py-2\"\n style={{ paddingTop: 'calc(env(safe-area-inset-top) + 0.5rem)' }}\n >\n <Button\n variant=\"ghost\" size=\"sm\"\n aria-label={t('chat.back', { defaultValue: 'Back' })}\n onClick={() => window.history.length > 1 ? window.history.back() : window.location.assign('/')}\n className=\"h-9 w-9 p-0\"\n >\n <ChevronLeft className=\"h-5 w-5\" />\n </Button>\n <div className=\"flex min-w-0 flex-1 flex-col items-center\">\n <span className=\"truncate text-sm font-semibold\">\n {t('chat.mobileTitle', { defaultValue: 'agim chat' })}\n </span>\n <span className=\"flex items-center gap-1.5 text-[11px] text-text-dim\">\n <span\n className={cn('inline-block h-1.5 w-1.5 rounded-full', STATUS_STYLES[state.status])}\n />\n <span>{state.agent}</span>\n <span>·</span>\n <span>{state.status}</span>\n </span>\n </div>\n <div className=\"relative\">\n <Button\n variant=\"ghost\" size=\"sm\"\n aria-label={t('chat.menu', { defaultValue: 'Menu' })}\n onClick={() => setMenuOpen((v) => !v)}\n className=\"h-9 w-9 p-0\"\n >\n <MoreVertical className=\"h-5 w-5\" />\n </Button>\n {menuOpen && (\n <>\n <div\n className=\"fixed inset-0 z-30\"\n onClick={() => setMenuOpen(false)}\n aria-hidden\n />\n <div\n className=\"absolute right-0 top-10 z-40 w-56 rounded-md border border-border bg-surface p-2 shadow-lg\"\n role=\"menu\"\n >\n <div className=\"px-2 py-1 text-[11px] uppercase text-text-dim\">\n {t('chat.agent', { defaultValue: 'Agent' })}\n </div>\n <div className=\"px-1 pb-2\">\n <AgentPicker\n agents={state.agents}\n value={state.agent}\n onChange={(a) => { switchAgent(a); setMenuOpen(false) }}\n />\n </div>\n <button\n type=\"button\"\n className=\"block w-full rounded px-2 py-2 text-left text-sm hover:bg-surface-hover disabled:opacity-50\"\n disabled={state.status !== 'open'}\n onClick={() => {\n newConversation()\n setMenuOpen(false)\n toast.success(t('chat.newConvToast', { defaultValue: 'Started a new conversation' }))\n }}\n >\n {t('chat.newConv', { defaultValue: 'New conversation' })}\n </button>\n <button\n type=\"button\"\n className=\"block w-full rounded px-2 py-2 text-left text-sm hover:bg-surface-hover\"\n onClick={onLogout}\n >\n {t('chat.logout', { defaultValue: 'Log out' })}\n </button>\n </div>\n </>\n )}\n </div>\n </header>\n\n {/* Message list */}\n <div ref={listRef} className=\"flex-1 overflow-y-auto\">\n <div className=\"flex flex-col gap-2 px-3 py-3\">\n {state.messages.length === 0 && state.status === 'open' && (\n <div className=\"flex flex-col items-center gap-2 py-16 text-center\">\n <div className=\"flex h-12 w-12 items-center justify-center rounded-full bg-surface-2 text-2xl\">\n 💬\n </div>\n <h2 className=\"text-base font-semibold\">\n {t('chat.welcomeTitle', { defaultValue: 'Start a conversation' })}\n </h2>\n <p className=\"max-w-xs text-sm text-text-dim\">\n {t('chat.welcomeBodyMobile', {\n defaultValue: 'Type a message below. Switch agent or start over from the ⋯ menu.',\n })}\n </p>\n </div>\n )}\n {state.messages.length === 0 && state.status !== 'open' && (\n <div className=\"grid place-items-center py-16 text-center\">\n <p className=\"text-sm text-text-dim\">\n {state.status === 'connecting'\n ? t('chat.connecting', { defaultValue: 'Connecting to agim…' })\n : t('chat.disconnected', {\n defaultValue: 'Disconnected. Reconnecting automatically.',\n })}\n </p>\n </div>\n )}\n {state.messages\n .filter((m) => !m.approval)\n .map((m) => (\n <MessageBubble\n key={m.id}\n msg={m}\n onApprove={(mid, reqId, choice) => approvalClick(mid, reqId, choice)}\n />\n ))}\n </div>\n </div>\n\n {/* Floating scroll-to-bottom pill. Position keeps it clear of\n the input bar (~80px above bottom). */}\n {showScrollDown && (\n <button\n type=\"button\"\n onClick={onScrollToBottom}\n className=\"absolute bottom-24 left-1/2 z-20 -translate-x-1/2 rounded-full border border-border bg-surface p-2 shadow-md\"\n aria-label={t('chat.scrollDown', { defaultValue: 'Scroll to bottom' })}\n >\n <ArrowDown className=\"h-4 w-4\" />\n </button>\n )}\n\n <ApprovalDock\n approvals={state.pendingApprovals}\n onApprove={(mid, reqId, choice) => approvalClick(mid, reqId, choice)}\n />\n\n {/* Input bar — sticky, safe-area aware. */}\n <form\n onSubmit={onSubmit}\n className=\"sticky bottom-0 border-t border-border bg-surface px-3 py-2\"\n style={{ paddingBottom: 'calc(env(safe-area-inset-bottom) + 0.5rem)' }}\n >\n <div ref={textareaWrapperRef} className=\"flex items-end gap-2\">\n <textarea\n ref={inputRef}\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={onKeyDown}\n placeholder={t('chat.inputPlaceholderMobile', {\n defaultValue: 'Message…',\n })}\n rows={1}\n className={cn(\n 'flex-1 resize-none rounded-2xl border border-border bg-bg',\n 'px-3 py-2 text-[15px] leading-6',\n 'focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-1 focus:ring-offset-bg',\n )}\n />\n <Button\n type=\"submit\"\n disabled={!input.trim() || state.status !== 'open'}\n aria-label={t('chat.send', { defaultValue: 'Send' })}\n className=\"h-10 w-10 shrink-0 rounded-full p-0\"\n >\n <Send className=\"h-4 w-4\" />\n </Button>\n </div>\n {state.currentReplyId && (\n <div className=\"mt-2 flex items-center gap-2\">\n <Badge variant=\"info\">\n {t('chat.streaming', { defaultValue: '… streaming' })}\n </Badge>\n </div>\n )}\n </form>\n </div>\n )\n}\n"],"names":["EllipsisVertical","createLucideIcon","STATUS_STYLES","MobileChatRoute","t","useTranslation","state","send","switchAgent","approvalClick","newConversation","clearError","useChat","input","setInput","useState","menuOpen","setMenuOpen","showScrollDown","setShowScrollDown","listRef","useRef","inputRef","textareaWrapperRef","useEffect","el","onScroll","dist","toast","ta","onSubmit","e","v","onKeyDown","onScrollToBottom","onLogout","jsxs","jsx","Button","ChevronLeft","cn","MoreVertical","Fragment","AgentPicker","a","m","MessageBubble","mid","reqId","choice","ArrowDown","ApprovalDock","Send","Badge"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import{n as t}from"./index-D1ulN_24.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 h=t("ChevronRight",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]]);export{h as C};
|
|
7
|
-
//# sourceMappingURL=chevron-right-CDiFYKGo.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{u as j,j as a,B as r}from"./index-D1ulN_24.js";import{r as n}from"./react-DlP5eolq.js";import{D as y,a as D,b,c as g,d as h,e as p}from"./dialog-xeyu8dCf.js";function C({open:c,onOpenChange:t,title:d,description:e,confirmLabel:u,cancelLabel:f,intent:m="default",onConfirm:l}){const{t:i}=j("common"),[s,o]=n.useState(!1),x=n.useCallback(async()=>{o(!0);try{await l(),t(!1)}catch{}finally{o(!1)}},[l,t]);return a.jsx(y,{open:c,onOpenChange:s?()=>{}:t,children:a.jsxs(D,{children:[a.jsxs(b,{children:[a.jsx(g,{children:d}),e&&a.jsx(h,{children:e})]}),a.jsxs(p,{children:[a.jsx(r,{type:"button",variant:"secondary",onClick:()=>t(!1),disabled:s,children:f??i("actions.cancel")}),a.jsx(r,{type:"button",variant:m==="danger"?"destructive":"default",onClick:x,disabled:s,"aria-busy":s,children:s?i("states.saving"):u??i("actions.confirm")})]})]})})}C.displayName="ConfirmDialog";export{C};
|
|
2
|
-
//# sourceMappingURL=confirm-dialog-CMWuyC3w.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{z as G,j as n,v,G as R,H,P as g,w as p,s as U,x as C,J as V,a1 as X,Q as J,M as K,U as Q,V as Y,X as Z,c as u}from"./index-D1ulN_24.js";import{r as l}from"./react-DlP5eolq.js";import{X as q}from"./x-DXACg96C.js";var x="Dialog",[P]=U(x),[B,c]=P(x),w=e=>{const{__scopeDialog:t,children:a,open:r,defaultOpen:s,onOpenChange:o,modal:i=!0}=e,d=l.useRef(null),O=l.useRef(null),[$,D]=G({prop:r,defaultProp:s??!1,onChange:o,caller:x});return n.jsx(B,{scope:t,triggerRef:d,contentRef:O,contentId:v(),titleId:v(),descriptionId:v(),open:$,onOpenChange:D,onOpenToggle:l.useCallback(()=>D(z=>!z),[D]),modal:i,children:a})};w.displayName=x;var E="DialogTrigger",W=l.forwardRef((e,t)=>{const{__scopeDialog:a,...r}=e,s=c(E,a),o=C(t,s.triggerRef);return n.jsx(g.button,{type:"button","aria-haspopup":"dialog","aria-expanded":s.open,"aria-controls":s.open?s.contentId:void 0,"data-state":j(s.open),...r,ref:o,onClick:p(e.onClick,s.onOpenToggle)})});W.displayName=E;var h="DialogPortal",[ee,I]=P(h,{forceMount:void 0}),A=e=>{const{__scopeDialog:t,forceMount:a,children:r,container:s}=e,o=c(h,t);return n.jsx(ee,{scope:t,forceMount:a,children:l.Children.map(r,i=>n.jsx(R,{present:a||o.open,children:n.jsx(H,{asChild:!0,container:s,children:i})}))})};A.displayName=h;var m="DialogOverlay",y=l.forwardRef((e,t)=>{const a=I(m,e.__scopeDialog),{forceMount:r=a.forceMount,...s}=e,o=c(m,e.__scopeDialog);return o.modal?n.jsx(R,{present:r||o.open,children:n.jsx(oe,{...s,ref:t})}):null});y.displayName=m;var te=Z("DialogOverlay.RemoveScroll"),oe=l.forwardRef((e,t)=>{const{__scopeDialog:a,...r}=e,s=c(m,a),o=X(),i=C(t,o);return n.jsx(J,{as:te,allowPinchZoom:!0,shards:[s.contentRef],children:n.jsx(g.div,{"data-state":j(s.open),...r,ref:i,style:{pointerEvents:"auto",...r.style}})})}),f="DialogContent",N=l.forwardRef((e,t)=>{const a=I(f,e.__scopeDialog),{forceMount:r=a.forceMount,...s}=e,o=c(f,e.__scopeDialog);return n.jsx(R,{present:r||o.open,children:o.modal?n.jsx(ae,{...s,ref:t}):n.jsx(se,{...s,ref:t})})});N.displayName=f;var ae=l.forwardRef((e,t)=>{const a=c(f,e.__scopeDialog),r=l.useRef(null),s=C(t,a.contentRef,r);return l.useEffect(()=>{const o=r.current;if(o)return V(o)},[]),n.jsx(F,{...e,ref:s,trapFocus:a.open,disableOutsidePointerEvents:a.open,onCloseAutoFocus:p(e.onCloseAutoFocus,o=>{o.preventDefault(),a.triggerRef.current?.focus()}),onPointerDownOutside:p(e.onPointerDownOutside,o=>{const i=o.detail.originalEvent,d=i.button===0&&i.ctrlKey===!0;(i.button===2||d)&&o.preventDefault()}),onFocusOutside:p(e.onFocusOutside,o=>o.preventDefault())})}),se=l.forwardRef((e,t)=>{const a=c(f,e.__scopeDialog),r=l.useRef(!1),s=l.useRef(!1);return n.jsx(F,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:o=>{e.onCloseAutoFocus?.(o),o.defaultPrevented||(r.current||a.triggerRef.current?.focus(),o.preventDefault()),r.current=!1,s.current=!1},onInteractOutside:o=>{e.onInteractOutside?.(o),o.defaultPrevented||(r.current=!0,o.detail.originalEvent.type==="pointerdown"&&(s.current=!0));const i=o.target;a.triggerRef.current?.contains(i)&&o.preventDefault(),o.detail.originalEvent.type==="focusin"&&s.current&&o.preventDefault()}})}),F=l.forwardRef((e,t)=>{const{__scopeDialog:a,trapFocus:r,onOpenAutoFocus:s,onCloseAutoFocus:o,...i}=e,d=c(f,a);return K(),n.jsx(n.Fragment,{children:n.jsx(Q,{asChild:!0,loop:!0,trapped:r,onMountAutoFocus:s,onUnmountAutoFocus:o,children:n.jsx(Y,{role:"dialog",id:d.contentId,"aria-describedby":d.descriptionId,"aria-labelledby":d.titleId,"data-state":j(d.open),...i,ref:t,deferPointerDownOutside:!0,onDismiss:()=>d.onOpenChange(!1)})})})}),M="DialogTitle",_=l.forwardRef((e,t)=>{const{__scopeDialog:a,...r}=e,s=c(M,a);return n.jsx(g.h2,{id:s.titleId,...r,ref:t})});_.displayName=M;var T="DialogDescription",b=l.forwardRef((e,t)=>{const{__scopeDialog:a,...r}=e,s=c(T,a);return n.jsx(g.p,{id:s.descriptionId,...r,ref:t})});b.displayName=T;var S="DialogClose",k=l.forwardRef((e,t)=>{const{__scopeDialog:a,...r}=e,s=c(S,a);return n.jsx(g.button,{type:"button",...r,ref:t,onClick:p(e.onClick,()=>s.onOpenChange(!1))})});k.displayName=S;function j(e){return e?"open":"closed"}const ge=w,ne=A,L=l.forwardRef(({className:e,...t},a)=>n.jsx(y,{ref:a,className:u("fixed inset-0 z-50 bg-black/50 backdrop-blur-sm","data-[state=open]:animate-in data-[state=closed]:animate-out","data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",e),...t}));L.displayName=y.displayName;const re=l.forwardRef(({className:e,children:t,...a},r)=>n.jsxs(ne,{children:[n.jsx(L,{}),n.jsxs(N,{ref:r,className:u("fixed left-[50%] top-[50%] z-50 grid w-full max-w-[calc(100vw-2rem)] sm:max-w-lg","translate-x-[-50%] translate-y-[-50%] gap-4","border border-border bg-surface p-4 shadow-lg","rounded-lg","max-h-[85dvh] overflow-y-auto pb-[calc(env(safe-area-inset-bottom)+1.5rem)]","duration-200","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","data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]","data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",e),...a,children:[t,n.jsx(k,{className:u("absolute right-4 top-4 rounded-md p-1","text-text-dim hover:bg-surface-hover hover:text-text","focus:outline-none focus:ring-2 focus:ring-accent","tap-target","disabled:pointer-events-none"),"aria-label":"Close",children:n.jsx(q,{className:"h-4 w-4"})})]})]}));re.displayName=N.displayName;const le=({className:e,...t})=>n.jsx("div",{className:u("flex flex-col gap-1.5 text-left",e),...t});le.displayName="DialogHeader";const ie=({className:e,...t})=>n.jsx("div",{className:u("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",e),...t});ie.displayName="DialogFooter";const ce=l.forwardRef(({className:e,...t},a)=>n.jsx(_,{ref:a,className:u("text-lg font-semibold leading-snug",e),...t}));ce.displayName=_.displayName;const de=l.forwardRef(({className:e,...t},a)=>n.jsx(b,{ref:a,className:u("text-sm text-text-dim",e),...t}));de.displayName=b.displayName;export{ge as D,re as a,le as b,ce as c,de as d,ie as e};
|
|
2
|
-
//# sourceMappingURL=dialog-xeyu8dCf.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dialog-xeyu8dCf.js","sources":["../../node_modules/@radix-ui/react-dialog/dist/index.mjs","../../src/components/ui/dialog.tsx"],"sourcesContent":["\"use client\";\n\n// src/dialog.tsx\nimport * as React from \"react\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { createContextScope } from \"@radix-ui/react-context\";\nimport { useId } from \"@radix-ui/react-id\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { DismissableLayer, useDismissableLayerSurface } from \"@radix-ui/react-dismissable-layer\";\nimport { FocusScope } from \"@radix-ui/react-focus-scope\";\nimport { Portal as PortalPrimitive } from \"@radix-ui/react-portal\";\nimport { Presence } from \"@radix-ui/react-presence\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { useFocusGuards } from \"@radix-ui/react-focus-guards\";\nimport { RemoveScroll } from \"react-remove-scroll\";\nimport { hideOthers } from \"aria-hidden\";\nimport { createSlot } from \"@radix-ui/react-slot\";\nimport { Fragment, jsx } from \"react/jsx-runtime\";\nvar DIALOG_NAME = \"Dialog\";\nvar [createDialogContext, createDialogScope] = createContextScope(DIALOG_NAME);\nvar [DialogProvider, useDialogContext] = createDialogContext(DIALOG_NAME);\nvar Dialog = (props) => {\n const {\n __scopeDialog,\n children,\n open: openProp,\n defaultOpen,\n onOpenChange,\n modal = true\n } = props;\n const triggerRef = React.useRef(null);\n const contentRef = React.useRef(null);\n const [open, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen ?? false,\n onChange: onOpenChange,\n caller: DIALOG_NAME\n });\n return /* @__PURE__ */ jsx(\n DialogProvider,\n {\n scope: __scopeDialog,\n triggerRef,\n contentRef,\n contentId: useId(),\n titleId: useId(),\n descriptionId: useId(),\n open,\n onOpenChange: setOpen,\n onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),\n modal,\n children\n }\n );\n};\nDialog.displayName = DIALOG_NAME;\nvar TRIGGER_NAME = \"DialogTrigger\";\nvar DialogTrigger = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...triggerProps } = props;\n const context = useDialogContext(TRIGGER_NAME, __scopeDialog);\n const composedTriggerRef = useComposedRefs(forwardedRef, context.triggerRef);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n \"aria-haspopup\": \"dialog\",\n \"aria-expanded\": context.open,\n \"aria-controls\": context.open ? context.contentId : void 0,\n \"data-state\": getState(context.open),\n ...triggerProps,\n ref: composedTriggerRef,\n onClick: composeEventHandlers(props.onClick, context.onOpenToggle)\n }\n );\n }\n);\nDialogTrigger.displayName = TRIGGER_NAME;\nvar PORTAL_NAME = \"DialogPortal\";\nvar [PortalProvider, usePortalContext] = createDialogContext(PORTAL_NAME, {\n forceMount: void 0\n});\nvar DialogPortal = (props) => {\n const { __scopeDialog, forceMount, children, container } = props;\n const context = useDialogContext(PORTAL_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopeDialog, forceMount, children: React.Children.map(children, (child) => /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(PortalPrimitive, { asChild: true, container, children: child }) })) });\n};\nDialogPortal.displayName = PORTAL_NAME;\nvar OVERLAY_NAME = \"DialogOverlay\";\nvar DialogOverlay = React.forwardRef(\n (props, forwardedRef) => {\n const portalContext = usePortalContext(OVERLAY_NAME, props.__scopeDialog);\n const { forceMount = portalContext.forceMount, ...overlayProps } = props;\n const context = useDialogContext(OVERLAY_NAME, props.__scopeDialog);\n return context.modal ? /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(DialogOverlayImpl, { ...overlayProps, ref: forwardedRef }) }) : null;\n }\n);\nDialogOverlay.displayName = OVERLAY_NAME;\nvar Slot = createSlot(\"DialogOverlay.RemoveScroll\");\nvar DialogOverlayImpl = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...overlayProps } = props;\n const context = useDialogContext(OVERLAY_NAME, __scopeDialog);\n const registerDismissableSurface = useDismissableLayerSurface();\n const composedRefs = useComposedRefs(forwardedRef, registerDismissableSurface);\n return (\n // Make sure `Content` is scrollable even when it doesn't live inside `RemoveScroll`\n // ie. when `Overlay` and `Content` are siblings\n /* @__PURE__ */ jsx(RemoveScroll, { as: Slot, allowPinchZoom: true, shards: [context.contentRef], children: /* @__PURE__ */ jsx(\n Primitive.div,\n {\n \"data-state\": getState(context.open),\n ...overlayProps,\n ref: composedRefs,\n style: { pointerEvents: \"auto\", ...overlayProps.style }\n }\n ) })\n );\n }\n);\nvar CONTENT_NAME = \"DialogContent\";\nvar DialogContent = React.forwardRef(\n (props, forwardedRef) => {\n const portalContext = usePortalContext(CONTENT_NAME, props.__scopeDialog);\n const { forceMount = portalContext.forceMount, ...contentProps } = props;\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: context.modal ? /* @__PURE__ */ jsx(DialogContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(DialogContentNonModal, { ...contentProps, ref: forwardedRef }) });\n }\n);\nDialogContent.displayName = CONTENT_NAME;\nvar DialogContentModal = React.forwardRef(\n (props, forwardedRef) => {\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n const contentRef = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, context.contentRef, contentRef);\n React.useEffect(() => {\n const content = contentRef.current;\n if (content) return hideOthers(content);\n }, []);\n return /* @__PURE__ */ jsx(\n DialogContentImpl,\n {\n ...props,\n ref: composedRefs,\n trapFocus: context.open,\n disableOutsidePointerEvents: context.open,\n onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {\n event.preventDefault();\n context.triggerRef.current?.focus();\n }),\n onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => {\n const originalEvent = event.detail.originalEvent;\n const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;\n const isRightClick = originalEvent.button === 2 || ctrlLeftClick;\n if (isRightClick) event.preventDefault();\n }),\n onFocusOutside: composeEventHandlers(\n props.onFocusOutside,\n (event) => event.preventDefault()\n )\n }\n );\n }\n);\nvar DialogContentNonModal = React.forwardRef(\n (props, forwardedRef) => {\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n const hasInteractedOutsideRef = React.useRef(false);\n const hasPointerDownOutsideRef = React.useRef(false);\n return /* @__PURE__ */ jsx(\n DialogContentImpl,\n {\n ...props,\n ref: forwardedRef,\n trapFocus: false,\n disableOutsidePointerEvents: false,\n onCloseAutoFocus: (event) => {\n props.onCloseAutoFocus?.(event);\n if (!event.defaultPrevented) {\n if (!hasInteractedOutsideRef.current) context.triggerRef.current?.focus();\n event.preventDefault();\n }\n hasInteractedOutsideRef.current = false;\n hasPointerDownOutsideRef.current = false;\n },\n onInteractOutside: (event) => {\n props.onInteractOutside?.(event);\n if (!event.defaultPrevented) {\n hasInteractedOutsideRef.current = true;\n if (event.detail.originalEvent.type === \"pointerdown\") {\n hasPointerDownOutsideRef.current = true;\n }\n }\n const target = event.target;\n const targetIsTrigger = context.triggerRef.current?.contains(target);\n if (targetIsTrigger) event.preventDefault();\n if (event.detail.originalEvent.type === \"focusin\" && hasPointerDownOutsideRef.current) {\n event.preventDefault();\n }\n }\n }\n );\n }\n);\nvar DialogContentImpl = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, trapFocus, onOpenAutoFocus, onCloseAutoFocus, ...contentProps } = props;\n const context = useDialogContext(CONTENT_NAME, __scopeDialog);\n useFocusGuards();\n return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(\n FocusScope,\n {\n asChild: true,\n loop: true,\n trapped: trapFocus,\n onMountAutoFocus: onOpenAutoFocus,\n onUnmountAutoFocus: onCloseAutoFocus,\n children: /* @__PURE__ */ jsx(\n DismissableLayer,\n {\n role: \"dialog\",\n id: context.contentId,\n \"aria-describedby\": context.descriptionId,\n \"aria-labelledby\": context.titleId,\n \"data-state\": getState(context.open),\n ...contentProps,\n ref: forwardedRef,\n deferPointerDownOutside: true,\n onDismiss: () => context.onOpenChange(false)\n }\n )\n }\n ) });\n }\n);\nvar TITLE_NAME = \"DialogTitle\";\nvar DialogTitle = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...titleProps } = props;\n const context = useDialogContext(TITLE_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(Primitive.h2, { id: context.titleId, ...titleProps, ref: forwardedRef });\n }\n);\nDialogTitle.displayName = TITLE_NAME;\nvar DESCRIPTION_NAME = \"DialogDescription\";\nvar DialogDescription = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...descriptionProps } = props;\n const context = useDialogContext(DESCRIPTION_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(Primitive.p, { id: context.descriptionId, ...descriptionProps, ref: forwardedRef });\n }\n);\nDialogDescription.displayName = DESCRIPTION_NAME;\nvar CLOSE_NAME = \"DialogClose\";\nvar DialogClose = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...closeProps } = props;\n const context = useDialogContext(CLOSE_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n ...closeProps,\n ref: forwardedRef,\n onClick: composeEventHandlers(props.onClick, () => context.onOpenChange(false))\n }\n );\n }\n);\nDialogClose.displayName = CLOSE_NAME;\nvar WarningProvider = (props) => {\n return props.children;\n};\nfunction getState(open) {\n return open ? \"open\" : \"closed\";\n}\nexport {\n DialogClose as Close,\n DialogContent as Content,\n DialogDescription as Description,\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n DialogOverlay as Overlay,\n DialogPortal as Portal,\n Dialog as Root,\n DialogTitle as Title,\n DialogTrigger as Trigger,\n WarningProvider,\n createDialogScope\n};\n//# sourceMappingURL=index.mjs.map\n","/**\n * Dialog — modal overlay backed by Radix Dialog primitive.\n * Use this for: tool approval, confirm-delete, job detail drawer's\n * mobile fallback, form modals.\n *\n * Mobile-aware: padding-bottom honors safe-area, content is scrollable\n * within 90dvh max-height so the soft keyboard doesn't clip Confirm\n * buttons on phones.\n */\n\nimport * as React from 'react'\nimport * as DialogPrimitive from '@radix-ui/react-dialog'\nimport { X } from 'lucide-react'\nimport { cn } from '@/lib/utils'\n\nconst Dialog = DialogPrimitive.Root\nconst DialogTrigger = DialogPrimitive.Trigger\nconst DialogPortal = DialogPrimitive.Portal\nconst DialogClose = DialogPrimitive.Close\n\nconst DialogOverlay = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Overlay\n ref={ref}\n className={cn(\n 'fixed inset-0 z-50 bg-black/50 backdrop-blur-sm',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n className,\n )}\n {...props}\n />\n))\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName\n\nconst DialogContent = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>\n>(({ className, children, ...props }, ref) => (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n ref={ref}\n className={cn(\n 'fixed left-[50%] top-[50%] z-50 grid w-full max-w-[calc(100vw-2rem)] sm:max-w-lg',\n 'translate-x-[-50%] translate-y-[-50%] gap-4',\n 'border border-border bg-surface p-4 shadow-lg',\n 'rounded-lg',\n // pb-safe alone gives ~34px for the home-indicator, but iOS Safari\n // can slide the URL bar back in on tap and eat another ~50px of\n // viewport. Reserve a generous floor so the last action button\n // never lands under the toolbar.\n 'max-h-[85dvh] overflow-y-auto pb-[calc(env(safe-area-inset-bottom)+1.5rem)]',\n 'duration-200',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n 'data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]',\n 'data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]',\n className,\n )}\n {...props}\n >\n {children}\n <DialogPrimitive.Close\n className={cn(\n 'absolute right-4 top-4 rounded-md p-1',\n 'text-text-dim hover:bg-surface-hover hover:text-text',\n 'focus:outline-none focus:ring-2 focus:ring-accent',\n 'tap-target',\n 'disabled:pointer-events-none',\n )}\n aria-label=\"Close\"\n >\n <X className=\"h-4 w-4\" />\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </DialogPortal>\n))\nDialogContent.displayName = DialogPrimitive.Content.displayName\n\nconst DialogHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>): JSX.Element => (\n <div\n className={cn('flex flex-col gap-1.5 text-left', className)}\n {...props}\n />\n)\nDialogHeader.displayName = 'DialogHeader'\n\nconst DialogFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>): JSX.Element => (\n <div\n className={cn(\n 'flex flex-col-reverse gap-2 sm:flex-row sm:justify-end',\n className,\n )}\n {...props}\n />\n)\nDialogFooter.displayName = 'DialogFooter'\n\nconst DialogTitle = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Title\n ref={ref}\n className={cn('text-lg font-semibold leading-snug', className)}\n {...props}\n />\n))\nDialogTitle.displayName = DialogPrimitive.Title.displayName\n\nconst DialogDescription = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Description\n ref={ref}\n className={cn('text-sm text-text-dim', className)}\n {...props}\n />\n))\nDialogDescription.displayName = DialogPrimitive.Description.displayName\n\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogTrigger,\n DialogClose,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n}\n"],"names":["DIALOG_NAME","createDialogContext","createContextScope","DialogProvider","useDialogContext","Dialog","props","__scopeDialog","children","openProp","defaultOpen","onOpenChange","modal","triggerRef","React.useRef","contentRef","open","setOpen","useControllableState","jsx","useId","React.useCallback","prevOpen","TRIGGER_NAME","DialogTrigger","React.forwardRef","forwardedRef","triggerProps","context","composedTriggerRef","useComposedRefs","Primitive","getState","composeEventHandlers","PORTAL_NAME","PortalProvider","usePortalContext","DialogPortal","forceMount","container","React.Children","child","Presence","PortalPrimitive","OVERLAY_NAME","DialogOverlay","portalContext","overlayProps","DialogOverlayImpl","Slot","createSlot","registerDismissableSurface","useDismissableLayerSurface","composedRefs","RemoveScroll","CONTENT_NAME","DialogContent","contentProps","DialogContentModal","DialogContentNonModal","React.useEffect","content","hideOthers","DialogContentImpl","event","originalEvent","ctrlLeftClick","hasInteractedOutsideRef","hasPointerDownOutsideRef","target","trapFocus","onOpenAutoFocus","onCloseAutoFocus","useFocusGuards","Fragment","FocusScope","DismissableLayer","TITLE_NAME","DialogTitle","titleProps","DESCRIPTION_NAME","DialogDescription","descriptionProps","CLOSE_NAME","DialogClose","closeProps","DialogPrimitive.Root","DialogPrimitive.Portal","className","ref","DialogPrimitive.Overlay","cn","jsxs","DialogPrimitive.Content","DialogPrimitive.Close","X","DialogHeader","DialogFooter","DialogPrimitive.Title","DialogPrimitive.Description"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{u as Q,e as Y,j as e,k as D,B as b,L as E,I as J,S as W,f as X,g as Z,h as ee,i as k,l as p,m as T}from"./index-D1ulN_24.js";import{r}from"./react-DlP5eolq.js";import{D as te}from"./data-table-CHGndGOY.js";import{E as B}from"./empty-state-D8kx-FwO.js";import{P as se}from"./pagination-C6qu72mB.js";import{C as M}from"./confirm-dialog-CMWuyC3w.js";import{a as ae,b as ne,c as ce}from"./use-memory-BHYuPOc9.js";import{T as A}from"./trash-2-CT_B0mSH.js";import{B as R}from"./brain-V9r2NcZc.js";import{L as re}from"./loader-circle-Bgi0H_iI.js";import{R as ie}from"./refresh-ccw-MHrCmmSv.js";import{S as le}from"./search-wZEXSmcX.js";import"./table-Bmwe7n4n.js";import"./arrow-up-Byeo8HHt.js";import"./arrow-down-Dhsj-A0i.js";import"./chevron-left-CTwCYqyt.js";import"./chevron-right-CDiFYKGo.js";import"./dialog-xeyu8dCf.js";import"./x-DXACg96C.js";import"./useQuery-Bt7Ty7IO.js";const oe=["fact","preference","goal","history","profile"],me=[25,50,100],F=50,de=300;function Be(){const{t:s}=Q(["memory","common"]),[n,L]=Y(),c=n.get("user")??"",i=n.get("q")??"",m=n.get("cat")??null,d=Math.max(1,Number(n.get("page"))||1),l=Number(n.get("per_page"))||F,[f,I]=r.useState(i);r.useEffect(()=>{if(f===i)return;const t=window.setTimeout(()=>h({q:f||null}),de);return()=>window.clearTimeout(t)},[f]);const q=r.useMemo(()=>({user_key:c,...i?{query:i}:{},...m?{category:m}:{},limit:l,offset:(d-1)*l}),[c,i,m,d,l]),{data:S,isLoading:z,isFetching:C,refetch:U}=ae(q,{enabled:!!c}),_=S?.facts??[],P=S?.total??0,G=Math.max(1,Math.ceil(P/l)),[u,g]=r.useState(new Set);r.useEffect(()=>{g(new Set)},[c,i,m,d,l]);const j=ne(),x=ce(),[y,v]=r.useState(null),[V,O]=r.useState(!1);function h(t){const a=new URLSearchParams(n);for(const[o,w]of Object.entries(t))w==null||w===""?a.delete(o):a.set(o,w);Object.keys(t).some(o=>o!=="page")&&a.delete("page"),L(a,{replace:!1})}async function $(){if(!(y==null||!c))try{await j.mutateAsync({id:y,user_key:c}),p.success(s("facts.toast.deletedOne"))}catch(t){const{message:a}=T(t,s);throw p.error(a),t}}async function H(){if(!c||u.size===0)return;const t=Array.from(u).map(Number).filter(Number.isFinite);try{const a=await x.mutateAsync({user_key:c,body:{ids:t}});p.success(s("facts.toast.deletedMany",{count:a.deleted})),g(new Set)}catch(a){const{message:o}=T(a,s);throw p.error(o),a}}const K=r.useMemo(()=>[{id:"id",header:s("facts.col.id"),cell:t=>e.jsxs("span",{className:"tabular-nums text-text-dim",children:["#",t.id]}),headClassName:"w-16"},{id:"what",header:s("facts.col.what"),cell:t=>e.jsx("span",{className:"line-clamp-2 text-text",children:t.what}),asCardTitle:!0},{id:"category",header:s("facts.col.category"),cell:t=>e.jsx(D,{variant:"outline",children:s(`facts.category.${t.category}`,{defaultValue:t.category})}),headClassName:"w-28"},{id:"confidence",header:s("facts.col.confidence"),cell:t=>e.jsx("span",{className:"tabular-nums text-text-dim",children:t.confidence.toFixed(2)}),headClassName:"w-24",hideOnMobile:!0},{id:"source",header:s("facts.col.source"),cell:t=>e.jsx("span",{className:"text-text-dim text-xs",children:t.source}),headClassName:"w-28",hideOnMobile:!0},{id:"createdAt",header:s("facts.col.createdAt"),cell:t=>e.jsx("span",{className:"text-text-dim",children:fe(t.created_at)}),headClassName:"w-32",hideOnMobile:!0},{id:"actions",header:"",cell:t=>e.jsx("div",{className:"flex justify-end",children:e.jsxs(b,{variant:"ghost",size:"sm",onClick:a=>{a.stopPropagation(),v(t.id)},disabled:j.isPending||x.isPending,"aria-label":s("facts.action.delete"),children:[e.jsx(A,{className:"h-3 w-3"}),e.jsx("span",{className:"sr-only sm:not-sr-only sm:ml-1",children:s("facts.action.delete")})]})}),headClassName:"w-24"}],[s,j.isPending,x.isPending]);if(!c)return e.jsx("div",{className:"mx-auto max-w-3xl",children:e.jsx(B,{icon:e.jsx(R,{}),title:s("noUserSelected.title"),description:s("noUserSelected.description")})});const N=u.size;return e.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("facts.title")}),e.jsxs(b,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>U(),disabled:C,"aria-label":s("actions.refresh",{ns:"common"}),children:[C?e.jsx(re,{className:"h-4 w-4 animate-spin"}):e.jsx(ie,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("subtitle")})]}),e.jsxs("div",{className:"flex flex-wrap items-end gap-2",children:[e.jsxs("div",{className:"relative flex-1 min-w-[200px] max-w-md",children:[e.jsx(E,{htmlFor:"search",className:"text-xs text-text-dim",children:s("facts.filter.search")}),e.jsx(le,{className:"pointer-events-none absolute left-2 bottom-2 h-4 w-4 text-text-muted"}),e.jsx(J,{id:"search",value:f,onChange:t=>I(t.target.value),className:"pl-7 mt-1"})]}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(E,{htmlFor:"category",className:"text-xs text-text-dim",children:s("facts.filter.category")}),e.jsxs(W,{value:m??"__any__",onValueChange:t=>h({cat:t==="__any__"?null:t}),children:[e.jsx(X,{id:"category",className:"w-[140px]",children:e.jsx(Z,{})}),e.jsxs(ee,{children:[e.jsx(k,{value:"__any__",children:s("facts.filter.categoryAny")}),oe.map(t=>e.jsx(k,{value:t,children:s(`facts.category.${t}`)},t))]})]})]}),N>0&&e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[e.jsx(D,{variant:"secondary",children:s("facts.batch.selected",{count:N})}),e.jsxs(b,{variant:"destructive",size:"sm",onClick:()=>O(!0),disabled:x.isPending,children:[e.jsx(A,{className:"h-4 w-4"}),s("facts.batch.deleteSelected")]})]})]}),e.jsx(te,{columns:K,rows:_,getRowId:t=>String(t.id),loading:z,selection:u,onSelectionChange:g,emptyState:e.jsx(B,{icon:e.jsx(R,{}),title:s("facts.empty.title"),description:s("facts.empty.description")})}),(_.length>0||d>1)&&e.jsx(se,{page:d,totalPages:G,totalRows:P,perPage:l,perPageOptions:me,onPageChange:t=>h({page:t===1?null:String(t)}),onPerPageChange:t=>h({per_page:t===F?null:String(t)})}),e.jsx(M,{open:y!=null,onOpenChange:t=>{t||v(null)},title:s("facts.action.confirmDelete"),description:s("facts.action.confirmDeleteDesc"),intent:"danger",confirmLabel:s("facts.action.delete"),onConfirm:$}),e.jsx(M,{open:V,onOpenChange:O,title:s("facts.batch.confirmDelete",{count:N}),description:s("facts.batch.confirmDeleteDesc"),intent:"danger",confirmLabel:s("facts.batch.deleteSelected"),onConfirm:H})]})}function fe(s){try{const n=new Date(s);return Number.isNaN(n.getTime())?String(s):n.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(s)}}export{Be as default};
|
|
2
|
-
//# sourceMappingURL=facts-CoWF4O82.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{u as p,e as f,j as e,B as g,c as y}from"./index-D1ulN_24.js";import{r as N}from"./react-DlP5eolq.js";import{E as v}from"./empty-state-D8kx-FwO.js";import{T as w,a as C,b as h,c as i,d as M,e as o}from"./table-Bmwe7n4n.js";import{u as L}from"./use-observability-CHv6H0zQ.js";import{L as T}from"./loader-circle-Bgi0H_iI.js";import{R as k}from"./refresh-ccw-MHrCmmSv.js";import{A as D}from"./activity-SXgxjjhd.js";import"./useQuery-Bt7Ty7IO.js";function P(){const{t:s}=p(["observability","common"]),[l]=f(),n=Math.max(1,Number(l.get("days"))||7),{data:c,isLoading:u,isFetching:m,refetch:j}=L(n),a=c?.totals,d=c?.byDay??[],b=N.useMemo(()=>d.reduce((t,x)=>x.calls>t?x.calls:t,0),[d]);return e.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("health.title")}),e.jsxs(g,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>j(),disabled:m,"aria-label":s("actions.refresh",{ns:"common"}),children:[m?e.jsx(T,{className:"h-4 w-4 animate-spin"}):e.jsx(k,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]}),c&&e.jsxs("p",{className:"text-xs text-text-dim tabular-nums",children:[c.since," → ",c.until]})]}),u?e.jsx("div",{className:"h-48 w-full rounded-md bg-surface-2 animate-pulse"}):!a||a.calls===0&&d.length===0?e.jsx(v,{icon:e.jsx(D,{}),title:s("health.empty.title"),description:s("health.empty.description")}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6",children:[e.jsx(r,{label:s("health.kpi.calls"),value:String(a.calls),tone:"info"}),e.jsx(r,{label:s("health.kpi.cost"),value:`$${a.cost.toFixed(4)}`,tone:"info"}),e.jsx(r,{label:s("health.kpi.errors"),value:String(a.errors),tone:a.errors>0?"danger":"success"}),e.jsx(r,{label:s("health.kpi.errorRate"),value:`${(a.errorRate*100).toFixed(1)}%`,tone:a.errorRate>.05?"warning":"success"}),e.jsx(r,{label:s("health.kpi.avgLatencyMs"),value:`${Math.round(a.avgLatencyMs)}ms`,tone:"info"}),e.jsx(r,{label:s("health.kpi.p95LatencyMs"),value:`${Math.round(a.p95LatencyMs)}ms`,tone:"info"})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"mb-2 text-sm font-medium uppercase tracking-wide text-text-dim",children:s("health.byDay")}),e.jsxs(w,{children:[e.jsx(C,{children:e.jsxs(h,{children:[e.jsx(i,{className:"w-28",children:s("health.byDayCol.date")}),e.jsx(i,{children:s("health.byDayCol.calls")}),e.jsx(i,{className:"w-24",children:s("health.byDayCol.cost")}),e.jsx(i,{className:"w-24",children:s("health.byDayCol.errors")}),e.jsx(i,{className:"w-32",children:s("health.byDayCol.avgLatencyMs")})]})}),e.jsx(M,{children:d.map(t=>e.jsxs(h,{children:[e.jsx(o,{className:"font-mono text-xs",children:t.date}),e.jsx(o,{children:e.jsx(S,{value:t.calls,max:b})}),e.jsxs(o,{className:"tabular-nums",children:["$",t.cost.toFixed(4)]}),e.jsx(o,{className:"tabular-nums",children:e.jsx("span",{className:t.errors>0?"text-danger":"text-text-dim",children:t.errors})}),e.jsxs(o,{className:"tabular-nums",children:[Math.round(t.avgLatencyMs),"ms"]})]},t.date))})]})]})]})]})}const R={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 r({label:s,value:l,tone:n}){return e.jsxs("div",{className:y("rounded-md border bg-surface px-3 py-2",R[n]),children:[e.jsx("div",{className:"text-xs uppercase tracking-wide text-text-dim",children:s}),e.jsx("div",{className:"text-xl font-semibold tabular-nums",children:l})]})}function S({value:s,max:l}){const n=l>0?s/l*100:0;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"relative h-3 w-full max-w-xs overflow-hidden rounded bg-surface-2",children:e.jsx("div",{className:"absolute inset-y-0 left-0 bg-accent/60",style:{width:`${n}%`}})}),e.jsx("span",{className:"tabular-nums text-sm text-text-dim",children:s})]})}export{P as default};
|
|
2
|
-
//# sourceMappingURL=health-C3lSUr_r.js.map
|