@nextclaw/ui 0.26.5 → 0.27.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (433) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/dist/.vite/manifest.json +1342 -1227
  3. package/dist/assets/{abnfDiagram-VRR7QNED-Dcw10Yt1.js → abnfDiagram-VRR7QNED-BT0_ycaq.js} +1 -1
  4. package/dist/assets/account-panel-BVNV8XqM.js +1 -0
  5. package/dist/assets/agents-CfpN8PQc.js +1 -0
  6. package/dist/assets/agents-E4nu-17c.js +1 -0
  7. package/dist/assets/{aiden0z-pptx-renderer.es--oNqetPA.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-2DwHRRle.js +28 -0
  10. package/dist/assets/app-presenter-provider-D3BuuOyZ.css +1 -0
  11. package/dist/assets/appearance-settings-page-Cn9w3F-K.js +1 -0
  12. package/dist/assets/apps-YFlJirpx.js +1 -0
  13. package/dist/assets/{arc-DBRedCax.js → arc-cmSdpq1Z.js} +1 -1
  14. package/dist/assets/architecture-TIHT7OUA-BImoGh10.js +1 -0
  15. package/dist/assets/{architectureDiagram-ZJ3FMSHR-Dufhtuv-.js → architectureDiagram-ZJ3FMSHR-aYglVeoS.js} +1 -1
  16. package/dist/assets/{blockDiagram-677ZJIJ3-BUk0vtJ7.js → blockDiagram-677ZJIJ3-Di_PBl5q.js} +1 -1
  17. package/dist/assets/{book-open-Bcnn2_uV.js → book-open-i_BjUBqL.js} +1 -1
  18. package/dist/assets/{c4Diagram-LMCZKHZV-CxDcVE9p.js → c4Diagram-LMCZKHZV-CfuxybOL.js} +1 -1
  19. package/dist/assets/{card-Cqs73hGI.js → card-DokH7OBp.js} +1 -1
  20. package/dist/assets/channel-BDQry0ob.js +1 -0
  21. package/dist/assets/channels-list-page-B7G9lHUm.js +8 -0
  22. package/dist/assets/chunk-2Q5K7J3B-DkgSFfIy.js +1 -0
  23. package/dist/assets/{chunk-32BRIVSS-DSF3KElA.js → chunk-32BRIVSS-CCGc4qg4.js} +1 -1
  24. package/dist/assets/{chunk-52WLFC77-Costxzr3.js → chunk-52WLFC77-aJoxU2Ow.js} +1 -1
  25. package/dist/assets/{chunk-5FCAYU7R-rhqzGGZo.js → chunk-5FCAYU7R-CGwtZSax.js} +1 -1
  26. package/dist/assets/{chunk-5HE753X5-BsEsmIao.js → chunk-5HE753X5-DqaMSMeS.js} +1 -1
  27. package/dist/assets/{chunk-5JV3BV7I-Dqw_DCoN.js → chunk-5JV3BV7I-DnabINcd.js} +1 -1
  28. package/dist/assets/{chunk-5TONJI2A-Cft82fp8.js → chunk-5TONJI2A-BhpKv1k2.js} +1 -1
  29. package/dist/assets/{chunk-5VM5RSS4-DqNHn9Dl.js → chunk-5VM5RSS4-DvkRPit_.js} +1 -1
  30. package/dist/assets/{chunk-7BUUIJ7U-A5SBEMYY.js → chunk-7BUUIJ7U-CgDQOLnC.js} +1 -1
  31. package/dist/assets/{chunk-BIQX33UG-1Ng3mTrH.js → chunk-BIQX33UG-9FEv5b7T.js} +1 -1
  32. package/dist/assets/{chunk-C7G6YPKG-DRJEy8ZI.js → chunk-C7G6YPKG-CNGFAFYL.js} +1 -1
  33. package/dist/assets/{chunk-CQNSW5MT-Bydv_J3J.js → chunk-CQNSW5MT-DovTZx0M.js} +1 -1
  34. package/dist/assets/{chunk-CYSBUYHQ-HkMIg12u.js → chunk-CYSBUYHQ-DpLEgYa1.js} +1 -1
  35. package/dist/assets/{chunk-EMLP6XTP-C5ndDvm3.js → chunk-EMLP6XTP-D4NuN01W.js} +1 -1
  36. package/dist/assets/{chunk-EX3LRPZG-DzeloZRo.js → chunk-EX3LRPZG-D8Jf4kc2.js} +1 -1
  37. package/dist/assets/{chunk-FWX5IMBZ-n_2_CLTQ.js → chunk-FWX5IMBZ-BdHymAs0.js} +2 -2
  38. package/dist/assets/{chunk-HOUHSVGY-kx_slvu3.js → chunk-HOUHSVGY-Dd_Ycn9Z.js} +1 -1
  39. package/dist/assets/{chunk-ICXQ74PX-sQLMURqL.js → chunk-ICXQ74PX-BRPUu3ff.js} +1 -1
  40. package/dist/assets/{chunk-JG7HCLWE-CMUn5Elc.js → chunk-JG7HCLWE-DnCasQja.js} +1 -1
  41. package/dist/assets/{chunk-JWPE2WC7-Cra3s-Uk.js → chunk-JWPE2WC7-C3CkbEj1.js} +1 -1
  42. package/dist/assets/{chunk-MOJQB5TN-umcrg5Bi.js → chunk-MOJQB5TN-Pi--K4-1.js} +1 -1
  43. package/dist/assets/{chunk-MOZMSUNE-BnljD1ig.js → chunk-MOZMSUNE-3VTspvlh.js} +1 -1
  44. package/dist/assets/{chunk-OGEWGWER-BXx5pQjU.js → chunk-OGEWGWER-BetLLyJt.js} +1 -1
  45. package/dist/assets/{chunk-OSBZ3O6U-D-1qfdWu.js → chunk-OSBZ3O6U-D1VcupAj.js} +1 -1
  46. package/dist/assets/{chunk-PUDLZKDR-DLzX78LC.js → chunk-PUDLZKDR-Cy4G8SjV.js} +1 -1
  47. package/dist/assets/{chunk-Q4XR5HBZ-DTK-rtW6.js → chunk-Q4XR5HBZ-UYxXzi7_.js} +1 -1
  48. package/dist/assets/{chunk-QBLGF6JB-CsFeIGfr.js → chunk-QBLGF6JB-CHiGeRY1.js} +1 -1
  49. package/dist/assets/{chunk-R7FJI6CG-4xNYUeng.js → chunk-R7FJI6CG-C5kVJus8.js} +1 -1
  50. package/dist/assets/{chunk-RYQCIY6F-DJiHiTE5.js → chunk-RYQCIY6F-C6cuuEBn.js} +1 -1
  51. package/dist/assets/{chunk-U6XO7XAA-BVYkauHz.js → chunk-U6XO7XAA-CM0EK7Y0.js} +1 -1
  52. package/dist/assets/{chunk-V7JOEXUC-BsazE8cS.js → chunk-V7JOEXUC-DWJZIsME.js} +1 -1
  53. package/dist/assets/chunk-VAUOI2AC-CsTIB8qD.js +1 -0
  54. package/dist/assets/{chunk-VR4S4FIN-7RoZQffO.js → chunk-VR4S4FIN-CY5KYeEi.js} +1 -1
  55. package/dist/assets/{chunk-WYO6CB5R-DEuS6N1R.js → chunk-WYO6CB5R-B30N3ZP8.js} +3 -3
  56. package/dist/assets/chunk-XXDRQBXY-DK6dz0Q3.js +1 -0
  57. package/dist/assets/{chunk-YOTPTUD7-9KBrosZL.js → chunk-YOTPTUD7-CBu82JpO.js} +1 -1
  58. package/dist/assets/{chunk-ZGVPDNZ5-IYgN9f5A.js → chunk-ZGVPDNZ5-BN5NX5qA.js} +1 -1
  59. package/dist/assets/{chunk-ZIRB5QZD-BUo0-zcp.js → chunk-ZIRB5QZD-DcDXK29L.js} +1 -1
  60. package/dist/assets/{circle-dashed-EY1ScSMe.js → circle-dashed-Cx8CIEbg.js} +1 -1
  61. package/dist/assets/classDiagram-OUVF2IWQ-BYygHCrp.js +1 -0
  62. package/dist/assets/classDiagram-v2-EOCWNBFH-BgQ0XKYz.js +1 -0
  63. package/dist/assets/{client-CH7w6yRV.js → client-CUJUci3r.js} +1 -1
  64. package/dist/assets/config-split-page-hY1xug28.js +1 -0
  65. package/dist/assets/confirm-dialog-B-ejV666.js +1 -0
  66. package/dist/assets/{app-presenter-provider-jNGlmBLe.css → context-menu-DEcVZfaU.css} +1 -1
  67. package/dist/assets/context-menu-dGVv8klA.js +211 -0
  68. package/dist/assets/{cose-bilkent-JH36ORCC-DhqbC1fR.js → cose-bilkent-JH36ORCC-CmeJVoTw.js} +1 -1
  69. package/dist/assets/{createLucideIcon-Cfo2ySi5.js → createLucideIcon-reFMl-W-.js} +1 -1
  70. package/dist/assets/cron-CH5c55CR.js +1 -0
  71. package/dist/assets/cynefin-VYW2F7L2-DKbotNWS.js +1 -0
  72. package/dist/assets/{cynefinDiagram-TSTJHNR4-C-TBRi5V.js → cynefinDiagram-TSTJHNR4-DGOUMgPP.js} +1 -1
  73. package/dist/assets/{dagre-CrgsRasE.js → dagre-CMxSkbJJ.js} +1 -1
  74. package/dist/assets/{dagre-VKFMJZFB-BmafJymp.js → dagre-VKFMJZFB-3YUBEXwo.js} +1 -1
  75. package/dist/assets/{desktop-capabilities-page-BDYITStl.js → desktop-capabilities-page-CYJTQ3nC.js} +1 -1
  76. package/dist/assets/desktop-update-config-guKAozXO.js +1 -0
  77. package/dist/assets/{diagram-FQU43EPY-BoOMwa6D.js → diagram-FQU43EPY-Br1g--ww.js} +1 -1
  78. package/dist/assets/{diagram-G47NLZAW-Le7N6Uym.js → diagram-G47NLZAW-D1wJCBgr.js} +1 -1
  79. package/dist/assets/{diagram-NH7WQ7WH-Fbpj3-MO.js → diagram-NH7WQ7WH-Cgg2auLH.js} +1 -1
  80. package/dist/assets/{diagram-OA4YK3LP-D3QuGGuu.js → diagram-OA4YK3LP-R-wHiWqh.js} +1 -1
  81. package/dist/assets/{diagram-WEI45ONY-Cxu1uiN6.js → diagram-WEI45ONY-CsNnKV0P.js} +1 -1
  82. package/dist/assets/dialog-DLOwdjT1.js +1 -0
  83. package/dist/assets/dist-ZaFFmAGl.js +41 -0
  84. package/dist/assets/doc-browser-ClDUWo9V.js +1 -0
  85. package/dist/assets/doc-browser-context-CTmOmuqa.js +1 -0
  86. package/dist/assets/{docx-preview-CkU2psnd.js → docx-preview-kPn_EtAr.js} +1 -1
  87. package/dist/assets/{download-BoaKzDJk.js → download-DovI3Yvf.js} +1 -1
  88. package/dist/assets/{ebnfDiagram-CCIWWBDH-CCAjuQM6.js → ebnfDiagram-CCIWWBDH-DCyhIPdi.js} +1 -1
  89. package/dist/assets/{erDiagram-Q63AITRT-BuzUAq-d.js → erDiagram-Q63AITRT-D0ZJYAUf.js} +1 -1
  90. package/dist/assets/eventmodeling-45OFAUF4-SIhbIFIw.js +1 -0
  91. package/dist/assets/extensions-BZ3qrM8M.js +1 -0
  92. package/dist/assets/external-link-DUD3AbsF.js +1 -0
  93. package/dist/assets/flowDiagram-23GEKE2U-DdAjkU7I.js +1 -0
  94. package/dist/assets/{form-actions-D9JWSFQu.js → form-actions-B8VniHts.js} +1 -1
  95. package/dist/assets/{ganttDiagram-NO4QXBWP-cJmWVY8F.js → ganttDiagram-NO4QXBWP-CiXDcXZD.js} +1 -1
  96. package/dist/assets/gitGraph-TEB2WS4Q-DnMNpESZ.js +1 -0
  97. package/dist/assets/{gitGraphDiagram-IHSO6WYX-F58o-vtP.js → gitGraphDiagram-IHSO6WYX-BSiIV48S.js} +1 -1
  98. package/dist/assets/{i18n-Bm3Ov7Fy.js → i18n-IGQbjBqS.js} +2 -2
  99. package/dist/assets/inbox-BjBZIbgx.js +1 -0
  100. package/dist/assets/inbox-ClAG7SI_.js +1 -0
  101. package/dist/assets/info-DKCQHKI2-BSm-69p_.js +1 -0
  102. package/dist/assets/{infoDiagram-FWYZ7A6U-Gt59b83C.js → infoDiagram-FWYZ7A6U-CCIgBCVq.js} +1 -1
  103. package/dist/assets/{ishikawaDiagram-FXEZZL3T-1u4IAj1I.js → ishikawaDiagram-FXEZZL3T-nQ_baN5u.js} +1 -1
  104. package/dist/assets/{journeyDiagram-5HDEW3XC-CCQsfV-5.js → journeyDiagram-5HDEW3XC-ABueIPzj.js} +1 -1
  105. package/dist/assets/{kanban-definition-HUTT4EX6-vlB6O_Zn.js → kanban-definition-HUTT4EX6-8FKS3fmQ.js} +1 -1
  106. package/dist/assets/katex-DPgHtix3.js +1 -0
  107. package/dist/assets/keyboard-shortcuts-settings-page-BqfbbKir.js +1 -0
  108. package/dist/assets/{line-D_bHubTL.js → line-Biw8iEUz.js} +1 -1
  109. package/dist/assets/{linear-ChlwuS5y.js → linear-D7CWUHTF.js} +1 -1
  110. package/dist/assets/login-page-BxSMwUsc.js +1 -0
  111. package/dist/assets/{login-page-C-DvcG3L.js → login-page-DYaozpzz.js} +1 -1
  112. package/dist/assets/main-CWYF9QU_.js +2 -0
  113. package/dist/assets/main-D_zmSVS1.css +1 -0
  114. package/dist/assets/main-i18n-catalog.config-itg3Gvzp.js +1 -0
  115. package/dist/assets/{map-oGHTsIu8.js → map-CDu47gTf.js} +1 -1
  116. package/dist/assets/marketplace-CnQ5USfr.js +1 -0
  117. package/dist/assets/mcp-marketplace-page-Dor6H9IC.js +1 -0
  118. package/dist/assets/{mermaid-parser.core-CuRe1ZG4.js → mermaid-parser.core-Cc9wjl82.js} +2 -2
  119. package/dist/assets/{mermaid.core-u4YCFKRf.js → mermaid.core-GWlaVWz1.js} +3 -3
  120. package/dist/assets/{mindmap-definition-LN4V7U3C-DeJAQYTu.js → mindmap-definition-LN4V7U3C-oqnKsz-R.js} +1 -1
  121. package/dist/assets/model-config-page-Cduyz2Hy.js +1 -0
  122. package/dist/assets/{navigation-link-CjxNC8aT.js → navigation-link-D-JSWFxj.js} +2 -2
  123. package/dist/assets/{ordinal-C6JFfkKN.js → ordinal-DImbxqBz.js} +1 -1
  124. package/dist/assets/packet-7NZHBO7P-1YQvC6mT.js +1 -0
  125. package/dist/assets/panel-app-BBTg0tVp.js +1 -0
  126. package/dist/assets/panel-app-i18n-catalog.config-BfLHr1tc.js +1 -0
  127. package/dist/assets/panel-apps-C-izvtu9.js +1 -0
  128. package/dist/assets/panelStandalone-XRlWxbRS.css +1 -0
  129. package/dist/assets/panelStandalone-oHxbXvYt.js +2 -0
  130. package/dist/assets/{pegDiagram-2B236MQR-nVMkxShH.js → pegDiagram-2B236MQR-DYAB8CEz.js} +1 -1
  131. package/dist/assets/pie-RZYD4A2V-BGoNOSwu.js +1 -0
  132. package/dist/assets/{pieDiagram-ENE6RG2P-8aUH44QZ.js → pieDiagram-ENE6RG2P-DGsH0Kk5.js} +1 -1
  133. package/dist/assets/plus-DUdl68Eo.js +1 -0
  134. package/dist/assets/privacy-settings-page-DG9E8N-F.js +1 -0
  135. package/dist/assets/projects-CzBaTOTL.js +1 -0
  136. package/dist/assets/provider-models-COzjYl29.js +1 -0
  137. package/dist/assets/provider-scoped-model-input-Cvy74uj8.js +1 -0
  138. package/dist/assets/providers-config-page-7rCwVnhh.js +1 -0
  139. package/dist/assets/puzzle-C5Wfpjk_.js +1 -0
  140. package/dist/assets/pwa-CAg_9zFs.js +1 -0
  141. package/dist/assets/{quadrantDiagram-ABIIQ3AL-EY8hpFv8.js → quadrantDiagram-ABIIQ3AL-BegGcT3l.js} +1 -1
  142. package/dist/assets/radar-I7S5WNFK-uPku9RRq.js +1 -0
  143. package/dist/assets/railroad-3IZDKUUU-DHnmbuIo.js +1 -0
  144. package/dist/assets/railroad-abnf-AHOZXSZD-DiZs--Iw.js +1 -0
  145. package/dist/assets/railroad-ebnf-EBAXGLYW-Nr53gnNE.js +1 -0
  146. package/dist/assets/railroad-peg-LSFZ7HO6-Cm_PuwJS.js +1 -0
  147. package/dist/assets/{railroadDiagram-RFXS5EU6-CNhcIeji.js → railroadDiagram-RFXS5EU6-B3yJ2yxE.js} +1 -1
  148. package/dist/assets/{refresh-cw-BlXDrVP0.js → refresh-cw-OhwaPDn1.js} +1 -1
  149. package/dist/assets/remote-DvCdHjzA.js +1 -0
  150. package/dist/assets/{requirementDiagram-TGXJPOKE-D8Dcs-Rt.js → requirementDiagram-TGXJPOKE-DtEyoEXG.js} +1 -1
  151. package/dist/assets/{rotate-cw-ei6rPD6z.js → rotate-cw-aBponvp7.js} +1 -1
  152. package/dist/assets/runtime-config-page-BF1wxvzR.js +1 -0
  153. package/dist/assets/{sankeyDiagram-HTMAVEWB-HTrb6aa-.js → sankeyDiagram-HTMAVEWB-h9AYS2UB.js} +1 -1
  154. package/dist/assets/{save-DdF-bXgC.js → save-394QCMXn.js} +1 -1
  155. package/dist/assets/search-BG2qAlNZ.js +1 -0
  156. package/dist/assets/search-config-page-D4LeiB9y.js +1 -0
  157. package/dist/assets/secrets-config-page-BzGcr5Vw.js +3 -0
  158. package/dist/assets/security-config-vD_V0BQF.js +1 -0
  159. package/dist/assets/select-xUXYV0Gr.js +1 -0
  160. package/dist/assets/{sequenceDiagram-DBY2YBRQ-6f_4X16Y.js → sequenceDiagram-DBY2YBRQ-D-uxCkob.js} +1 -1
  161. package/dist/assets/service-apps-panel-D3wwPRzV.js +1 -0
  162. package/dist/assets/{settings-2-CrNhfInU.js → settings-2-CWOGRRaA.js} +1 -1
  163. package/dist/assets/{sizeCapture-X5ZJPWSS-Ck9rsuwL.js → sizeCapture-X5ZJPWSS-DBzZytQo.js} +1 -1
  164. package/dist/assets/{src-C8AUg09O.js → src-zrGbZsfc.js} +1 -1
  165. package/dist/assets/{stateDiagram-2N3HPSRC-Cm33MLHu.js → stateDiagram-2N3HPSRC-DyDy7AHq.js} +1 -1
  166. package/dist/assets/stateDiagram-v2-6OUMAXLB-CtkpO6aA.js +1 -0
  167. package/dist/assets/{status-dot-C3SRFEta.js → status-dot-CYifnSnt.js} +1 -1
  168. package/dist/assets/{swimlanes-5IMT3BWC-B107vmvM.js → swimlanes-5IMT3BWC-BzOduS38.js} +2 -2
  169. package/dist/assets/swimlanesDiagram-G3AALYLV-BSdi6mvi.js +8 -0
  170. package/dist/assets/tag-chip-CjM6lyeh.js +1 -0
  171. package/dist/assets/theme-provider-BToFZGZG.js +1 -0
  172. package/dist/assets/{timeline-definition-FHXFAJF6-CJEoAj33.js → timeline-definition-FHXFAJF6-CmgnEF2t.js} +1 -1
  173. package/dist/assets/trash-2-DvJ6duOW.js +1 -0
  174. package/dist/assets/treeView-QDETBFTQ-DBoqypPR.js +1 -0
  175. package/dist/assets/treemap-6X3UGDF4-BMeL3P0q.js +1 -0
  176. package/dist/assets/use-config-COusaY5p.js +1 -0
  177. package/dist/assets/{use-desktop-capabilities-BYDjFlpt.js → use-desktop-capabilities-B-u6ojjW.js} +1 -1
  178. package/dist/assets/use-viewport-layout-IKKGpjzF.js +1 -0
  179. package/dist/assets/{vennDiagram-L72KCM5P-DzsUHk5I.js → vennDiagram-L72KCM5P-DwS7D2kg.js} +1 -1
  180. package/dist/assets/wardley-OPB4EBWU-Dqxe7zN6.js +1 -0
  181. package/dist/assets/{wardleyDiagram-EHGQE667-1NfFs5ua.js → wardleyDiagram-EHGQE667-B4X8OOL4.js} +1 -1
  182. package/dist/assets/x-E9VB4HQx.js +1 -0
  183. package/dist/assets/{xychartDiagram-FW5EYKEG-Ci8AI3Qo.js → xychartDiagram-FW5EYKEG-BjRQ_0nx.js} +1 -1
  184. package/dist/index.html +44 -106
  185. package/dist/panel-standalone.html +19 -13
  186. package/index.html +15 -66
  187. package/package.json +5 -5
  188. package/src/app/styles/design-system.css +85 -1
  189. package/src/app/styles/island-theme.css +8 -6
  190. package/src/features/agents/components/__tests__/agents-page.test.tsx +8 -5
  191. package/src/features/agents/components/agent-details-dialog.tsx +24 -18
  192. package/src/features/agents/components/agents-page.tsx +27 -38
  193. package/src/features/app-data/components/app-retained-data-section.tsx +4 -4
  194. package/src/features/apps/components/__tests__/app-marketplace-catalog.test.tsx +2 -2
  195. package/src/features/apps/components/__tests__/app-packages-panel.test.tsx +94 -23
  196. package/src/features/apps/components/__tests__/apps-panel.test.tsx +5 -3
  197. package/src/features/apps/components/app-document-access-section.tsx +17 -14
  198. package/src/features/apps/components/app-marketplace-catalog.tsx +69 -42
  199. package/src/features/apps/components/app-marketplace-cover.tsx +5 -2
  200. package/src/features/apps/components/app-marketplace-detail.tsx +20 -8
  201. package/src/features/apps/components/app-marketplace-operation.tsx +8 -3
  202. package/src/features/apps/components/app-marketplace-panel.tsx +168 -0
  203. package/src/features/apps/components/app-package-card.tsx +224 -147
  204. package/src/features/apps/components/app-package-details-dialog.tsx +103 -0
  205. package/src/features/apps/components/app-packages-panel.tsx +162 -147
  206. package/src/features/apps/components/apps-panel.tsx +43 -12
  207. package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +1 -1
  208. package/src/features/chat/components/conversation/chat-conversation-header.tsx +1 -1
  209. package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +2 -2
  210. package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +9 -7
  211. package/src/features/chat/components/providers/chat-runtime.provider.tsx +1 -1
  212. package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +0 -1
  213. package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +13 -2
  214. package/src/features/chat/features/conversation/components/floating-session-conversation.tsx +2 -3
  215. package/src/features/chat/features/conversation/components/session-conversation-area.tsx +9 -1
  216. package/src/features/chat/features/conversation/components/session-conversation-input-top-slot.tsx +44 -0
  217. package/src/features/chat/features/conversation/components/session-conversation-input.tsx +4 -38
  218. package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-controller.test.tsx +86 -10
  219. package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-input-state.test.tsx +44 -1
  220. package/src/features/chat/features/conversation/hooks/use-session-conversation-controller.ts +85 -73
  221. package/src/features/chat/features/conversation/hooks/use-session-conversation-input-query.ts +5 -15
  222. package/src/features/chat/features/conversation/hooks/use-session-conversation-input-state.ts +53 -13
  223. package/src/features/chat/features/conversation/hooks/use-session-submission-recovery.ts +83 -0
  224. package/src/features/chat/features/conversation/types/session-conversation-input.types.ts +38 -0
  225. package/src/features/chat/features/input/utils/__tests__/ncp-chat-input-availability.utils.test.ts +1 -29
  226. package/src/features/chat/features/input/utils/ncp-chat-input-availability.utils.ts +1 -8
  227. package/src/features/chat/features/message/components/__tests__/chat-message-list-skill-preview.container.test.tsx +14 -1
  228. package/src/features/chat/features/message/hooks/use-chat-inline-token-actions.ts +7 -2
  229. package/src/features/chat/features/message/utils/chat-message-execution-summary.utils.ts +3 -0
  230. package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +1 -0
  231. package/src/features/chat/features/message/utils/chat-message-trigger-details.utils.ts +3 -0
  232. package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +1 -1
  233. package/src/features/chat/features/session/components/session-header/chat-session-metadata-dialog.tsx +1 -1
  234. package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx +2 -2
  235. package/src/features/chat/features/session/utils/__tests__/chat-session-route.utils.test.ts +26 -0
  236. package/src/features/chat/features/session/utils/chat-session-preference-governance.utils.ts +14 -8
  237. package/src/features/chat/features/session/utils/chat-session-route.utils.ts +9 -12
  238. package/src/features/chat/features/welcome/components/__tests__/chat-welcome.test.tsx +31 -6
  239. package/src/features/chat/features/welcome/components/chat-conversation-welcome.tsx +13 -1
  240. package/src/features/chat/features/welcome/components/chat-welcome-agent-picker.tsx +1 -1
  241. package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +1 -1
  242. package/src/features/chat/features/welcome/components/chat-welcome-prompt-suggestions.tsx +56 -13
  243. package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +3 -3
  244. package/src/features/chat/features/welcome/components/chat-welcome.tsx +14 -4
  245. package/src/features/chat/features/welcome/utils/__tests__/chat-welcome-continuation.utils.test.ts +40 -0
  246. package/src/features/chat/features/welcome/utils/chat-welcome-continuation.utils.ts +21 -0
  247. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-file-preview.selection.test.tsx +14 -2
  248. package/src/features/chat/features/workspace/components/__tests__/session-cron-job-content.test.tsx +5 -1
  249. package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +1 -1
  250. package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +3 -7
  251. package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +6 -5
  252. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +27 -27
  253. package/src/features/chat/features/workspace/components/overview/chat-session-continuous-attention.tsx +11 -11
  254. package/src/features/chat/features/workspace/components/overview/chat-session-token-usage.tsx +15 -15
  255. package/src/features/chat/features/workspace/components/project-files/workspace-directory-tree.tsx +2 -2
  256. package/src/features/chat/features/workspace/components/project-files/workspace-new-folder-tree-item.tsx +1 -1
  257. package/src/features/chat/features/workspace/components/project-files/workspace-project-files-toolbar.tsx +2 -2
  258. package/src/features/chat/features/workspace/components/session-cron-job-content.tsx +13 -26
  259. package/src/features/chat/index.ts +1 -0
  260. package/src/features/chat/pages/__tests__/ncp-chat-page.test.ts +37 -47
  261. package/src/features/chat/pages/ncp-chat-page.tsx +3 -3
  262. package/src/features/chat/stores/__tests__/chat-composer-draft.store.test.ts +67 -1
  263. package/src/features/chat/stores/chat-composer-draft.store.ts +230 -29
  264. package/src/features/cron/components/__tests__/cron-config.test.tsx +8 -2
  265. package/src/features/cron/components/cron-config.tsx +6 -17
  266. package/src/features/cron/components/cron-job-detail-dialog.tsx +10 -9
  267. package/src/features/cron/components/cron-job-resource.tsx +51 -0
  268. package/src/features/cron/components/cron-job-row.tsx +5 -4
  269. package/src/features/cron/index.ts +1 -0
  270. package/src/features/desktop-capabilities/components/desktop-authorization-dialog.tsx +5 -5
  271. package/src/features/inbox/components/inbox-reader-dialog.test.tsx +46 -6
  272. package/src/features/inbox/components/inbox-reader-dialog.tsx +38 -29
  273. package/src/features/inbox/managers/inbox.manager.test.ts +28 -0
  274. package/src/features/inbox/managers/inbox.manager.ts +18 -4
  275. package/src/features/inbox/pages/inbox-page.test.ts +4 -2
  276. package/src/features/inbox/pages/inbox-page.tsx +14 -10
  277. package/src/features/marketplace/components/__tests__/marketplace-page-detail.test.tsx +1 -0
  278. package/src/features/marketplace/components/__tests__/marketplace-page.test.tsx +1 -0
  279. package/src/features/marketplace/components/mcp/__tests__/mcp-marketplace-page.test.tsx +2 -0
  280. package/src/features/marketplace/components/mcp/mcp-marketplace-card.tsx +2 -2
  281. package/src/features/marketplace/components/mcp/mcp-marketplace-page.tsx +23 -1
  282. package/src/features/marketplace/hooks/use-marketplace-item-detail.ts +11 -0
  283. package/src/features/panel-apps/components/panel-app-list-item.tsx +4 -3
  284. package/src/features/panel-apps/components/panel-app-service-action-authorization-dialog.tsx +2 -2
  285. package/src/features/panel-apps/index.ts +1 -0
  286. package/src/features/panel-apps/utils/panel-app-doc-browser.utils.tsx +5 -24
  287. package/src/features/projects/components/work/project-work-item-drawer.tsx +7 -10
  288. package/src/features/projects/components/work/project-work-items.tsx +1 -1
  289. package/src/features/projects/pages/project-home-page.tsx +18 -23
  290. package/src/features/projects/pages/projects-page.test.tsx +4 -1
  291. package/src/features/pwa/managers/__tests__/pwa-shell-theme.manager.test.ts +3 -3
  292. package/src/features/pwa/managers/pwa-shell-theme.manager.ts +8 -3
  293. package/src/features/right-panel-resources/components/__tests__/page-resource-icon.test.tsx +13 -2
  294. package/src/features/right-panel-resources/components/__tests__/system-object-resource.test.tsx +74 -6
  295. package/src/features/right-panel-resources/components/native-object-resource.tsx +134 -0
  296. package/src/features/right-panel-resources/components/page-resource-icon.tsx +16 -8
  297. package/src/features/right-panel-resources/components/system-object-resource.tsx +66 -1
  298. package/src/features/right-panel-resources/components/workspace-file-resource.tsx +9 -0
  299. package/src/features/right-panel-resources/configs/right-panel-resource-routes.config.ts +11 -21
  300. package/src/features/right-panel-resources/index.ts +3 -0
  301. package/src/features/right-panel-resources/managers/__tests__/page-resource.manager.test.ts +14 -4
  302. package/src/features/right-panel-resources/managers/page-resource.manager.ts +38 -21
  303. package/src/features/right-panel-resources/utils/__tests__/right-panel-resource-route-resolver.utils.test.ts +17 -0
  304. package/src/features/right-panel-resources/utils/right-panel-resource-uri.utils.ts +3 -2
  305. package/src/features/service-apps/components/service-action-row.tsx +4 -3
  306. package/src/features/service-apps/components/service-app-delete-dialog.tsx +2 -2
  307. package/src/features/service-apps/components/service-app-list-item.tsx +5 -4
  308. package/src/features/service-apps/components/service-apps-panel.tsx +5 -2
  309. package/src/features/settings/components/config/provider-model-suggestions-panel.tsx +1 -1
  310. package/src/features/settings/pages/providers-config-page.tsx +3 -2
  311. package/src/index.css +42 -8
  312. package/src/shared/components/doc-browser/__tests__/doc-browser-context.test.tsx +16 -0
  313. package/src/shared/components/doc-browser/__tests__/doc-browser.test.tsx +2 -2
  314. package/src/shared/components/doc-browser/__tests__/resource-link-interceptor.test.tsx +29 -1
  315. package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +2 -2
  316. package/src/shared/components/doc-browser/stores/doc-browser.store.ts +13 -7
  317. package/src/shared/components/doc-browser/utils/doc-browser-url.utils.ts +2 -1
  318. package/src/shared/components/path-picker/server-path-picker-dialog.tsx +5 -3
  319. package/src/shared/components/ui/__tests__/dialog.test.tsx +37 -1
  320. package/src/shared/components/ui/actions/action-feedback.ts +1 -8
  321. package/src/shared/components/ui/actions/icon-action-button.tsx +1 -1
  322. package/src/shared/components/ui/confirm-dialog.tsx +1 -2
  323. package/src/shared/components/ui/context-menu/context-menu-items.tsx +2 -2
  324. package/src/shared/components/ui/dialog.tsx +29 -7
  325. package/src/shared/components/ui/popover.tsx +14 -3
  326. package/src/shared/components/ui/skeleton.tsx +16 -2
  327. package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +2 -2
  328. package/src/shared/components/ui/tooltip.tsx +2 -1
  329. package/src/shared/components/workbench/__tests__/workbench-surface.test.tsx +21 -0
  330. package/src/shared/components/workbench/workbench-surface-toolbar.tsx +4 -0
  331. package/src/shared/components/workbench/workbench-surface.tsx +4 -1
  332. package/src/shared/lib/i18n/locales/en-US/chat.json +21 -7
  333. package/src/shared/lib/i18n/locales/en-US/core.json +5 -1
  334. package/src/shared/lib/i18n/locales/en-US/doc-browser.json +10 -5
  335. package/src/shared/lib/i18n/locales/en-US/inbox.json +1 -0
  336. package/src/shared/lib/i18n/locales/zh-CN/chat.json +21 -7
  337. package/src/shared/lib/i18n/locales/zh-CN/core.json +5 -1
  338. package/src/shared/lib/i18n/locales/zh-CN/doc-browser.json +11 -6
  339. package/src/shared/lib/i18n/locales/zh-CN/inbox.json +1 -0
  340. package/src/shared/lib/theme/index.test.ts +28 -1
  341. package/src/shared/lib/theme/index.ts +14 -3
  342. package/src/shared/lib/transport/__tests__/local-transport.service.test.ts +24 -0
  343. package/src/shared/lib/transport/local-transport.service.ts +8 -6
  344. package/dist/assets/account-panel-BAH7FW6z.js +0 -1
  345. package/dist/assets/api-DjiZvIa0.js +0 -20
  346. package/dist/assets/app-presenter-provider-CCRFsFYr.js +0 -232
  347. package/dist/assets/appearance-settings-page-CdP86QJ7.js +0 -1
  348. package/dist/assets/architecture-TIHT7OUA-CvnC-LeA.js +0 -1
  349. package/dist/assets/channel-CpMstUPF.js +0 -1
  350. package/dist/assets/channels-list-page-5qGagKuE.js +0 -8
  351. package/dist/assets/chunk-2Q5K7J3B-Djp3VF0s.js +0 -1
  352. package/dist/assets/chunk-VAUOI2AC-BrbiIC1Q.js +0 -1
  353. package/dist/assets/chunk-XXDRQBXY-Cx9N40wF.js +0 -1
  354. package/dist/assets/classDiagram-OUVF2IWQ-DFN1v3PQ.js +0 -1
  355. package/dist/assets/classDiagram-v2-EOCWNBFH-DRvglADa.js +0 -1
  356. package/dist/assets/config-split-page-CuEGQL8Z.js +0 -1
  357. package/dist/assets/confirm-dialog-CxfecBzO.js +0 -1
  358. package/dist/assets/context-menu-BsCj2fRs.js +0 -1
  359. package/dist/assets/cynefin-VYW2F7L2-DXUGnpJH.js +0 -1
  360. package/dist/assets/desktop-update-config-e-zhkJuS.js +0 -1
  361. package/dist/assets/dialog-QjQoKbIV.js +0 -5
  362. package/dist/assets/doc-browser-CLEdkH9z.js +0 -1
  363. package/dist/assets/doc-browser-context-DwgG6wrz.js +0 -1
  364. package/dist/assets/es2015-Bp6cuSGh.js +0 -41
  365. package/dist/assets/eventmodeling-45OFAUF4-ZBfVS3ZC.js +0 -1
  366. package/dist/assets/extensions-CgShSIkd.js +0 -1
  367. package/dist/assets/eye-kisejBFH.js +0 -1
  368. package/dist/assets/flowDiagram-23GEKE2U-CqdsKk6x.js +0 -1
  369. package/dist/assets/gitGraph-TEB2WS4Q-fHYFd9Es.js +0 -1
  370. package/dist/assets/info-DKCQHKI2-CSaOL_bb.js +0 -1
  371. package/dist/assets/katex-B4FQSo9k.js +0 -1
  372. package/dist/assets/keyboard-shortcuts-settings-page-DZ8A1iLg.js +0 -1
  373. package/dist/assets/loader-circle-Bd1fTm-x.js +0 -1
  374. package/dist/assets/login-page-D99JjH9F.js +0 -1
  375. package/dist/assets/main-Bt5r6b21.js +0 -2
  376. package/dist/assets/main-DXd_aKJV.css +0 -1
  377. package/dist/assets/main-i18n-catalog.config-D0Ll36J_.js +0 -1
  378. package/dist/assets/mcp-marketplace-page-DUoGfSmY.js +0 -1
  379. package/dist/assets/model-config-page-9NNf-mzK.js +0 -1
  380. package/dist/assets/packet-7NZHBO7P-D-YFTczs.js +0 -1
  381. package/dist/assets/panel-app-BYfQu_TS.js +0 -1
  382. package/dist/assets/panel-app-i18n-catalog.config-Ddf2Kv8A.js +0 -1
  383. package/dist/assets/panelStandalone-BRg7B1EI.css +0 -1
  384. package/dist/assets/panelStandalone-BaUzY8Wy.js +0 -2
  385. package/dist/assets/pie-RZYD4A2V-VEnYu9s5.js +0 -1
  386. package/dist/assets/privacy-settings-page-CVMBFuak.js +0 -1
  387. package/dist/assets/projects-BEsU3box.js +0 -1
  388. package/dist/assets/provider-models-Dm-pmWAA.js +0 -1
  389. package/dist/assets/provider-scoped-model-input-CzrXg4cX.js +0 -1
  390. package/dist/assets/providers-config-page-839uUADZ.js +0 -1
  391. package/dist/assets/puzzle-BGvD2DPZ.js +0 -1
  392. package/dist/assets/pwa-DNNK_8E9.js +0 -1
  393. package/dist/assets/radar-I7S5WNFK-BFNIekC1.js +0 -1
  394. package/dist/assets/railroad-3IZDKUUU-lVqJ3Hak.js +0 -1
  395. package/dist/assets/railroad-abnf-AHOZXSZD-DYaefdFC.js +0 -1
  396. package/dist/assets/railroad-ebnf-EBAXGLYW-CTAk6lVq.js +0 -1
  397. package/dist/assets/railroad-peg-LSFZ7HO6-Cob294tg.js +0 -1
  398. package/dist/assets/remote-B5qIuUbT.js +0 -1
  399. package/dist/assets/runtime-config-page-Bf-4JYxQ.js +0 -1
  400. package/dist/assets/search-config-page-C0qA3j-T.js +0 -1
  401. package/dist/assets/secrets-config-page-DxfZWpnk.js +0 -3
  402. package/dist/assets/security-config-CItfIQZ4.js +0 -1
  403. package/dist/assets/select-CWyjnar7.js +0 -1
  404. package/dist/assets/service-apps-panel-D3SOkRVv.js +0 -1
  405. package/dist/assets/stateDiagram-v2-6OUMAXLB-BrNv-raG.js +0 -1
  406. package/dist/assets/swimlanesDiagram-G3AALYLV-ntcxaPXp.js +0 -8
  407. package/dist/assets/tag-chip-BIuavK2K.js +0 -1
  408. package/dist/assets/theme-provider-CWUz4yO9.js +0 -1
  409. package/dist/assets/trash-2-hAbJh9VZ.js +0 -1
  410. package/dist/assets/treeView-QDETBFTQ-DbFmr-gw.js +0 -1
  411. package/dist/assets/treemap-6X3UGDF4-C8aY96pi.js +0 -1
  412. package/dist/assets/use-config-evzage09.js +0 -1
  413. package/dist/assets/use-viewport-layout-D_9XWGDV.js +0 -1
  414. package/dist/assets/wardley-OPB4EBWU-D8d6DbbJ.js +0 -1
  415. package/dist/assets/x-ChPbNv39.js +0 -1
  416. package/src/features/apps/components/app-marketplace-dialog.tsx +0 -168
  417. /package/dist/assets/{array-BV9OtnO8.js → array-DsNX3jRj.js} +0 -0
  418. /package/dist/assets/{chunk-KEIR6QF5-Cx-8EJ4_.js → chunk-KEIR6QF5-BOAXXeyv.js} +0 -0
  419. /package/dist/assets/{chunk-Y2CYZVJY-Dy1ufvjf.js → chunk-Y2CYZVJY-CHjSjwoV.js} +0 -0
  420. /package/dist/assets/{config-hints-DbmiyTKg.js → config-hints-CaB3I7KP.js} +0 -0
  421. /package/dist/assets/{cytoscape.esm-CSCjuT4Z.js → cytoscape.esm-j4J9a91l.js} +0 -0
  422. /package/dist/assets/{defaultLocale-DWTiNsbT.js → defaultLocale-Bmxjp-V_.js} +0 -0
  423. /package/dist/assets/{dist-BVCSkfWY.js → dist-DwLj1Wg5.js} +0 -0
  424. /package/dist/assets/{graphlib-B1yb1Wl8.js → graphlib-CC0HTn1v.js} +0 -0
  425. /package/dist/assets/{host-capabilities-DuIFVsvM.js → host-capabilities-B107nwS3.js} +0 -0
  426. /package/dist/assets/{init-BF6GH5oe.js → init-Biz9Rus1.js} +0 -0
  427. /package/dist/assets/{jszip.min-D12teKzP.js → jszip.min-DQvBVV_R.js} +0 -0
  428. /package/dist/assets/{katex-CsAM73R9.js → katex-BzT-4KBu.js} +0 -0
  429. /package/dist/assets/{navigation-history-CzErJuPG.js → navigation-history-CCnxsAKR.js} +0 -0
  430. /package/dist/assets/{path-C56XkznJ.js → path-4azsBPZv.js} +0 -0
  431. /package/dist/assets/{preload-helper-ca-nBW7U.js → preload-helper-DWTEM3RW.js} +0 -0
  432. /package/dist/assets/{rough.esm-CGfeEbtE.js → rough.esm-w1lBArN6.js} +0 -0
  433. /package/dist/assets/{xlsx-sds5nUpL.js → xlsx--SB9KlFl.js} +0 -0
@@ -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
 
@@ -1,7 +1,6 @@
1
1
  import { PageResourceActionsMenu } from '@/features/right-panel-resources';
2
2
  import { pageResourceFromTarget } from '@/features/right-panel-resources';
3
3
  import { buildSessionPanelUrl } from '@/features/chat/features/session/utils/chat-session-route.utils';
4
- import { MessageSquare } from 'lucide-react';
5
4
  import { useNavigate } from 'react-router-dom';
6
5
  import { getAppPresenter } from '@/app/presenters/app.presenter';
7
6
  import { sessionSurfaceManager } from '@/features/chat/managers/session-surface.manager';
@@ -17,8 +16,8 @@ export function FloatingSessionConversation() {
17
16
  const presenter = getAppPresenter();
18
17
  if (!session) return null;
19
18
  return <WorkbenchSurface id={SESSION_WORKBENCH_SURFACE} manager={presenter.workbenchSurfaceManager}
20
- title={session.title} icon={<MessageSquare className="h-4 w-4 shrink-0" />} testId="floating-session-conversation" focusOnOpen
21
- navigation={<div className="flex min-w-0 flex-1 items-center gap-2"><span className="min-w-0 flex-1 truncate text-xs">{session.title}</span><PageResourceActionsMenu page={pageResourceFromTarget({ kind: 'chat-session', title: session.title, url: buildSessionPanelUrl(session.sessionKey), resourceUri: buildSessionPanelUrl(session.sessionKey), historyPolicy: 'none' })} /></div>}
19
+ title={session.title} testId="floating-session-conversation" focusOnOpen
20
+ moreActions={<PageResourceActionsMenu page={pageResourceFromTarget({ kind: 'chat-session', title: session.title, url: buildSessionPanelUrl(session.sessionKey), resourceUri: buildSessionPanelUrl(session.sessionKey), historyPolicy: 'none' })} />}
22
21
  onClose={sessionSurfaceManager.close}
23
22
  onPlace={() => sessionSurfaceManager.dock(session, presenter.docBrowserManager)}
24
23
  onOpenMain={() => { navigate(buildSessionPath(session.sessionKey)); sessionSurfaceManager.close(); }}>
@@ -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,
@@ -437,6 +444,7 @@ export function SessionConversationArea(props: SessionConversationAreaProps) {
437
444
  onEditMessage={(payload) => controllerRef.current.editMessage(payload)}
438
445
  welcomeSlot={
439
446
  <ChatConversationWelcome
447
+ hasDraftContent={Boolean(inputSnapshot.text.trim() || inputSnapshot.attachments.length || inputSnapshot.selectedSkills.length)}
440
448
  inputSlot={
441
449
  <div className="space-y-2">
442
450
  {renderInput("embedded", t("chatWelcomeInputPlaceholder"))}
@@ -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={{
@@ -2,8 +2,13 @@ import { act, renderHook, waitFor } from '@testing-library/react';
2
2
  import { describe, expect, it, vi } from 'vitest';
3
3
  import { NextClawClientError, type UiNcpSessionQueuedInputView } from '@nextclaw/client-sdk';
4
4
  import type { NcpAgentSendEnvelope, NcpMessage, NcpRunHandle } from '@nextclaw/ncp';
5
+ import { NcpHttpSendError } from '@nextclaw/ncp-http-agent-client';
6
+
7
+ const fetchNcpSessionMessages = vi.hoisted(() => vi.fn());
8
+ vi.mock('@/shared/lib/api', () => ({ fetchNcpSessionMessages }));
5
9
 
6
10
  import { useSessionConversationController } from '@/features/chat/features/conversation/hooks/use-session-conversation-controller';
11
+ import type { ChatComposerSubmission } from '@/features/chat/stores/chat-composer-draft.store';
7
12
 
8
13
  type TestAgentSend = (envelope: NcpAgentSendEnvelope) => Promise<NcpRunHandle | null>;
9
14
 
@@ -107,6 +112,7 @@ function createControllerParams(params: {
107
112
  composerFocusRequestId: 0,
108
113
  nodes: [createTextNode('next task')],
109
114
  pendingProjectRoot: null,
115
+ pendingSubmission: null as ChatComposerSubmission | null,
110
116
  pendingSessionType: 'default',
111
117
  selectedModel: undefined,
112
118
  selectedSessionType: 'default',
@@ -126,8 +132,12 @@ function createControllerParams(params: {
126
132
  },
127
133
  selectedAgentId: 'main',
128
134
  sessionKey: 'session-1',
129
- resetComposer: vi.fn(),
130
135
  restoreComposer: vi.fn(),
136
+ beginSubmission: vi.fn(),
137
+ acceptSubmission: vi.fn(),
138
+ failSubmission: vi.fn(),
139
+ restoreSubmission: vi.fn(),
140
+ discardSubmission: vi.fn(),
131
141
  onSessionMaterialized: vi.fn(),
132
142
  setSendError: vi.fn(),
133
143
  };
@@ -162,6 +172,7 @@ describe('useSessionConversationController backend run queue', () => {
162
172
  const envelope = send.mock.calls[0]?.[0];
163
173
  expect(envelope?.sessionId).toMatch(/^ncp-/);
164
174
  expect(envelope?.message.sessionId).toBe(envelope?.sessionId);
175
+ expect(envelope?.idempotencyKey).toBe(envelope?.message.id);
165
176
  expect(params.onSessionMaterialized).toHaveBeenCalledWith(envelope?.sessionId);
166
177
  });
167
178
 
@@ -182,7 +193,21 @@ describe('useSessionConversationController backend run queue', () => {
182
193
  parts: [{ type: 'text', text: 'next task' }],
183
194
  }),
184
195
  });
185
- expect(params.resetComposer).toHaveBeenCalledTimes(1);
196
+ expect(params.beginSubmission).toHaveBeenCalledTimes(1);
197
+ });
198
+
199
+ it('attempts a send when a nonempty draft has a stale blocked runtime status', async () => {
200
+ const send = createSendMock();
201
+ const params = { ...createControllerParams({ isRunning: false, send }), isRuntimeBlocked: true };
202
+ const { result } = renderHook(() => useSessionConversationController(params));
203
+
204
+ expect(result.current.sendDisabled).toBe(false);
205
+ await act(async () => {
206
+ await result.current.send();
207
+ });
208
+
209
+ expect(send).toHaveBeenCalledTimes(1);
210
+ expect(params.setSendError).toHaveBeenLastCalledWith(null);
186
211
  });
187
212
 
188
213
  it('uses prefer-steer for command/control-enter submission without changing the send button path', async () => {
@@ -241,7 +266,7 @@ describe('useSessionConversationController backend run queue', () => {
241
266
  }),
242
267
  });
243
268
  expect(envelope?.metadata).not.toHaveProperty('ui_inline_tokens');
244
- expect(params.resetComposer).not.toHaveBeenCalled();
269
+ expect(params.beginSubmission).not.toHaveBeenCalled();
245
270
  expect(params.restoreComposer).not.toHaveBeenCalled();
246
271
  });
247
272
 
@@ -257,7 +282,7 @@ describe('useSessionConversationController backend run queue', () => {
257
282
  await expect(result.current.sendPresetMessage('Update title')).rejects.toThrow(sendError);
258
283
  });
259
284
 
260
- expect(params.resetComposer).not.toHaveBeenCalled();
285
+ expect(params.beginSubmission).not.toHaveBeenCalled();
261
286
  expect(params.restoreComposer).not.toHaveBeenCalled();
262
287
  expect(params.setSendError).toHaveBeenLastCalledWith(sendError.message);
263
288
  });
@@ -275,7 +300,7 @@ describe('useSessionConversationController backend run queue', () => {
275
300
  submission = result.current.send();
276
301
  });
277
302
 
278
- expect(params.resetComposer).toHaveBeenCalledTimes(1);
303
+ expect(params.beginSubmission).toHaveBeenCalledTimes(1);
279
304
  expect(result.current.queuedInputs).toEqual([
280
305
  expect.objectContaining({
281
306
  isSubmitting: true,
@@ -306,13 +331,64 @@ describe('useSessionConversationController backend run queue', () => {
306
331
  });
307
332
 
308
333
  expect(result.current.queuedInputs).toEqual([]);
309
- expect(params.restoreComposer).toHaveBeenCalledWith(expect.objectContaining({
310
- text: 'next task',
311
- }));
312
- expect(params.setSendError).toHaveBeenLastCalledWith(sendError.message);
334
+ expect(params.failSubmission).toHaveBeenCalledWith(expect.any(String), 'uncertain', sendError.message);
313
335
  expect(params.runQueue.refreshQueuedInputs).not.toHaveBeenCalled();
314
336
  });
315
337
 
338
+ it('shows a send failure and restores the draft when the client returns no acceptance handle', async () => {
339
+ const send = createSendMock(null);
340
+ const params = createControllerParams({ isRunning: false, send });
341
+ const { result } = renderHook(() => useSessionConversationController(params));
342
+
343
+ await act(async () => {
344
+ await expect(result.current.send()).rejects.toThrow('Failed to send message');
345
+ });
346
+
347
+ expect(params.failSubmission).toHaveBeenCalledWith(expect.any(String), 'rejected', 'Failed to send message');
348
+ expect(params.onSessionMaterialized).not.toHaveBeenCalled();
349
+ });
350
+
351
+ it('classifies an explicit HTTP rejection so the draft can be restored', async () => {
352
+ const error = new NcpHttpSendError('invalid request', true);
353
+ const send = vi.fn<TestAgentSend>(async () => { throw error; });
354
+ const params = createControllerParams({ isRunning: false, send });
355
+ const { result } = renderHook(() => useSessionConversationController(params));
356
+ await act(async () => {
357
+ await expect(result.current.send()).rejects.toThrow(error);
358
+ });
359
+ expect(params.failSubmission).toHaveBeenCalledWith(expect.any(String), 'rejected', 'invalid request');
360
+ });
361
+
362
+ it('rechecks the original message before retrying with the same identity', async () => {
363
+ fetchNcpSessionMessages.mockResolvedValue({ messages: [] });
364
+ const params = createControllerParams({ isRunning: false });
365
+ const envelope: NcpAgentSendEnvelope = {
366
+ sessionId: 'session-1', idempotencyKey: 'user-original',
367
+ message: {
368
+ id: 'user-original', sessionId: 'session-1', role: 'user', status: 'final',
369
+ timestamp: '2026-09-24T00:00:00.000Z', parts: [{ type: 'text', text: 'next task' }],
370
+ },
371
+ };
372
+ params.inputSnapshot.pendingSubmission = {
373
+ envelope,
374
+ composer: {
375
+ text: 'next task', nodes: [createTextNode('next task')],
376
+ selectedSkills: [], skillRecords: [], attachments: [],
377
+ },
378
+ status: 'uncertain',
379
+ };
380
+ const { result } = renderHook(() => useSessionConversationController(params));
381
+ expect(result.current.sendDisabled).toBe(true);
382
+ await act(async () => {
383
+ await result.current.send();
384
+ await result.current.retryPendingSubmission();
385
+ });
386
+ expect(fetchNcpSessionMessages).toHaveBeenCalledWith('session-1', { limit: 100 });
387
+ expect(params.agent.send).toHaveBeenCalledTimes(1);
388
+ expect(params.agent.send).toHaveBeenCalledWith(envelope);
389
+ expect(params.acceptSubmission).toHaveBeenCalledWith('user-original');
390
+ });
391
+
316
392
  it('keeps an existing session bound to its agent instead of the global draft selection', async () => {
317
393
  const send = createSendMock();
318
394
  const params = createControllerParams({ isRunning: false, send });
@@ -406,7 +482,7 @@ describe('useSessionConversationController backend run queue', () => {
406
482
 
407
483
  expect(params.agent.continueRun).toHaveBeenCalledWith({ sessionId: 'session-1' });
408
484
  expect(params.agent.send).not.toHaveBeenCalled();
409
- expect(params.resetComposer).not.toHaveBeenCalled();
485
+ expect(params.beginSubmission).not.toHaveBeenCalled();
410
486
  });
411
487
 
412
488
  it('keeps continuation available but restores send as primary when the user types', () => {
@@ -36,7 +36,7 @@ const THINKING_MODEL_OPTIONS: ChatModelOption[] = [
36
36
  describe('useSessionConversationInputState session preferences', () => {
37
37
  beforeEach(() => {
38
38
  window.localStorage.clear();
39
- useChatComposerDraftStore.setState({ drafts: {} });
39
+ useChatComposerDraftStore.setState({ drafts: {}, submissions: {}, recentSubmittedNodes: {} });
40
40
  useChatThreadStore.getState().setSnapshot({ draftProjectRoot: null });
41
41
  });
42
42
 
@@ -198,4 +198,47 @@ describe('useSessionConversationInputState session preferences', () => {
198
198
  rerender({ sessionKey: null });
199
199
  expect(result.current.inputSnapshot.text).toBe('新会话草稿');
200
200
  });
201
+
202
+ it('keeps a successfully cleared draft empty after switching away and back', () => {
203
+ const { result, rerender } = renderHook(
204
+ ({ sessionKey }: { sessionKey: string }) =>
205
+ useSessionConversationInputState(null, sessionKey),
206
+ { initialProps: { sessionKey: 'session-sent' } },
207
+ );
208
+
209
+ act(() => {
210
+ result.current.inputActions.syncComposer({
211
+ text: '已经发送的消息',
212
+ nodes: [],
213
+ selectedSkills: [],
214
+ skillRecords: [],
215
+ });
216
+ result.current.inputActions.beginSubmission({
217
+ sessionId: 'session-sent',
218
+ message: {
219
+ id: 'user-sent', sessionId: 'session-sent', role: 'user', status: 'final',
220
+ timestamp: '2026-09-24T00:00:00.000Z',
221
+ parts: [{ type: 'text', text: '已经发送的消息' }],
222
+ },
223
+ }, {
224
+ text: '已经发送的消息', nodes: [], selectedSkills: [], skillRecords: [], attachments: [],
225
+ });
226
+ result.current.inputActions.acceptSubmission('user-sent');
227
+ });
228
+ rerender({ sessionKey: 'session-unsent' });
229
+ act(() => {
230
+ result.current.inputActions.syncComposer({
231
+ text: '仍未发送的草稿',
232
+ nodes: [],
233
+ selectedSkills: [],
234
+ skillRecords: [],
235
+ });
236
+ });
237
+
238
+ rerender({ sessionKey: 'session-sent' });
239
+ expect(result.current.inputSnapshot.text).toBe('');
240
+
241
+ rerender({ sessionKey: 'session-unsent' });
242
+ expect(result.current.inputSnapshot.text).toBe('仍未发送的草稿');
243
+ });
201
244
  });