@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.
Files changed (320) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/.vite/manifest.json +1246 -1175
  3. package/dist/assets/{abnfDiagram-VRR7QNED-DmeCRAkd.js → abnfDiagram-VRR7QNED-BT0_ycaq.js} +1 -1
  4. package/dist/assets/account-panel-svU9I6E6.js +1 -0
  5. package/dist/assets/agents-CtI89gpb.js +1 -0
  6. package/dist/assets/agents-DWygCmAK.js +1 -0
  7. package/dist/assets/{aiden0z-pptx-renderer.es-ChX5DHqP.js → aiden0z-pptx-renderer.es-ClCaf_Wh.js} +1 -1
  8. package/dist/assets/api-CI6_8Qt1.js +20 -0
  9. package/dist/assets/app-presenter-provider-_UK6sArj.js +28 -0
  10. package/dist/assets/appearance-settings-page-BhedtMx9.js +1 -0
  11. package/dist/assets/apps-C4c4NXqB.js +1 -0
  12. package/dist/assets/{arc-Cu6Ols44.js → arc-cmSdpq1Z.js} +1 -1
  13. package/dist/assets/architecture-TIHT7OUA-BImoGh10.js +1 -0
  14. package/dist/assets/{architectureDiagram-ZJ3FMSHR-DrNB0eLE.js → architectureDiagram-ZJ3FMSHR-aYglVeoS.js} +1 -1
  15. package/dist/assets/{blockDiagram-677ZJIJ3-08rHt6DJ.js → blockDiagram-677ZJIJ3-Di_PBl5q.js} +1 -1
  16. package/dist/assets/{book-open-ClbJmmxP.js → book-open-i_BjUBqL.js} +1 -1
  17. package/dist/assets/{c4Diagram-LMCZKHZV-CCVgRG-u.js → c4Diagram-LMCZKHZV-CfuxybOL.js} +1 -1
  18. package/dist/assets/{card-BdC01NFF.js → card-DokH7OBp.js} +1 -1
  19. package/dist/assets/channel-BDQry0ob.js +1 -0
  20. package/dist/assets/{channels-list-page-BrIvJlop.js → channels-list-page-B7G9lHUm.js} +2 -2
  21. package/dist/assets/chunk-2Q5K7J3B-DkgSFfIy.js +1 -0
  22. package/dist/assets/{chunk-32BRIVSS-BeCaI-JN.js → chunk-32BRIVSS-CCGc4qg4.js} +1 -1
  23. package/dist/assets/{chunk-52WLFC77-ZXIcYPYs.js → chunk-52WLFC77-aJoxU2Ow.js} +1 -1
  24. package/dist/assets/{chunk-5FCAYU7R-DDwTPcy8.js → chunk-5FCAYU7R-CGwtZSax.js} +1 -1
  25. package/dist/assets/{chunk-5HE753X5-WygrMYPL.js → chunk-5HE753X5-DqaMSMeS.js} +1 -1
  26. package/dist/assets/{chunk-5JV3BV7I-o8T3KZgk.js → chunk-5JV3BV7I-DnabINcd.js} +1 -1
  27. package/dist/assets/{chunk-5TONJI2A-BKFbUT7J.js → chunk-5TONJI2A-BhpKv1k2.js} +1 -1
  28. package/dist/assets/{chunk-5VM5RSS4-DYxCRV86.js → chunk-5VM5RSS4-DvkRPit_.js} +1 -1
  29. package/dist/assets/{chunk-7BUUIJ7U-CvSeJlKZ.js → chunk-7BUUIJ7U-CgDQOLnC.js} +1 -1
  30. package/dist/assets/{chunk-BIQX33UG-BhH3RHCY.js → chunk-BIQX33UG-9FEv5b7T.js} +1 -1
  31. package/dist/assets/{chunk-C7G6YPKG-BTL0-xL3.js → chunk-C7G6YPKG-CNGFAFYL.js} +1 -1
  32. package/dist/assets/{chunk-CQNSW5MT-DWAU4QaD.js → chunk-CQNSW5MT-DovTZx0M.js} +1 -1
  33. package/dist/assets/{chunk-CYSBUYHQ-B7ZBMXTx.js → chunk-CYSBUYHQ-DpLEgYa1.js} +1 -1
  34. package/dist/assets/{chunk-EMLP6XTP-D92HvnHE.js → chunk-EMLP6XTP-D4NuN01W.js} +1 -1
  35. package/dist/assets/{chunk-EX3LRPZG-DfOGKwW8.js → chunk-EX3LRPZG-D8Jf4kc2.js} +1 -1
  36. package/dist/assets/{chunk-FWX5IMBZ-DUuJUrXJ.js → chunk-FWX5IMBZ-BdHymAs0.js} +2 -2
  37. package/dist/assets/{chunk-HOUHSVGY-i3MDyUY5.js → chunk-HOUHSVGY-Dd_Ycn9Z.js} +1 -1
  38. package/dist/assets/{chunk-ICXQ74PX-F_pmNX6t.js → chunk-ICXQ74PX-BRPUu3ff.js} +1 -1
  39. package/dist/assets/{chunk-JG7HCLWE-DygOelrU.js → chunk-JG7HCLWE-DnCasQja.js} +1 -1
  40. package/dist/assets/{chunk-JWPE2WC7-BpiZMeRl.js → chunk-JWPE2WC7-C3CkbEj1.js} +1 -1
  41. package/dist/assets/{chunk-MOJQB5TN-CV10sB1I.js → chunk-MOJQB5TN-Pi--K4-1.js} +1 -1
  42. package/dist/assets/{chunk-MOZMSUNE-Cf1WZNm0.js → chunk-MOZMSUNE-3VTspvlh.js} +1 -1
  43. package/dist/assets/{chunk-OGEWGWER-DuSw54VR.js → chunk-OGEWGWER-BetLLyJt.js} +1 -1
  44. package/dist/assets/{chunk-OSBZ3O6U-_rt_XKSZ.js → chunk-OSBZ3O6U-D1VcupAj.js} +1 -1
  45. package/dist/assets/{chunk-PUDLZKDR-BFPaAGNW.js → chunk-PUDLZKDR-Cy4G8SjV.js} +1 -1
  46. package/dist/assets/{chunk-Q4XR5HBZ-GE0v_E5y.js → chunk-Q4XR5HBZ-UYxXzi7_.js} +1 -1
  47. package/dist/assets/{chunk-QBLGF6JB-BK_FpnlJ.js → chunk-QBLGF6JB-CHiGeRY1.js} +1 -1
  48. package/dist/assets/{chunk-R7FJI6CG-CpYh6rGo.js → chunk-R7FJI6CG-C5kVJus8.js} +1 -1
  49. package/dist/assets/{chunk-RYQCIY6F-htnxL_Cl.js → chunk-RYQCIY6F-C6cuuEBn.js} +1 -1
  50. package/dist/assets/{chunk-U6XO7XAA-wDbE4BZ7.js → chunk-U6XO7XAA-CM0EK7Y0.js} +1 -1
  51. package/dist/assets/{chunk-V7JOEXUC-DDRSVFTB.js → chunk-V7JOEXUC-DWJZIsME.js} +1 -1
  52. package/dist/assets/chunk-VAUOI2AC-CsTIB8qD.js +1 -0
  53. package/dist/assets/{chunk-VR4S4FIN-COdhHR1o.js → chunk-VR4S4FIN-CY5KYeEi.js} +1 -1
  54. package/dist/assets/{chunk-WYO6CB5R-DPDGhyF6.js → chunk-WYO6CB5R-B30N3ZP8.js} +3 -3
  55. package/dist/assets/chunk-XXDRQBXY-DK6dz0Q3.js +1 -0
  56. package/dist/assets/{chunk-YOTPTUD7-D8ir9Nx5.js → chunk-YOTPTUD7-CBu82JpO.js} +1 -1
  57. package/dist/assets/{chunk-ZGVPDNZ5-BuNKD836.js → chunk-ZGVPDNZ5-BN5NX5qA.js} +1 -1
  58. package/dist/assets/{chunk-ZIRB5QZD-DyHzq8jH.js → chunk-ZIRB5QZD-DcDXK29L.js} +1 -1
  59. package/dist/assets/{circle-dashed-nDaMRmP-.js → circle-dashed-Cx8CIEbg.js} +1 -1
  60. package/dist/assets/classDiagram-OUVF2IWQ-BYygHCrp.js +1 -0
  61. package/dist/assets/classDiagram-v2-EOCWNBFH-BgQ0XKYz.js +1 -0
  62. package/dist/assets/{client-DlFB5dW5.js → client-CUJUci3r.js} +1 -1
  63. package/dist/assets/{config-split-page-C06fU9OQ.js → config-split-page-hY1xug28.js} +1 -1
  64. package/dist/assets/{confirm-dialog-DpcmlXhd.js → confirm-dialog-B-ejV666.js} +1 -1
  65. package/dist/assets/{context-menu-DKIEaY7f.js → context-menu-dGVv8klA.js} +9 -9
  66. package/dist/assets/{cose-bilkent-JH36ORCC-B1I1_P6a.js → cose-bilkent-JH36ORCC-CmeJVoTw.js} +1 -1
  67. package/dist/assets/{createLucideIcon-Lnt-4LMC.js → createLucideIcon-reFMl-W-.js} +1 -1
  68. package/dist/assets/cron-DkYSmE-f.js +1 -0
  69. package/dist/assets/cynefin-VYW2F7L2-DKbotNWS.js +1 -0
  70. package/dist/assets/{cynefinDiagram-TSTJHNR4-DcOnhnCo.js → cynefinDiagram-TSTJHNR4-DGOUMgPP.js} +1 -1
  71. package/dist/assets/{dagre-nSYhf9yY.js → dagre-CMxSkbJJ.js} +1 -1
  72. package/dist/assets/{dagre-VKFMJZFB-hAX89lg3.js → dagre-VKFMJZFB-3YUBEXwo.js} +1 -1
  73. package/dist/assets/{desktop-capabilities-page-DPORyZAu.js → desktop-capabilities-page-CYJTQ3nC.js} +1 -1
  74. package/dist/assets/{desktop-update-config-BMTeWZmn.js → desktop-update-config-guKAozXO.js} +1 -1
  75. package/dist/assets/{diagram-FQU43EPY-C1mRMD2k.js → diagram-FQU43EPY-Br1g--ww.js} +1 -1
  76. package/dist/assets/{diagram-G47NLZAW-D2XBn5al.js → diagram-G47NLZAW-D1wJCBgr.js} +1 -1
  77. package/dist/assets/{diagram-NH7WQ7WH-3LmRsmkC.js → diagram-NH7WQ7WH-Cgg2auLH.js} +1 -1
  78. package/dist/assets/{diagram-OA4YK3LP-CFWn-osC.js → diagram-OA4YK3LP-R-wHiWqh.js} +1 -1
  79. package/dist/assets/{diagram-WEI45ONY-BqNRbUvU.js → diagram-WEI45ONY-CsNnKV0P.js} +1 -1
  80. package/dist/assets/{dialog-BNXSPMX_.js → dialog-DLOwdjT1.js} +1 -1
  81. package/dist/assets/{dist-Cuiqqp1O.js → dist-ZaFFmAGl.js} +1 -1
  82. package/dist/assets/doc-browser-B0zg0EXA.js +1 -0
  83. package/dist/assets/doc-browser-context-CTmOmuqa.js +1 -0
  84. package/dist/assets/{docx-preview-CunAATyC.js → docx-preview-kPn_EtAr.js} +1 -1
  85. package/dist/assets/{download-f_sPcoLZ.js → download-DovI3Yvf.js} +1 -1
  86. package/dist/assets/{ebnfDiagram-CCIWWBDH-CYb8IwqD.js → ebnfDiagram-CCIWWBDH-DCyhIPdi.js} +1 -1
  87. package/dist/assets/{erDiagram-Q63AITRT-H47mUoeK.js → erDiagram-Q63AITRT-D0ZJYAUf.js} +1 -1
  88. package/dist/assets/eventmodeling-45OFAUF4-SIhbIFIw.js +1 -0
  89. package/dist/assets/{extensions-B-0xQz3L.js → extensions-BZ3qrM8M.js} +1 -1
  90. package/dist/assets/{external-link-CbVlnlNy.js → external-link-DUD3AbsF.js} +1 -1
  91. package/dist/assets/flowDiagram-23GEKE2U-DdAjkU7I.js +1 -0
  92. package/dist/assets/{form-actions-BoTqELHB.js → form-actions-B8VniHts.js} +1 -1
  93. package/dist/assets/{ganttDiagram-NO4QXBWP-hSX45zfV.js → ganttDiagram-NO4QXBWP-CiXDcXZD.js} +1 -1
  94. package/dist/assets/gitGraph-TEB2WS4Q-DnMNpESZ.js +1 -0
  95. package/dist/assets/{gitGraphDiagram-IHSO6WYX-Br0UW2qg.js → gitGraphDiagram-IHSO6WYX-BSiIV48S.js} +1 -1
  96. package/dist/assets/{i18n-B0V5NkFj.js → i18n-IGQbjBqS.js} +2 -2
  97. package/dist/assets/inbox-CJBCLB1X.js +1 -0
  98. package/dist/assets/{inbox-Bna8iUy0.js → inbox-ClAG7SI_.js} +1 -1
  99. package/dist/assets/info-DKCQHKI2-BSm-69p_.js +1 -0
  100. package/dist/assets/{infoDiagram-FWYZ7A6U-DQmP_67w.js → infoDiagram-FWYZ7A6U-CCIgBCVq.js} +1 -1
  101. package/dist/assets/{ishikawaDiagram-FXEZZL3T-BHAV2oes.js → ishikawaDiagram-FXEZZL3T-nQ_baN5u.js} +1 -1
  102. package/dist/assets/{journeyDiagram-5HDEW3XC-CFHax4_d.js → journeyDiagram-5HDEW3XC-ABueIPzj.js} +1 -1
  103. package/dist/assets/{kanban-definition-HUTT4EX6-B4ZA9rp5.js → kanban-definition-HUTT4EX6-8FKS3fmQ.js} +1 -1
  104. package/dist/assets/katex-DPgHtix3.js +1 -0
  105. package/dist/assets/keyboard-shortcuts-settings-page-B5oxyPS2.js +1 -0
  106. package/dist/assets/{line-BboM0HLF.js → line-Biw8iEUz.js} +1 -1
  107. package/dist/assets/{linear-4K_M1oYM.js → linear-D7CWUHTF.js} +1 -1
  108. package/dist/assets/login-page-BxSMwUsc.js +1 -0
  109. package/dist/assets/{login-page-JNr5JCEw.js → login-page-DYaozpzz.js} +1 -1
  110. package/dist/assets/main-D_zmSVS1.css +1 -0
  111. package/dist/assets/main-gFUvLF57.js +2 -0
  112. package/dist/assets/main-i18n-catalog.config-itg3Gvzp.js +1 -0
  113. package/dist/assets/{map-26GpO1wn.js → map-CDu47gTf.js} +1 -1
  114. package/dist/assets/marketplace-DsAf_rnt.js +1 -0
  115. package/dist/assets/mcp-marketplace-page-BqUz09cj.js +1 -0
  116. package/dist/assets/{mermaid-parser.core-BTJFnvRC.js → mermaid-parser.core-Cc9wjl82.js} +2 -2
  117. package/dist/assets/{mermaid.core-B7ufoXgq.js → mermaid.core-GWlaVWz1.js} +3 -3
  118. package/dist/assets/{mindmap-definition-LN4V7U3C-BHyru6KE.js → mindmap-definition-LN4V7U3C-oqnKsz-R.js} +1 -1
  119. package/dist/assets/{model-config-page-C-wbM6Fe.js → model-config-page-Cduyz2Hy.js} +1 -1
  120. package/dist/assets/{navigation-link-DFLSVIut.js → navigation-link-D-JSWFxj.js} +1 -1
  121. package/dist/assets/{ordinal-BqFe2ePF.js → ordinal-DImbxqBz.js} +1 -1
  122. package/dist/assets/packet-7NZHBO7P-1YQvC6mT.js +1 -0
  123. package/dist/assets/panel-app-i18n-catalog.config-BfLHr1tc.js +1 -0
  124. package/dist/assets/panel-apps-Bg5Fzm3T.js +1 -0
  125. package/dist/assets/panelStandalone-oHxbXvYt.js +2 -0
  126. package/dist/assets/{pegDiagram-2B236MQR-PVTatU5j.js → pegDiagram-2B236MQR-DYAB8CEz.js} +1 -1
  127. package/dist/assets/pie-RZYD4A2V-BGoNOSwu.js +1 -0
  128. package/dist/assets/{pieDiagram-ENE6RG2P-CGc-QCc7.js → pieDiagram-ENE6RG2P-DGsH0Kk5.js} +1 -1
  129. package/dist/assets/plus-DUdl68Eo.js +1 -0
  130. package/dist/assets/{privacy-settings-page-CPdEiouE.js → privacy-settings-page-DG9E8N-F.js} +1 -1
  131. package/dist/assets/projects-DvHyoKIF.js +1 -0
  132. package/dist/assets/{provider-models-XRArsply.js → provider-models-COzjYl29.js} +1 -1
  133. package/dist/assets/{provider-scoped-model-input-C8JI-hus.js → provider-scoped-model-input-Cvy74uj8.js} +1 -1
  134. package/dist/assets/{providers-config-page-fyMlVgvq.js → providers-config-page-7rCwVnhh.js} +1 -1
  135. package/dist/assets/{puzzle-Bk3ud1KI.js → puzzle-C5Wfpjk_.js} +1 -1
  136. package/dist/assets/{pwa-Cx6Fnox4.js → pwa-CAg_9zFs.js} +1 -1
  137. package/dist/assets/{quadrantDiagram-ABIIQ3AL-DGL36riv.js → quadrantDiagram-ABIIQ3AL-BegGcT3l.js} +1 -1
  138. package/dist/assets/radar-I7S5WNFK-uPku9RRq.js +1 -0
  139. package/dist/assets/railroad-3IZDKUUU-DHnmbuIo.js +1 -0
  140. package/dist/assets/railroad-abnf-AHOZXSZD-DiZs--Iw.js +1 -0
  141. package/dist/assets/railroad-ebnf-EBAXGLYW-Nr53gnNE.js +1 -0
  142. package/dist/assets/railroad-peg-LSFZ7HO6-Cm_PuwJS.js +1 -0
  143. package/dist/assets/{railroadDiagram-RFXS5EU6-CyNwvhSb.js → railroadDiagram-RFXS5EU6-B3yJ2yxE.js} +1 -1
  144. package/dist/assets/{refresh-cw-Ca2napNx.js → refresh-cw-OhwaPDn1.js} +1 -1
  145. package/dist/assets/remote-Dhr4K1oK.js +1 -0
  146. package/dist/assets/{requirementDiagram-TGXJPOKE-C31NMKJ0.js → requirementDiagram-TGXJPOKE-DtEyoEXG.js} +1 -1
  147. package/dist/assets/{rotate-cw-DXg7sNUE.js → rotate-cw-aBponvp7.js} +1 -1
  148. package/dist/assets/runtime-config-page-FI2pk3HH.js +1 -0
  149. package/dist/assets/{sankeyDiagram-HTMAVEWB-CwrQ_7PA.js → sankeyDiagram-HTMAVEWB-h9AYS2UB.js} +1 -1
  150. package/dist/assets/{save-DNigywZ9.js → save-394QCMXn.js} +1 -1
  151. package/dist/assets/{search-U9C0oTQJ.js → search-BG2qAlNZ.js} +1 -1
  152. package/dist/assets/{search-config-page-Bdx_RR1q.js → search-config-page-D4LeiB9y.js} +1 -1
  153. package/dist/assets/{secrets-config-page-CvMIcsfJ.js → secrets-config-page-BzGcr5Vw.js} +2 -2
  154. package/dist/assets/security-config-vD_V0BQF.js +1 -0
  155. package/dist/assets/{select-DxwDeKUR.js → select-xUXYV0Gr.js} +1 -1
  156. package/dist/assets/{sequenceDiagram-DBY2YBRQ-EFD482_y.js → sequenceDiagram-DBY2YBRQ-D-uxCkob.js} +1 -1
  157. package/dist/assets/service-apps-panel-BTqXn0pg.js +1 -0
  158. package/dist/assets/{settings-2-BrBUdRoY.js → settings-2-CWOGRRaA.js} +1 -1
  159. package/dist/assets/{sizeCapture-X5ZJPWSS-TDvULTE1.js → sizeCapture-X5ZJPWSS-DBzZytQo.js} +1 -1
  160. package/dist/assets/{src-CI2AvEMj.js → src-zrGbZsfc.js} +1 -1
  161. package/dist/assets/{stateDiagram-2N3HPSRC-JdPsIYHo.js → stateDiagram-2N3HPSRC-DyDy7AHq.js} +1 -1
  162. package/dist/assets/stateDiagram-v2-6OUMAXLB-CtkpO6aA.js +1 -0
  163. package/dist/assets/{status-dot-BbGsrkIX.js → status-dot-CYifnSnt.js} +1 -1
  164. package/dist/assets/{swimlanes-5IMT3BWC-BnxpKeK_.js → swimlanes-5IMT3BWC-BzOduS38.js} +2 -2
  165. package/dist/assets/swimlanesDiagram-G3AALYLV-BSdi6mvi.js +8 -0
  166. package/dist/assets/{tag-chip-BDbxcf6P.js → tag-chip-CjM6lyeh.js} +1 -1
  167. package/dist/assets/theme-provider-BToFZGZG.js +1 -0
  168. package/dist/assets/{timeline-definition-FHXFAJF6-2IL22-uC.js → timeline-definition-FHXFAJF6-CmgnEF2t.js} +1 -1
  169. package/dist/assets/{trash-2-DwSkRfeB.js → trash-2-DvJ6duOW.js} +1 -1
  170. package/dist/assets/treeView-QDETBFTQ-DBoqypPR.js +1 -0
  171. package/dist/assets/treemap-6X3UGDF4-BMeL3P0q.js +1 -0
  172. package/dist/assets/use-config-COusaY5p.js +1 -0
  173. package/dist/assets/{use-desktop-capabilities-D7odgaTB.js → use-desktop-capabilities-B-u6ojjW.js} +1 -1
  174. package/dist/assets/{use-viewport-layout-BANU5E1t.js → use-viewport-layout-IKKGpjzF.js} +1 -1
  175. package/dist/assets/{vennDiagram-L72KCM5P-Cjf6n5Va.js → vennDiagram-L72KCM5P-DwS7D2kg.js} +1 -1
  176. package/dist/assets/wardley-OPB4EBWU-Dqxe7zN6.js +1 -0
  177. package/dist/assets/{wardleyDiagram-EHGQE667-yv4qKbBO.js → wardleyDiagram-EHGQE667-B4X8OOL4.js} +1 -1
  178. package/dist/assets/{x-BqGj6_Vq.js → x-E9VB4HQx.js} +1 -1
  179. package/dist/assets/{xychartDiagram-FW5EYKEG-Bmp8Ck8X.js → xychartDiagram-FW5EYKEG-BjRQ_0nx.js} +1 -1
  180. package/dist/index.html +41 -40
  181. package/dist/panel-standalone.html +16 -16
  182. package/package.json +6 -6
  183. package/src/features/agents/components/__tests__/agents-page.test.tsx +8 -5
  184. package/src/features/agents/components/agent-details-dialog.tsx +19 -15
  185. package/src/features/agents/components/agents-page.tsx +27 -38
  186. package/src/features/app-data/components/app-retained-data-section.tsx +2 -2
  187. package/src/features/apps/components/app-marketplace-catalog.tsx +5 -5
  188. package/src/features/apps/components/app-marketplace-detail.tsx +11 -2
  189. package/src/features/apps/components/app-packages-panel.tsx +4 -4
  190. package/src/features/apps/components/apps-panel.tsx +3 -1
  191. package/src/features/chat/components/providers/chat-runtime.provider.tsx +1 -1
  192. package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +0 -1
  193. package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +13 -2
  194. package/src/features/chat/features/conversation/components/session-conversation-area.tsx +8 -1
  195. package/src/features/chat/features/conversation/components/session-conversation-input-top-slot.tsx +44 -0
  196. package/src/features/chat/features/conversation/components/session-conversation-input.tsx +4 -38
  197. package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-controller.test.tsx +127 -10
  198. package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-input-state.test.tsx +12 -2
  199. package/src/features/chat/features/conversation/hooks/use-session-conversation-controller.ts +88 -73
  200. package/src/features/chat/features/conversation/hooks/use-session-conversation-input-query.ts +5 -15
  201. package/src/features/chat/features/conversation/hooks/use-session-conversation-input-state.ts +53 -13
  202. package/src/features/chat/features/conversation/hooks/use-session-submission-recovery.ts +83 -0
  203. package/src/features/chat/features/conversation/types/session-conversation-input.types.ts +38 -0
  204. package/src/features/chat/features/input/utils/__tests__/ncp-chat-input-availability.utils.test.ts +1 -29
  205. package/src/features/chat/features/input/utils/ncp-chat-input-availability.utils.ts +1 -8
  206. package/src/features/chat/features/message/components/__tests__/chat-message-list-skill-preview.container.test.tsx +14 -1
  207. package/src/features/chat/features/message/hooks/use-chat-inline-token-actions.ts +7 -2
  208. package/src/features/chat/features/session/utils/__tests__/chat-session-route.utils.test.ts +26 -0
  209. package/src/features/chat/features/session/utils/chat-session-preference-governance.utils.ts +14 -8
  210. package/src/features/chat/features/session/utils/chat-session-route.utils.ts +9 -12
  211. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-file-preview.selection.test.tsx +14 -2
  212. package/src/features/chat/features/workspace/components/__tests__/session-cron-job-content.test.tsx +5 -1
  213. package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +1 -1
  214. package/src/features/chat/features/workspace/components/session-cron-job-content.tsx +6 -22
  215. package/src/features/chat/index.ts +1 -0
  216. package/src/features/chat/pages/__tests__/ncp-chat-page.test.ts +37 -47
  217. package/src/features/chat/pages/ncp-chat-page.tsx +3 -3
  218. package/src/features/chat/stores/__tests__/chat-composer-draft.store.test.ts +67 -1
  219. package/src/features/chat/stores/chat-composer-draft.store.ts +230 -29
  220. package/src/features/cron/components/__tests__/cron-config.test.tsx +8 -2
  221. package/src/features/cron/components/cron-config.tsx +6 -17
  222. package/src/features/cron/components/cron-job-detail-dialog.tsx +10 -9
  223. package/src/features/cron/components/cron-job-resource.tsx +51 -0
  224. package/src/features/cron/index.ts +1 -0
  225. package/src/features/inbox/pages/inbox-page.tsx +8 -5
  226. package/src/features/marketplace/components/__tests__/marketplace-page-detail.test.tsx +1 -0
  227. package/src/features/marketplace/components/__tests__/marketplace-page.test.tsx +1 -0
  228. package/src/features/marketplace/components/mcp/__tests__/mcp-marketplace-page.test.tsx +2 -0
  229. package/src/features/marketplace/components/mcp/mcp-marketplace-card.tsx +2 -2
  230. package/src/features/marketplace/components/mcp/mcp-marketplace-page.tsx +23 -1
  231. package/src/features/marketplace/hooks/use-marketplace-item-detail.ts +11 -0
  232. package/src/features/panel-apps/index.ts +1 -0
  233. package/src/features/projects/components/work/project-work-item-drawer.tsx +7 -10
  234. package/src/features/projects/pages/project-home-page.tsx +18 -23
  235. package/src/features/projects/pages/projects-page.test.tsx +4 -1
  236. package/src/features/right-panel-resources/components/__tests__/system-object-resource.test.tsx +74 -6
  237. package/src/features/right-panel-resources/components/native-object-resource.tsx +134 -0
  238. package/src/features/right-panel-resources/components/page-resource-icon.tsx +1 -1
  239. package/src/features/right-panel-resources/components/system-object-resource.tsx +66 -1
  240. package/src/features/right-panel-resources/components/workspace-file-resource.tsx +9 -0
  241. package/src/features/right-panel-resources/configs/right-panel-resource-routes.config.ts +11 -21
  242. package/src/features/right-panel-resources/managers/__tests__/page-resource.manager.test.ts +14 -4
  243. package/src/features/right-panel-resources/managers/page-resource.manager.ts +38 -21
  244. package/src/features/right-panel-resources/utils/__tests__/right-panel-resource-route-resolver.utils.test.ts +12 -0
  245. package/src/features/service-apps/components/service-apps-panel.tsx +5 -2
  246. package/src/shared/components/doc-browser/__tests__/doc-browser-context.test.tsx +16 -0
  247. package/src/shared/components/doc-browser/__tests__/doc-browser.test.tsx +2 -2
  248. package/src/shared/components/doc-browser/__tests__/resource-link-interceptor.test.tsx +29 -1
  249. package/src/shared/components/doc-browser/stores/doc-browser.store.ts +13 -7
  250. package/src/shared/components/doc-browser/utils/doc-browser-url.utils.ts +2 -1
  251. package/src/shared/components/ui/skeleton.tsx +16 -2
  252. package/src/shared/lib/i18n/locales/en-US/chat.json +8 -0
  253. package/src/shared/lib/i18n/locales/zh-CN/chat.json +8 -0
  254. package/src/shared/lib/transport/__tests__/local-transport.service.test.ts +24 -0
  255. package/src/shared/lib/transport/local-transport.service.ts +8 -6
  256. package/dist/assets/account-panel-BYxGT4m4.js +0 -1
  257. package/dist/assets/api-CG22BskB.js +0 -20
  258. package/dist/assets/app-presenter-provider-CJFjhVYI.js +0 -28
  259. package/dist/assets/appearance-settings-page-BcXr0vHp.js +0 -1
  260. package/dist/assets/architecture-TIHT7OUA-CLjV_xu4.js +0 -1
  261. package/dist/assets/channel-BgpbPyEH.js +0 -1
  262. package/dist/assets/chunk-2Q5K7J3B-DjhMPqAC.js +0 -1
  263. package/dist/assets/chunk-VAUOI2AC-GYimZYx9.js +0 -1
  264. package/dist/assets/chunk-XXDRQBXY-KKCf0HV5.js +0 -1
  265. package/dist/assets/classDiagram-OUVF2IWQ-iRMPRR8M.js +0 -1
  266. package/dist/assets/classDiagram-v2-EOCWNBFH-BguFy_wj.js +0 -1
  267. package/dist/assets/cynefin-VYW2F7L2-CtbjXuCW.js +0 -1
  268. package/dist/assets/doc-browser-CDEapjmj.js +0 -1
  269. package/dist/assets/doc-browser-context-0QDWYorh.js +0 -1
  270. package/dist/assets/eventmodeling-45OFAUF4-Djd6id_u.js +0 -1
  271. package/dist/assets/flowDiagram-23GEKE2U-DUrsM_ZL.js +0 -1
  272. package/dist/assets/gitGraph-TEB2WS4Q-CU6P_2Cm.js +0 -1
  273. package/dist/assets/info-DKCQHKI2-Bj2P_7RC.js +0 -1
  274. package/dist/assets/katex-BprZ-Wwb.js +0 -1
  275. package/dist/assets/keyboard-shortcuts-settings-page-BluWKrSo.js +0 -1
  276. package/dist/assets/login-page-BMHW0Hh0.js +0 -1
  277. package/dist/assets/main-BCX_Untx.css +0 -1
  278. package/dist/assets/main-C5kbmGUV.js +0 -2
  279. package/dist/assets/main-i18n-catalog.config-DO4wNT7T.js +0 -1
  280. package/dist/assets/mcp-marketplace-page-CV-PHKTN.js +0 -1
  281. package/dist/assets/packet-7NZHBO7P-ti5ge2jr.js +0 -1
  282. package/dist/assets/panel-app-i18n-catalog.config-Bo52dPuF.js +0 -1
  283. package/dist/assets/panelStandalone-PuuMF65O.js +0 -2
  284. package/dist/assets/pie-RZYD4A2V-Bnep8TyV.js +0 -1
  285. package/dist/assets/plus-CywSlIbG.js +0 -1
  286. package/dist/assets/projects-D_cd_t4G.js +0 -1
  287. package/dist/assets/radar-I7S5WNFK-BYg-icAP.js +0 -1
  288. package/dist/assets/railroad-3IZDKUUU-_CHO-Fi1.js +0 -1
  289. package/dist/assets/railroad-abnf-AHOZXSZD-hbQDevHe.js +0 -1
  290. package/dist/assets/railroad-ebnf-EBAXGLYW-v4RZkOfi.js +0 -1
  291. package/dist/assets/railroad-peg-LSFZ7HO6-bC9BqkI5.js +0 -1
  292. package/dist/assets/remote-D5MBQNZE.js +0 -1
  293. package/dist/assets/runtime-config-page--ivCxBT4.js +0 -1
  294. package/dist/assets/security-config-CQmMqQ8v.js +0 -1
  295. package/dist/assets/service-apps-panel-CiYO1Be4.js +0 -1
  296. package/dist/assets/stateDiagram-v2-6OUMAXLB-4_aAQfB_.js +0 -1
  297. package/dist/assets/swimlanesDiagram-G3AALYLV-wCqfwsw-.js +0 -8
  298. package/dist/assets/theme-provider-D98XGa-c.js +0 -1
  299. package/dist/assets/treeView-QDETBFTQ-BAyOb14Z.js +0 -1
  300. package/dist/assets/treemap-6X3UGDF4-DgPDM0zS.js +0 -1
  301. package/dist/assets/use-config-D3cNzk2k.js +0 -1
  302. package/dist/assets/wardley-OPB4EBWU-eCElh8z5.js +0 -1
  303. /package/dist/assets/{array-DstOKG9P.js → array-DsNX3jRj.js} +0 -0
  304. /package/dist/assets/{chunk-KEIR6QF5-0TA8nwgf.js → chunk-KEIR6QF5-BOAXXeyv.js} +0 -0
  305. /package/dist/assets/{chunk-Y2CYZVJY-rfGCG6pM.js → chunk-Y2CYZVJY-CHjSjwoV.js} +0 -0
  306. /package/dist/assets/{config-hints-BfGoD7-o.js → config-hints-CaB3I7KP.js} +0 -0
  307. /package/dist/assets/{cytoscape.esm-DdIcNEda.js → cytoscape.esm-j4J9a91l.js} +0 -0
  308. /package/dist/assets/{defaultLocale-CzXix2iJ.js → defaultLocale-Bmxjp-V_.js} +0 -0
  309. /package/dist/assets/{dist-D5dwMwKA.js → dist-DwLj1Wg5.js} +0 -0
  310. /package/dist/assets/{graphlib-BKOe0eFe.js → graphlib-CC0HTn1v.js} +0 -0
  311. /package/dist/assets/{host-capabilities-CnSVTaot.js → host-capabilities-B107nwS3.js} +0 -0
  312. /package/dist/assets/{init-OCFb3zgY.js → init-Biz9Rus1.js} +0 -0
  313. /package/dist/assets/{jszip.min-B2uhSxvV.js → jszip.min-DQvBVV_R.js} +0 -0
  314. /package/dist/assets/{katex-dBrYsE7B.js → katex-BzT-4KBu.js} +0 -0
  315. /package/dist/assets/{middleware-CAXxl-af.js → middleware-B--6mAUM.js} +0 -0
  316. /package/dist/assets/{navigation-history-CzErJuPG.js → navigation-history-CCnxsAKR.js} +0 -0
  317. /package/dist/assets/{panel-app-CSQmm_7E.js → panel-app-BBTg0tVp.js} +0 -0
  318. /package/dist/assets/{path-T5eoIRSJ.js → path-4azsBPZv.js} +0 -0
  319. /package/dist/assets/{rough.esm-DmGXmZEB.js → rough.esm-w1lBArN6.js} +0 -0
  320. /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.getByText("身份").closest("[role='dialog']");
303
- expect(detailsDialog?.className).toContain("sm:max-w-2xl");
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-[10rem_minmax(0,1fr)]") &&
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
- return (
74
- <Dialog open={agent !== null} onOpenChange={onOpenChange}>
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
- </DialogContent>
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-x-6 gap-y-2.5 pl-5 sm:grid-cols-2">
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-1 sm:grid-cols-[10rem_minmax(0,1fr)] items-baseline gap-x-2 gap-y-1",
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="whitespace-nowrap text-xs font-medium text-muted-foreground">
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
- setViewingAgent(agent);
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
- <AgentDetailsDialog
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 { Skeleton } from '@/shared/components/ui/skeleton';
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 ? <Skeleton className="h-28 w-full rounded-xl" /> : null}
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 { Skeleton } from '@/shared/components/ui/skeleton';
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
- <Skeleton className="aspect-[16/9] w-full rounded-2xl" />
226
- <Skeleton className="aspect-[16/9] w-full rounded-2xl" />
227
- <Skeleton className="hidden aspect-[16/9] w-full rounded-2xl [@container(min-width:52rem)]:block" />
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 <div className="space-y-4 p-6"><Skeleton className="h-24 w-full rounded-2xl" /><Skeleton className="h-40 w-full rounded-2xl" /></div>;
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 { Skeleton } from '@/shared/components/ui/skeleton';
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
- <Skeleton className="h-44 w-full rounded-2xl" />
288
- <Skeleton className="h-32 w-full rounded-2xl" />
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?.params.sessionId);
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 &&
@@ -13,7 +13,6 @@ const mocks = vi.hoisted(() => {
13
13
  const inputActions = {
14
14
  update: vi.fn(),
15
15
  syncComposer: vi.fn(),
16
- resetComposer: vi.fn(),
17
16
  restoreComposer: vi.fn(),
18
17
  applyPromptSuggestion: vi.fn(),
19
18
  requestComposerFocusAtEnd: vi.fn(),
@@ -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,
@@ -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 { SessionQueuedInputRows } from './session-queued-input-rows';
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={controller.queuedInputs.length > 0 ? <SessionQueuedInputRows controller={controller} /> : null}
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={{