agim-cli 1.2.22 → 1.2.35
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 +151 -0
- package/README.md +8 -8
- package/README.zh-CN.md +6 -6
- package/dist/cli-ui/cmd-handlers.d.ts.map +1 -1
- package/dist/cli-ui/cmd-handlers.js +172 -13
- package/dist/cli-ui/cmd-handlers.js.map +1 -1
- package/dist/cli-ui/config-wizard.d.ts.map +1 -1
- package/dist/cli-ui/config-wizard.js +134 -24
- package/dist/cli-ui/config-wizard.js.map +1 -1
- package/dist/cli-ui/i18n.d.ts +33 -4
- package/dist/cli-ui/i18n.d.ts.map +1 -1
- package/dist/cli-ui/i18n.js +66 -8
- package/dist/cli-ui/i18n.js.map +1 -1
- package/dist/cli-ui/service.d.ts +44 -0
- package/dist/cli-ui/service.d.ts.map +1 -1
- package/dist/cli-ui/service.js +176 -8
- package/dist/cli-ui/service.js.map +1 -1
- package/dist/cli.js +193 -33
- package/dist/cli.js.map +1 -1
- package/dist/core/access-token.d.ts +51 -5
- package/dist/core/access-token.d.ts.map +1 -1
- package/dist/core/access-token.js +114 -15
- package/dist/core/access-token.js.map +1 -1
- package/dist/core/acp-server.d.ts.map +1 -1
- package/dist/core/acp-server.js +44 -3
- package/dist/core/acp-server.js.map +1 -1
- package/dist/core/admin-allowlist.d.ts +4 -1
- package/dist/core/admin-allowlist.d.ts.map +1 -1
- package/dist/core/admin-allowlist.js +14 -1
- package/dist/core/admin-allowlist.js.map +1 -1
- package/dist/core/admin-bootstrap.d.ts.map +1 -1
- package/dist/core/admin-bootstrap.js +8 -5
- package/dist/core/admin-bootstrap.js.map +1 -1
- package/dist/core/agent-base.d.ts.map +1 -1
- package/dist/core/agent-base.js +25 -0
- package/dist/core/agent-base.js.map +1 -1
- package/dist/core/agent-cwd.d.ts +1 -1
- package/dist/core/agent-cwd.d.ts.map +1 -1
- package/dist/core/agent-cwd.js +73 -2
- package/dist/core/agent-cwd.js.map +1 -1
- package/dist/core/agent-helper.d.ts +1 -1
- package/dist/core/agent-helper.js +4 -4
- package/dist/core/agent-helper.js.map +1 -1
- package/dist/core/approval-bus.d.ts +10 -0
- package/dist/core/approval-bus.d.ts.map +1 -1
- package/dist/core/approval-bus.js +130 -0
- package/dist/core/approval-bus.js.map +1 -1
- package/dist/core/approval-router.d.ts.map +1 -1
- package/dist/core/approval-router.js +18 -0
- package/dist/core/approval-router.js.map +1 -1
- package/dist/core/artifacts.d.ts +9 -1
- package/dist/core/artifacts.d.ts.map +1 -1
- package/dist/core/artifacts.js +22 -5
- package/dist/core/artifacts.js.map +1 -1
- package/dist/core/audit-log.d.ts +28 -0
- package/dist/core/audit-log.d.ts.map +1 -1
- package/dist/core/audit-log.js +100 -2
- package/dist/core/audit-log.js.map +1 -1
- package/dist/core/commands/coord.d.ts +4 -0
- package/dist/core/commands/coord.d.ts.map +1 -0
- package/dist/core/commands/coord.js +88 -0
- package/dist/core/commands/coord.js.map +1 -0
- package/dist/core/commands/service.d.ts +6 -5
- package/dist/core/commands/service.d.ts.map +1 -1
- package/dist/core/commands/service.js +59 -8
- package/dist/core/commands/service.js.map +1 -1
- package/dist/core/coord-systems.d.ts +10 -1
- package/dist/core/coord-systems.d.ts.map +1 -1
- package/dist/core/coord-systems.js +42 -17
- package/dist/core/coord-systems.js.map +1 -1
- package/dist/core/feature-flags.d.ts +10 -0
- package/dist/core/feature-flags.d.ts.map +1 -0
- package/dist/core/feature-flags.js +30 -0
- package/dist/core/feature-flags.js.map +1 -0
- package/dist/core/intent.d.ts.map +1 -1
- package/dist/core/intent.js +0 -4
- package/dist/core/intent.js.map +1 -1
- package/dist/core/logger.d.ts +31 -0
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +41 -1
- package/dist/core/logger.js.map +1 -1
- package/dist/core/memo-rpc.d.ts.map +1 -1
- package/dist/core/memo-rpc.js +6 -0
- package/dist/core/memo-rpc.js.map +1 -1
- package/dist/core/memory-distill.js +1 -1
- package/dist/core/memory-distill.js.map +1 -1
- package/dist/core/memory-rpc.d.ts.map +1 -1
- package/dist/core/memory-rpc.js +55 -12
- package/dist/core/memory-rpc.js.map +1 -1
- package/dist/core/memory.d.ts +5 -0
- package/dist/core/memory.d.ts.map +1 -1
- package/dist/core/memory.js +151 -1
- package/dist/core/memory.js.map +1 -1
- package/dist/core/memos.d.ts.map +1 -1
- package/dist/core/memos.js +20 -2
- package/dist/core/memos.js.map +1 -1
- package/dist/core/onboarding.d.ts +6 -0
- package/dist/core/onboarding.d.ts.map +1 -1
- package/dist/core/onboarding.js +21 -10
- package/dist/core/onboarding.js.map +1 -1
- package/dist/core/outbox.d.ts +8 -1
- package/dist/core/outbox.d.ts.map +1 -1
- package/dist/core/outbox.js +46 -2
- package/dist/core/outbox.js.map +1 -1
- package/dist/core/persona.d.ts.map +1 -1
- package/dist/core/persona.js +1 -18
- package/dist/core/persona.js.map +1 -1
- package/dist/core/prompt-injection-guard.d.ts +23 -0
- package/dist/core/prompt-injection-guard.d.ts.map +1 -0
- package/dist/core/prompt-injection-guard.js +94 -0
- package/dist/core/prompt-injection-guard.js.map +1 -0
- package/dist/core/registry.d.ts +8 -0
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/registry.js +41 -7
- package/dist/core/registry.js.map +1 -1
- package/dist/core/restart-flow.d.ts.map +1 -1
- package/dist/core/restart-flow.js +27 -0
- package/dist/core/restart-flow.js.map +1 -1
- package/dist/core/router.d.ts.map +1 -1
- package/dist/core/router.js +22 -0
- package/dist/core/router.js.map +1 -1
- package/dist/core/sensitive-paths.d.ts +28 -0
- package/dist/core/sensitive-paths.d.ts.map +1 -0
- package/dist/core/sensitive-paths.js +234 -0
- package/dist/core/sensitive-paths.js.map +1 -0
- package/dist/core/session.d.ts +9 -0
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +35 -4
- package/dist/core/session.js.map +1 -1
- package/dist/core/types.d.ts +9 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/user-coord-prefs.d.ts +17 -0
- package/dist/core/user-coord-prefs.d.ts.map +1 -0
- package/dist/core/user-coord-prefs.js +86 -0
- package/dist/core/user-coord-prefs.js.map +1 -0
- package/dist/core/viewer-local.d.ts +4 -0
- package/dist/core/viewer-local.d.ts.map +1 -1
- package/dist/core/viewer-local.js +74 -0
- package/dist/core/viewer-local.js.map +1 -1
- package/dist/plugins/agents/antigravity/ensure-mcp-config.d.ts +49 -0
- package/dist/plugins/agents/antigravity/ensure-mcp-config.d.ts.map +1 -0
- package/dist/plugins/agents/antigravity/ensure-mcp-config.js +110 -0
- package/dist/plugins/agents/antigravity/ensure-mcp-config.js.map +1 -0
- package/dist/plugins/agents/antigravity/index.d.ts +34 -0
- package/dist/plugins/agents/antigravity/index.d.ts.map +1 -0
- package/dist/plugins/agents/antigravity/index.js +330 -0
- package/dist/plugins/agents/antigravity/index.js.map +1 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.js +5 -5
- package/dist/plugins/agents/claude-code/mcp-approval-server.js.map +1 -1
- package/dist/plugins/messengers/feishu/card-builder.d.ts.map +1 -1
- package/dist/plugins/messengers/feishu/card-builder.js +0 -1
- package/dist/plugins/messengers/feishu/card-builder.js.map +1 -1
- package/dist/plugins/messengers/telegram/telegram-adapter.d.ts.map +1 -1
- package/dist/plugins/messengers/telegram/telegram-adapter.js +11 -2
- package/dist/plugins/messengers/telegram/telegram-adapter.js.map +1 -1
- package/dist/utils/cross-platform.d.ts +0 -5
- package/dist/utils/cross-platform.d.ts.map +1 -1
- package/dist/utils/cross-platform.js +1 -21
- package/dist/utils/cross-platform.js.map +1 -1
- package/dist/web/public/assets/{a2a-Dk2fSs33.js → a2a-BFM2Ojvs.js} +2 -2
- package/dist/web/public/assets/{a2a-Dk2fSs33.js.map → a2a-BFM2Ojvs.js.map} +1 -1
- package/dist/web/public/assets/{activity-eiIPshcV.js → activity-DNe1vn9s.js} +2 -2
- package/dist/web/public/assets/{activity-eiIPshcV.js.map → activity-DNe1vn9s.js.map} +1 -1
- package/dist/web/public/assets/{admins-DlbQYdW_.js → admins-DtIF8yji.js} +2 -2
- package/dist/web/public/assets/{admins-DlbQYdW_.js.map → admins-DtIF8yji.js.map} +1 -1
- package/dist/web/public/assets/agents-BJ3jyH1u.js +12 -0
- package/dist/web/public/assets/agents-BJ3jyH1u.js.map +1 -0
- package/dist/web/public/assets/{approvals-DlXS_sKD.js → approvals-8ifx3_0b.js} +2 -2
- package/dist/web/public/assets/{approvals-DlXS_sKD.js.map → approvals-8ifx3_0b.js.map} +1 -1
- package/dist/web/public/assets/{audit-C8I8xC_6.js → audit-BiFOljMy.js} +2 -2
- package/dist/web/public/assets/{audit-C8I8xC_6.js.map → audit-BiFOljMy.js.map} +1 -1
- package/dist/web/public/assets/{bgjobs-PFYinH7D.js → bgjobs-Dve01ab0.js} +2 -2
- package/dist/web/public/assets/{bgjobs-PFYinH7D.js.map → bgjobs-Dve01ab0.js.map} +1 -1
- package/dist/web/public/assets/{brain-DEEJttEL.js → brain-BI78EY6_.js} +2 -2
- package/dist/web/public/assets/{brain-DEEJttEL.js.map → brain-BI78EY6_.js.map} +1 -1
- package/dist/web/public/assets/{briefcase-BlMy8gI6.js → briefcase-CuwoOW31.js} +2 -2
- package/dist/web/public/assets/{briefcase-BlMy8gI6.js.map → briefcase-CuwoOW31.js.map} +1 -1
- package/dist/web/public/assets/{chevron-right-DmABPvoA.js → chevron-right-D5JanEQ3.js} +2 -2
- package/dist/web/public/assets/{chevron-right-DmABPvoA.js.map → chevron-right-D5JanEQ3.js.map} +1 -1
- package/dist/web/public/assets/{circle-check-C0Qpg1vL.js → circle-check-DXMzdFtD.js} +2 -2
- package/dist/web/public/assets/{circle-check-C0Qpg1vL.js.map → circle-check-DXMzdFtD.js.map} +1 -1
- package/dist/web/public/assets/{circle-check-big-C8LG3beV.js → circle-check-big-CyJIIhiq.js} +2 -2
- package/dist/web/public/assets/{circle-check-big-C8LG3beV.js.map → circle-check-big-CyJIIhiq.js.map} +1 -1
- package/dist/web/public/assets/{circle-x-D_cRHcHK.js → circle-x-DTwfNpvp.js} +2 -2
- package/dist/web/public/assets/{circle-x-D_cRHcHK.js.map → circle-x-DTwfNpvp.js.map} +1 -1
- package/dist/web/public/assets/{confirm-dialog-Baz_xFle.js → confirm-dialog-F0sdcLGN.js} +2 -2
- package/dist/web/public/assets/{confirm-dialog-Baz_xFle.js.map → confirm-dialog-F0sdcLGN.js.map} +1 -1
- package/dist/web/public/assets/{data-table--I_ktDF4.js → data-table-DN_-VLbp.js} +2 -2
- package/dist/web/public/assets/{data-table--I_ktDF4.js.map → data-table-DN_-VLbp.js.map} +1 -1
- package/dist/web/public/assets/{dialog-DZpoEskO.js → dialog-CM16nfWK.js} +2 -2
- package/dist/web/public/assets/{dialog-DZpoEskO.js.map → dialog-CM16nfWK.js.map} +1 -1
- package/dist/web/public/assets/{download-DbFGHwZ5.js → download-tFqY3Zj6.js} +2 -2
- package/dist/web/public/assets/{download-DbFGHwZ5.js.map → download-tFqY3Zj6.js.map} +1 -1
- package/dist/web/public/assets/{email-BB1Hq8eE.js → email-By2-ARPV.js} +2 -2
- package/dist/web/public/assets/{email-BB1Hq8eE.js.map → email-By2-ARPV.js.map} +1 -1
- package/dist/web/public/assets/{empty-state-DXNa90pP.js → empty-state-Dq9_8t-M.js} +2 -2
- package/dist/web/public/assets/{empty-state-DXNa90pP.js.map → empty-state-Dq9_8t-M.js.map} +1 -1
- package/dist/web/public/assets/{external-link-nhnJN0qg.js → external-link-amfAWSUX.js} +2 -2
- package/dist/web/public/assets/{external-link-nhnJN0qg.js.map → external-link-amfAWSUX.js.map} +1 -1
- package/dist/web/public/assets/{eye-IKkn_oUo.js → eye-BfgN09Lx.js} +2 -2
- package/dist/web/public/assets/{eye-IKkn_oUo.js.map → eye-BfgN09Lx.js.map} +1 -1
- package/dist/web/public/assets/{facts-C7Qy9vTw.js → facts-uvL__ilQ.js} +2 -2
- package/dist/web/public/assets/{facts-C7Qy9vTw.js.map → facts-uvL__ilQ.js.map} +1 -1
- package/dist/web/public/assets/{health-CMRdeNEW.js → health-fiU-ueEw.js} +2 -2
- package/dist/web/public/assets/{health-CMRdeNEW.js.map → health-fiU-ueEw.js.map} +1 -1
- package/dist/web/public/assets/{hot-Bh5Nrc7i.js → hot-Dt4V3jM_.js} +2 -2
- package/dist/web/public/assets/{hot-Bh5Nrc7i.js.map → hot-Dt4V3jM_.js.map} +1 -1
- package/dist/web/public/assets/{index-CpGWCLE5.js → index-6GMwymev.js} +8 -8
- package/dist/web/public/assets/index-6GMwymev.js.map +1 -0
- package/dist/web/public/assets/{index-GpceOxum.css → index-CDYTPZH0.css} +1 -1
- package/dist/web/public/assets/{installed-FYLkPij2.js → installed-B_x6no76.js} +2 -2
- package/dist/web/public/assets/{installed-FYLkPij2.js.map → installed-B_x6no76.js.map} +1 -1
- package/dist/web/public/assets/{jobs-BmqLUzHp.js → jobs-LqWH3CIe.js} +2 -2
- package/dist/web/public/assets/{jobs-BmqLUzHp.js.map → jobs-LqWH3CIe.js.map} +1 -1
- package/dist/web/public/assets/layout-CvxcdPD9.js +2 -0
- package/dist/web/public/assets/layout-CvxcdPD9.js.map +1 -0
- package/dist/web/public/assets/{layout-BZaHqf69.js → layout-DHUzlXrd.js} +2 -2
- package/dist/web/public/assets/{layout-BZaHqf69.js.map → layout-DHUzlXrd.js.map} +1 -1
- package/dist/web/public/assets/{layout-CXsUyEpG.js → layout-MNk0bLGe.js} +2 -2
- package/dist/web/public/assets/{layout-CXsUyEpG.js.map → layout-MNk0bLGe.js.map} +1 -1
- package/dist/web/public/assets/{layout-DFxtpNut.js → layout-WcrkE0es.js} +2 -2
- package/dist/web/public/assets/{layout-DFxtpNut.js.map → layout-WcrkE0es.js.map} +1 -1
- package/dist/web/public/assets/{layout-d8qxPKQk.js → layout-apvyE2JN.js} +2 -2
- package/dist/web/public/assets/{layout-d8qxPKQk.js.map → layout-apvyE2JN.js.map} +1 -1
- package/dist/web/public/assets/{loader-circle-JaKY-xMt.js → loader-circle-hxNy7hSm.js} +2 -2
- package/dist/web/public/assets/{loader-circle-JaKY-xMt.js.map → loader-circle-hxNy7hSm.js.map} +1 -1
- package/dist/web/public/assets/{map-pin-hFFSWZ3B.js → map-pin-CCmA7ke2.js} +2 -2
- package/dist/web/public/assets/{map-pin-hFFSWZ3B.js.map → map-pin-CCmA7ke2.js.map} +1 -1
- package/dist/web/public/assets/{memos-EhjMUvVZ.js → memos-pEjDfEj3.js} +2 -2
- package/dist/web/public/assets/{memos-EhjMUvVZ.js.map → memos-pEjDfEj3.js.map} +1 -1
- package/dist/web/public/assets/messengers-Ba7opEc1.js +7 -0
- package/dist/web/public/assets/messengers-Ba7opEc1.js.map +1 -0
- package/dist/web/public/assets/{network-DtCI2ZUU.js → network-DJw-ei_k.js} +2 -2
- package/dist/web/public/assets/{network-DtCI2ZUU.js.map → network-DJw-ei_k.js.map} +1 -1
- package/dist/web/public/assets/{outbox-CxUbMp6o.js → outbox-Ckq-VT5C.js} +2 -2
- package/dist/web/public/assets/{outbox-CxUbMp6o.js.map → outbox-Ckq-VT5C.js.map} +1 -1
- package/dist/web/public/assets/{pagination-CkZY8YNa.js → pagination-DGS-TnI5.js} +2 -2
- package/dist/web/public/assets/{pagination-CkZY8YNa.js.map → pagination-DGS-TnI5.js.map} +1 -1
- package/dist/web/public/assets/{persona-B6TFMSnI.js → persona--LsrhCVU.js} +2 -2
- package/dist/web/public/assets/{persona-B6TFMSnI.js.map → persona--LsrhCVU.js.map} +1 -1
- package/dist/web/public/assets/{play-BxRcWaH5.js → play-Cb7co2DX.js} +2 -2
- package/dist/web/public/assets/{play-BxRcWaH5.js.map → play-Cb7co2DX.js.map} +1 -1
- package/dist/web/public/assets/{policy-ndE1Y8zD.js → policy-CbCotzr6.js} +2 -2
- package/dist/web/public/assets/{policy-ndE1Y8zD.js.map → policy-CbCotzr6.js.map} +1 -1
- package/dist/web/public/assets/{refresh-ccw-Bx817_KW.js → refresh-ccw-CINxCmwV.js} +2 -2
- package/dist/web/public/assets/{refresh-ccw-Bx817_KW.js.map → refresh-ccw-CINxCmwV.js.map} +1 -1
- package/dist/web/public/assets/{reminders-XynkGQc5.js → reminders-CSKrWre3.js} +2 -2
- package/dist/web/public/assets/{reminders-XynkGQc5.js.map → reminders-CSKrWre3.js.map} +1 -1
- package/dist/web/public/assets/{save-CqMcATrh.js → save-Bib9iAA-.js} +2 -2
- package/dist/web/public/assets/{save-CqMcATrh.js.map → save-Bib9iAA-.js.map} +1 -1
- package/dist/web/public/assets/{schedules-VM02w_Om.js → schedules-DUD_FfEX.js} +2 -2
- package/dist/web/public/assets/{schedules-VM02w_Om.js.map → schedules-DUD_FfEX.js.map} +1 -1
- package/dist/web/public/assets/{search-Ba-e1t1P.js → search-DZOHNA81.js} +2 -2
- package/dist/web/public/assets/{search-Ba-e1t1P.js.map → search-DZOHNA81.js.map} +1 -1
- package/dist/web/public/assets/{service-C-wnwJ-b.js → service-Cf7EQ4Sj.js} +3 -3
- package/dist/web/public/assets/{service-C-wnwJ-b.js.map → service-Cf7EQ4Sj.js.map} +1 -1
- package/dist/web/public/assets/{status-badge-CsdJ6k8Q.js → status-badge-RpKtiHgj.js} +2 -2
- package/dist/web/public/assets/{status-badge-CsdJ6k8Q.js.map → status-badge-RpKtiHgj.js.map} +1 -1
- package/dist/web/public/assets/{subtasks-mGRKpF0G.js → subtasks-xCHP5uI6.js} +2 -2
- package/dist/web/public/assets/{subtasks-mGRKpF0G.js.map → subtasks-xCHP5uI6.js.map} +1 -1
- package/dist/web/public/assets/{table-vmLMgj6_.js → table-S43AHY-3.js} +2 -2
- package/dist/web/public/assets/{table-vmLMgj6_.js.map → table-S43AHY-3.js.map} +1 -1
- package/dist/web/public/assets/{topn-nu66Fotx.js → topn-C2tcvmnB.js} +2 -2
- package/dist/web/public/assets/{topn-nu66Fotx.js.map → topn-C2tcvmnB.js.map} +1 -1
- package/dist/web/public/assets/{trash-2-ZIitN_U3.js → trash-2-Ct7YJmZO.js} +2 -2
- package/dist/web/public/assets/{trash-2-ZIitN_U3.js.map → trash-2-Ct7YJmZO.js.map} +1 -1
- package/dist/web/public/assets/{use-memory-DgEqHEca.js → use-memory-CCn0h8EP.js} +2 -2
- package/dist/web/public/assets/{use-memory-DgEqHEca.js.map → use-memory-CCn0h8EP.js.map} +1 -1
- package/dist/web/public/assets/{use-observability-CQev_A8e.js → use-observability-Dbal-WXR.js} +2 -2
- package/dist/web/public/assets/{use-observability-CQev_A8e.js.map → use-observability-Dbal-WXR.js.map} +1 -1
- package/dist/web/public/assets/{use-settings-CU-UcrVD.js → use-settings-erlkhPqn.js} +2 -2
- package/dist/web/public/assets/{use-settings-CU-UcrVD.js.map → use-settings-erlkhPqn.js.map} +1 -1
- package/dist/web/public/assets/{use-skills-Dr77CXLA.js → use-skills-C8Ukv8B4.js} +2 -2
- package/dist/web/public/assets/{use-skills-Dr77CXLA.js.map → use-skills-C8Ukv8B4.js.map} +1 -1
- package/dist/web/public/assets/{use-workspace-PNv9Z4de.js → use-workspace-8VZDPppc.js} +2 -2
- package/dist/web/public/assets/{use-workspace-PNv9Z4de.js.map → use-workspace-8VZDPppc.js.map} +1 -1
- package/dist/web/public/assets/{useQuery-BTyugXYV.js → useQuery-BnCHQlxq.js} +2 -2
- package/dist/web/public/assets/{useQuery-BTyugXYV.js.map → useQuery-BnCHQlxq.js.map} +1 -1
- package/dist/web/public/assets/{vector-w-Ea3pg6.js → vector-DDnIidyp.js} +2 -2
- package/dist/web/public/assets/{vector-w-Ea3pg6.js.map → vector-DDnIidyp.js.map} +1 -1
- package/dist/web/public/assets/{viewer-DKA7QP9U.js → viewer-BV0Cux3V.js} +2 -2
- package/dist/web/public/assets/{viewer-DKA7QP9U.js.map → viewer-BV0Cux3V.js.map} +1 -1
- package/dist/web/public/assets/{workspace-DVLZca7t.js → workspace-DbLMyUTn.js} +2 -2
- package/dist/web/public/assets/{workspace-DVLZca7t.js.map → workspace-DbLMyUTn.js.map} +1 -1
- package/dist/web/public/assets/{workspaces-DYZsMmY-.js → workspaces-BhF0IAJg.js} +2 -2
- package/dist/web/public/assets/{workspaces-DYZsMmY-.js.map → workspaces-BhF0IAJg.js.map} +1 -1
- package/dist/web/public/assets/{x-Ru3rHT82.js → x-BmgfwQRl.js} +2 -2
- package/dist/web/public/assets/{x-Ru3rHT82.js.map → x-BmgfwQRl.js.map} +1 -1
- package/dist/web/public/index.html +2 -2
- package/dist/web/public/settings.html +0 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +600 -16
- package/dist/web/server.js.map +1 -1
- package/package.json +3 -2
- package/dist/plugins/agents/copilot/index.d.ts +0 -35
- package/dist/plugins/agents/copilot/index.d.ts.map +0 -1
- package/dist/plugins/agents/copilot/index.js +0 -182
- package/dist/plugins/agents/copilot/index.js.map +0 -1
- package/dist/web/public/assets/agents-BMI1WbZj.js +0 -12
- package/dist/web/public/assets/agents-BMI1WbZj.js.map +0 -1
- package/dist/web/public/assets/env-Bqrb9XkC.js +0 -2
- package/dist/web/public/assets/env-Bqrb9XkC.js.map +0 -1
- package/dist/web/public/assets/index-CpGWCLE5.js.map +0 -1
- package/dist/web/public/assets/layout-9Gp_myEd.js +0 -2
- package/dist/web/public/assets/layout-9Gp_myEd.js.map +0 -1
- package/dist/web/public/assets/messengers-BRV1IVGX.js +0 -7
- package/dist/web/public/assets/messengers-BRV1IVGX.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agim-cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.35",
|
|
4
4
|
"description": "Agim (阿吉姆) — universal messenger-to-agent bridge. Connect WeChat / Feishu / DingTalk / Telegram / Discord to Claude Code / Codex / Copilot / OpenCode, or any custom agent via ACP. Installs the `agim` command.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"LICENSE"
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
|
-
"build": "rm -rf
|
|
20
|
+
"build:spa": "cd src/web-app && npm run build && cd ../.. && rm -rf src/web/public/assets && cp -r src/web-app/dist/assets src/web/public/assets && cp src/web-app/dist/index.html src/web/public/index.html && cp src/web-app/dist/manifest.webmanifest src/web/public/manifest.webmanifest && cp src/web-app/dist/favicon.svg src/web/public/favicon.svg",
|
|
21
|
+
"build": "npm run build:spa && rm -rf dist && tsc && cp -r src/web/public dist/web/public && chmod +x dist/cli.js",
|
|
21
22
|
"dev": "tsc --watch",
|
|
22
23
|
"start": "node dist/cli.js",
|
|
23
24
|
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { AgentBase } from '../../../core/agent-base.js';
|
|
2
|
-
/**
|
|
3
|
-
* Copilot adapter built on AgentBase. Differs from the other CLI agents
|
|
4
|
-
* in two ways:
|
|
5
|
-
* 1. The binary path is discovered async (gh / standalone / VSCode)
|
|
6
|
-
* 2. The CLI is not JSONL — its stdout is plain text
|
|
7
|
-
*
|
|
8
|
-
* AgentBase already handles plain text via the JSON.parse fallback (yields
|
|
9
|
-
* the line verbatim). We override commandName/buildArgs/extractText after
|
|
10
|
-
* resolving the install, and use isAvailable() to short-circuit when no
|
|
11
|
-
* install was found.
|
|
12
|
-
*/
|
|
13
|
-
declare class CopilotAdapter extends AgentBase {
|
|
14
|
-
readonly name = "copilot";
|
|
15
|
-
readonly aliases: string[];
|
|
16
|
-
/** Resolved install, populated by isAvailable() and reused by spawn calls. */
|
|
17
|
-
private resolvedInstall;
|
|
18
|
-
protected get commandName(): string;
|
|
19
|
-
protected buildArgs(prompt: string): string[];
|
|
20
|
-
protected extractText(event: unknown): string;
|
|
21
|
-
isAvailable(): Promise<boolean>;
|
|
22
|
-
healthCheck(): Promise<{
|
|
23
|
-
ok: boolean;
|
|
24
|
-
latencyMs?: number;
|
|
25
|
-
}>;
|
|
26
|
-
protected handleError(_code: number, stderr: string, _errorMessage: string): string | null;
|
|
27
|
-
protected notAvailableMessage(): string;
|
|
28
|
-
sendPrompt(sessionId: string, prompt: string, history?: import('../../../core/types.js').ChatMessage[], _opts?: {
|
|
29
|
-
model?: string;
|
|
30
|
-
variant?: string;
|
|
31
|
-
}): AsyncGenerator<string>;
|
|
32
|
-
}
|
|
33
|
-
export declare const copilotAdapter: CopilotAdapter;
|
|
34
|
-
export {};
|
|
35
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/plugins/agents/copilot/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAA;AAgGvD;;;;;;;;;;GAUG;AACH,cAAM,cAAe,SAAQ,SAAS;IACpC,QAAQ,CAAC,IAAI,aAAY;IACzB,QAAQ,CAAC,OAAO,WAAyC;IAEzD,8EAA8E;IAC9E,OAAO,CAAC,eAAe,CAA8B;IAErD,SAAS,KAAK,WAAW,IAAI,MAAM,CAQlC;IAED,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAS7C,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;IAYvC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAK/B,WAAW,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAMjE,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAY1F,SAAS,CAAC,mBAAmB,IAAI,MAAM;IAchC,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,wBAAwB,EAAE,WAAW,EAAE,EAAE,KAAK,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,cAAc,CAAC,MAAM,CAAC;CAQrL;AAED,eAAO,MAAM,cAAc,gBAAuB,CAAA"}
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
// GitHub Copilot CLI agent adapter
|
|
2
|
-
// Supports multiple installation methods:
|
|
3
|
-
// 1. GitHub CLI extension: `gh copilot` (recommended)
|
|
4
|
-
// 2. Standalone npm: `copilot` command
|
|
5
|
-
// 3. VS Code extension: bundled copilot CLI
|
|
6
|
-
// 4. Homebrew (macOS): `brew install copilot-cli`
|
|
7
|
-
// 5. WinGet (Windows): `winget install GitHub.Copilot`
|
|
8
|
-
import { access, constants, readdir } from 'node:fs/promises';
|
|
9
|
-
import { homedir } from 'node:os';
|
|
10
|
-
import { join } from 'node:path';
|
|
11
|
-
import { AgentBase } from '../../../core/agent-base.js';
|
|
12
|
-
import { crossSpawn, isWindows, isMac } from '../../../utils/cross-platform.js';
|
|
13
|
-
import { logger as rootLogger } from '../../../core/logger.js';
|
|
14
|
-
/** Check if a command exists and can be executed */
|
|
15
|
-
async function commandExists(cmd) {
|
|
16
|
-
return new Promise((resolve) => {
|
|
17
|
-
const proc = crossSpawn(cmd, ['--version'], { stdio: 'ignore' });
|
|
18
|
-
proc.on('error', () => resolve(false));
|
|
19
|
-
proc.on('close', (code) => resolve(code === 0));
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
async function checkGHCopilot() {
|
|
23
|
-
if (!(await commandExists('gh')))
|
|
24
|
-
return null;
|
|
25
|
-
return new Promise((resolve) => {
|
|
26
|
-
const proc = crossSpawn('gh', ['copilot', '--version'], { stdio: 'ignore' });
|
|
27
|
-
proc.on('error', () => resolve(null));
|
|
28
|
-
proc.on('close', (code) => {
|
|
29
|
-
if (code === 0) {
|
|
30
|
-
resolve({ type: 'gh-ext', command: 'gh', argsPrefix: ['copilot'] });
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
resolve(null);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
async function checkStandaloneCopilot() {
|
|
39
|
-
if (await commandExists('copilot')) {
|
|
40
|
-
return { type: 'standalone', command: 'copilot', argsPrefix: [] };
|
|
41
|
-
}
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
async function findVSCodeCopilot() {
|
|
45
|
-
if (isMac) {
|
|
46
|
-
const macPath = join(homedir(), 'Library/Application Support/Code/User/globalStorage/github.copilot-chat/copilotCli/copilot');
|
|
47
|
-
try {
|
|
48
|
-
await access(macPath, constants.X_OK);
|
|
49
|
-
return { type: 'vscode', command: macPath, argsPrefix: [] };
|
|
50
|
-
}
|
|
51
|
-
catch { /* fall through */ }
|
|
52
|
-
}
|
|
53
|
-
if (isWindows) {
|
|
54
|
-
const extensionsDir = join(homedir(), '.vscode', 'extensions');
|
|
55
|
-
try {
|
|
56
|
-
const entries = await readdir(extensionsDir, { withFileTypes: true });
|
|
57
|
-
const copilotDir = entries.find((entry) => entry.isDirectory() && entry.name.startsWith('github.copilot-chat-'));
|
|
58
|
-
if (copilotDir) {
|
|
59
|
-
const copilotBin = join(extensionsDir, copilotDir.name, 'copilotCli', 'copilot.exe');
|
|
60
|
-
try {
|
|
61
|
-
await access(copilotBin, constants.X_OK);
|
|
62
|
-
return { type: 'vscode', command: copilotBin, argsPrefix: [] };
|
|
63
|
-
}
|
|
64
|
-
catch { /* fall through */ }
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
catch { /* ignore readdir errors */ }
|
|
68
|
-
}
|
|
69
|
-
const linuxPath = join(homedir(), '.vscode/extensions/github.copilot-chat/copilotCli/copilot');
|
|
70
|
-
try {
|
|
71
|
-
await access(linuxPath, constants.X_OK);
|
|
72
|
-
return { type: 'vscode', command: linuxPath, argsPrefix: [] };
|
|
73
|
-
}
|
|
74
|
-
catch {
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
/** TTL'd installation cache so a fresh install is picked up within 2min. */
|
|
79
|
-
const INSTALL_CACHE_TTL = 2 * 60 * 1000;
|
|
80
|
-
let cachedInstall = null;
|
|
81
|
-
let cachedAt = 0;
|
|
82
|
-
async function detectCopilotInstall() {
|
|
83
|
-
if (cachedInstall && Date.now() - cachedAt < INSTALL_CACHE_TTL)
|
|
84
|
-
return cachedInstall;
|
|
85
|
-
cachedInstall =
|
|
86
|
-
(await checkGHCopilot()) ||
|
|
87
|
-
(await checkStandaloneCopilot()) ||
|
|
88
|
-
(await findVSCodeCopilot());
|
|
89
|
-
cachedAt = Date.now();
|
|
90
|
-
return cachedInstall;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Copilot adapter built on AgentBase. Differs from the other CLI agents
|
|
94
|
-
* in two ways:
|
|
95
|
-
* 1. The binary path is discovered async (gh / standalone / VSCode)
|
|
96
|
-
* 2. The CLI is not JSONL — its stdout is plain text
|
|
97
|
-
*
|
|
98
|
-
* AgentBase already handles plain text via the JSON.parse fallback (yields
|
|
99
|
-
* the line verbatim). We override commandName/buildArgs/extractText after
|
|
100
|
-
* resolving the install, and use isAvailable() to short-circuit when no
|
|
101
|
-
* install was found.
|
|
102
|
-
*/
|
|
103
|
-
class CopilotAdapter extends AgentBase {
|
|
104
|
-
name = 'copilot';
|
|
105
|
-
aliases = ['gh', 'github', 'copilotcli', 'ghcp'];
|
|
106
|
-
/** Resolved install, populated by isAvailable() and reused by spawn calls. */
|
|
107
|
-
resolvedInstall = null;
|
|
108
|
-
get commandName() {
|
|
109
|
-
if (!this.resolvedInstall) {
|
|
110
|
-
// Should never happen — sendPrompt awaits isAvailable() first. But if
|
|
111
|
-
// someone calls spawnAndCollect directly we degrade by using a
|
|
112
|
-
// sentinel that the spawn will fail on, surfaced via handleError.
|
|
113
|
-
return 'copilot';
|
|
114
|
-
}
|
|
115
|
-
return this.resolvedInstall.command;
|
|
116
|
-
}
|
|
117
|
-
buildArgs(prompt) {
|
|
118
|
-
const install = this.resolvedInstall;
|
|
119
|
-
if (!install)
|
|
120
|
-
return ['-p', prompt, '-s'];
|
|
121
|
-
if (install.type === 'gh-ext') {
|
|
122
|
-
return [...install.argsPrefix, 'suggest', prompt, '--prompt-only'];
|
|
123
|
-
}
|
|
124
|
-
return [...install.argsPrefix, '-p', prompt, '-s'];
|
|
125
|
-
}
|
|
126
|
-
extractText(event) {
|
|
127
|
-
// Copilot CLI is not JSONL; AgentBase's fallback already yields the
|
|
128
|
-
// raw line. extractText is only consulted on successfully-parsed JSON,
|
|
129
|
-
// which Copilot never emits.
|
|
130
|
-
if (event && typeof event === 'object') {
|
|
131
|
-
const e = event;
|
|
132
|
-
if (typeof e.content === 'string')
|
|
133
|
-
return e.content;
|
|
134
|
-
if (typeof e.text === 'string')
|
|
135
|
-
return e.text;
|
|
136
|
-
}
|
|
137
|
-
return '';
|
|
138
|
-
}
|
|
139
|
-
async isAvailable() {
|
|
140
|
-
this.resolvedInstall = await detectCopilotInstall();
|
|
141
|
-
return this.resolvedInstall !== null;
|
|
142
|
-
}
|
|
143
|
-
async healthCheck() {
|
|
144
|
-
const start = Date.now();
|
|
145
|
-
const ok = await this.isAvailable();
|
|
146
|
-
return { ok, latencyMs: Date.now() - start };
|
|
147
|
-
}
|
|
148
|
-
handleError(_code, stderr, _errorMessage) {
|
|
149
|
-
if (stderr.includes('402') || stderr.includes('no quota') || stderr.includes('insufficient')) {
|
|
150
|
-
return `❌ Copilot 额度不足,请检查您的 GitHub Copilot 订阅。
|
|
151
|
-
|
|
152
|
-
💡 可以使用以下命令切换到其他 Agent:
|
|
153
|
-
• /claude - 切换到 Claude Code
|
|
154
|
-
• /codex - 切换到 OpenAI Codex
|
|
155
|
-
• /agents - 查看所有可用 Agent`;
|
|
156
|
-
}
|
|
157
|
-
return null;
|
|
158
|
-
}
|
|
159
|
-
notAvailableMessage() {
|
|
160
|
-
return `❌ Copilot CLI 未找到。
|
|
161
|
-
|
|
162
|
-
安装方式 (选择其一):
|
|
163
|
-
npm i -g @github/copilot
|
|
164
|
-
gh extension install github/gh-copilot
|
|
165
|
-
brew install copilot-cli (macOS)
|
|
166
|
-
winget install GitHub.Copilot (Windows)
|
|
167
|
-
|
|
168
|
-
或安装 VS Code Copilot Chat 扩展。`;
|
|
169
|
-
}
|
|
170
|
-
// Override sendPrompt to short-circuit when not installed — gives a
|
|
171
|
-
// friendlier message than spawnStream would after spawn failure.
|
|
172
|
-
async *sendPrompt(sessionId, prompt, history, _opts) {
|
|
173
|
-
if (!(await this.isAvailable())) {
|
|
174
|
-
yield this.notAvailableMessage();
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
rootLogger.info({ component: `agent.${this.name}`, agent: this.name, install: this.resolvedInstall?.type }, '[copilot] sendPrompt');
|
|
178
|
-
yield* super.sendPrompt(sessionId, prompt, history, _opts);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
export const copilotAdapter = new CopilotAdapter();
|
|
182
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/plugins/agents/copilot/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import{x as G,ac as L,Q as e,c as N,L as O,S as Z,l as X,m as Y,j as J,k as I,B as U,a2 as f,z as F,r as K,I as M}from"./index-CpGWCLE5.js";import{e as u}from"./react-C9F3QeMB.js";import{E as re}from"./empty-state-DXNa90pP.js";import{u as oe}from"./use-workspace-PNv9Z4de.js";import{b as de,m as me,k as xe,c as ue}from"./use-settings-CU-UcrVD.js";import{L as B}from"./loader-circle-JaKY-xMt.js";import{R as pe}from"./refresh-ccw-Bx817_KW.js";import{X as he}from"./x-Ru3rHT82.js";import{S as ge}from"./save-CqMcATrh.js";import{N as q}from"./network-DtCI2ZUU.js";import{S as H}from"./search-Ba-e1t1P.js";import{T as fe}from"./trash-2-ZIitN_U3.js";import"./useQuery-BTyugXYV.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 je=G("Bot",[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]]);/**
|
|
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 be=G("Plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]),W={"claude-code":{aliases:["cc","claude"],pkg:"@anthropic-ai/claude-code"},codex:{aliases:["cx"],pkg:"@openai/codex"},copilot:{aliases:["co"],pkg:"@github/copilot"},opencode:{aliases:["oc"],pkg:"opencode-ai"}},Q=Object.keys(W);function Ue(){const{t}=L(["settings","common"]),r=de(),s=oe(),i=me(),n=r.data,o=s.data??{},[d,m]=u.useState(null),[p,g]=u.useState(null),[S,j]=u.useState(null);u.useEffect(()=>{n&&d==null&&m(n.agents??[]),n&&p==null&&g(n.defaultAgent??""),n&&S==null&&j(n.acpAgents??[])},[n,d,p,S]);const h=d??n?.agents??[],b=p??n?.defaultAgent??"",k=S??n?.acpAgents??[],$=u.useMemo(()=>{if(!n)return!1;const c=h.length===(n.agents?.length??0)&&h.every(w=>n.agents?.includes(w)),v=b===(n.defaultAgent??""),y=we(k,n.acpAgents??[]);return!c||!v||!y},[n,h,b,k]),T=u.useMemo(()=>Q.filter(c=>h.includes(c)&&o[c]),[h,o]);function _(c,v){const y=v?Array.from(new Set([...h,c])):h.filter(w=>w!==c);m(y),!v&&c===b&&g("")}async function z(){if(n)try{await i.mutateAsync({...n,agents:h,defaultAgent:b||n.defaultAgent,acpAgents:k}),f.success(t("agents.toast.saved")),m(null),g(null),j(null)}catch(c){f.error(F(c,t).message)}}function C(){m(null),g(null),j(null)}function D(c){j(c)}return e.jsxs("div",{className:"mx-auto flex max-w-4xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:t("agents.title")}),e.jsxs(N,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>{r.refetch(),s.refetch()},disabled:r.isFetching||s.isFetching,"aria-label":t("actions.refresh",{ns:"common"}),children:[r.isFetching||s.isFetching?e.jsx(B,{className:"h-4 w-4 animate-spin"}):e.jsx(pe,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:t("actions.refresh",{ns:"common"})})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:t("agents.subtitle")})]}),r.isLoading?e.jsx("div",{className:"h-64 rounded-md bg-surface-2 animate-pulse"}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"flex flex-col divide-y divide-border rounded-md border border-border bg-surface",children:Q.map(c=>{const v=W[c],y=!!o[c],w=h.includes(c);return e.jsx(Ne,{name:c,aliases:v.aliases,pkg:v.pkg,installed:y,enabled:w,onToggle:P=>_(c,P)},c)})}),e.jsxs("section",{className:"rounded-md border border-border bg-surface p-4",children:[e.jsx(O,{htmlFor:"default-agent",className:"text-sm font-medium",children:t("agents.defaultAgent")}),e.jsx("p",{className:"mt-1 text-xs text-text-dim",children:t("agents.defaultAgentHint")}),e.jsxs(Z,{value:b||"__none__",onValueChange:c=>g(c==="__none__"?"":c),disabled:T.length===0,children:[e.jsx(X,{id:"default-agent",className:"mt-2 w-64",children:e.jsx(Y,{placeholder:t("agents.noEligible")})}),e.jsx(J,{children:T.length===0?e.jsx(I,{value:"__none__",disabled:!0,children:t("agents.noEligible")}):T.map(c=>e.jsx(I,{value:c,children:c},c))})]})]}),e.jsx(ke,{agents:k,onChange:D}),$&&e.jsxs("div",{className:"sticky bottom-0 flex items-center gap-2 rounded-md border border-border bg-surface px-4 py-2 shadow-md",children:[e.jsx(U,{variant:"info",children:t("agents.dirtyHint")}),e.jsxs(N,{variant:"secondary",size:"sm",onClick:C,disabled:i.isPending,children:[e.jsx(he,{className:"h-4 w-4"}),t("agents.discard")]}),e.jsxs(N,{size:"sm",onClick:()=>void z(),disabled:i.isPending,children:[i.isPending?e.jsx(B,{className:"h-4 w-4 animate-spin"}):e.jsx(ge,{className:"h-4 w-4"}),i.isPending?t("agents.saving"):t("agents.saveBtn")]})]})]})]})}function Ne({name:t,aliases:r,pkg:s,installed:i,enabled:n,onToggle:o}){const{t:d}=L("settings");return e.jsxs("div",{className:"flex items-start gap-3 px-3 py-3",children:[e.jsx("div",{className:"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-surface-2 text-text-dim",children:e.jsx(je,{className:"h-4 w-4"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:t}),e.jsxs(U,{variant:i?"success":"outline",className:"text-[10px]",children:[e.jsx("span",{className:K("inline-block h-1.5 w-1.5 rounded-full",i?"bg-success":"bg-text-muted")}),d(i?"agents.online":"agents.offline")]})]}),e.jsxs("p",{className:"mt-0.5 text-xs text-text-dim",children:[e.jsxs("span",{className:"text-text-muted",children:[d("agents.aliasesLabel"),": "]}),e.jsx("span",{className:"font-mono",children:r.map(m=>`/${m}`).join(", ")})]}),!i&&e.jsx("p",{className:"mt-1 text-xs text-warning",children:d("agents.installHint",{pkg:s})})]}),e.jsx("input",{type:"checkbox",checked:n,onChange:m=>o(m.target.checked),className:"h-4 w-4 mt-2 accent-accent cursor-pointer"})]})}const ve=["none","apikey","bearer"],ye=/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;function we(t,r){if(t.length!==r.length)return!1;for(let s=0;s<t.length;s++){const i=t[s],n=r[s];if(i.name!==n.name||i.endpoint!==n.endpoint||(i.enabled??!0)!==(n.enabled??!0))return!1;const o=(i.aliases??[]).join(","),d=(n.aliases??[]).join(",");if(o!==d)return!1;const m=i.auth?.type??"none",p=n.auth?.type??"none";if(m!==p||(i.auth?.token??"")!==(n.auth?.token??""))return!1}return!0}function ke({agents:t,onChange:r}){const{t:s}=L(["settings","common"]),i=xe(),n=ue(),[o,d]=u.useState(""),[m,p]=u.useState(""),[g,S]=u.useState(""),[j,h]=u.useState("none"),[b,k]=u.useState(""),[$,T]=u.useState(!1),[_,z]=u.useState(""),C=o.trim(),D=C.length>0&&ye.test(C),c=t.some(a=>a.name===C),y=!(j!=="none")||b.trim().length>0,w=D&&g.trim().length>0&&y&&!c,P=g.trim().length>0&&y;function ee(){d(""),p(""),S(""),h("none"),k("")}function se(a){return a.split(",").map(l=>l.trim()).filter(Boolean)}function V(a,l){if(a==="none")return{type:"none"};const x=l.trim();return x?{type:a,token:x}:{type:a}}async function te(){if(!w)return;const a={name:C,endpoint:g.trim(),aliases:se(m),auth:V(j,b),enabled:!0};r([...t,a]),ee(),f.success(s("agents.acp.toast.staged"))}async function ae(){if(P)try{const a=await i.mutateAsync({endpoint:g.trim(),auth:V(j,b)});f.success(s("agents.acp.toast.testOk",{name:a.name}))}catch(a){f.error(F(a,s).message)}}async function ne(a){const l=t[a];if(l){if(l.auth?.type!=="none"&&l.auth?.token&&Se(l.auth.token)){f.error(s("agents.acp.toast.testMasked"));return}try{const x=await i.mutateAsync({endpoint:l.endpoint,auth:l.auth});f.success(s("agents.acp.toast.testOk",{name:x.name}))}catch(x){f.error(F(x,s).message)}}}function ce(a,l){const x=t.map((E,A)=>A===a?{...E,enabled:l}:E);r(x)}function ie(a){r(t.filter((l,x)=>x!==a))}async function le(){const a=_.trim();if(a)try{const l=await n.mutateAsync({baseUrl:a,register:!1}),x=new Set(t.map(A=>A.name)),E=l.agents.filter(A=>!x.has(A.name));if(E.length===0){f.info(s("agents.acp.toast.discoverEmpty"));return}r([...t,...E.map(A=>({...A,enabled:!0}))]),f.success(s("agents.acp.toast.discoverAdded",{count:E.length})),z(""),T(!1)}catch(l){f.error(F(l,s).message)}}return e.jsxs("section",{className:"rounded-md border border-border bg-surface",children:[e.jsxs("header",{className:"flex items-center gap-2 border-b border-border px-4 py-3",children:[e.jsx(q,{className:"h-4 w-4 text-text-dim"}),e.jsx("h2",{className:"text-sm font-semibold",children:s("agents.acp.title")}),e.jsx(U,{variant:"outline",className:"text-[10px]",children:t.length}),e.jsxs(N,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>T(a=>!a),children:[e.jsx(H,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("agents.acp.discoverBtn")})]})]}),e.jsx("p",{className:"px-4 pt-2 text-xs text-text-dim",children:s("agents.acp.subtitle")}),$&&e.jsxs("div",{className:"border-t border-border bg-surface-2 px-4 py-3",children:[e.jsx(O,{htmlFor:"acp-baseurl",className:"text-xs font-medium",children:s("agents.acp.baseUrl")}),e.jsx("p",{className:"mt-1 text-[11px] text-text-dim",children:s("agents.acp.baseUrlHint")}),e.jsxs("div",{className:"mt-2 flex flex-wrap gap-2",children:[e.jsx(M,{id:"acp-baseurl",value:_,onChange:a=>z(a.target.value),placeholder:"https://agents.example.com",className:"flex-1 min-w-[200px] font-mono text-xs"}),e.jsxs(N,{variant:"secondary",size:"sm",onClick:()=>void le(),disabled:!_.trim()||n.isPending,children:[n.isPending?e.jsx(B,{className:"h-4 w-4 animate-spin"}):e.jsx(H,{className:"h-4 w-4"}),s("agents.acp.runDiscover")]})]})]}),t.length===0?e.jsx("div",{className:"px-4 py-6",children:e.jsx(re,{icon:e.jsx(q,{}),title:s("agents.acp.empty.title"),description:s("agents.acp.empty.description")})}):e.jsx("ul",{className:"divide-y divide-border",children:t.map((a,l)=>e.jsx(Ae,{agent:a,onToggle:x=>ce(l,x),onTest:()=>void ne(l),onRemove:()=>ie(l),testing:i.isPending},`${a.name}-${l}`))}),e.jsxs("div",{className:"border-t border-border px-4 py-3",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-text-dim",children:s("agents.acp.addTitle")}),e.jsxs("div",{className:"mt-2 grid grid-cols-1 gap-2 sm:grid-cols-2",children:[e.jsx(R,{label:s("agents.acp.name"),hint:s("agents.acp.nameHint"),children:e.jsx(M,{value:o,onChange:a=>d(a.target.value),placeholder:"my-agent","aria-invalid":o.length>0&&!D})}),e.jsx(R,{label:s("agents.acp.aliases"),hint:s("agents.acp.aliasesHint"),children:e.jsx(M,{value:m,onChange:a=>p(a.target.value),placeholder:"ma, agent1"})}),e.jsx(R,{label:s("agents.acp.endpoint"),hint:s("agents.acp.endpointHint"),children:e.jsx(M,{value:g,onChange:a=>S(a.target.value),placeholder:"https://example.com/agents/weather",className:"font-mono text-xs"})}),e.jsx(R,{label:s("agents.acp.authType"),children:e.jsxs(Z,{value:j,onValueChange:a=>h(a),children:[e.jsx(X,{children:e.jsx(Y,{})}),e.jsx(J,{children:ve.map(a=>e.jsx(I,{value:a,children:s(`agents.acp.auth.${a}`)},a))})]})}),j!=="none"&&e.jsx(R,{label:s("agents.acp.token"),className:"sm:col-span-2",children:e.jsx(M,{type:"password",value:b,onChange:a=>k(a.target.value),placeholder:s("agents.acp.tokenPlaceholder"),autoComplete:"new-password"})})]}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsxs(N,{variant:"secondary",size:"sm",onClick:()=>void ae(),disabled:!P||i.isPending,children:[i.isPending?e.jsx(B,{className:"h-4 w-4 animate-spin"}):e.jsx(H,{className:"h-4 w-4"}),s("agents.acp.testBtn")]}),e.jsxs(N,{size:"sm",onClick:()=>void te(),disabled:!w,children:[e.jsx(be,{className:"h-4 w-4"}),s("agents.acp.addBtn")]}),c&&e.jsx("span",{className:"self-center text-xs text-warning",children:s("agents.acp.dupName")})]})]})]})}function Ae({agent:t,onToggle:r,onTest:s,onRemove:i,testing:n}){const{t:o}=L("settings"),d=t.enabled!==!1,m=t.auth?.type??"none";return e.jsxs("li",{className:"flex flex-wrap items-center gap-3 px-4 py-3",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:t.name}),e.jsx(U,{variant:"outline",className:"text-[10px] uppercase",children:o(`agents.acp.auth.${m}`)}),t.aliases&&t.aliases.length>0&&e.jsx("span",{className:"text-xs text-text-muted font-mono",children:t.aliases.map(p=>`/${p}`).join(", ")})]}),e.jsx("p",{className:"mt-0.5 truncate font-mono text-xs text-text-dim",title:t.endpoint,children:t.endpoint})]}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-text-dim",children:[e.jsx("input",{type:"checkbox",checked:d,onChange:p=>r(p.target.checked),className:"h-4 w-4 accent-accent cursor-pointer"}),o(d?"agents.acp.on":"agents.acp.off")]}),e.jsx(N,{variant:"ghost",size:"sm",onClick:s,disabled:n,"aria-label":o("agents.acp.testBtn"),children:n?e.jsx(B,{className:"h-4 w-4 animate-spin"}):e.jsx(H,{className:"h-4 w-4"})}),e.jsx(N,{variant:"ghost",size:"sm",onClick:i,"aria-label":o("agents.acp.removeBtn"),className:"text-danger hover:text-danger",children:e.jsx(fe,{className:"h-4 w-4"})})]})}function R({label:t,hint:r,className:s,children:i}){return e.jsxs("div",{className:K("flex flex-col gap-1",s),children:[e.jsx(O,{className:"text-xs font-medium",children:t}),i,r&&e.jsx("p",{className:"text-[11px] text-text-dim",children:r})]})}function Se(t){return/\*{3,}/.test(t)}export{Ue as default};
|
|
12
|
-
//# sourceMappingURL=agents-BMI1WbZj.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agents-BMI1WbZj.js","sources":["../../node_modules/lucide-react/dist/esm/icons/bot.js","../../node_modules/lucide-react/dist/esm/icons/plus.js","../../src/routes/settings/agents.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Bot = createLucideIcon(\"Bot\", [\n [\"path\", { d: \"M12 8V4H8\", key: \"hb8ula\" }],\n [\"rect\", { width: \"16\", height: \"12\", x: \"4\", y: \"8\", rx: \"2\", key: \"enze0r\" }],\n [\"path\", { d: \"M2 14h2\", key: \"vft8re\" }],\n [\"path\", { d: \"M20 14h2\", key: \"4cs60a\" }],\n [\"path\", { d: \"M15 13v2\", key: \"1xurst\" }],\n [\"path\", { d: \"M9 13v2\", key: \"rq6x2g\" }]\n]);\n\nexport { Bot as default };\n//# sourceMappingURL=bot.js.map\n","/**\n * @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 Plus = createLucideIcon(\"Plus\", [\n [\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }],\n [\"path\", { d: \"M12 5v14\", key: \"s699le\" }]\n]);\n\nexport { Plus as default };\n//# sourceMappingURL=plus.js.map\n","/**\n * /settings/agents — built-in adapters + remote (ACP) agents.\n *\n * Two cards on one page:\n * 1. Built-in adapters (claude-code / codex / copilot / opencode):\n * enable/disable + default-agent picker. Mirrors v1's \"Agents\".\n * 2. Remote (ACP) agents: name/endpoint/auth-type table + manual\n * add form. Mirrors v1's \"Remote Agents (ACP)\" card. Discover\n * via `<baseUrl>/.well-known/acp` is available as a secondary\n * bulk-import form.\n *\n * Both cards share one save bar — PUT /api/config writes `agents[]`,\n * `defaultAgent`, and `acpAgents[]` atomically so the default never\n * goes out of sync with the enabled list, and partial ACP edits\n * don't ship without the user's intent.\n *\n * Masked tokens: GET returns `ab****yz` for ACP auth.token; PUT\n * detects this pattern and preserves the on-disk value so we never\n * overwrite a real token with its mask. New tokens (typed into the\n * add form or \"edit\" inline) flow through verbatim.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport {\n Bot, Loader2, Network, Plus, RefreshCcw, Save, Search, Trash2, X,\n} from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { useAgentsStatus } from '@/hooks/use-workspace'\nimport {\n useConfig,\n useDiscoverAcp,\n useTestAcp,\n useUpdateConfig,\n} from '@/hooks/use-settings'\nimport { describeError } from '@/lib/api/errors'\nimport { cn } from '@/lib/utils'\nimport type { ACPAgentConfig, ACPAuthConfig, ACPAuthType } from '@/types/api'\n\n/** Mirror of v1 settings.html:BUILTIN_AGENTS. Hardcoded because\n * backend doesn't expose this metadata yet; the table changes\n * rarely enough that copying it here is fine. */\nconst BUILTIN_AGENTS: Record<string, { aliases: string[]; pkg: string }> = {\n 'claude-code': { aliases: ['cc', 'claude'], pkg: '@anthropic-ai/claude-code' },\n 'codex': { aliases: ['cx'], pkg: '@openai/codex' },\n 'copilot': { aliases: ['co'], pkg: '@github/copilot' },\n 'opencode': { aliases: ['oc'], pkg: 'opencode-ai' },\n}\n\nconst AGENT_NAMES = Object.keys(BUILTIN_AGENTS)\n\nexport default function SettingsAgentsRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const cfgQuery = useConfig()\n const statusQuery = useAgentsStatus()\n const updateCfg = useUpdateConfig()\n\n const cfg = cfgQuery.data\n const status = statusQuery.data ?? {}\n\n /** Local draft so toggles + default-picker + ACP edits can stage\n * changes before a single Save. `null` means \"sync from cfg on\n * next paint\". */\n const [draftEnabled, setDraftEnabled] = useState<string[] | null>(null)\n const [draftDefault, setDraftDefault] = useState<string | null>(null)\n const [draftAcp, setDraftAcp] = useState<ACPAgentConfig[] | null>(null)\n\n useEffect(() => {\n if (cfg && draftEnabled == null) setDraftEnabled(cfg.agents ?? [])\n if (cfg && draftDefault == null) setDraftDefault(cfg.defaultAgent ?? '')\n if (cfg && draftAcp == null) setDraftAcp(cfg.acpAgents ?? [])\n }, [cfg, draftEnabled, draftDefault, draftAcp])\n\n const enabled = draftEnabled ?? cfg?.agents ?? []\n const defaultAgent = draftDefault ?? cfg?.defaultAgent ?? ''\n const acpAgents = draftAcp ?? cfg?.acpAgents ?? []\n\n const isDirty = useMemo(() => {\n if (!cfg) return false\n const enabledSame =\n enabled.length === (cfg.agents?.length ?? 0)\n && enabled.every((a) => cfg.agents?.includes(a))\n const defaultSame = defaultAgent === (cfg.defaultAgent ?? '')\n const acpSame = acpEqual(acpAgents, cfg.acpAgents ?? [])\n return !enabledSame || !defaultSame || !acpSame\n }, [cfg, enabled, defaultAgent, acpAgents])\n\n /** Eligible defaults = installed + enabled. Picker disables when\n * empty (no agent is both). */\n const eligibleDefaults = useMemo(\n () => AGENT_NAMES.filter((a) => enabled.includes(a) && status[a]),\n [enabled, status],\n )\n\n function toggleAgent(name: string, on: boolean): void {\n const next = on\n ? Array.from(new Set([...enabled, name]))\n : enabled.filter((a) => a !== name)\n setDraftEnabled(next)\n // If the default just got disabled, clear it so save doesn't\n // ship an inconsistent pair.\n if (!on && name === defaultAgent) setDraftDefault('')\n }\n\n async function onSave(): Promise<void> {\n if (!cfg) return\n try {\n await updateCfg.mutateAsync({\n ...cfg,\n agents: enabled,\n defaultAgent: defaultAgent || cfg.defaultAgent,\n acpAgents,\n })\n toast.success(t('agents.toast.saved'))\n // Reset drafts so the next paint reads from refreshed cfg.\n setDraftEnabled(null)\n setDraftDefault(null)\n setDraftAcp(null)\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n function onDiscard(): void {\n setDraftEnabled(null)\n setDraftDefault(null)\n setDraftAcp(null)\n }\n\n function updateAcp(next: ACPAgentConfig[]): void {\n setDraftAcp(next)\n }\n\n return (\n <div className=\"mx-auto flex max-w-4xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('agents.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => {\n void cfgQuery.refetch()\n void statusQuery.refetch()\n }}\n disabled={cfgQuery.isFetching || statusQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {(cfgQuery.isFetching || statusQuery.isFetching)\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('agents.subtitle')}</p>\n </header>\n\n {cfgQuery.isLoading ? (\n <div className=\"h-64 rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <>\n {/* Agent rows */}\n <div className=\"flex flex-col divide-y divide-border rounded-md border border-border bg-surface\">\n {AGENT_NAMES.map((name) => {\n const info = BUILTIN_AGENTS[name]!\n const installed = !!status[name]\n const isEnabled = enabled.includes(name)\n return (\n <AgentRow\n key={name}\n name={name}\n aliases={info.aliases}\n pkg={info.pkg}\n installed={installed}\n enabled={isEnabled}\n onToggle={(on) => toggleAgent(name, on)}\n />\n )\n })}\n </div>\n\n {/* Default agent picker */}\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <Label htmlFor=\"default-agent\" className=\"text-sm font-medium\">\n {t('agents.defaultAgent')}\n </Label>\n <p className=\"mt-1 text-xs text-text-dim\">{t('agents.defaultAgentHint')}</p>\n <Select\n value={defaultAgent || '__none__'}\n onValueChange={(v) => setDraftDefault(v === '__none__' ? '' : v)}\n disabled={eligibleDefaults.length === 0}\n >\n <SelectTrigger id=\"default-agent\" className=\"mt-2 w-64\">\n <SelectValue placeholder={t('agents.noEligible')} />\n </SelectTrigger>\n <SelectContent>\n {eligibleDefaults.length === 0 ? (\n <SelectItem value=\"__none__\" disabled>{t('agents.noEligible')}</SelectItem>\n ) : (\n eligibleDefaults.map((a) => (\n <SelectItem key={a} value={a}>{a}</SelectItem>\n ))\n )}\n </SelectContent>\n </Select>\n </section>\n\n {/* Remote (ACP) agents */}\n <AcpCard\n agents={acpAgents}\n onChange={updateAcp}\n />\n\n {/* Save bar */}\n {isDirty && (\n <div className=\"sticky bottom-0 flex items-center gap-2 rounded-md border border-border bg-surface px-4 py-2 shadow-md\">\n <Badge variant=\"info\">{t('agents.dirtyHint')}</Badge>\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={onDiscard}\n disabled={updateCfg.isPending}\n >\n <X className=\"h-4 w-4\" />\n {t('agents.discard')}\n </Button>\n <Button\n size=\"sm\"\n onClick={() => void onSave()}\n disabled={updateCfg.isPending}\n >\n {updateCfg.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Save className=\"h-4 w-4\" />}\n {updateCfg.isPending ? t('agents.saving') : t('agents.saveBtn')}\n </Button>\n </div>\n )}\n </>\n )}\n </div>\n )\n}\n\n/* ─────────────── Row ─────────────── */\n\ninterface AgentRowProps {\n name: string\n aliases: string[]\n pkg: string\n installed: boolean\n enabled: boolean\n onToggle: (on: boolean) => void\n}\n\nfunction AgentRow({\n name, aliases, pkg, installed, enabled, onToggle,\n}: AgentRowProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <div className=\"flex items-start gap-3 px-3 py-3\">\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-surface-2 text-text-dim\">\n <Bot className=\"h-4 w-4\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium text-text\">{name}</span>\n <Badge variant={installed ? 'success' : 'outline'} className=\"text-[10px]\">\n <span className={cn(\n 'inline-block h-1.5 w-1.5 rounded-full',\n installed ? 'bg-success' : 'bg-text-muted',\n )} />\n {installed ? t('agents.online') : t('agents.offline')}\n </Badge>\n </div>\n <p className=\"mt-0.5 text-xs text-text-dim\">\n <span className=\"text-text-muted\">{t('agents.aliasesLabel')}: </span>\n <span className=\"font-mono\">{aliases.map((a) => `/${a}`).join(', ')}</span>\n </p>\n {!installed && (\n <p className=\"mt-1 text-xs text-warning\">\n {t('agents.installHint', { pkg })}\n </p>\n )}\n </div>\n <input\n type=\"checkbox\"\n checked={enabled}\n onChange={(e) => onToggle(e.target.checked)}\n className=\"h-4 w-4 mt-2 accent-accent cursor-pointer\"\n />\n </div>\n )\n}\n\n/* ─────────────── Remote (ACP) ─────────────── */\n\nconst AUTH_TYPES: ACPAuthType[] = ['none', 'apikey', 'bearer']\nconst NAME_RE = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/\n\n/** Compare two ACP lists by value. Order matters because the backend\n * preserves index identity (`existing.acpAgents[i]`) when merging\n * masked tokens — reordering = mask drift risk. */\nfunction acpEqual(a: ACPAgentConfig[], b: ACPAgentConfig[]): boolean {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n const x = a[i]!\n const y = b[i]!\n if (x.name !== y.name) return false\n if (x.endpoint !== y.endpoint) return false\n if ((x.enabled ?? true) !== (y.enabled ?? true)) return false\n const xa = (x.aliases ?? []).join(',')\n const ya = (y.aliases ?? []).join(',')\n if (xa !== ya) return false\n const xat = x.auth?.type ?? 'none'\n const yat = y.auth?.type ?? 'none'\n if (xat !== yat) return false\n if ((x.auth?.token ?? '') !== (y.auth?.token ?? '')) return false\n }\n return true\n}\n\ninterface AcpCardProps {\n agents: ACPAgentConfig[]\n onChange: (next: ACPAgentConfig[]) => void\n}\n\nfunction AcpCard({ agents, onChange }: AcpCardProps): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const testMut = useTestAcp()\n const discoverMut = useDiscoverAcp()\n\n // Add-form state. We keep the typed token in plain state so the\n // user can paste before save; the masked round-trip from backend\n // only matters for existing rows.\n const [name, setName] = useState('')\n const [aliasesText, setAliasesText] = useState('')\n const [endpoint, setEndpoint] = useState('')\n const [authType, setAuthType] = useState<ACPAuthType>('none')\n const [token, setToken] = useState('')\n\n // Bulk-discover sub-form state. Hidden behind a toggle so the\n // primary path (manual add) stays uncluttered.\n const [showDiscover, setShowDiscover] = useState(false)\n const [baseUrl, setBaseUrl] = useState('')\n\n const trimmedName = name.trim()\n const nameValid = trimmedName.length > 0 && NAME_RE.test(trimmedName)\n const dup = agents.some((a) => a.name === trimmedName)\n const tokenRequired = authType !== 'none'\n const tokenOk = !tokenRequired || token.trim().length > 0\n const canAdd = nameValid && endpoint.trim().length > 0 && tokenOk && !dup\n const canTestNew = endpoint.trim().length > 0 && tokenOk\n\n function clearForm(): void {\n setName('')\n setAliasesText('')\n setEndpoint('')\n setAuthType('none')\n setToken('')\n }\n\n function parseAliases(text: string): string[] {\n return text.split(',').map((s) => s.trim()).filter(Boolean)\n }\n\n function buildAuth(type: ACPAuthType, tok: string): ACPAuthConfig | undefined {\n if (type === 'none') return { type: 'none' }\n const trimmed = tok.trim()\n if (!trimmed) return { type } // no token yet; save will reject\n return { type, token: trimmed }\n }\n\n async function onAdd(): Promise<void> {\n if (!canAdd) return\n const next: ACPAgentConfig = {\n name: trimmedName,\n endpoint: endpoint.trim(),\n aliases: parseAliases(aliasesText),\n auth: buildAuth(authType, token),\n enabled: true,\n }\n onChange([...agents, next])\n clearForm()\n toast.success(t('agents.acp.toast.staged'))\n }\n\n async function onTestNew(): Promise<void> {\n if (!canTestNew) return\n try {\n const res = await testMut.mutateAsync({\n endpoint: endpoint.trim(),\n auth: buildAuth(authType, token),\n })\n toast.success(t('agents.acp.toast.testOk', { name: res.name }))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n async function onTestRow(idx: number): Promise<void> {\n const a = agents[idx]\n if (!a) return\n // Masked tokens stay masked on the wire — backend's PUT mask-detect\n // is symmetric, but the test endpoint reads what we send. We can't\n // unmask client-side; warn the operator.\n if (a.auth?.type !== 'none' && a.auth?.token && isMaskedToken(a.auth.token)) {\n toast.error(t('agents.acp.toast.testMasked'))\n return\n }\n try {\n const res = await testMut.mutateAsync({\n endpoint: a.endpoint,\n auth: a.auth,\n })\n toast.success(t('agents.acp.toast.testOk', { name: res.name }))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n function onToggleRow(idx: number, on: boolean): void {\n const next = agents.map((a, i) => (i === idx ? { ...a, enabled: on } : a))\n onChange(next)\n }\n\n function onRemoveRow(idx: number): void {\n onChange(agents.filter((_, i) => i !== idx))\n }\n\n async function onDiscoverRun(): Promise<void> {\n const url = baseUrl.trim()\n if (!url) return\n try {\n const res = await discoverMut.mutateAsync({ baseUrl: url, register: false })\n // Stage new agents that aren't already in the list (by name).\n const existing = new Set(agents.map((a) => a.name))\n const incoming = res.agents.filter((a) => !existing.has(a.name))\n if (incoming.length === 0) {\n toast.info(t('agents.acp.toast.discoverEmpty'))\n return\n }\n onChange([...agents, ...incoming.map((a) => ({ ...a, enabled: true }))])\n toast.success(t('agents.acp.toast.discoverAdded', { count: incoming.length }))\n setBaseUrl('')\n setShowDiscover(false)\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"flex items-center gap-2 border-b border-border px-4 py-3\">\n <Network className=\"h-4 w-4 text-text-dim\" />\n <h2 className=\"text-sm font-semibold\">{t('agents.acp.title')}</h2>\n <Badge variant=\"outline\" className=\"text-[10px]\">{agents.length}</Badge>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => setShowDiscover((v) => !v)}\n >\n <Search className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">{t('agents.acp.discoverBtn')}</span>\n </Button>\n </header>\n <p className=\"px-4 pt-2 text-xs text-text-dim\">{t('agents.acp.subtitle')}</p>\n\n {/* Discover form (collapsed by default) */}\n {showDiscover && (\n <div className=\"border-t border-border bg-surface-2 px-4 py-3\">\n <Label htmlFor=\"acp-baseurl\" className=\"text-xs font-medium\">\n {t('agents.acp.baseUrl')}\n </Label>\n <p className=\"mt-1 text-[11px] text-text-dim\">{t('agents.acp.baseUrlHint')}</p>\n <div className=\"mt-2 flex flex-wrap gap-2\">\n <Input\n id=\"acp-baseurl\"\n value={baseUrl}\n onChange={(e) => setBaseUrl(e.target.value)}\n placeholder=\"https://agents.example.com\"\n className=\"flex-1 min-w-[200px] font-mono text-xs\"\n />\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => void onDiscoverRun()}\n disabled={!baseUrl.trim() || discoverMut.isPending}\n >\n {discoverMut.isPending\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <Search className=\"h-4 w-4\" />}\n {t('agents.acp.runDiscover')}\n </Button>\n </div>\n </div>\n )}\n\n {/* Registered ACP agents */}\n {agents.length === 0 ? (\n <div className=\"px-4 py-6\">\n <EmptyState\n icon={<Network />}\n title={t('agents.acp.empty.title')}\n description={t('agents.acp.empty.description')}\n />\n </div>\n ) : (\n <ul className=\"divide-y divide-border\">\n {agents.map((a, i) => (\n <AcpRow\n key={`${a.name}-${i}`}\n agent={a}\n onToggle={(on) => onToggleRow(i, on)}\n onTest={() => void onTestRow(i)}\n onRemove={() => onRemoveRow(i)}\n testing={testMut.isPending}\n />\n ))}\n </ul>\n )}\n\n {/* Add-agent form */}\n <div className=\"border-t border-border px-4 py-3\">\n <h3 className=\"text-xs font-semibold uppercase tracking-wide text-text-dim\">\n {t('agents.acp.addTitle')}\n </h3>\n <div className=\"mt-2 grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <Field label={t('agents.acp.name')} hint={t('agents.acp.nameHint')}>\n <Input\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"my-agent\"\n aria-invalid={name.length > 0 && !nameValid}\n />\n </Field>\n <Field label={t('agents.acp.aliases')} hint={t('agents.acp.aliasesHint')}>\n <Input\n value={aliasesText}\n onChange={(e) => setAliasesText(e.target.value)}\n placeholder=\"ma, agent1\"\n />\n </Field>\n <Field label={t('agents.acp.endpoint')} hint={t('agents.acp.endpointHint')}>\n <Input\n value={endpoint}\n onChange={(e) => setEndpoint(e.target.value)}\n placeholder=\"https://example.com/agents/weather\"\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field label={t('agents.acp.authType')}>\n <Select value={authType} onValueChange={(v) => setAuthType(v as ACPAuthType)}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n {AUTH_TYPES.map((a) => (\n <SelectItem key={a} value={a}>{t(`agents.acp.auth.${a}`)}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n {authType !== 'none' && (\n <Field label={t('agents.acp.token')} className=\"sm:col-span-2\">\n <Input\n type=\"password\"\n value={token}\n onChange={(e) => setToken(e.target.value)}\n placeholder={t('agents.acp.tokenPlaceholder')}\n autoComplete=\"new-password\"\n />\n </Field>\n )}\n </div>\n <div className=\"mt-3 flex flex-wrap gap-2\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => void onTestNew()}\n disabled={!canTestNew || testMut.isPending}\n >\n {testMut.isPending\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <Search className=\"h-4 w-4\" />}\n {t('agents.acp.testBtn')}\n </Button>\n <Button\n size=\"sm\"\n onClick={() => void onAdd()}\n disabled={!canAdd}\n >\n <Plus className=\"h-4 w-4\" />\n {t('agents.acp.addBtn')}\n </Button>\n {dup && (\n <span className=\"self-center text-xs text-warning\">\n {t('agents.acp.dupName')}\n </span>\n )}\n </div>\n </div>\n </section>\n )\n}\n\ninterface AcpRowProps {\n agent: ACPAgentConfig\n onToggle: (on: boolean) => void\n onTest: () => void\n onRemove: () => void\n testing: boolean\n}\n\nfunction AcpRow({ agent, onToggle, onTest, onRemove, testing }: AcpRowProps): JSX.Element {\n const { t } = useTranslation('settings')\n const isOn = agent.enabled !== false\n const authType = agent.auth?.type ?? 'none'\n return (\n <li className=\"flex flex-wrap items-center gap-3 px-4 py-3\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium text-text\">{agent.name}</span>\n <Badge variant=\"outline\" className=\"text-[10px] uppercase\">\n {t(`agents.acp.auth.${authType}`)}\n </Badge>\n {agent.aliases && agent.aliases.length > 0 && (\n <span className=\"text-xs text-text-muted font-mono\">\n {agent.aliases.map((a) => `/${a}`).join(', ')}\n </span>\n )}\n </div>\n <p className=\"mt-0.5 truncate font-mono text-xs text-text-dim\" title={agent.endpoint}>\n {agent.endpoint}\n </p>\n </div>\n <label className=\"flex items-center gap-1.5 text-xs text-text-dim\">\n <input\n type=\"checkbox\"\n checked={isOn}\n onChange={(e) => onToggle(e.target.checked)}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n {isOn ? t('agents.acp.on') : t('agents.acp.off')}\n </label>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onTest}\n disabled={testing}\n aria-label={t('agents.acp.testBtn')}\n >\n {testing ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Search className=\"h-4 w-4\" />}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onRemove}\n aria-label={t('agents.acp.removeBtn')}\n className=\"text-danger hover:text-danger\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </li>\n )\n}\n\ninterface FieldProps {\n label: string\n hint?: string\n className?: string\n children: React.ReactNode\n}\n\nfunction Field({ label, hint, className, children }: FieldProps): JSX.Element {\n return (\n <div className={cn('flex flex-col gap-1', className)}>\n <Label className=\"text-xs font-medium\">{label}</Label>\n {children}\n {hint && <p className=\"text-[11px] text-text-dim\">{hint}</p>}\n </div>\n )\n}\n\n/** Tokens look like `ab****yz` from the masked GET response. We\n * shouldn't send them back unchanged for test (the backend would\n * fail auth), and we shouldn't include them in the test mutation\n * body either. Treat any string with 3+ consecutive `*` as masked. */\nfunction isMaskedToken(s: string): boolean {\n return /\\*{3,}/.test(s)\n}\n"],"names":["Bot","createLucideIcon","Plus","BUILTIN_AGENTS","AGENT_NAMES","SettingsAgentsRoute","useTranslation","cfgQuery","useConfig","statusQuery","useAgentsStatus","updateCfg","useUpdateConfig","cfg","status","draftEnabled","setDraftEnabled","useState","draftDefault","setDraftDefault","draftAcp","setDraftAcp","useEffect","enabled","defaultAgent","acpAgents","isDirty","useMemo","enabledSame","a","defaultSame","acpSame","acpEqual","eligibleDefaults","toggleAgent","name","on","next","onSave","toast","err","describeError","onDiscard","updateAcp","jsxs","jsx","Button","Loader2","RefreshCcw","Fragment","info","installed","isEnabled","AgentRow","Label","Select","v","SelectTrigger","SelectValue","SelectContent","SelectItem","AcpCard","Badge","X","Save","aliases","pkg","onToggle","t","cn","e","AUTH_TYPES","NAME_RE","b","i","x","y","xa","ya","xat","yat","agents","onChange","testMut","useTestAcp","discoverMut","useDiscoverAcp","setName","aliasesText","setAliasesText","endpoint","setEndpoint","authType","setAuthType","token","setToken","showDiscover","setShowDiscover","baseUrl","setBaseUrl","trimmedName","nameValid","dup","tokenOk","canAdd","canTestNew","clearForm","parseAliases","text","s","buildAuth","type","tok","trimmed","onAdd","onTestNew","res","onTestRow","idx","isMaskedToken","onToggleRow","onRemoveRow","_","onDiscoverRun","url","existing","incoming","Network","Search","Input","EmptyState","AcpRow","Field","agent","onTest","onRemove","testing","isOn","Trash2","label","hint","className","children"],"mappings":"qqBAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,GAAMC,EAAiB,MAAO,CAClC,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAQ,CAAE,EAC1C,CAAC,OAAQ,CAAE,MAAO,KAAM,OAAQ,KAAM,EAAG,IAAK,EAAG,IAAK,GAAI,IAAK,IAAK,QAAQ,CAAE,EAC9E,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAQ,CAAE,EACxC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAQ,CAAE,CAC1C,CAAC,EChBD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMC,GAAOD,EAAiB,OAAQ,CACpC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,CAC3C,CAAC,EC2CKE,EAAqE,CACzE,cAAe,CAAE,QAAS,CAAC,KAAM,QAAQ,EAAG,IAAK,2BAAA,EACjD,MAAe,CAAE,QAAS,CAAC,IAAI,EAAa,IAAK,eAAA,EACjD,QAAe,CAAE,QAAS,CAAC,IAAI,EAAa,IAAK,iBAAA,EACjD,SAAe,CAAE,QAAS,CAAC,IAAI,EAAa,IAAK,aAAA,CACnD,EAEMC,EAAc,OAAO,KAAKD,CAAc,EAE9C,SAAwBE,IAAmC,CACzD,KAAM,CAAE,CAAA,EAAMC,EAAe,CAAC,WAAY,QAAQ,CAAC,EAC7CC,EAAWC,GAAA,EACXC,EAAcC,GAAA,EACdC,EAAYC,GAAA,EAEZC,EAAMN,EAAS,KACfO,EAASL,EAAY,MAAQ,CAAA,EAK7B,CAACM,EAAcC,CAAe,EAAIC,EAAAA,SAA0B,IAAI,EAChE,CAACC,EAAcC,CAAe,EAAIF,EAAAA,SAAwB,IAAI,EAC9D,CAACG,EAAUC,CAAW,EAAIJ,EAAAA,SAAkC,IAAI,EAEtEK,EAAAA,UAAU,IAAM,CACVT,GAAOE,GAAgB,QAAsBF,EAAI,QAAU,EAAE,EAC7DA,GAAOK,GAAgB,MAAMC,EAAgBN,EAAI,cAAgB,EAAE,EACnEA,GAAOO,GAAY,QAAkBP,EAAI,WAAa,EAAE,CAC9D,EAAG,CAACA,EAAKE,EAAcG,EAAcE,CAAQ,CAAC,EAE9C,MAAMG,EAAUR,GAAgBF,GAAK,QAAU,CAAA,EACzCW,EAAeN,GAAgBL,GAAK,cAAgB,GACpDY,EAAYL,GAAYP,GAAK,WAAa,CAAA,EAE1Ca,EAAUC,EAAAA,QAAQ,IAAM,CAC5B,GAAI,CAACd,EAAK,MAAO,GACjB,MAAMe,EACJL,EAAQ,UAAYV,EAAI,QAAQ,QAAU,IACvCU,EAAQ,MAAOM,GAAMhB,EAAI,QAAQ,SAASgB,CAAC,CAAC,EAC3CC,EAAcN,KAAkBX,EAAI,cAAgB,IACpDkB,EAAUC,GAASP,EAAWZ,EAAI,WAAa,CAAA,CAAE,EACvD,MAAO,CAACe,GAAe,CAACE,GAAe,CAACC,CAC1C,EAAG,CAAClB,EAAKU,EAASC,EAAcC,CAAS,CAAC,EAIpCQ,EAAmBN,EAAAA,QACvB,IAAMvB,EAAY,OAAQyB,GAAMN,EAAQ,SAASM,CAAC,GAAKf,EAAOe,CAAC,CAAC,EAChE,CAACN,EAAST,CAAM,CAAA,EAGlB,SAASoB,EAAYC,EAAcC,EAAmB,CACpD,MAAMC,EAAOD,EACT,MAAM,KAAK,IAAI,IAAI,CAAC,GAAGb,EAASY,CAAI,CAAC,CAAC,EACtCZ,EAAQ,OAAQM,GAAMA,IAAMM,CAAI,EACpCnB,EAAgBqB,CAAI,EAGhB,CAACD,GAAMD,IAASX,KAA8B,EAAE,CACtD,CAEA,eAAec,GAAwB,CACrC,GAAKzB,EACL,GAAI,CACF,MAAMF,EAAU,YAAY,CAC1B,GAAGE,EACH,OAAQU,EACR,aAAcC,GAAgBX,EAAI,aAClC,UAAAY,CAAA,CACD,EACDc,EAAM,QAAQ,EAAE,oBAAoB,CAAC,EAErCvB,EAAgB,IAAI,EACpBG,EAAgB,IAAI,EACpBE,EAAY,IAAI,CAClB,OAASmB,EAAK,CACZD,EAAM,MAAME,EAAcD,EAAK,CAAC,EAAE,OAAO,CAC3C,CACF,CAEA,SAASE,GAAkB,CACzB1B,EAAgB,IAAI,EACpBG,EAAgB,IAAI,EACpBE,EAAY,IAAI,CAClB,CAEA,SAASsB,EAAUN,EAA8B,CAC/ChB,EAAYgB,CAAI,CAClB,CAEA,OACEO,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,sBAChB,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAC,MAAC,KAAA,CAAG,UAAU,wBAAyB,SAAA,EAAE,cAAc,EAAE,EACzDD,EAAAA,KAACE,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,UACV,QAAS,IAAM,CACRvC,EAAS,QAAA,EACTE,EAAY,QAAA,CACnB,EACA,SAAUF,EAAS,YAAcE,EAAY,WAC7C,aAAY,EAAE,kBAAmB,CAAE,GAAI,SAAU,EAE/C,SAAA,CAAAF,EAAS,YAAcE,EAAY,WACjCoC,EAAAA,IAACE,EAAA,CAAQ,UAAU,sBAAA,CAAuB,EAC1CF,EAAAA,IAACG,GAAA,CAAW,UAAU,SAAA,CAAU,EACpCH,EAAAA,IAAC,OAAA,CAAK,UAAU,mBAAoB,SAAA,EAAE,kBAAmB,CAAE,GAAI,QAAA,CAAU,CAAA,CAAE,CAAA,CAAA,CAAA,CAC7E,EACF,QACC,IAAA,CAAE,UAAU,wBAAyB,SAAA,EAAE,iBAAiB,CAAA,CAAE,CAAA,EAC7D,EAECtC,EAAS,UACRsC,MAAC,OAAI,UAAU,4CAAA,CAA6C,EAE5DD,EAAAA,KAAAK,EAAAA,SAAA,CAEE,SAAA,CAAAJ,MAAC,OAAI,UAAU,kFACZ,SAAAzC,EAAY,IAAK+B,GAAS,CACzB,MAAMe,EAAO/C,EAAegC,CAAI,EAC1BgB,EAAY,CAAC,CAACrC,EAAOqB,CAAI,EACzBiB,EAAY7B,EAAQ,SAASY,CAAI,EACvC,OACEU,EAAAA,IAACQ,GAAA,CAEC,KAAAlB,EACA,QAASe,EAAK,QACd,IAAKA,EAAK,IACV,UAAAC,EACA,QAASC,EACT,SAAWhB,GAAOF,EAAYC,EAAMC,CAAE,CAAA,EANjCD,CAAA,CASX,CAAC,CAAA,CACH,EAGAS,EAAAA,KAAC,UAAA,CAAQ,UAAU,iDACjB,SAAA,CAAAC,EAAAA,IAACS,GAAM,QAAQ,gBAAgB,UAAU,sBACtC,SAAA,EAAE,qBAAqB,EAC1B,QACC,IAAA,CAAE,UAAU,6BAA8B,SAAA,EAAE,yBAAyB,EAAE,EACxEV,EAAAA,KAACW,EAAA,CACC,MAAO/B,GAAgB,WACvB,cAAgBgC,GAAMrC,EAAgBqC,IAAM,WAAa,GAAKA,CAAC,EAC/D,SAAUvB,EAAiB,SAAW,EAEtC,SAAA,CAAAY,EAAAA,IAACY,EAAA,CAAc,GAAG,gBAAgB,UAAU,YAC1C,SAAAZ,EAAAA,IAACa,EAAA,CAAY,YAAa,EAAE,mBAAmB,CAAA,CAAG,EACpD,EACAb,EAAAA,IAACc,EAAA,CACE,SAAA1B,EAAiB,SAAW,EAC3BY,EAAAA,IAACe,EAAA,CAAW,MAAM,WAAW,SAAQ,GAAE,SAAA,EAAE,mBAAmB,EAAE,EAE9D3B,EAAiB,IAAKJ,GACpBgB,EAAAA,IAACe,EAAA,CAAmB,MAAO/B,EAAI,SAAAA,CAAA,EAAdA,CAAgB,CAClC,CAAA,CAEL,CAAA,CAAA,CAAA,CACF,EACF,EAGAgB,EAAAA,IAACgB,GAAA,CACC,OAAQpC,EACR,SAAUkB,CAAA,CAAA,EAIXjB,GACCkB,EAAAA,KAAC,MAAA,CAAI,UAAU,yGACb,SAAA,CAAAC,MAACiB,EAAA,CAAM,QAAQ,OAAQ,SAAA,EAAE,kBAAkB,EAAE,EAC7ClB,EAAAA,KAACE,EAAA,CACC,QAAQ,YACR,KAAK,KACL,QAASJ,EACT,SAAU/B,EAAU,UAEpB,SAAA,CAAAkC,EAAAA,IAACkB,GAAA,CAAE,UAAU,SAAA,CAAU,EACtB,EAAE,gBAAgB,CAAA,CAAA,CAAA,EAErBnB,EAAAA,KAACE,EAAA,CACC,KAAK,KACL,QAAS,IAAM,KAAKR,EAAA,EACpB,SAAU3B,EAAU,UAEnB,SAAA,CAAAA,EAAU,gBAAaoC,EAAA,CAAQ,UAAU,uBAAuB,EAAKF,EAAAA,IAACmB,GAAA,CAAK,UAAU,SAAA,CAAU,EAC/FrD,EAAU,UAAY,EAAE,eAAe,EAAI,EAAE,gBAAgB,CAAA,CAAA,CAAA,CAChE,CAAA,CACF,CAAA,CAAA,CAEJ,CAAA,EAEJ,CAEJ,CAaA,SAAS0C,GAAS,CAChB,KAAAlB,EAAM,QAAA8B,EAAS,IAAAC,EAAK,UAAAf,EAAW,QAAA5B,EAAS,SAAA4C,CAC1C,EAA+B,CAC7B,KAAM,CAAE,EAAAC,CAAA,EAAM9D,EAAe,UAAU,EACvC,OACEsC,EAAAA,KAAC,MAAA,CAAI,UAAU,mCACb,SAAA,CAAAC,EAAAA,IAAC,OAAI,UAAU,4FACb,eAAC7C,GAAA,CAAI,UAAU,UAAU,CAAA,CAC3B,EACA4C,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAyB,SAAAV,EAAK,SAC7C2B,EAAA,CAAM,QAASX,EAAY,UAAY,UAAW,UAAU,cAC3D,SAAA,CAAAN,MAAC,QAAK,UAAWwB,EACf,wCACAlB,EAAY,aAAe,eAAA,EAC1B,EACUiB,EAAZjB,EAAc,gBAAqB,gBAAN,CAAsB,CAAA,CACtD,CAAA,EACF,EACAP,EAAAA,KAAC,IAAA,CAAE,UAAU,+BACX,SAAA,CAAAA,EAAAA,KAAC,OAAA,CAAK,UAAU,kBAAmB,SAAA,CAAAwB,EAAE,qBAAqB,EAAE,IAAA,EAAE,EAC9DvB,EAAAA,IAAC,OAAA,CAAK,UAAU,YAAa,WAAQ,IAAKhB,GAAM,IAAIA,CAAC,EAAE,EAAE,KAAK,IAAI,CAAA,CAAE,CAAA,EACtE,EACC,CAACsB,GACAN,EAAAA,IAAC,IAAA,CAAE,UAAU,4BACV,SAAAuB,EAAE,qBAAsB,CAAE,IAAAF,CAAA,CAAK,CAAA,CAClC,CAAA,EAEJ,EACArB,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,QAAStB,EACT,SAAW+C,GAAMH,EAASG,EAAE,OAAO,OAAO,EAC1C,UAAU,2CAAA,CAAA,CACZ,EACF,CAEJ,CAIA,MAAMC,GAA4B,CAAC,OAAQ,SAAU,QAAQ,EACvDC,GAAU,+BAKhB,SAASxC,GAASH,EAAqB4C,EAA8B,CACnE,GAAI5C,EAAE,SAAW4C,EAAE,OAAQ,MAAO,GAClC,QAASC,EAAI,EAAGA,EAAI7C,EAAE,OAAQ6C,IAAK,CACjC,MAAMC,EAAI9C,EAAE6C,CAAC,EACPE,EAAIH,EAAEC,CAAC,EAGb,GAFIC,EAAE,OAASC,EAAE,MACbD,EAAE,WAAaC,EAAE,WAChBD,EAAE,SAAW,OAAWC,EAAE,SAAW,IAAO,MAAO,GACxD,MAAMC,GAAMF,EAAE,SAAW,CAAA,GAAI,KAAK,GAAG,EAC/BG,GAAMF,EAAE,SAAW,CAAA,GAAI,KAAK,GAAG,EACrC,GAAIC,IAAOC,EAAI,MAAO,GACtB,MAAMC,EAAMJ,EAAE,MAAM,MAAQ,OACtBK,EAAMJ,EAAE,MAAM,MAAQ,OAE5B,GADIG,IAAQC,IACPL,EAAE,MAAM,OAAS,OAASC,EAAE,MAAM,OAAS,IAAK,MAAO,EAC9D,CACA,MAAO,EACT,CAOA,SAASf,GAAQ,CAAE,OAAAoB,EAAQ,SAAAC,GAAuC,CAChE,KAAM,CAAE,EAAAd,CAAA,EAAM9D,EAAe,CAAC,WAAY,QAAQ,CAAC,EAC7C6E,EAAUC,GAAA,EACVC,EAAcC,GAAA,EAKd,CAACnD,EAAMoD,CAAO,EAAItE,EAAAA,SAAS,EAAE,EAC7B,CAACuE,EAAaC,CAAc,EAAIxE,EAAAA,SAAS,EAAE,EAC3C,CAACyE,EAAUC,CAAW,EAAI1E,EAAAA,SAAS,EAAE,EACrC,CAAC2E,EAAUC,CAAW,EAAI5E,EAAAA,SAAsB,MAAM,EACtD,CAAC6E,EAAOC,CAAQ,EAAI9E,EAAAA,SAAS,EAAE,EAI/B,CAAC+E,EAAcC,CAAe,EAAIhF,EAAAA,SAAS,EAAK,EAChD,CAACiF,EAASC,CAAU,EAAIlF,EAAAA,SAAS,EAAE,EAEnCmF,EAAcjE,EAAK,KAAA,EACnBkE,EAAYD,EAAY,OAAS,GAAK5B,GAAQ,KAAK4B,CAAW,EAC9DE,EAAMrB,EAAO,KAAM,GAAM,EAAE,OAASmB,CAAW,EAE/CG,EAAU,EADMX,IAAa,SACDE,EAAM,KAAA,EAAO,OAAS,EAClDU,EAASH,GAAaX,EAAS,KAAA,EAAO,OAAS,GAAKa,GAAW,CAACD,EAChEG,EAAaf,EAAS,KAAA,EAAO,OAAS,GAAKa,EAEjD,SAASG,IAAkB,CACzBnB,EAAQ,EAAE,EACVE,EAAe,EAAE,EACjBE,EAAY,EAAE,EACdE,EAAY,MAAM,EAClBE,EAAS,EAAE,CACb,CAEA,SAASY,GAAaC,EAAwB,CAC5C,OAAOA,EAAK,MAAM,GAAG,EAAE,IAAKC,GAAMA,EAAE,KAAA,CAAM,EAAE,OAAO,OAAO,CAC5D,CAEA,SAASC,EAAUC,EAAmBC,EAAwC,CAC5E,GAAID,IAAS,OAAQ,MAAO,CAAE,KAAM,MAAA,EACpC,MAAME,EAAUD,EAAI,KAAA,EACpB,OAAKC,EACE,CAAE,KAAAF,EAAM,MAAOE,CAAA,EADD,CAAE,KAAAF,CAAA,CAEzB,CAEA,eAAeG,IAAuB,CACpC,GAAI,CAACV,EAAQ,OACb,MAAMnE,EAAuB,CAC3B,KAAM+D,EACN,SAAUV,EAAS,KAAA,EACnB,QAASiB,GAAanB,CAAW,EACjC,KAAMsB,EAAUlB,EAAUE,CAAK,EAC/B,QAAS,EAAA,EAEXZ,EAAS,CAAC,GAAGD,EAAQ5C,CAAI,CAAC,EAC1BqE,GAAA,EACAnE,EAAM,QAAQ6B,EAAE,yBAAyB,CAAC,CAC5C,CAEA,eAAe+C,IAA2B,CACxC,GAAKV,EACL,GAAI,CACF,MAAMW,EAAM,MAAMjC,EAAQ,YAAY,CACpC,SAAUO,EAAS,KAAA,EACnB,KAAMoB,EAAUlB,EAAUE,CAAK,CAAA,CAChC,EACDvD,EAAM,QAAQ6B,EAAE,0BAA2B,CAAE,KAAMgD,EAAI,IAAA,CAAM,CAAC,CAChE,OAAS5E,EAAK,CACZD,EAAM,MAAME,EAAcD,EAAK4B,CAAC,EAAE,OAAO,CAC3C,CACF,CAEA,eAAeiD,GAAUC,EAA4B,CACnD,MAAMzF,EAAIoD,EAAOqC,CAAG,EACpB,GAAKzF,EAIL,IAAIA,EAAE,MAAM,OAAS,QAAUA,EAAE,MAAM,OAAS0F,GAAc1F,EAAE,KAAK,KAAK,EAAG,CAC3EU,EAAM,MAAM6B,EAAE,6BAA6B,CAAC,EAC5C,MACF,CACA,GAAI,CACF,MAAMgD,EAAM,MAAMjC,EAAQ,YAAY,CACpC,SAAUtD,EAAE,SACZ,KAAMA,EAAE,IAAA,CACT,EACDU,EAAM,QAAQ6B,EAAE,0BAA2B,CAAE,KAAMgD,EAAI,IAAA,CAAM,CAAC,CAChE,OAAS5E,EAAK,CACZD,EAAM,MAAME,EAAcD,EAAK4B,CAAC,EAAE,OAAO,CAC3C,EACF,CAEA,SAASoD,GAAYF,EAAalF,EAAmB,CACnD,MAAMC,EAAO4C,EAAO,IAAI,CAACpD,EAAG6C,IAAOA,IAAM4C,EAAM,CAAE,GAAGzF,EAAG,QAASO,CAAA,EAAOP,CAAE,EACzEqD,EAAS7C,CAAI,CACf,CAEA,SAASoF,GAAYH,EAAmB,CACtCpC,EAASD,EAAO,OAAO,CAACyC,EAAGhD,IAAMA,IAAM4C,CAAG,CAAC,CAC7C,CAEA,eAAeK,IAA+B,CAC5C,MAAMC,EAAM1B,EAAQ,KAAA,EACpB,GAAK0B,EACL,GAAI,CACF,MAAMR,EAAM,MAAM/B,EAAY,YAAY,CAAE,QAASuC,EAAK,SAAU,GAAO,EAErEC,EAAW,IAAI,IAAI5C,EAAO,IAAKpD,GAAMA,EAAE,IAAI,CAAC,EAC5CiG,EAAWV,EAAI,OAAO,OAAQvF,GAAM,CAACgG,EAAS,IAAIhG,EAAE,IAAI,CAAC,EAC/D,GAAIiG,EAAS,SAAW,EAAG,CACzBvF,EAAM,KAAK6B,EAAE,gCAAgC,CAAC,EAC9C,MACF,CACAc,EAAS,CAAC,GAAGD,EAAQ,GAAG6C,EAAS,IAAKjG,IAAO,CAAE,GAAGA,EAAG,QAAS,EAAA,EAAO,CAAC,CAAC,EACvEU,EAAM,QAAQ6B,EAAE,iCAAkC,CAAE,MAAO0D,EAAS,MAAA,CAAQ,CAAC,EAC7E3B,EAAW,EAAE,EACbF,EAAgB,EAAK,CACvB,OAASzD,EAAK,CACZD,EAAM,MAAME,EAAcD,EAAK4B,CAAC,EAAE,OAAO,CAC3C,CACF,CAEA,OACExB,EAAAA,KAAC,UAAA,CAAQ,UAAU,6CACjB,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,2DAChB,SAAA,CAAAC,EAAAA,IAACkF,EAAA,CAAQ,UAAU,uBAAA,CAAwB,QAC1C,KAAA,CAAG,UAAU,wBAAyB,SAAA3D,EAAE,kBAAkB,EAAE,QAC5DN,EAAA,CAAM,QAAQ,UAAU,UAAU,cAAe,WAAO,OAAO,EAChElB,EAAAA,KAACE,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,UACV,QAAS,IAAMmD,EAAiBzC,GAAM,CAACA,CAAC,EAExC,SAAA,CAAAX,EAAAA,IAACmF,EAAA,CAAO,UAAU,SAAA,CAAU,QAC3B,OAAA,CAAK,UAAU,mBAAoB,SAAA5D,EAAE,wBAAwB,CAAA,CAAE,CAAA,CAAA,CAAA,CAClE,EACF,QACC,IAAA,CAAE,UAAU,kCAAmC,SAAAA,EAAE,qBAAqB,EAAE,EAGxE4B,GACCpD,EAAAA,KAAC,MAAA,CAAI,UAAU,gDACb,SAAA,CAAAC,EAAAA,IAACS,GAAM,QAAQ,cAAc,UAAU,sBACpC,SAAAc,EAAE,oBAAoB,EACzB,QACC,IAAA,CAAE,UAAU,iCAAkC,SAAAA,EAAE,wBAAwB,EAAE,EAC3ExB,EAAAA,KAAC,MAAA,CAAI,UAAU,4BACb,SAAA,CAAAC,EAAAA,IAACoF,EAAA,CACC,GAAG,cACH,MAAO/B,EACP,SAAW5B,GAAM6B,EAAW7B,EAAE,OAAO,KAAK,EAC1C,YAAY,6BACZ,UAAU,wCAAA,CAAA,EAEZ1B,EAAAA,KAACE,EAAA,CACC,QAAQ,YACR,KAAK,KACL,QAAS,IAAM,KAAK6E,GAAA,EACpB,SAAU,CAACzB,EAAQ,KAAA,GAAUb,EAAY,UAExC,SAAA,CAAAA,EAAY,gBACRtC,EAAA,CAAQ,UAAU,uBAAuB,EAC1CF,EAAAA,IAACmF,EAAA,CAAO,UAAU,SAAA,CAAU,EAC/B5D,EAAE,wBAAwB,CAAA,CAAA,CAAA,CAC7B,CAAA,CACF,CAAA,EACF,EAIDa,EAAO,SAAW,EACjBpC,EAAAA,IAAC,MAAA,CAAI,UAAU,YACb,SAAAA,EAAAA,IAACqF,GAAA,CACC,WAAOH,EAAA,EAAQ,EACf,MAAO3D,EAAE,wBAAwB,EACjC,YAAaA,EAAE,8BAA8B,CAAA,CAAA,CAC/C,CACF,EAEAvB,EAAAA,IAAC,KAAA,CAAG,UAAU,yBACX,SAAAoC,EAAO,IAAI,CAAC,EAAGP,IACd7B,EAAAA,IAACsF,GAAA,CAEC,MAAO,EACP,SAAW/F,GAAOoF,GAAY9C,EAAGtC,CAAE,EACnC,OAAQ,IAAM,KAAKiF,GAAU3C,CAAC,EAC9B,SAAU,IAAM+C,GAAY/C,CAAC,EAC7B,QAASS,EAAQ,SAAA,EALZ,GAAG,EAAE,IAAI,IAAIT,CAAC,EAAA,CAOtB,EACH,EAIF9B,EAAAA,KAAC,MAAA,CAAI,UAAU,mCACb,SAAA,CAAAC,MAAC,KAAA,CAAG,UAAU,8DACX,SAAAuB,EAAE,qBAAqB,EAC1B,EACAxB,EAAAA,KAAC,MAAA,CAAI,UAAU,6CACb,SAAA,CAAAC,EAAAA,IAACuF,EAAA,CAAM,MAAOhE,EAAE,iBAAiB,EAAG,KAAMA,EAAE,qBAAqB,EAC/D,SAAAvB,EAAAA,IAACoF,EAAA,CACC,MAAO9F,EACP,SAAWmC,GAAMiB,EAAQjB,EAAE,OAAO,KAAK,EACvC,YAAY,WACZ,eAAcnC,EAAK,OAAS,GAAK,CAACkE,CAAA,CAAA,EAEtC,EACAxD,EAAAA,IAACuF,GAAM,MAAOhE,EAAE,oBAAoB,EAAG,KAAMA,EAAE,wBAAwB,EACrE,SAAAvB,EAAAA,IAACoF,EAAA,CACC,MAAOzC,EACP,SAAWlB,GAAMmB,EAAenB,EAAE,OAAO,KAAK,EAC9C,YAAY,YAAA,CAAA,EAEhB,EACAzB,EAAAA,IAACuF,GAAM,MAAOhE,EAAE,qBAAqB,EAAG,KAAMA,EAAE,yBAAyB,EACvE,SAAAvB,EAAAA,IAACoF,EAAA,CACC,MAAOvC,EACP,SAAWpB,GAAMqB,EAAYrB,EAAE,OAAO,KAAK,EAC3C,YAAY,qCACZ,UAAU,mBAAA,CAAA,EAEd,EACAzB,EAAAA,IAACuF,EAAA,CAAM,MAAOhE,EAAE,qBAAqB,EACnC,SAAAxB,OAACW,EAAA,CAAO,MAAOqC,EAAU,cAAgBpC,GAAMqC,EAAYrC,CAAgB,EACzE,SAAA,CAAAX,EAAAA,IAACY,EAAA,CAAc,SAAAZ,EAAAA,IAACa,EAAA,CAAA,CAAY,EAAE,QAC7BC,EAAA,CACE,SAAAY,GAAW,IAAK,GACf1B,EAAAA,IAACe,EAAA,CAAmB,MAAO,EAAI,WAAE,mBAAmB,CAAC,EAAE,CAAA,EAAtC,CAAwC,CAC1D,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CACF,EACCgC,IAAa,QACZ/C,MAACuF,EAAA,CAAM,MAAOhE,EAAE,kBAAkB,EAAG,UAAU,gBAC7C,SAAAvB,EAAAA,IAACoF,EAAA,CACC,KAAK,WACL,MAAOnC,EACP,SAAWxB,GAAMyB,EAASzB,EAAE,OAAO,KAAK,EACxC,YAAaF,EAAE,6BAA6B,EAC5C,aAAa,cAAA,CAAA,CACf,CACF,CAAA,EAEJ,EACAxB,EAAAA,KAAC,MAAA,CAAI,UAAU,4BACb,SAAA,CAAAA,EAAAA,KAACE,EAAA,CACC,QAAQ,YACR,KAAK,KACL,QAAS,IAAM,KAAKqE,GAAA,EACpB,SAAU,CAACV,GAActB,EAAQ,UAEhC,SAAA,CAAAA,EAAQ,gBACJpC,EAAA,CAAQ,UAAU,uBAAuB,EAC1CF,EAAAA,IAACmF,EAAA,CAAO,UAAU,SAAA,CAAU,EAC/B5D,EAAE,oBAAoB,CAAA,CAAA,CAAA,EAEzBxB,EAAAA,KAACE,EAAA,CACC,KAAK,KACL,QAAS,IAAM,KAAKoE,GAAA,EACpB,SAAU,CAACV,EAEX,SAAA,CAAA3D,EAAAA,IAAC3C,GAAA,CAAK,UAAU,SAAA,CAAU,EACzBkE,EAAE,mBAAmB,CAAA,CAAA,CAAA,EAEvBkC,GACCzD,EAAAA,IAAC,OAAA,CAAK,UAAU,mCACb,SAAAuB,EAAE,oBAAoB,CAAA,CACzB,CAAA,CAAA,CAEJ,CAAA,CAAA,CACF,CAAA,EACF,CAEJ,CAUA,SAAS+D,GAAO,CAAE,MAAAE,EAAO,SAAAlE,EAAU,OAAAmE,EAAQ,SAAAC,EAAU,QAAAC,GAAqC,CACxF,KAAM,CAAE,EAAApE,CAAA,EAAM9D,EAAe,UAAU,EACjCmI,EAAOJ,EAAM,UAAY,GACzBzC,EAAWyC,EAAM,MAAM,MAAQ,OACrC,OACEzF,EAAAA,KAAC,KAAA,CAAG,UAAU,8CACZ,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAyB,SAAAwF,EAAM,KAAK,EACpDxF,EAAAA,IAACiB,EAAA,CAAM,QAAQ,UAAU,UAAU,wBAChC,SAAAM,EAAE,mBAAmBwB,CAAQ,EAAE,CAAA,CAClC,EACCyC,EAAM,SAAWA,EAAM,QAAQ,OAAS,GACvCxF,EAAAA,IAAC,QAAK,UAAU,oCACb,WAAM,QAAQ,IAAKhB,GAAM,IAAIA,CAAC,EAAE,EAAE,KAAK,IAAI,CAAA,CAC9C,CAAA,EAEJ,EACAgB,EAAAA,IAAC,KAAE,UAAU,kDAAkD,MAAOwF,EAAM,SACzE,WAAM,QAAA,CACT,CAAA,EACF,EACAzF,EAAAA,KAAC,QAAA,CAAM,UAAU,kDACf,SAAA,CAAAC,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,QAAS4F,EACT,SAAWnE,GAAMH,EAASG,EAAE,OAAO,OAAO,EAC1C,UAAU,sCAAA,CAAA,EAEJF,EAAPqE,EAAS,gBAAqB,gBAAN,CAAsB,EACjD,EACA5F,EAAAA,IAACC,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAASwF,EACT,SAAUE,EACV,aAAYpE,EAAE,oBAAoB,EAEjC,SAAAoE,QAAWzF,EAAA,CAAQ,UAAU,uBAAuB,EAAKF,EAAAA,IAACmF,EAAA,CAAO,UAAU,SAAA,CAAU,CAAA,CAAA,EAExFnF,EAAAA,IAACC,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAASyF,EACT,aAAYnE,EAAE,sBAAsB,EACpC,UAAU,gCAEV,SAAAvB,EAAAA,IAAC6F,GAAA,CAAO,UAAU,SAAA,CAAU,CAAA,CAAA,CAC9B,EACF,CAEJ,CASA,SAASN,EAAM,CAAE,MAAAO,EAAO,KAAAC,EAAM,UAAAC,EAAW,SAAAC,GAAqC,CAC5E,cACG,MAAA,CAAI,UAAWzE,EAAG,sBAAuBwE,CAAS,EACjD,SAAA,CAAAhG,EAAAA,IAACS,EAAA,CAAM,UAAU,sBAAuB,SAAAqF,EAAM,EAC7CG,EACAF,GAAQ/F,EAAAA,IAAC,IAAA,CAAE,UAAU,4BAA6B,SAAA+F,CAAA,CAAK,CAAA,EAC1D,CAEJ,CAMA,SAASrB,GAAcV,EAAoB,CACzC,MAAO,SAAS,KAAKA,CAAC,CACxB","x_google_ignoreList":[0,1]}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{ac as b,ab as B,Q as e,c as x,I as y,B as E,a2 as N,z as L,r as F}from"./index-CpGWCLE5.js";import{e as c}from"./react-C9F3QeMB.js";import{E as P}from"./empty-state-DXNa90pP.js";import{d as D,n as O}from"./use-settings-CU-UcrVD.js";import{L as w}from"./loader-circle-JaKY-xMt.js";import{R as T}from"./refresh-ccw-Bx817_KW.js";import{a as I,E as Q}from"./eye-IKkn_oUo.js";import{X as C}from"./x-Ru3rHT82.js";import{S as U}from"./save-CqMcATrh.js";import"./useQuery-BTyugXYV.js";function $(){const{t:a}=b(["settings","common"]),[o,m]=c.useState(!1),t=D({reveal:o}),l=t.data?.env??{},h=c.useMemo(()=>new Set(t.data?.secretKeys??[]),[t.data?.secretKeys]),[n,i]=c.useState(()=>new Map),[v]=B(),[f,S]=c.useState(v.get("q")??""),u=O(),p=c.useMemo(()=>Object.keys(l).sort(),[l]),z=c.useMemo(()=>p.filter(s=>s.toLowerCase().includes(f.toLowerCase())),[p,f]);function j(s,r){i(d=>{const g=new Map(d),R=l[s]??"";return r!=null&&r===R?g.delete(s):g.set(s,r),g})}async function M(){if(n.size===0)return;const s={};for(const[r,d]of n)s[r]=d;try{await u.mutateAsync({updates:s}),i(new Map),N.success(a("env.savedToast",{count:Object.keys(s).length}))}catch(r){const{message:d}=L(r,a);N.error(d)}}function K(){i(new Map)}return e.jsxs("div",{className:"mx-auto flex max-w-5xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:a("env.title")}),e.jsxs(x,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>t.refetch(),disabled:t.isFetching,"aria-label":a("actions.refresh",{ns:"common"}),children:[t.isFetching?e.jsx(w,{className:"h-4 w-4 animate-spin"}):e.jsx(T,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:a("actions.refresh",{ns:"common"})})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:a("env.subtitle")})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(y,{value:f,onChange:s=>S(s.target.value),placeholder:a("env.search"),className:"w-64"}),e.jsxs(x,{type:"button",variant:o?"default":"outline",size:"sm",onClick:()=>m(s=>!s),children:[o?e.jsx(I,{className:"h-4 w-4"}):e.jsx(Q,{className:"h-4 w-4"}),a("env.reveal")]}),e.jsx("div",{className:"ml-auto flex items-center gap-2",children:n.size>0?e.jsxs(e.Fragment,{children:[e.jsx(E,{variant:"info",children:a("env.dirtyHint",{count:n.size})}),e.jsxs(x,{type:"button",variant:"secondary",size:"sm",onClick:K,disabled:u.isPending,children:[e.jsx(C,{className:"h-4 w-4"}),a("env.discard")]}),e.jsxs(x,{type:"button",size:"sm",onClick:()=>void M(),disabled:u.isPending,children:[u.isPending?e.jsx(w,{className:"h-4 w-4 animate-spin"}):e.jsx(U,{className:"h-4 w-4"}),a("env.save")]})]}):e.jsx("span",{className:"text-xs text-text-muted",children:a("env.noChanges")})})]}),t.isLoading?e.jsx("div",{className:"h-64 w-full rounded-md bg-surface-2 animate-pulse"}):p.length===0?e.jsx(P,{title:a("env.empty")}):e.jsx("div",{className:"flex flex-col divide-y divide-border rounded-md border border-border bg-surface",children:z.map(s=>e.jsx(V,{envKey:s,serverValue:l[s]??"",draft:n.has(s)?n.get(s)??null:l[s]??"",isDirty:n.has(s),isSecret:h.has(s),onChange:r=>j(s,r),onUnset:()=>j(s,null)},s))})]})}function V({envKey:a,serverValue:o,draft:m,isDirty:t,isSecret:l,onChange:h,onUnset:n}){const{t:i}=b("settings");return e.jsxs("div",{className:F("grid grid-cols-1 gap-2 px-3 py-2 sm:grid-cols-[280px_1fr_auto] sm:items-center",t&&"bg-accent-bg/40"),children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2 min-w-0",children:[e.jsx("code",{className:"font-mono text-xs break-all",children:a}),l&&e.jsx(E,{variant:"warning",children:i("env.secretTag")})]}),m===null?e.jsx("div",{className:"text-sm text-text-muted italic",children:i("env.unset")}):e.jsx(y,{value:m,onChange:v=>h(v.target.value),className:"font-mono text-xs",placeholder:o}),e.jsx("div",{className:"flex justify-end gap-1",children:m!==null&&e.jsxs(x,{type:"button",variant:"ghost",size:"sm",onClick:n,"aria-label":i("env.unsetButton"),children:[e.jsx(C,{className:"h-3 w-3"}),e.jsx("span",{className:"sr-only sm:not-sr-only sm:ml-1",children:i("env.unsetButton")})]})})]})}export{$ as default};
|
|
2
|
-
//# sourceMappingURL=env-Bqrb9XkC.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"env-Bqrb9XkC.js","sources":["../../src/routes/settings/env.tsx"],"sourcesContent":["/**\n * /settings/env — bulk editor for the `~/.agim/.env` file.\n *\n * Tracks per-key dirty state in a Map<string, string|null>. The\n * `null` sentinel maps the backend's \"unset this key\" semantic.\n * Save submits only the dirty subset so we don't churn untouched\n * lines.\n *\n * Secrets (per the backend's `secretKeys` list) are masked unless\n * the Reveal toggle is on. The toggle issues a separate\n * `?reveal=1` fetch — it doesn't show locally-cached unmasked\n * values for free since the masked fetch never received them.\n */\n\nimport { useMemo, useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Eye, EyeOff, Loader2, RefreshCcw, Save, X } from 'lucide-react'\n\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 { useEnv, useUpdateEnv } from '@/hooks/use-settings'\nimport { describeError } from '@/lib/api/errors'\nimport { cn } from '@/lib/utils'\n\nexport default function SettingsEnvRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n\n const [reveal, setReveal] = useState(false)\n const envQuery = useEnv({ reveal })\n const env = envQuery.data?.env ?? {}\n const secretKeys = useMemo(\n () => new Set(envQuery.data?.secretKeys ?? []),\n [envQuery.data?.secretKeys],\n )\n\n /** Edits keyed by env name. null sentinel = explicit unset. */\n const [edits, setEdits] = useState<Map<string, string | null>>(() => new Map())\n // Pre-seed the filter from `?q=` so deep-links like\n // /settings/env?q=IMHUB_MEMORY_VECTOR open straight to the\n // matching subset.\n const [params] = useSearchParams()\n const [filter, setFilter] = useState(params.get('q') ?? '')\n\n const updateEnv = useUpdateEnv()\n\n const orderedKeys = useMemo(() => Object.keys(env).sort(), [env])\n const filteredKeys = useMemo(\n () => orderedKeys.filter((k) => k.toLowerCase().includes(filter.toLowerCase())),\n [orderedKeys, filter],\n )\n\n function setDraft(key: string, next: string | null): void {\n setEdits((prev) => {\n const m = new Map(prev)\n // If the new value matches the server value, drop the entry —\n // keeps the dirty count accurate after a round-trip.\n const serverVal = env[key] ?? ''\n if (next != null && next === serverVal) {\n m.delete(key)\n } else {\n m.set(key, next)\n }\n return m\n })\n }\n\n async function onSave(): Promise<void> {\n if (edits.size === 0) return\n const updates: Record<string, string | null> = {}\n for (const [k, v] of edits) updates[k] = v\n try {\n await updateEnv.mutateAsync({ updates })\n setEdits(new Map())\n toast.success(t('env.savedToast', { count: Object.keys(updates).length }))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n function onDiscard(): void {\n setEdits(new Map())\n }\n\n return (\n <div className=\"mx-auto flex max-w-5xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('env.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => envQuery.refetch()}\n disabled={envQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {envQuery.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('env.subtitle')}</p>\n </header>\n\n {/* Controls row */}\n <div className=\"flex flex-wrap items-center gap-2\">\n <Input\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n placeholder={t('env.search')}\n className=\"w-64\"\n />\n <Button\n type=\"button\"\n variant={reveal ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setReveal((v) => !v)}\n >\n {reveal ? <EyeOff className=\"h-4 w-4\" /> : <Eye className=\"h-4 w-4\" />}\n {t('env.reveal')}\n </Button>\n <div className=\"ml-auto flex items-center gap-2\">\n {edits.size > 0 ? (\n <>\n <Badge variant=\"info\">{t('env.dirtyHint', { count: edits.size })}</Badge>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n onClick={onDiscard}\n disabled={updateEnv.isPending}\n >\n <X className=\"h-4 w-4\" />\n {t('env.discard')}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={() => void onSave()}\n disabled={updateEnv.isPending}\n >\n {updateEnv.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Save className=\"h-4 w-4\" />}\n {t('env.save')}\n </Button>\n </>\n ) : (\n <span className=\"text-xs text-text-muted\">{t('env.noChanges')}</span>\n )}\n </div>\n </div>\n\n {envQuery.isLoading ? (\n <div className=\"h-64 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : orderedKeys.length === 0 ? (\n <EmptyState title={t('env.empty')} />\n ) : (\n <div className=\"flex flex-col divide-y divide-border rounded-md border border-border bg-surface\">\n {filteredKeys.map((key) => (\n <EnvRow\n key={key}\n envKey={key}\n serverValue={env[key] ?? ''}\n draft={edits.has(key) ? edits.get(key) ?? null : env[key] ?? ''}\n isDirty={edits.has(key)}\n isSecret={secretKeys.has(key)}\n onChange={(v) => setDraft(key, v)}\n onUnset={() => setDraft(key, null)}\n />\n ))}\n </div>\n )}\n </div>\n )\n}\n\ninterface EnvRowProps {\n envKey: string\n serverValue: string\n /** Current displayed value — string when edited or server-side\n * value; null when the user staged an \"unset\". */\n draft: string | null\n isDirty: boolean\n isSecret: boolean\n onChange: (v: string) => void\n onUnset: () => void\n}\n\nfunction EnvRow({\n envKey, serverValue, draft, isDirty, isSecret, onChange, onUnset,\n}: EnvRowProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <div className={cn(\n 'grid grid-cols-1 gap-2 px-3 py-2 sm:grid-cols-[280px_1fr_auto] sm:items-center',\n isDirty && 'bg-accent-bg/40',\n )}>\n <div className=\"flex flex-wrap items-center gap-2 min-w-0\">\n <code className=\"font-mono text-xs break-all\">{envKey}</code>\n {isSecret && <Badge variant=\"warning\">{t('env.secretTag')}</Badge>}\n </div>\n {draft === null ? (\n <div className=\"text-sm text-text-muted italic\">{t('env.unset')}</div>\n ) : (\n <Input\n value={draft}\n onChange={(e) => onChange(e.target.value)}\n className=\"font-mono text-xs\"\n placeholder={serverValue}\n />\n )}\n <div className=\"flex justify-end gap-1\">\n {draft !== null && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={onUnset}\n aria-label={t('env.unsetButton')}\n >\n <X className=\"h-3 w-3\" />\n <span className=\"sr-only sm:not-sr-only sm:ml-1\">{t('env.unsetButton')}</span>\n </Button>\n )}\n </div>\n </div>\n )\n}\n"],"names":["SettingsEnvRoute","t","useTranslation","reveal","setReveal","useState","envQuery","useEnv","env","secretKeys","useMemo","edits","setEdits","params","useSearchParams","filter","setFilter","updateEnv","useUpdateEnv","orderedKeys","filteredKeys","k","setDraft","key","next","prev","m","serverVal","onSave","updates","v","toast","err","message","describeError","onDiscard","jsxs","jsx","Button","Loader2","RefreshCcw","Input","e","EyeOff","Eye","Fragment","Badge","X","Save","EmptyState","EnvRow","envKey","serverValue","draft","isDirty","isSecret","onChange","onUnset","cn"],"mappings":"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"}
|