@nextclaw/ui 0.27.0 → 0.27.2
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 +36 -0
- package/dist/.vite/manifest.json +1246 -1175
- package/dist/assets/{abnfDiagram-VRR7QNED-DmeCRAkd.js → abnfDiagram-VRR7QNED-BT0_ycaq.js} +1 -1
- package/dist/assets/account-panel-svU9I6E6.js +1 -0
- package/dist/assets/agents-CtI89gpb.js +1 -0
- package/dist/assets/agents-DWygCmAK.js +1 -0
- package/dist/assets/{aiden0z-pptx-renderer.es-ChX5DHqP.js → aiden0z-pptx-renderer.es-ClCaf_Wh.js} +1 -1
- package/dist/assets/api-CI6_8Qt1.js +20 -0
- package/dist/assets/app-presenter-provider-_UK6sArj.js +28 -0
- package/dist/assets/appearance-settings-page-BhedtMx9.js +1 -0
- package/dist/assets/apps-C4c4NXqB.js +1 -0
- package/dist/assets/{arc-Cu6Ols44.js → arc-cmSdpq1Z.js} +1 -1
- package/dist/assets/architecture-TIHT7OUA-BImoGh10.js +1 -0
- package/dist/assets/{architectureDiagram-ZJ3FMSHR-DrNB0eLE.js → architectureDiagram-ZJ3FMSHR-aYglVeoS.js} +1 -1
- package/dist/assets/{blockDiagram-677ZJIJ3-08rHt6DJ.js → blockDiagram-677ZJIJ3-Di_PBl5q.js} +1 -1
- package/dist/assets/{book-open-ClbJmmxP.js → book-open-i_BjUBqL.js} +1 -1
- package/dist/assets/{c4Diagram-LMCZKHZV-CCVgRG-u.js → c4Diagram-LMCZKHZV-CfuxybOL.js} +1 -1
- package/dist/assets/{card-BdC01NFF.js → card-DokH7OBp.js} +1 -1
- package/dist/assets/channel-BDQry0ob.js +1 -0
- package/dist/assets/{channels-list-page-BrIvJlop.js → channels-list-page-B7G9lHUm.js} +2 -2
- package/dist/assets/chunk-2Q5K7J3B-DkgSFfIy.js +1 -0
- package/dist/assets/{chunk-32BRIVSS-BeCaI-JN.js → chunk-32BRIVSS-CCGc4qg4.js} +1 -1
- package/dist/assets/{chunk-52WLFC77-ZXIcYPYs.js → chunk-52WLFC77-aJoxU2Ow.js} +1 -1
- package/dist/assets/{chunk-5FCAYU7R-DDwTPcy8.js → chunk-5FCAYU7R-CGwtZSax.js} +1 -1
- package/dist/assets/{chunk-5HE753X5-WygrMYPL.js → chunk-5HE753X5-DqaMSMeS.js} +1 -1
- package/dist/assets/{chunk-5JV3BV7I-o8T3KZgk.js → chunk-5JV3BV7I-DnabINcd.js} +1 -1
- package/dist/assets/{chunk-5TONJI2A-BKFbUT7J.js → chunk-5TONJI2A-BhpKv1k2.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-DYxCRV86.js → chunk-5VM5RSS4-DvkRPit_.js} +1 -1
- package/dist/assets/{chunk-7BUUIJ7U-CvSeJlKZ.js → chunk-7BUUIJ7U-CgDQOLnC.js} +1 -1
- package/dist/assets/{chunk-BIQX33UG-BhH3RHCY.js → chunk-BIQX33UG-9FEv5b7T.js} +1 -1
- package/dist/assets/{chunk-C7G6YPKG-BTL0-xL3.js → chunk-C7G6YPKG-CNGFAFYL.js} +1 -1
- package/dist/assets/{chunk-CQNSW5MT-DWAU4QaD.js → chunk-CQNSW5MT-DovTZx0M.js} +1 -1
- package/dist/assets/{chunk-CYSBUYHQ-B7ZBMXTx.js → chunk-CYSBUYHQ-DpLEgYa1.js} +1 -1
- package/dist/assets/{chunk-EMLP6XTP-D92HvnHE.js → chunk-EMLP6XTP-D4NuN01W.js} +1 -1
- package/dist/assets/{chunk-EX3LRPZG-DfOGKwW8.js → chunk-EX3LRPZG-D8Jf4kc2.js} +1 -1
- package/dist/assets/{chunk-FWX5IMBZ-DUuJUrXJ.js → chunk-FWX5IMBZ-BdHymAs0.js} +2 -2
- package/dist/assets/{chunk-HOUHSVGY-i3MDyUY5.js → chunk-HOUHSVGY-Dd_Ycn9Z.js} +1 -1
- package/dist/assets/{chunk-ICXQ74PX-F_pmNX6t.js → chunk-ICXQ74PX-BRPUu3ff.js} +1 -1
- package/dist/assets/{chunk-JG7HCLWE-DygOelrU.js → chunk-JG7HCLWE-DnCasQja.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-BpiZMeRl.js → chunk-JWPE2WC7-C3CkbEj1.js} +1 -1
- package/dist/assets/{chunk-MOJQB5TN-CV10sB1I.js → chunk-MOJQB5TN-Pi--K4-1.js} +1 -1
- package/dist/assets/{chunk-MOZMSUNE-Cf1WZNm0.js → chunk-MOZMSUNE-3VTspvlh.js} +1 -1
- package/dist/assets/{chunk-OGEWGWER-DuSw54VR.js → chunk-OGEWGWER-BetLLyJt.js} +1 -1
- package/dist/assets/{chunk-OSBZ3O6U-_rt_XKSZ.js → chunk-OSBZ3O6U-D1VcupAj.js} +1 -1
- package/dist/assets/{chunk-PUDLZKDR-BFPaAGNW.js → chunk-PUDLZKDR-Cy4G8SjV.js} +1 -1
- package/dist/assets/{chunk-Q4XR5HBZ-GE0v_E5y.js → chunk-Q4XR5HBZ-UYxXzi7_.js} +1 -1
- package/dist/assets/{chunk-QBLGF6JB-BK_FpnlJ.js → chunk-QBLGF6JB-CHiGeRY1.js} +1 -1
- package/dist/assets/{chunk-R7FJI6CG-CpYh6rGo.js → chunk-R7FJI6CG-C5kVJus8.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-htnxL_Cl.js → chunk-RYQCIY6F-C6cuuEBn.js} +1 -1
- package/dist/assets/{chunk-U6XO7XAA-wDbE4BZ7.js → chunk-U6XO7XAA-CM0EK7Y0.js} +1 -1
- package/dist/assets/{chunk-V7JOEXUC-DDRSVFTB.js → chunk-V7JOEXUC-DWJZIsME.js} +1 -1
- package/dist/assets/chunk-VAUOI2AC-CsTIB8qD.js +1 -0
- package/dist/assets/{chunk-VR4S4FIN-COdhHR1o.js → chunk-VR4S4FIN-CY5KYeEi.js} +1 -1
- package/dist/assets/{chunk-WYO6CB5R-DPDGhyF6.js → chunk-WYO6CB5R-B30N3ZP8.js} +3 -3
- package/dist/assets/chunk-XXDRQBXY-DK6dz0Q3.js +1 -0
- package/dist/assets/{chunk-YOTPTUD7-D8ir9Nx5.js → chunk-YOTPTUD7-CBu82JpO.js} +1 -1
- package/dist/assets/{chunk-ZGVPDNZ5-BuNKD836.js → chunk-ZGVPDNZ5-BN5NX5qA.js} +1 -1
- package/dist/assets/{chunk-ZIRB5QZD-DyHzq8jH.js → chunk-ZIRB5QZD-DcDXK29L.js} +1 -1
- package/dist/assets/{circle-dashed-nDaMRmP-.js → circle-dashed-Cx8CIEbg.js} +1 -1
- package/dist/assets/classDiagram-OUVF2IWQ-BYygHCrp.js +1 -0
- package/dist/assets/classDiagram-v2-EOCWNBFH-BgQ0XKYz.js +1 -0
- package/dist/assets/{client-DlFB5dW5.js → client-CUJUci3r.js} +1 -1
- package/dist/assets/{config-split-page-C06fU9OQ.js → config-split-page-hY1xug28.js} +1 -1
- package/dist/assets/{confirm-dialog-DpcmlXhd.js → confirm-dialog-B-ejV666.js} +1 -1
- package/dist/assets/{context-menu-DKIEaY7f.js → context-menu-dGVv8klA.js} +9 -9
- package/dist/assets/{cose-bilkent-JH36ORCC-B1I1_P6a.js → cose-bilkent-JH36ORCC-CmeJVoTw.js} +1 -1
- package/dist/assets/{createLucideIcon-Lnt-4LMC.js → createLucideIcon-reFMl-W-.js} +1 -1
- package/dist/assets/cron-DkYSmE-f.js +1 -0
- package/dist/assets/cynefin-VYW2F7L2-DKbotNWS.js +1 -0
- package/dist/assets/{cynefinDiagram-TSTJHNR4-DcOnhnCo.js → cynefinDiagram-TSTJHNR4-DGOUMgPP.js} +1 -1
- package/dist/assets/{dagre-nSYhf9yY.js → dagre-CMxSkbJJ.js} +1 -1
- package/dist/assets/{dagre-VKFMJZFB-hAX89lg3.js → dagre-VKFMJZFB-3YUBEXwo.js} +1 -1
- package/dist/assets/{desktop-capabilities-page-DPORyZAu.js → desktop-capabilities-page-CYJTQ3nC.js} +1 -1
- package/dist/assets/{desktop-update-config-BMTeWZmn.js → desktop-update-config-guKAozXO.js} +1 -1
- package/dist/assets/{diagram-FQU43EPY-C1mRMD2k.js → diagram-FQU43EPY-Br1g--ww.js} +1 -1
- package/dist/assets/{diagram-G47NLZAW-D2XBn5al.js → diagram-G47NLZAW-D1wJCBgr.js} +1 -1
- package/dist/assets/{diagram-NH7WQ7WH-3LmRsmkC.js → diagram-NH7WQ7WH-Cgg2auLH.js} +1 -1
- package/dist/assets/{diagram-OA4YK3LP-CFWn-osC.js → diagram-OA4YK3LP-R-wHiWqh.js} +1 -1
- package/dist/assets/{diagram-WEI45ONY-BqNRbUvU.js → diagram-WEI45ONY-CsNnKV0P.js} +1 -1
- package/dist/assets/{dialog-BNXSPMX_.js → dialog-DLOwdjT1.js} +1 -1
- package/dist/assets/{dist-Cuiqqp1O.js → dist-ZaFFmAGl.js} +1 -1
- package/dist/assets/doc-browser-B0zg0EXA.js +1 -0
- package/dist/assets/doc-browser-context-CTmOmuqa.js +1 -0
- package/dist/assets/{docx-preview-CunAATyC.js → docx-preview-kPn_EtAr.js} +1 -1
- package/dist/assets/{download-f_sPcoLZ.js → download-DovI3Yvf.js} +1 -1
- package/dist/assets/{ebnfDiagram-CCIWWBDH-CYb8IwqD.js → ebnfDiagram-CCIWWBDH-DCyhIPdi.js} +1 -1
- package/dist/assets/{erDiagram-Q63AITRT-H47mUoeK.js → erDiagram-Q63AITRT-D0ZJYAUf.js} +1 -1
- package/dist/assets/eventmodeling-45OFAUF4-SIhbIFIw.js +1 -0
- package/dist/assets/{extensions-B-0xQz3L.js → extensions-BZ3qrM8M.js} +1 -1
- package/dist/assets/{external-link-CbVlnlNy.js → external-link-DUD3AbsF.js} +1 -1
- package/dist/assets/flowDiagram-23GEKE2U-DdAjkU7I.js +1 -0
- package/dist/assets/{form-actions-BoTqELHB.js → form-actions-B8VniHts.js} +1 -1
- package/dist/assets/{ganttDiagram-NO4QXBWP-hSX45zfV.js → ganttDiagram-NO4QXBWP-CiXDcXZD.js} +1 -1
- package/dist/assets/gitGraph-TEB2WS4Q-DnMNpESZ.js +1 -0
- package/dist/assets/{gitGraphDiagram-IHSO6WYX-Br0UW2qg.js → gitGraphDiagram-IHSO6WYX-BSiIV48S.js} +1 -1
- package/dist/assets/{i18n-B0V5NkFj.js → i18n-IGQbjBqS.js} +2 -2
- package/dist/assets/inbox-CJBCLB1X.js +1 -0
- package/dist/assets/{inbox-Bna8iUy0.js → inbox-ClAG7SI_.js} +1 -1
- package/dist/assets/info-DKCQHKI2-BSm-69p_.js +1 -0
- package/dist/assets/{infoDiagram-FWYZ7A6U-DQmP_67w.js → infoDiagram-FWYZ7A6U-CCIgBCVq.js} +1 -1
- package/dist/assets/{ishikawaDiagram-FXEZZL3T-BHAV2oes.js → ishikawaDiagram-FXEZZL3T-nQ_baN5u.js} +1 -1
- package/dist/assets/{journeyDiagram-5HDEW3XC-CFHax4_d.js → journeyDiagram-5HDEW3XC-ABueIPzj.js} +1 -1
- package/dist/assets/{kanban-definition-HUTT4EX6-B4ZA9rp5.js → kanban-definition-HUTT4EX6-8FKS3fmQ.js} +1 -1
- package/dist/assets/katex-DPgHtix3.js +1 -0
- package/dist/assets/keyboard-shortcuts-settings-page-B5oxyPS2.js +1 -0
- package/dist/assets/{line-BboM0HLF.js → line-Biw8iEUz.js} +1 -1
- package/dist/assets/{linear-4K_M1oYM.js → linear-D7CWUHTF.js} +1 -1
- package/dist/assets/login-page-BxSMwUsc.js +1 -0
- package/dist/assets/{login-page-JNr5JCEw.js → login-page-DYaozpzz.js} +1 -1
- package/dist/assets/main-D_zmSVS1.css +1 -0
- package/dist/assets/main-gFUvLF57.js +2 -0
- package/dist/assets/main-i18n-catalog.config-itg3Gvzp.js +1 -0
- package/dist/assets/{map-26GpO1wn.js → map-CDu47gTf.js} +1 -1
- package/dist/assets/marketplace-DsAf_rnt.js +1 -0
- package/dist/assets/mcp-marketplace-page-BqUz09cj.js +1 -0
- package/dist/assets/{mermaid-parser.core-BTJFnvRC.js → mermaid-parser.core-Cc9wjl82.js} +2 -2
- package/dist/assets/{mermaid.core-B7ufoXgq.js → mermaid.core-GWlaVWz1.js} +3 -3
- package/dist/assets/{mindmap-definition-LN4V7U3C-BHyru6KE.js → mindmap-definition-LN4V7U3C-oqnKsz-R.js} +1 -1
- package/dist/assets/{model-config-page-C-wbM6Fe.js → model-config-page-Cduyz2Hy.js} +1 -1
- package/dist/assets/{navigation-link-DFLSVIut.js → navigation-link-D-JSWFxj.js} +1 -1
- package/dist/assets/{ordinal-BqFe2ePF.js → ordinal-DImbxqBz.js} +1 -1
- package/dist/assets/packet-7NZHBO7P-1YQvC6mT.js +1 -0
- package/dist/assets/panel-app-i18n-catalog.config-BfLHr1tc.js +1 -0
- package/dist/assets/panel-apps-Bg5Fzm3T.js +1 -0
- package/dist/assets/panelStandalone-oHxbXvYt.js +2 -0
- package/dist/assets/{pegDiagram-2B236MQR-PVTatU5j.js → pegDiagram-2B236MQR-DYAB8CEz.js} +1 -1
- package/dist/assets/pie-RZYD4A2V-BGoNOSwu.js +1 -0
- package/dist/assets/{pieDiagram-ENE6RG2P-CGc-QCc7.js → pieDiagram-ENE6RG2P-DGsH0Kk5.js} +1 -1
- package/dist/assets/plus-DUdl68Eo.js +1 -0
- package/dist/assets/{privacy-settings-page-CPdEiouE.js → privacy-settings-page-DG9E8N-F.js} +1 -1
- package/dist/assets/projects-DvHyoKIF.js +1 -0
- package/dist/assets/{provider-models-XRArsply.js → provider-models-COzjYl29.js} +1 -1
- package/dist/assets/{provider-scoped-model-input-C8JI-hus.js → provider-scoped-model-input-Cvy74uj8.js} +1 -1
- package/dist/assets/{providers-config-page-fyMlVgvq.js → providers-config-page-7rCwVnhh.js} +1 -1
- package/dist/assets/{puzzle-Bk3ud1KI.js → puzzle-C5Wfpjk_.js} +1 -1
- package/dist/assets/{pwa-Cx6Fnox4.js → pwa-CAg_9zFs.js} +1 -1
- package/dist/assets/{quadrantDiagram-ABIIQ3AL-DGL36riv.js → quadrantDiagram-ABIIQ3AL-BegGcT3l.js} +1 -1
- package/dist/assets/radar-I7S5WNFK-uPku9RRq.js +1 -0
- package/dist/assets/railroad-3IZDKUUU-DHnmbuIo.js +1 -0
- package/dist/assets/railroad-abnf-AHOZXSZD-DiZs--Iw.js +1 -0
- package/dist/assets/railroad-ebnf-EBAXGLYW-Nr53gnNE.js +1 -0
- package/dist/assets/railroad-peg-LSFZ7HO6-Cm_PuwJS.js +1 -0
- package/dist/assets/{railroadDiagram-RFXS5EU6-CyNwvhSb.js → railroadDiagram-RFXS5EU6-B3yJ2yxE.js} +1 -1
- package/dist/assets/{refresh-cw-Ca2napNx.js → refresh-cw-OhwaPDn1.js} +1 -1
- package/dist/assets/remote-Dhr4K1oK.js +1 -0
- package/dist/assets/{requirementDiagram-TGXJPOKE-C31NMKJ0.js → requirementDiagram-TGXJPOKE-DtEyoEXG.js} +1 -1
- package/dist/assets/{rotate-cw-DXg7sNUE.js → rotate-cw-aBponvp7.js} +1 -1
- package/dist/assets/runtime-config-page-FI2pk3HH.js +1 -0
- package/dist/assets/{sankeyDiagram-HTMAVEWB-CwrQ_7PA.js → sankeyDiagram-HTMAVEWB-h9AYS2UB.js} +1 -1
- package/dist/assets/{save-DNigywZ9.js → save-394QCMXn.js} +1 -1
- package/dist/assets/{search-U9C0oTQJ.js → search-BG2qAlNZ.js} +1 -1
- package/dist/assets/{search-config-page-Bdx_RR1q.js → search-config-page-D4LeiB9y.js} +1 -1
- package/dist/assets/{secrets-config-page-CvMIcsfJ.js → secrets-config-page-BzGcr5Vw.js} +2 -2
- package/dist/assets/security-config-vD_V0BQF.js +1 -0
- package/dist/assets/{select-DxwDeKUR.js → select-xUXYV0Gr.js} +1 -1
- package/dist/assets/{sequenceDiagram-DBY2YBRQ-EFD482_y.js → sequenceDiagram-DBY2YBRQ-D-uxCkob.js} +1 -1
- package/dist/assets/service-apps-panel-BTqXn0pg.js +1 -0
- package/dist/assets/{settings-2-BrBUdRoY.js → settings-2-CWOGRRaA.js} +1 -1
- package/dist/assets/{sizeCapture-X5ZJPWSS-TDvULTE1.js → sizeCapture-X5ZJPWSS-DBzZytQo.js} +1 -1
- package/dist/assets/{src-CI2AvEMj.js → src-zrGbZsfc.js} +1 -1
- package/dist/assets/{stateDiagram-2N3HPSRC-JdPsIYHo.js → stateDiagram-2N3HPSRC-DyDy7AHq.js} +1 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-CtkpO6aA.js +1 -0
- package/dist/assets/{status-dot-BbGsrkIX.js → status-dot-CYifnSnt.js} +1 -1
- package/dist/assets/{swimlanes-5IMT3BWC-BnxpKeK_.js → swimlanes-5IMT3BWC-BzOduS38.js} +2 -2
- package/dist/assets/swimlanesDiagram-G3AALYLV-BSdi6mvi.js +8 -0
- package/dist/assets/{tag-chip-BDbxcf6P.js → tag-chip-CjM6lyeh.js} +1 -1
- package/dist/assets/theme-provider-BToFZGZG.js +1 -0
- package/dist/assets/{timeline-definition-FHXFAJF6-2IL22-uC.js → timeline-definition-FHXFAJF6-CmgnEF2t.js} +1 -1
- package/dist/assets/{trash-2-DwSkRfeB.js → trash-2-DvJ6duOW.js} +1 -1
- package/dist/assets/treeView-QDETBFTQ-DBoqypPR.js +1 -0
- package/dist/assets/treemap-6X3UGDF4-BMeL3P0q.js +1 -0
- package/dist/assets/use-config-COusaY5p.js +1 -0
- package/dist/assets/{use-desktop-capabilities-D7odgaTB.js → use-desktop-capabilities-B-u6ojjW.js} +1 -1
- package/dist/assets/{use-viewport-layout-BANU5E1t.js → use-viewport-layout-IKKGpjzF.js} +1 -1
- package/dist/assets/{vennDiagram-L72KCM5P-Cjf6n5Va.js → vennDiagram-L72KCM5P-DwS7D2kg.js} +1 -1
- package/dist/assets/wardley-OPB4EBWU-Dqxe7zN6.js +1 -0
- package/dist/assets/{wardleyDiagram-EHGQE667-yv4qKbBO.js → wardleyDiagram-EHGQE667-B4X8OOL4.js} +1 -1
- package/dist/assets/{x-BqGj6_Vq.js → x-E9VB4HQx.js} +1 -1
- package/dist/assets/{xychartDiagram-FW5EYKEG-Bmp8Ck8X.js → xychartDiagram-FW5EYKEG-BjRQ_0nx.js} +1 -1
- package/dist/index.html +41 -40
- package/dist/panel-standalone.html +16 -16
- package/package.json +6 -6
- package/src/features/agents/components/__tests__/agents-page.test.tsx +8 -5
- package/src/features/agents/components/agent-details-dialog.tsx +19 -15
- package/src/features/agents/components/agents-page.tsx +27 -38
- package/src/features/app-data/components/app-retained-data-section.tsx +2 -2
- package/src/features/apps/components/app-marketplace-catalog.tsx +5 -5
- package/src/features/apps/components/app-marketplace-detail.tsx +11 -2
- package/src/features/apps/components/app-packages-panel.tsx +4 -4
- package/src/features/apps/components/apps-panel.tsx +3 -1
- package/src/features/chat/components/providers/chat-runtime.provider.tsx +1 -1
- package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +0 -1
- package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +13 -2
- package/src/features/chat/features/conversation/components/session-conversation-area.tsx +8 -1
- package/src/features/chat/features/conversation/components/session-conversation-input-top-slot.tsx +44 -0
- package/src/features/chat/features/conversation/components/session-conversation-input.tsx +4 -38
- package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-controller.test.tsx +127 -10
- package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-input-state.test.tsx +12 -2
- package/src/features/chat/features/conversation/hooks/use-session-conversation-controller.ts +88 -73
- package/src/features/chat/features/conversation/hooks/use-session-conversation-input-query.ts +5 -15
- package/src/features/chat/features/conversation/hooks/use-session-conversation-input-state.ts +53 -13
- package/src/features/chat/features/conversation/hooks/use-session-submission-recovery.ts +83 -0
- package/src/features/chat/features/conversation/types/session-conversation-input.types.ts +38 -0
- package/src/features/chat/features/input/utils/__tests__/ncp-chat-input-availability.utils.test.ts +1 -29
- package/src/features/chat/features/input/utils/ncp-chat-input-availability.utils.ts +1 -8
- package/src/features/chat/features/message/components/__tests__/chat-message-list-skill-preview.container.test.tsx +14 -1
- package/src/features/chat/features/message/hooks/use-chat-inline-token-actions.ts +7 -2
- package/src/features/chat/features/session/utils/__tests__/chat-session-route.utils.test.ts +26 -0
- package/src/features/chat/features/session/utils/chat-session-preference-governance.utils.ts +14 -8
- package/src/features/chat/features/session/utils/chat-session-route.utils.ts +9 -12
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-file-preview.selection.test.tsx +14 -2
- package/src/features/chat/features/workspace/components/__tests__/session-cron-job-content.test.tsx +5 -1
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +1 -1
- package/src/features/chat/features/workspace/components/session-cron-job-content.tsx +6 -22
- package/src/features/chat/index.ts +1 -0
- package/src/features/chat/pages/__tests__/ncp-chat-page.test.ts +37 -47
- package/src/features/chat/pages/ncp-chat-page.tsx +3 -3
- package/src/features/chat/stores/__tests__/chat-composer-draft.store.test.ts +67 -1
- package/src/features/chat/stores/chat-composer-draft.store.ts +230 -29
- package/src/features/cron/components/__tests__/cron-config.test.tsx +8 -2
- package/src/features/cron/components/cron-config.tsx +6 -17
- package/src/features/cron/components/cron-job-detail-dialog.tsx +10 -9
- package/src/features/cron/components/cron-job-resource.tsx +51 -0
- package/src/features/cron/index.ts +1 -0
- package/src/features/inbox/pages/inbox-page.tsx +8 -5
- package/src/features/marketplace/components/__tests__/marketplace-page-detail.test.tsx +1 -0
- package/src/features/marketplace/components/__tests__/marketplace-page.test.tsx +1 -0
- package/src/features/marketplace/components/mcp/__tests__/mcp-marketplace-page.test.tsx +2 -0
- package/src/features/marketplace/components/mcp/mcp-marketplace-card.tsx +2 -2
- package/src/features/marketplace/components/mcp/mcp-marketplace-page.tsx +23 -1
- package/src/features/marketplace/hooks/use-marketplace-item-detail.ts +11 -0
- package/src/features/panel-apps/index.ts +1 -0
- package/src/features/projects/components/work/project-work-item-drawer.tsx +7 -10
- package/src/features/projects/pages/project-home-page.tsx +18 -23
- package/src/features/projects/pages/projects-page.test.tsx +4 -1
- package/src/features/right-panel-resources/components/__tests__/system-object-resource.test.tsx +74 -6
- package/src/features/right-panel-resources/components/native-object-resource.tsx +134 -0
- package/src/features/right-panel-resources/components/page-resource-icon.tsx +1 -1
- package/src/features/right-panel-resources/components/system-object-resource.tsx +66 -1
- package/src/features/right-panel-resources/components/workspace-file-resource.tsx +9 -0
- package/src/features/right-panel-resources/configs/right-panel-resource-routes.config.ts +11 -21
- package/src/features/right-panel-resources/managers/__tests__/page-resource.manager.test.ts +14 -4
- package/src/features/right-panel-resources/managers/page-resource.manager.ts +38 -21
- package/src/features/right-panel-resources/utils/__tests__/right-panel-resource-route-resolver.utils.test.ts +12 -0
- package/src/features/service-apps/components/service-apps-panel.tsx +5 -2
- package/src/shared/components/doc-browser/__tests__/doc-browser-context.test.tsx +16 -0
- package/src/shared/components/doc-browser/__tests__/doc-browser.test.tsx +2 -2
- package/src/shared/components/doc-browser/__tests__/resource-link-interceptor.test.tsx +29 -1
- package/src/shared/components/doc-browser/stores/doc-browser.store.ts +13 -7
- package/src/shared/components/doc-browser/utils/doc-browser-url.utils.ts +2 -1
- package/src/shared/components/ui/skeleton.tsx +16 -2
- package/src/shared/lib/i18n/locales/en-US/chat.json +8 -0
- package/src/shared/lib/i18n/locales/zh-CN/chat.json +8 -0
- package/src/shared/lib/transport/__tests__/local-transport.service.test.ts +24 -0
- package/src/shared/lib/transport/local-transport.service.ts +8 -6
- package/dist/assets/account-panel-BYxGT4m4.js +0 -1
- package/dist/assets/api-CG22BskB.js +0 -20
- package/dist/assets/app-presenter-provider-CJFjhVYI.js +0 -28
- package/dist/assets/appearance-settings-page-BcXr0vHp.js +0 -1
- package/dist/assets/architecture-TIHT7OUA-CLjV_xu4.js +0 -1
- package/dist/assets/channel-BgpbPyEH.js +0 -1
- package/dist/assets/chunk-2Q5K7J3B-DjhMPqAC.js +0 -1
- package/dist/assets/chunk-VAUOI2AC-GYimZYx9.js +0 -1
- package/dist/assets/chunk-XXDRQBXY-KKCf0HV5.js +0 -1
- package/dist/assets/classDiagram-OUVF2IWQ-iRMPRR8M.js +0 -1
- package/dist/assets/classDiagram-v2-EOCWNBFH-BguFy_wj.js +0 -1
- package/dist/assets/cynefin-VYW2F7L2-CtbjXuCW.js +0 -1
- package/dist/assets/doc-browser-CDEapjmj.js +0 -1
- package/dist/assets/doc-browser-context-0QDWYorh.js +0 -1
- package/dist/assets/eventmodeling-45OFAUF4-Djd6id_u.js +0 -1
- package/dist/assets/flowDiagram-23GEKE2U-DUrsM_ZL.js +0 -1
- package/dist/assets/gitGraph-TEB2WS4Q-CU6P_2Cm.js +0 -1
- package/dist/assets/info-DKCQHKI2-Bj2P_7RC.js +0 -1
- package/dist/assets/katex-BprZ-Wwb.js +0 -1
- package/dist/assets/keyboard-shortcuts-settings-page-BluWKrSo.js +0 -1
- package/dist/assets/login-page-BMHW0Hh0.js +0 -1
- package/dist/assets/main-BCX_Untx.css +0 -1
- package/dist/assets/main-C5kbmGUV.js +0 -2
- package/dist/assets/main-i18n-catalog.config-DO4wNT7T.js +0 -1
- package/dist/assets/mcp-marketplace-page-CV-PHKTN.js +0 -1
- package/dist/assets/packet-7NZHBO7P-ti5ge2jr.js +0 -1
- package/dist/assets/panel-app-i18n-catalog.config-Bo52dPuF.js +0 -1
- package/dist/assets/panelStandalone-PuuMF65O.js +0 -2
- package/dist/assets/pie-RZYD4A2V-Bnep8TyV.js +0 -1
- package/dist/assets/plus-CywSlIbG.js +0 -1
- package/dist/assets/projects-D_cd_t4G.js +0 -1
- package/dist/assets/radar-I7S5WNFK-BYg-icAP.js +0 -1
- package/dist/assets/railroad-3IZDKUUU-_CHO-Fi1.js +0 -1
- package/dist/assets/railroad-abnf-AHOZXSZD-hbQDevHe.js +0 -1
- package/dist/assets/railroad-ebnf-EBAXGLYW-v4RZkOfi.js +0 -1
- package/dist/assets/railroad-peg-LSFZ7HO6-bC9BqkI5.js +0 -1
- package/dist/assets/remote-D5MBQNZE.js +0 -1
- package/dist/assets/runtime-config-page--ivCxBT4.js +0 -1
- package/dist/assets/security-config-CQmMqQ8v.js +0 -1
- package/dist/assets/service-apps-panel-CiYO1Be4.js +0 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-4_aAQfB_.js +0 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-wCqfwsw-.js +0 -8
- package/dist/assets/theme-provider-D98XGa-c.js +0 -1
- package/dist/assets/treeView-QDETBFTQ-BAyOb14Z.js +0 -1
- package/dist/assets/treemap-6X3UGDF4-DgPDM0zS.js +0 -1
- package/dist/assets/use-config-D3cNzk2k.js +0 -1
- package/dist/assets/wardley-OPB4EBWU-eCElh8z5.js +0 -1
- /package/dist/assets/{array-DstOKG9P.js → array-DsNX3jRj.js} +0 -0
- /package/dist/assets/{chunk-KEIR6QF5-0TA8nwgf.js → chunk-KEIR6QF5-BOAXXeyv.js} +0 -0
- /package/dist/assets/{chunk-Y2CYZVJY-rfGCG6pM.js → chunk-Y2CYZVJY-CHjSjwoV.js} +0 -0
- /package/dist/assets/{config-hints-BfGoD7-o.js → config-hints-CaB3I7KP.js} +0 -0
- /package/dist/assets/{cytoscape.esm-DdIcNEda.js → cytoscape.esm-j4J9a91l.js} +0 -0
- /package/dist/assets/{defaultLocale-CzXix2iJ.js → defaultLocale-Bmxjp-V_.js} +0 -0
- /package/dist/assets/{dist-D5dwMwKA.js → dist-DwLj1Wg5.js} +0 -0
- /package/dist/assets/{graphlib-BKOe0eFe.js → graphlib-CC0HTn1v.js} +0 -0
- /package/dist/assets/{host-capabilities-CnSVTaot.js → host-capabilities-B107nwS3.js} +0 -0
- /package/dist/assets/{init-OCFb3zgY.js → init-Biz9Rus1.js} +0 -0
- /package/dist/assets/{jszip.min-B2uhSxvV.js → jszip.min-DQvBVV_R.js} +0 -0
- /package/dist/assets/{katex-dBrYsE7B.js → katex-BzT-4KBu.js} +0 -0
- /package/dist/assets/{middleware-CAXxl-af.js → middleware-B--6mAUM.js} +0 -0
- /package/dist/assets/{navigation-history-CzErJuPG.js → navigation-history-CCnxsAKR.js} +0 -0
- /package/dist/assets/{panel-app-CSQmm_7E.js → panel-app-BBTg0tVp.js} +0 -0
- /package/dist/assets/{path-T5eoIRSJ.js → path-4azsBPZv.js} +0 -0
- /package/dist/assets/{rough.esm-DmGXmZEB.js → rough.esm-w1lBArN6.js} +0 -0
- /package/dist/assets/{xlsx-CoYacou7.js → xlsx--SB9KlFl.js} +0 -0
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
import { setLanguage } from "@/shared/lib/i18n";
|
|
11
11
|
|
|
12
12
|
const mocks = vi.hoisted(() => ({
|
|
13
|
+
openResource: vi.fn(),
|
|
13
14
|
createAgent: vi.fn(),
|
|
14
15
|
updateAgent: vi.fn(),
|
|
15
16
|
deleteAgent: vi.fn(),
|
|
@@ -99,6 +100,7 @@ const mocks = vi.hoisted(() => ({
|
|
|
99
100
|
},
|
|
100
101
|
},
|
|
101
102
|
}));
|
|
103
|
+
vi.mock("@/app/components/app-presenter-provider", () => ({ useAppPresenter: () => ({ pageResourceManager: { open: mocks.openResource } }) }));
|
|
102
104
|
const persistStorage = new Map<string, unknown>();
|
|
103
105
|
|
|
104
106
|
function createPersistStorage() {
|
|
@@ -290,18 +292,19 @@ describe("AgentsPage", () => {
|
|
|
290
292
|
it("separates read-only details from editing and keeps advanced config collapsed until requested", async () => {
|
|
291
293
|
const user = userEvent.setup();
|
|
292
294
|
|
|
293
|
-
renderAgentsPage();
|
|
295
|
+
const view = renderAgentsPage();
|
|
294
296
|
|
|
295
297
|
await user.click(screen.getAllByRole("button", { name: "更多操作" })[1]);
|
|
296
298
|
await user.click(screen.getByRole("button", { name: "查看详情" }));
|
|
299
|
+
expect(mocks.openResource).toHaveBeenCalled();
|
|
300
|
+
view.rerender(<MemoryRouter><AgentsPage resourceId="researcher" /></MemoryRouter>);
|
|
297
301
|
|
|
298
302
|
expect(screen.getByText("身份")).toBeTruthy();
|
|
299
303
|
expect(screen.getByText("上下文窗口大小")).toBeTruthy();
|
|
300
304
|
expect(screen.getByText("128,000")).toBeTruthy();
|
|
301
305
|
expect(screen.queryByRole("button", { name: "保存编辑" })).toBeNull();
|
|
302
|
-
const detailsDialog = screen.
|
|
303
|
-
expect(
|
|
304
|
-
expect(detailsDialog?.className).toContain("bg-popover");
|
|
306
|
+
const detailsDialog = screen.getByTestId("agent-detail");
|
|
307
|
+
expect(screen.queryByRole("dialog")).toBeNull();
|
|
305
308
|
const detailLists = Array.from(detailsDialog?.querySelectorAll("dl") ?? []);
|
|
306
309
|
expect(detailLists.length).toBeGreaterThan(0);
|
|
307
310
|
expect(
|
|
@@ -327,7 +330,7 @@ describe("AgentsPage", () => {
|
|
|
327
330
|
(term) => {
|
|
328
331
|
const item = term.parentElement;
|
|
329
332
|
return Boolean(
|
|
330
|
-
item?.className.includes("grid-cols-[
|
|
333
|
+
item?.className.includes("grid-cols-[minmax(0,30%)_minmax(0,1fr)]") &&
|
|
331
334
|
!item.className.includes("space-y"),
|
|
332
335
|
);
|
|
333
336
|
},
|
|
@@ -20,6 +20,8 @@ import { Bot, Brain, Gauge, Pencil, Sparkles, type LucideIcon } from "lucide-rea
|
|
|
20
20
|
type AgentDefaultsView = ConfigView["agents"]["defaults"];
|
|
21
21
|
|
|
22
22
|
type AgentDetailsDialogProps = {
|
|
23
|
+
embedded?: boolean;
|
|
24
|
+
onChat?: (agent: AgentProfileView) => void;
|
|
23
25
|
agent: AgentProfileView | null;
|
|
24
26
|
defaults?: AgentDefaultsView;
|
|
25
27
|
runtimeOptions: { value: string; label: string }[];
|
|
@@ -32,6 +34,8 @@ type AgentDetailsDialogProps = {
|
|
|
32
34
|
const numberFormatter = new Intl.NumberFormat();
|
|
33
35
|
|
|
34
36
|
export function AgentDetailsDialog({
|
|
37
|
+
embedded = false,
|
|
38
|
+
onChat,
|
|
35
39
|
agent,
|
|
36
40
|
defaults,
|
|
37
41
|
runtimeOptions,
|
|
@@ -70,11 +74,11 @@ export function AgentDetailsDialog({
|
|
|
70
74
|
);
|
|
71
75
|
const models = resolveRecordValue(agent.models, defaults?.models);
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
<DialogContent className="flex max-h-[calc(100vh-2rem)] flex-col overflow-hidden border-none bg-popover p-0 sm:max-h-[720px] sm:max-w-2xl">
|
|
77
|
+
const content = (
|
|
78
|
+
<>
|
|
76
79
|
<div className="shrink-0 px-5 pb-3 pt-5">
|
|
77
80
|
<DialogHeader
|
|
81
|
+
showClose={!embedded}
|
|
78
82
|
className="items-center"
|
|
79
83
|
actions={<PageResourceActionsMenu page={pageResourceFromSystemObject('agent', agent.id, agent.displayName || agent.id)} />}
|
|
80
84
|
>
|
|
@@ -113,13 +117,11 @@ export function AgentDetailsDialog({
|
|
|
113
117
|
<DetailItem
|
|
114
118
|
label={t("agentsDetailsFieldDescription")}
|
|
115
119
|
value={agent.description?.trim() || t("agentsDetailsEmptyValue")}
|
|
116
|
-
wide
|
|
117
120
|
/>
|
|
118
121
|
<DetailItem
|
|
119
122
|
label={t("agentsDetailsFieldWorkspace")}
|
|
120
123
|
value={agent.workspace ?? t("agentsDetailsUnsetValue")}
|
|
121
124
|
mono
|
|
122
|
-
wide
|
|
123
125
|
/>
|
|
124
126
|
</DetailSection>
|
|
125
127
|
|
|
@@ -186,13 +188,14 @@ export function AgentDetailsDialog({
|
|
|
186
188
|
</DetailSection>
|
|
187
189
|
</div>
|
|
188
190
|
<DialogFooter className="shrink-0 px-5 pb-4 pt-2">
|
|
189
|
-
<Button
|
|
191
|
+
{!embedded && <Button
|
|
190
192
|
type="button"
|
|
191
193
|
variant="ghost"
|
|
192
194
|
onClick={() => onOpenChange(false)}
|
|
193
195
|
>
|
|
194
196
|
{t("cancel")}
|
|
195
|
-
</Button>
|
|
197
|
+
</Button>}
|
|
198
|
+
{onChat && <Button onClick={() => onChat(agent)}>{t("agentsCardStartChat")}</Button>}
|
|
196
199
|
<Button
|
|
197
200
|
type="button"
|
|
198
201
|
variant="primary"
|
|
@@ -203,9 +206,13 @@ export function AgentDetailsDialog({
|
|
|
203
206
|
{t("agentsDetailsEditAction")}
|
|
204
207
|
</Button>
|
|
205
208
|
</DialogFooter>
|
|
206
|
-
|
|
207
|
-
</Dialog>
|
|
209
|
+
</>
|
|
208
210
|
);
|
|
211
|
+
return <Dialog open={!embedded && agent !== null} onOpenChange={onOpenChange}>
|
|
212
|
+
{embedded ? <div className="flex h-full min-h-0 flex-col" data-testid="agent-detail">{content}</div> : (
|
|
213
|
+
<DialogContent className="flex max-h-[calc(100vh-2rem)] flex-col overflow-hidden border-none bg-popover p-0 sm:max-h-[720px] sm:max-w-2xl">{content}</DialogContent>
|
|
214
|
+
)}
|
|
215
|
+
</Dialog>;
|
|
209
216
|
}
|
|
210
217
|
|
|
211
218
|
type DetailSource = "default" | "override";
|
|
@@ -322,7 +329,7 @@ function DetailSection(props: {
|
|
|
322
329
|
<Icon className="h-3.5 w-3.5 text-muted-foreground" />
|
|
323
330
|
{title}
|
|
324
331
|
</h3>
|
|
325
|
-
<dl className="grid min-w-0 gap-
|
|
332
|
+
<dl className="grid min-w-0 gap-y-2.5 pl-5">
|
|
326
333
|
{children}
|
|
327
334
|
</dl>
|
|
328
335
|
</section>
|
|
@@ -335,7 +342,6 @@ function DetailItem(props: {
|
|
|
335
342
|
source?: DetailSource;
|
|
336
343
|
mono?: boolean;
|
|
337
344
|
prewrap?: boolean;
|
|
338
|
-
wide?: boolean;
|
|
339
345
|
}) {
|
|
340
346
|
const {
|
|
341
347
|
label,
|
|
@@ -343,7 +349,6 @@ function DetailItem(props: {
|
|
|
343
349
|
source,
|
|
344
350
|
mono = false,
|
|
345
351
|
prewrap = false,
|
|
346
|
-
wide = false,
|
|
347
352
|
} = props;
|
|
348
353
|
|
|
349
354
|
const isStructuredValue = prewrap && value.trim().startsWith("{");
|
|
@@ -352,12 +357,11 @@ function DetailItem(props: {
|
|
|
352
357
|
return (
|
|
353
358
|
<div
|
|
354
359
|
className={cn(
|
|
355
|
-
"grid min-w-0 grid-cols-
|
|
356
|
-
(wide || isStructuredValue) && "sm:col-span-2",
|
|
360
|
+
"grid min-w-0 grid-cols-[minmax(0,30%)_minmax(0,1fr)] items-baseline gap-x-3 gap-y-1",
|
|
357
361
|
)}
|
|
358
362
|
>
|
|
359
363
|
<dt className="flex min-w-0 items-baseline leading-5">
|
|
360
|
-
<span className="
|
|
364
|
+
<span className="text-xs font-medium text-muted-foreground">
|
|
361
365
|
{label}
|
|
362
366
|
</span>
|
|
363
367
|
</dt>
|
|
@@ -48,6 +48,8 @@ import {
|
|
|
48
48
|
Trash2,
|
|
49
49
|
} from "lucide-react";
|
|
50
50
|
import { toast } from "sonner";
|
|
51
|
+
import { useAppPresenter } from "@/app/components/app-presenter-provider";
|
|
52
|
+
import { useNavigate } from "react-router-dom";
|
|
51
53
|
|
|
52
54
|
const AGENT_CREATION_PROMPT =
|
|
53
55
|
"请直接创建一个默认示例 Agent,不要问我问题。创建完成后,简单告诉我它能做什么。";
|
|
@@ -200,19 +202,19 @@ function AgentListCard(props: {
|
|
|
200
202
|
<AgentActionMenuItem
|
|
201
203
|
icon={Eye}
|
|
202
204
|
label={t("agentsViewDetailsAction")}
|
|
203
|
-
onClick={onView}
|
|
205
|
+
onClick={() => { setMenuOpen(false); onView(); }}
|
|
204
206
|
/>
|
|
205
207
|
<AgentActionMenuItem
|
|
206
208
|
icon={Pencil}
|
|
207
209
|
label={t("agentsEditAction")}
|
|
208
|
-
onClick={onEdit}
|
|
210
|
+
onClick={() => { setMenuOpen(false); onEdit(); }}
|
|
209
211
|
disabled={updatePending}
|
|
210
212
|
/>
|
|
211
213
|
{!agent.builtIn ? (
|
|
212
214
|
<AgentActionMenuItem
|
|
213
215
|
icon={Trash2}
|
|
214
216
|
label={t("agentsRemoveAction")}
|
|
215
|
-
onClick={onDelete}
|
|
217
|
+
onClick={() => { setMenuOpen(false); onDelete(); }}
|
|
216
218
|
disabled={deletePending}
|
|
217
219
|
destructive
|
|
218
220
|
/>
|
|
@@ -245,7 +247,9 @@ function AgentListCard(props: {
|
|
|
245
247
|
);
|
|
246
248
|
}
|
|
247
249
|
|
|
248
|
-
export function AgentsPage() {
|
|
250
|
+
export function AgentsPage({ resourceId }: { resourceId?: string } = {}) {
|
|
251
|
+
const app = useAppPresenter();
|
|
252
|
+
const navigate = useNavigate();
|
|
249
253
|
const presenter = usePresenter();
|
|
250
254
|
const agentsQuery = useAgents();
|
|
251
255
|
const configQuery = useConfig();
|
|
@@ -254,9 +258,6 @@ export function AgentsPage() {
|
|
|
254
258
|
const sessionTypesQuery = useNcpChatSessionTypes();
|
|
255
259
|
const updateAgent = useUpdateAgent();
|
|
256
260
|
const deleteAgent = useDeleteAgent();
|
|
257
|
-
const [viewingAgent, setViewingAgent] = useState<AgentProfileView | null>(
|
|
258
|
-
null,
|
|
259
|
-
);
|
|
260
261
|
const [editingAgent, setEditingAgent] = useState<AgentProfileView | null>(
|
|
261
262
|
null,
|
|
262
263
|
);
|
|
@@ -300,7 +301,7 @@ export function AgentsPage() {
|
|
|
300
301
|
const agentDefaults = configQuery.data?.agents.defaults;
|
|
301
302
|
|
|
302
303
|
const handleStartView = (agent: AgentProfileView) => {
|
|
303
|
-
|
|
304
|
+
app.pageResourceManager.open(pageResourceFromSystemObject("agent", agent.id, agent.displayName || agent.id), "default", navigate);
|
|
304
305
|
};
|
|
305
306
|
|
|
306
307
|
const handleStartEdit = (agent: AgentProfileView) => {
|
|
@@ -340,6 +341,23 @@ export function AgentsPage() {
|
|
|
340
341
|
);
|
|
341
342
|
};
|
|
342
343
|
|
|
344
|
+
const editDialog = <AgentEditDialog
|
|
345
|
+
agent={editingAgent} pending={updateAgent.isPending} providerCatalog={providerCatalog}
|
|
346
|
+
runtimeOptions={runtimeOptions} defaultRuntime={defaultRuntime}
|
|
347
|
+
onOpenChange={(open) => { if (!open && !updateAgent.isPending) setEditingAgent(null); }}
|
|
348
|
+
onSubmit={handleUpdate} />;
|
|
349
|
+
if (resourceId) {
|
|
350
|
+
const agent = agents.find((item) => item.id === resourceId) ?? null;
|
|
351
|
+
if (agentsQuery.isPending) return <p role="status" className="p-4">{t("loading")}</p>;
|
|
352
|
+
if (agentsQuery.isError) return <div className="p-4"><p role="alert">{t("resourceLoadFailed")}</p><button onClick={() => void agentsQuery.refetch()}>{t("resourceRetry")}</button></div>;
|
|
353
|
+
if (!agent) return <p role="alert" className="p-4">{t(agentsQuery.isError ? "resourceLoadFailed" : "resourceNotFound")}</p>;
|
|
354
|
+
return <>
|
|
355
|
+
<AgentDetailsDialog embedded agent={agent} defaults={agentDefaults} runtimeOptions={runtimeOptions}
|
|
356
|
+
defaultRuntime={defaultRuntime} defaultRuntimeLabel={defaultRuntimeLabel}
|
|
357
|
+
onOpenChange={() => {}} onEdit={handleStartEdit} onChat={startChatWithAgent} />
|
|
358
|
+
{editDialog}
|
|
359
|
+
</>;
|
|
360
|
+
}
|
|
343
361
|
return (
|
|
344
362
|
<PageLayout className="space-y-6">
|
|
345
363
|
<PageHeader
|
|
@@ -408,36 +426,7 @@ export function AgentsPage() {
|
|
|
408
426
|
)}
|
|
409
427
|
</div>
|
|
410
428
|
|
|
411
|
-
|
|
412
|
-
agent={viewingAgent}
|
|
413
|
-
defaults={agentDefaults}
|
|
414
|
-
runtimeOptions={runtimeOptions}
|
|
415
|
-
defaultRuntime={defaultRuntime}
|
|
416
|
-
defaultRuntimeLabel={defaultRuntimeLabel}
|
|
417
|
-
onOpenChange={(open) => {
|
|
418
|
-
if (!open) {
|
|
419
|
-
setViewingAgent(null);
|
|
420
|
-
}
|
|
421
|
-
}}
|
|
422
|
-
onEdit={(agent) => {
|
|
423
|
-
setViewingAgent(null);
|
|
424
|
-
setEditingAgent(agent);
|
|
425
|
-
}}
|
|
426
|
-
/>
|
|
427
|
-
|
|
428
|
-
<AgentEditDialog
|
|
429
|
-
agent={editingAgent}
|
|
430
|
-
pending={updateAgent.isPending}
|
|
431
|
-
providerCatalog={providerCatalog}
|
|
432
|
-
runtimeOptions={runtimeOptions}
|
|
433
|
-
defaultRuntime={defaultRuntime}
|
|
434
|
-
onOpenChange={(open) => {
|
|
435
|
-
if (!open && !updateAgent.isPending) {
|
|
436
|
-
setEditingAgent(null);
|
|
437
|
-
}
|
|
438
|
-
}}
|
|
439
|
-
onSubmit={handleUpdate}
|
|
440
|
-
/>
|
|
429
|
+
{editDialog}
|
|
441
430
|
</PageLayout>
|
|
442
431
|
);
|
|
443
432
|
}
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
DialogHeader,
|
|
13
13
|
DialogTitle,
|
|
14
14
|
} from '@/shared/components/ui/dialog';
|
|
15
|
-
import {
|
|
15
|
+
import { SkeletonContent } from '@/shared/components/ui/skeleton';
|
|
16
16
|
import { t } from '@/shared/lib/i18n';
|
|
17
17
|
|
|
18
18
|
export function AppRetainedDataSection({
|
|
@@ -57,7 +57,7 @@ export function AppRetainedDataSection({
|
|
|
57
57
|
{t('appDataRetainedDescription')}
|
|
58
58
|
</p>
|
|
59
59
|
</div>
|
|
60
|
-
{isLoading ? <
|
|
60
|
+
{isLoading ? <div role="status" aria-label={t('appPackagesLoading')}><SkeletonContent /></div> : null}
|
|
61
61
|
{error ? (
|
|
62
62
|
<div role="alert" className="rounded-xl border border-destructive/20 bg-destructive/5 px-3 py-2.5 text-xs text-destructive">
|
|
63
63
|
{error instanceof Error ? error.message : t('appDataLoadFailed')}
|
|
@@ -21,7 +21,7 @@ import { pickLocalizedText } from '@/features/marketplace';
|
|
|
21
21
|
import { Button } from '@/shared/components/ui/button';
|
|
22
22
|
import { IconActionButton } from '@/shared/components/ui/actions/icon-action-button';
|
|
23
23
|
import { Input } from '@/shared/components/ui/input';
|
|
24
|
-
import {
|
|
24
|
+
import { SkeletonContent } from '@/shared/components/ui/skeleton';
|
|
25
25
|
import { getLanguage, t } from '@/shared/lib/i18n';
|
|
26
26
|
import { cn } from '@/shared/lib/utils';
|
|
27
27
|
|
|
@@ -221,10 +221,10 @@ function MarketplaceCatalogContent({
|
|
|
221
221
|
}) {
|
|
222
222
|
if (isLoading) {
|
|
223
223
|
return (
|
|
224
|
-
<div className="mx-auto grid max-w-[872px] gap-4 [@container(min-width:36rem)]:grid-cols-2 [@container(min-width:52rem)]:grid-cols-3" aria-label={t('appPackagesMarketplaceLoading')}>
|
|
225
|
-
<
|
|
226
|
-
<
|
|
227
|
-
<
|
|
224
|
+
<div className="mx-auto grid max-w-[872px] gap-4 [@container(min-width:36rem)]:grid-cols-2 [@container(min-width:52rem)]:grid-cols-3" role="status" aria-label={t('appPackagesMarketplaceLoading')}>
|
|
225
|
+
<SkeletonContent />
|
|
226
|
+
<SkeletonContent />
|
|
227
|
+
<SkeletonContent className="hidden [@container(min-width:52rem)]:flex" />
|
|
228
228
|
</div>
|
|
229
229
|
);
|
|
230
230
|
}
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
resolveAppMarketplaceInstallability,
|
|
17
17
|
} from '@/features/apps/utils/app-marketplace-platform.utils';
|
|
18
18
|
import { pickLocalizedText } from '@/features/marketplace';
|
|
19
|
-
import { Skeleton } from '@/shared/components/ui/skeleton';
|
|
19
|
+
import { Skeleton, SkeletonContent } from '@/shared/components/ui/skeleton';
|
|
20
20
|
import { t } from '@/shared/lib/i18n';
|
|
21
21
|
|
|
22
22
|
export function MarketplaceDetail({
|
|
@@ -45,7 +45,16 @@ export function MarketplaceDetail({
|
|
|
45
45
|
operation?: AppPackageOperationView;
|
|
46
46
|
}) {
|
|
47
47
|
if (isLoading) {
|
|
48
|
-
return
|
|
48
|
+
return (
|
|
49
|
+
<div className="mx-auto max-w-3xl space-y-6 px-5 py-5" role="status" aria-label={t('appPackagesMarketplaceLoading')}>
|
|
50
|
+
<SkeletonContent />
|
|
51
|
+
<div className="space-y-3">
|
|
52
|
+
<Skeleton className="h-3 w-full" />
|
|
53
|
+
<Skeleton className="h-3 w-5/6" />
|
|
54
|
+
<Skeleton className="h-3 w-2/3" />
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
49
58
|
}
|
|
50
59
|
if (error || !detail) {
|
|
51
60
|
return <div role="alert" className="m-6 rounded-xl border border-destructive/20 bg-destructive/5 px-4 py-5 text-sm text-destructive">{error?.message ?? t('appPackagesMarketplaceFailed')}</div>;
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
DialogTitle,
|
|
28
28
|
} from '@/shared/components/ui/dialog';
|
|
29
29
|
import { Input } from '@/shared/components/ui/input';
|
|
30
|
-
import {
|
|
30
|
+
import { SkeletonContent } from '@/shared/components/ui/skeleton';
|
|
31
31
|
import { t } from '@/shared/lib/i18n';
|
|
32
32
|
|
|
33
33
|
export function AppPackagesPanel({
|
|
@@ -283,9 +283,9 @@ function AppPackageLibrary({
|
|
|
283
283
|
}) {
|
|
284
284
|
if (isLoading) {
|
|
285
285
|
return (
|
|
286
|
-
<div className="divide-y divide-border/50" aria-label={t('appPackagesLoading')}>
|
|
287
|
-
<
|
|
288
|
-
<
|
|
286
|
+
<div className="divide-y divide-border/50" role="status" aria-label={t('appPackagesLoading')}>
|
|
287
|
+
<SkeletonContent />
|
|
288
|
+
<SkeletonContent />
|
|
289
289
|
</div>
|
|
290
290
|
);
|
|
291
291
|
}
|
|
@@ -18,10 +18,12 @@ export function AppsPanel({
|
|
|
18
18
|
activeTab,
|
|
19
19
|
onActiveTabChange,
|
|
20
20
|
onOpenPanelApp,
|
|
21
|
+
serviceResourceId,
|
|
21
22
|
}: {
|
|
22
23
|
activeTab: AppsPanelTab;
|
|
23
24
|
onActiveTabChange: (tab: AppsPanelTab) => void;
|
|
24
25
|
onOpenPanelApp: (entry: PanelAppEntryView) => void;
|
|
26
|
+
serviceResourceId?: string;
|
|
25
27
|
}) {
|
|
26
28
|
const [focusedPackageId, setFocusedPackageId] = useState<string>();
|
|
27
29
|
const navigationRef = useRef<HTMLElement>(null);
|
|
@@ -88,7 +90,7 @@ export function AppsPanel({
|
|
|
88
90
|
<PanelAppsList onOpenPanelApp={onOpenPanelApp} />
|
|
89
91
|
) : activeTab === 'service-apps' ? (
|
|
90
92
|
<Suspense fallback={null}>
|
|
91
|
-
<ServiceAppsPanel onManagePackage={managePackage} />
|
|
93
|
+
<ServiceAppsPanel resourceId={serviceResourceId} onManagePackage={managePackage} />
|
|
92
94
|
</Suspense>
|
|
93
95
|
) : null}
|
|
94
96
|
</div>
|
|
@@ -21,7 +21,7 @@ function ChatRuntime({ children }: { children: ReactNode }) {
|
|
|
21
21
|
const navigate = useNavigate();
|
|
22
22
|
const { confirm, ConfirmDialog } = useConfirmDialog();
|
|
23
23
|
const match = useMatch('/chat/:sessionId');
|
|
24
|
-
const sessionKey = parseSessionKeyFromRoute(match
|
|
24
|
+
const sessionKey = parseSessionKeyFromRoute(match ? location.pathname.slice('/chat/'.length) : undefined);
|
|
25
25
|
const workspaceMinimized = useWorkbenchSurfaceStore((state) => state.surfaces[`session-workspace:${sessionKey ?? 'draft'}`]?.minimized ?? false);
|
|
26
26
|
const workspaceSessionKey = useChatThreadStore(({ snapshot }) =>
|
|
27
27
|
snapshot.workspacePanelParentKey === sessionKey && sessionKey && !snapshot.workspacePanelHidden && !workspaceMinimized &&
|
|
@@ -245,6 +245,9 @@ const controller: SessionConversationInputController = {
|
|
|
245
245
|
send: vi.fn(),
|
|
246
246
|
sendSteering: vi.fn(),
|
|
247
247
|
sendPresetMessage: vi.fn(),
|
|
248
|
+
retryPendingSubmission: vi.fn(),
|
|
249
|
+
restorePendingSubmission: vi.fn(),
|
|
250
|
+
discardPendingSubmission: vi.fn(),
|
|
248
251
|
sendDisabled: true,
|
|
249
252
|
stop: vi.fn(),
|
|
250
253
|
stopDisabled: false,
|
|
@@ -352,8 +355,12 @@ function StreamingSessionConversationInputHarness({
|
|
|
352
355
|
consumeComposerFocusRequest: vi.fn(),
|
|
353
356
|
removeAttachment: vi.fn(),
|
|
354
357
|
requestComposerFocusAtEnd: vi.fn(),
|
|
355
|
-
resetComposer: vi.fn(),
|
|
356
358
|
restoreComposer: vi.fn(),
|
|
359
|
+
beginSubmission: vi.fn(),
|
|
360
|
+
acceptSubmission: vi.fn(),
|
|
361
|
+
failSubmission: vi.fn(),
|
|
362
|
+
restoreSubmission: vi.fn(),
|
|
363
|
+
discardSubmission: vi.fn(),
|
|
357
364
|
setAttachments: vi.fn(),
|
|
358
365
|
setPendingProjectRoot: vi.fn(),
|
|
359
366
|
setPendingSessionType: vi.fn(),
|
|
@@ -665,8 +672,12 @@ function AttachmentSubmitHarness({
|
|
|
665
672
|
},
|
|
666
673
|
selectedAgentId: 'main',
|
|
667
674
|
sessionKey: 'session-attachment',
|
|
668
|
-
resetComposer: inputActions.resetComposer,
|
|
669
675
|
restoreComposer: inputActions.restoreComposer,
|
|
676
|
+
beginSubmission: inputActions.beginSubmission,
|
|
677
|
+
acceptSubmission: inputActions.acceptSubmission,
|
|
678
|
+
failSubmission: inputActions.failSubmission,
|
|
679
|
+
restoreSubmission: inputActions.restoreSubmission,
|
|
680
|
+
discardSubmission: inputActions.discardSubmission,
|
|
670
681
|
setSendError: inputActions.setSendError,
|
|
671
682
|
});
|
|
672
683
|
|
|
@@ -304,8 +304,12 @@ export function SessionConversationArea(props: SessionConversationAreaProps) {
|
|
|
304
304
|
selectedAgentId,
|
|
305
305
|
sessionKey,
|
|
306
306
|
onSessionMaterialized,
|
|
307
|
-
resetComposer: inputActions.resetComposer,
|
|
308
307
|
restoreComposer: inputActions.restoreComposer,
|
|
308
|
+
beginSubmission: inputActions.beginSubmission,
|
|
309
|
+
acceptSubmission: inputActions.acceptSubmission,
|
|
310
|
+
failSubmission: inputActions.failSubmission,
|
|
311
|
+
restoreSubmission: inputActions.restoreSubmission,
|
|
312
|
+
discardSubmission: inputActions.discardSubmission,
|
|
309
313
|
setSendError: inputActions.setSendError,
|
|
310
314
|
});
|
|
311
315
|
const conversationMessages = useMemo(() => {
|
|
@@ -336,6 +340,9 @@ export function SessionConversationArea(props: SessionConversationAreaProps) {
|
|
|
336
340
|
sendSteering: () => controllerRef.current.sendSteering(),
|
|
337
341
|
sendPresetMessage: (message: string) =>
|
|
338
342
|
controllerRef.current.sendPresetMessage(message).catch(() => undefined),
|
|
343
|
+
retryPendingSubmission: () => controllerRef.current.retryPendingSubmission(),
|
|
344
|
+
restorePendingSubmission: () => controllerRef.current.restorePendingSubmission(),
|
|
345
|
+
discardPendingSubmission: () => controllerRef.current.discardPendingSubmission(),
|
|
339
346
|
sendDisabled: controller.sendDisabled,
|
|
340
347
|
stop: () => controllerRef.current.stop(),
|
|
341
348
|
stopDisabled: controller.stopDisabled,
|
package/src/features/chat/features/conversation/components/session-conversation-input-top-slot.tsx
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ChatComposerSubmission } from '@/features/chat/stores/chat-composer-draft.store';
|
|
2
|
+
import type { SessionConversationInputController } from '@/features/chat/features/conversation/types/session-conversation-input.types';
|
|
3
|
+
import type { SessionConversationInputSnapshot } from '@/features/chat/features/conversation/hooks/use-session-conversation-input-state';
|
|
4
|
+
import { t } from '@/shared/lib/i18n';
|
|
5
|
+
import { SessionQueuedInputRows } from './session-queued-input-rows';
|
|
6
|
+
|
|
7
|
+
export function SessionConversationInputTopSlot({ inputSnapshot, controller }: {
|
|
8
|
+
readonly inputSnapshot: SessionConversationInputSnapshot;
|
|
9
|
+
readonly controller: SessionConversationInputController;
|
|
10
|
+
}) {
|
|
11
|
+
const submission = inputSnapshot.pendingSubmission;
|
|
12
|
+
if (!submission && controller.queuedInputs.length === 0) return null;
|
|
13
|
+
return <>
|
|
14
|
+
{controller.queuedInputs.length > 0 && <SessionQueuedInputRows controller={controller} />}
|
|
15
|
+
{submission && <SubmissionStatus submission={submission} controller={controller}
|
|
16
|
+
hasComposerContent={Boolean(inputSnapshot.text.trim() || inputSnapshot.selectedSkills.length || inputSnapshot.attachments.length)} />}
|
|
17
|
+
</>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function SubmissionStatus({ submission, controller, hasComposerContent }: {
|
|
21
|
+
readonly submission: ChatComposerSubmission;
|
|
22
|
+
readonly controller: SessionConversationInputController;
|
|
23
|
+
readonly hasComposerContent: boolean;
|
|
24
|
+
}) {
|
|
25
|
+
const statusText = submission.status === 'sending'
|
|
26
|
+
? t('chatSubmissionSending')
|
|
27
|
+
: submission.status === 'rejected'
|
|
28
|
+
? t('chatSubmissionRejected')
|
|
29
|
+
: t(submission.envelope.sessionId ? 'chatSendResultUnknown' : 'chatSendResultUnknownChild');
|
|
30
|
+
return <div className="rounded-lg border border-border bg-muted/50 px-3 py-2 text-sm" role="status">
|
|
31
|
+
<p>{statusText}</p>
|
|
32
|
+
<p className="mt-1 max-h-16 overflow-auto whitespace-pre-wrap text-muted-foreground">{submission.composer.text}</p>
|
|
33
|
+
<div className="mt-2 flex gap-3">
|
|
34
|
+
{submission.status === 'uncertain' && submission.envelope.sessionId &&
|
|
35
|
+
<button type="button" className="text-primary underline" onClick={controller.retryPendingSubmission}>{t('chatSubmissionRetry')}</button>}
|
|
36
|
+
{submission.status === 'rejected' && <>
|
|
37
|
+
<button type="button" className="text-primary underline" disabled={hasComposerContent} onClick={controller.restorePendingSubmission}>{t('chatSubmissionRestore')}</button>
|
|
38
|
+
<button type="button" className="text-muted-foreground underline" onClick={() => {
|
|
39
|
+
if (window.confirm(t('chatSubmissionDiscardConfirm'))) controller.discardPendingSubmission();
|
|
40
|
+
}}>{t('chatSubmissionDiscard')}</button>
|
|
41
|
+
</>}
|
|
42
|
+
</div>
|
|
43
|
+
</div>;
|
|
44
|
+
}
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
} from 'react';
|
|
8
8
|
import {
|
|
9
9
|
ChatInputBar,
|
|
10
|
-
type ChatContextWindowIndicator,
|
|
11
10
|
type ChatInputBarHandle,
|
|
12
11
|
} from '@nextclaw/agent-chat-ui';
|
|
13
12
|
import { isRuntimeDefaultModelValue } from '@nextclaw/shared';
|
|
@@ -56,41 +55,19 @@ import { useSystemObjectReferenceSelect } from '@/features/chat/features/convers
|
|
|
56
55
|
import { ChatConversationTrack } from '@/features/chat/components/conversation/chat-conversation-track';
|
|
57
56
|
import { useChatMessageLayoutStore } from '@/features/chat/stores/chat-message-layout.store';
|
|
58
57
|
import type { useSessionConversationInputQuery } from '@/features/chat/features/conversation/hooks/use-session-conversation-input-query';
|
|
59
|
-
import type {
|
|
60
|
-
SessionConversationQueuedInput,
|
|
61
|
-
} from '@/features/chat/features/conversation/hooks/use-session-conversation-controller';
|
|
62
|
-
import type {
|
|
63
|
-
SessionConversationInputActions,
|
|
64
|
-
SessionConversationInputSnapshot,
|
|
65
|
-
} from '@/features/chat/features/conversation/hooks/use-session-conversation-input-state';
|
|
66
58
|
import {
|
|
67
59
|
buildSessionConversationSkillPicker,
|
|
68
60
|
buildSessionConversationToolbarSelects,
|
|
69
61
|
resolveThinkingForConversationModel,
|
|
70
62
|
} from '@/features/chat/features/conversation/utils/session-conversation-input-toolbar.utils';
|
|
71
|
-
import {
|
|
63
|
+
import { SessionConversationInputTopSlot } from './session-conversation-input-top-slot';
|
|
64
|
+
import type { SessionConversationInputProps } from '@/features/chat/features/conversation/types/session-conversation-input.types';
|
|
65
|
+
export type { SessionConversationInputController } from '@/features/chat/features/conversation/types/session-conversation-input.types';
|
|
72
66
|
import { toast } from 'sonner';
|
|
73
67
|
|
|
74
68
|
type SessionConversationInputQuery = ReturnType<typeof useSessionConversationInputQuery>;
|
|
75
69
|
type SkillSource = SessionSkillEntryView['source'];
|
|
76
70
|
|
|
77
|
-
export type SessionConversationInputController = {
|
|
78
|
-
readonly canEditQueuedInput: boolean;
|
|
79
|
-
readonly canStopGeneration: boolean;
|
|
80
|
-
readonly deleteQueuedInput: (id: string) => void;
|
|
81
|
-
readonly editQueuedInput: (id: string) => void;
|
|
82
|
-
readonly isSending: boolean;
|
|
83
|
-
readonly queuedInputs: readonly SessionConversationQueuedInput[];
|
|
84
|
-
readonly primaryAction: 'continue' | 'send';
|
|
85
|
-
readonly sendDisabled: boolean;
|
|
86
|
-
readonly stopDisabled: boolean;
|
|
87
|
-
readonly send: () => Promise<void> | void;
|
|
88
|
-
readonly sendSteering: () => Promise<void> | void;
|
|
89
|
-
readonly sendPresetMessage: (message: string) => Promise<void> | void;
|
|
90
|
-
readonly stop: () => Promise<void> | void;
|
|
91
|
-
readonly steerQueuedInput: (id: string) => void;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
71
|
function toSkillRecords(
|
|
95
72
|
snapshotRecords: SessionSkillEntryView[],
|
|
96
73
|
scopeLabels: Record<SkillSource, string>,
|
|
@@ -181,17 +158,6 @@ function useSessionConversationInputCollections(params: {
|
|
|
181
158
|
};
|
|
182
159
|
}
|
|
183
160
|
|
|
184
|
-
type SessionConversationInputProps = {
|
|
185
|
-
readonly contextWindow: ChatContextWindowIndicator | null;
|
|
186
|
-
readonly controller: SessionConversationInputController;
|
|
187
|
-
readonly inputActions: SessionConversationInputActions;
|
|
188
|
-
readonly inputQuery: SessionConversationInputQuery;
|
|
189
|
-
readonly inputSnapshot: SessionConversationInputSnapshot;
|
|
190
|
-
readonly onContextCompactingChange?: (sessionId: string, isCompacting: boolean) => void;
|
|
191
|
-
readonly placeholder?: string;
|
|
192
|
-
readonly surface?: 'default' | 'embedded';
|
|
193
|
-
};
|
|
194
|
-
|
|
195
161
|
export const SessionConversationInput = memo(function SessionConversationInput(props: SessionConversationInputProps) {
|
|
196
162
|
const {
|
|
197
163
|
contextWindow,
|
|
@@ -431,7 +397,7 @@ export const SessionConversationInput = memo(function SessionConversationInput(p
|
|
|
431
397
|
<ChatInputBar
|
|
432
398
|
ref={inputBarRef}
|
|
433
399
|
surface={useReadingTrack ? 'embedded' : surface}
|
|
434
|
-
topSlot={
|
|
400
|
+
topSlot={<SessionConversationInputTopSlot inputSnapshot={inputSnapshot} controller={controller} />}
|
|
435
401
|
floatingSlot={voice.phase !== 'idle' ? <ChatVoiceInputPanel manager={voiceManager} snapshot={voice}
|
|
436
402
|
desktop={!isMobile} onStart={startVoice} /> : null}
|
|
437
403
|
composer={{
|