@nextclaw/ui 0.15.21 → 0.15.23

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 (476) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/dist/assets/{abnfDiagram-VRR7QNED-M4g_AyR8.js → abnfDiagram-VRR7QNED-DvTjgVMf.js} +1 -1
  3. package/dist/assets/{aiden0z-pptx-renderer.es-Bd99vut2.js → aiden0z-pptx-renderer.es-C1nfBAXR.js} +1 -1
  4. package/dist/assets/api-Glw2OGXK.js +13 -0
  5. package/dist/assets/appearance-settings-page-Bl_W_9m7.js +1 -0
  6. package/dist/assets/{arc-IO7WNWOB.js → arc-BvhODBXv.js} +1 -1
  7. package/dist/assets/architecture-TIHT7OUA-Bjp9jf0h.js +1 -0
  8. package/dist/assets/{architectureDiagram-ZJ3FMSHR-Dc-lvdUh.js → architectureDiagram-ZJ3FMSHR-BKO9RgNS.js} +1 -1
  9. package/dist/assets/{blockDiagram-677ZJIJ3-CcsoWpIY.js → blockDiagram-677ZJIJ3-DHpDXy7D.js} +1 -1
  10. package/dist/assets/{c4Diagram-LMCZKHZV-Bsrtg6b2.js → c4Diagram-LMCZKHZV-BG_iQnDr.js} +1 -1
  11. package/dist/assets/channel-5T3pdR-s.js +1 -0
  12. package/dist/assets/channels-list-page-C7E4Sxwd.js +8 -0
  13. package/dist/assets/chat-page-BT6dNI-4.js +1 -0
  14. package/dist/assets/chunk-2Q5K7J3B-DTZ3tGfE.js +1 -0
  15. package/dist/assets/{chunk-32BRIVSS-Bt08t8oG.js → chunk-32BRIVSS-DR9M0LLx.js} +1 -1
  16. package/dist/assets/{chunk-52WLFC77-Ddx68Xzx.js → chunk-52WLFC77-698iC3BB.js} +1 -1
  17. package/dist/assets/{chunk-5FCAYU7R-B7p9_q55.js → chunk-5FCAYU7R-DikTj9Ey.js} +1 -1
  18. package/dist/assets/{chunk-5HE753X5-D52KvdTm.js → chunk-5HE753X5-ko0o7_q0.js} +1 -1
  19. package/dist/assets/{chunk-5JV3BV7I-C329h8nI.js → chunk-5JV3BV7I-CEHufhgo.js} +1 -1
  20. package/dist/assets/{chunk-5TONJI2A-BZyUBxWt.js → chunk-5TONJI2A-CGgno1cu.js} +1 -1
  21. package/dist/assets/{chunk-5VM5RSS4-BUiYXZmu.js → chunk-5VM5RSS4-DkiB4cUQ.js} +1 -1
  22. package/dist/assets/{chunk-7BUUIJ7U-B7o-mn4r.js → chunk-7BUUIJ7U-DzptcytQ.js} +1 -1
  23. package/dist/assets/{chunk-BIQX33UG-Bey9GoRP.js → chunk-BIQX33UG-DMRSQJvT.js} +1 -1
  24. package/dist/assets/{chunk-C7G6YPKG-C6tosszM.js → chunk-C7G6YPKG-Bw1BwwuY.js} +1 -1
  25. package/dist/assets/{chunk-CQNSW5MT-BNrdkgGQ.js → chunk-CQNSW5MT-C0z6eHBk.js} +1 -1
  26. package/dist/assets/{chunk-CYSBUYHQ-DHODFeyB.js → chunk-CYSBUYHQ-ByPyAouO.js} +1 -1
  27. package/dist/assets/{chunk-EMLP6XTP-BcmLjrcq.js → chunk-EMLP6XTP-CJlAXWZg.js} +1 -1
  28. package/dist/assets/{chunk-EX3LRPZG-r-_eEtJI.js → chunk-EX3LRPZG-Dqq4zKJu.js} +1 -1
  29. package/dist/assets/{chunk-FWX5IMBZ-DOObDWbf.js → chunk-FWX5IMBZ-B0SNoCmi.js} +2 -2
  30. package/dist/assets/{chunk-HOUHSVGY-Bd0FnbWZ.js → chunk-HOUHSVGY-DG_GJih_.js} +1 -1
  31. package/dist/assets/{chunk-ICXQ74PX-ntNwAm4_.js → chunk-ICXQ74PX-Drxk_6bE.js} +1 -1
  32. package/dist/assets/{chunk-JG7HCLWE-YtRpblZN.js → chunk-JG7HCLWE-DdLFPpnd.js} +1 -1
  33. package/dist/assets/{chunk-JWPE2WC7-De5-D9ta.js → chunk-JWPE2WC7-B8M4G76F.js} +1 -1
  34. package/dist/assets/{chunk-MOJQB5TN-CdvKhyp2.js → chunk-MOJQB5TN-XP6FJHY_.js} +1 -1
  35. package/dist/assets/{chunk-MOZMSUNE-DJMMN_lu.js → chunk-MOZMSUNE-C_6x18Qw.js} +1 -1
  36. package/dist/assets/{chunk-OGEWGWER-DOFWVw3O.js → chunk-OGEWGWER-N25BzCmG.js} +1 -1
  37. package/dist/assets/{chunk-OSBZ3O6U-DZkrIN9r.js → chunk-OSBZ3O6U-ASDEm7y0.js} +1 -1
  38. package/dist/assets/{chunk-PUDLZKDR-D1wma2Yf.js → chunk-PUDLZKDR-CTlvAcn7.js} +1 -1
  39. package/dist/assets/{chunk-Q4XR5HBZ-CjPy94Lz.js → chunk-Q4XR5HBZ-Da9BWfB6.js} +1 -1
  40. package/dist/assets/{chunk-QBLGF6JB-Hy1bEgS-.js → chunk-QBLGF6JB-Bi6RpTJO.js} +1 -1
  41. package/dist/assets/{chunk-R7FJI6CG-CUPIHyh-.js → chunk-R7FJI6CG-DkMsSPvK.js} +1 -1
  42. package/dist/assets/{chunk-RYQCIY6F-D5Ua4pcv.js → chunk-RYQCIY6F-DZp0eU-j.js} +1 -1
  43. package/dist/assets/{chunk-U6XO7XAA-DaUQcqb7.js → chunk-U6XO7XAA-vfinDSrj.js} +1 -1
  44. package/dist/assets/{chunk-V7JOEXUC-DX2zLfQe.js → chunk-V7JOEXUC-C9Nksccs.js} +1 -1
  45. package/dist/assets/chunk-VAUOI2AC-HLGIHQ6k.js +1 -0
  46. package/dist/assets/{chunk-VR4S4FIN-CFA-WQik.js → chunk-VR4S4FIN-Xv6zfwXs.js} +1 -1
  47. package/dist/assets/{chunk-WYO6CB5R-Bk2HeDvJ.js → chunk-WYO6CB5R-mOJNzbWl.js} +2 -2
  48. package/dist/assets/chunk-XXDRQBXY-Dl0m6Ni-.js +1 -0
  49. package/dist/assets/{chunk-YOTPTUD7-DUG4FpBN.js → chunk-YOTPTUD7-1-aKSu4o.js} +1 -1
  50. package/dist/assets/{chunk-ZGVPDNZ5-70JdIGo0.js → chunk-ZGVPDNZ5-OJ8veMpK.js} +1 -1
  51. package/dist/assets/{chunk-ZIRB5QZD-XZdgBt5L.js → chunk-ZIRB5QZD-SR_Nq_PP.js} +1 -1
  52. package/dist/assets/classDiagram-OUVF2IWQ-DcDnzGNX.js +1 -0
  53. package/dist/assets/classDiagram-v2-EOCWNBFH-BKXKMzKM.js +1 -0
  54. package/dist/assets/config-split-page-D5BgtKrm.js +1 -0
  55. package/dist/assets/confirm-dialog-Bf907Azu.js +5 -0
  56. package/dist/assets/{cose-bilkent-JH36ORCC-B-PQoGX-.js → cose-bilkent-JH36ORCC-NjVgz2Bw.js} +1 -1
  57. package/dist/assets/cynefin-VYW2F7L2-BWg7U2UD.js +1 -0
  58. package/dist/assets/{cynefinDiagram-TSTJHNR4-BoLCPEM0.js → cynefinDiagram-TSTJHNR4-B_17LDqD.js} +1 -1
  59. package/dist/assets/{dagre-D7Ie4eXr.js → dagre-CMe101gk.js} +1 -1
  60. package/dist/assets/{dagre-VKFMJZFB-CKRrwZA-.js → dagre-VKFMJZFB-qo8nLb3B.js} +1 -1
  61. package/dist/assets/desktop-update-config-BwuyBPJb.js +1 -0
  62. package/dist/assets/{diagram-FQU43EPY-CASL1J3_.js → diagram-FQU43EPY-Ba3XIklC.js} +1 -1
  63. package/dist/assets/{diagram-G47NLZAW-CvLPBIzf.js → diagram-G47NLZAW-CG45TcUx.js} +1 -1
  64. package/dist/assets/{diagram-NH7WQ7WH-Ba6fGdYP.js → diagram-NH7WQ7WH-2F2HrwV-.js} +1 -1
  65. package/dist/assets/{diagram-OA4YK3LP-DkpfgEjM.js → diagram-OA4YK3LP-CXfWH9NZ.js} +1 -1
  66. package/dist/assets/{diagram-WEI45ONY-BP5UMVsN.js → diagram-WEI45ONY-CH_4yepc.js} +1 -1
  67. package/dist/assets/dist-CtLyEJeO.js +1 -0
  68. package/dist/assets/dist-dv_SUR54.js +1 -0
  69. package/dist/assets/doc-browser-C23NDGh5.js +1 -0
  70. package/dist/assets/doc-browser-DlOOhBxI.js +1 -0
  71. package/dist/assets/doc-browser-context-BIBjkwfV.js +1 -0
  72. package/dist/assets/{docx-preview-D0tp3a9T.js → docx-preview-CoM4JK7_.js} +1 -1
  73. package/dist/assets/{ebnfDiagram-CCIWWBDH-TJKbUcmc.js → ebnfDiagram-CCIWWBDH-BwiG4Ea1.js} +1 -1
  74. package/dist/assets/{erDiagram-Q63AITRT-DzGPKkKH.js → erDiagram-Q63AITRT-BML3hpnQ.js} +1 -1
  75. package/dist/assets/eventmodeling-45OFAUF4-SB-J4tpq.js +1 -0
  76. package/dist/assets/flowDiagram-23GEKE2U-BQ_u-eLM.js +1 -0
  77. package/dist/assets/{form-actions-DvvxCpL4.js → form-actions-DAzi68Cn.js} +1 -1
  78. package/dist/assets/{ganttDiagram-NO4QXBWP-JhJzsGp2.js → ganttDiagram-NO4QXBWP-80enfWbD.js} +1 -1
  79. package/dist/assets/gitGraph-TEB2WS4Q-DPxNwsFd.js +1 -0
  80. package/dist/assets/{gitGraphDiagram-IHSO6WYX-DZ1CKMj8.js → gitGraphDiagram-IHSO6WYX-CVLqXr-b.js} +1 -1
  81. package/dist/assets/host-capabilities-D9C4CBK5.js +1 -0
  82. package/dist/assets/index-BLNg2yg0.css +1 -0
  83. package/dist/assets/index-D3EKjEyK.js +107 -0
  84. package/dist/assets/info-DKCQHKI2-DNlNGH90.js +1 -0
  85. package/dist/assets/{infoDiagram-FWYZ7A6U-BNXNKfRQ.js → infoDiagram-FWYZ7A6U-Dyvs2t0i.js} +1 -1
  86. package/dist/assets/{ishikawaDiagram-FXEZZL3T-DoiEfjNw.js → ishikawaDiagram-FXEZZL3T-sSnxDKfh.js} +1 -1
  87. package/dist/assets/{journeyDiagram-5HDEW3XC-D6oK2HSy.js → journeyDiagram-5HDEW3XC-D22V71Mf.js} +1 -1
  88. package/dist/assets/{kanban-definition-HUTT4EX6-B2UnLOH-.js → kanban-definition-HUTT4EX6-D3ds0p-g.js} +1 -1
  89. package/dist/assets/{line-BM7PoxY5.js → line-CbyFs065.js} +1 -1
  90. package/dist/assets/{linear-B3DiqMjk.js → linear-4DKtnZBS.js} +1 -1
  91. package/dist/assets/loader-circle-BSg5u0r4.js +1 -0
  92. package/dist/assets/{map-BAAdHTqR.js → map-CcZzEoz6.js} +1 -1
  93. package/dist/assets/mcp-marketplace-page-ByhvQQj5.js +9 -0
  94. package/dist/assets/mcp-marketplace-page-CytXwnUs.js +1 -0
  95. package/dist/assets/{mermaid-parser.core-BeMviefY.js → mermaid-parser.core-DPmMOjXD.js} +2 -2
  96. package/dist/assets/{mermaid.core-D0Q77r9I.js → mermaid.core-BSf-ddRa.js} +3 -3
  97. package/dist/assets/{mindmap-definition-LN4V7U3C-BQ7r7bR8.js → mindmap-definition-LN4V7U3C-BUTwWPyx.js} +1 -1
  98. package/dist/assets/model-config-page-bgEx3MjQ.js +1 -0
  99. package/dist/assets/navigation-link-CB0OQbnY.js +3 -0
  100. package/dist/assets/{ordinal-Bt2N4IkA.js → ordinal-BgLYtOZE.js} +1 -1
  101. package/dist/assets/packet-7NZHBO7P-BpeiqkBZ.js +1 -0
  102. package/dist/assets/{pegDiagram-2B236MQR-B-C9-LGz.js → pegDiagram-2B236MQR-BEu_ZBjc.js} +1 -1
  103. package/dist/assets/pie-RZYD4A2V-Cy1yxsPd.js +1 -0
  104. package/dist/assets/{pieDiagram-ENE6RG2P-CtirZLtn.js → pieDiagram-ENE6RG2P-CAwAwuBd.js} +1 -1
  105. package/dist/assets/plus-CNjWdLhZ.js +1 -0
  106. package/dist/assets/provider-scoped-model-input-8F6JMd2n.js +1 -0
  107. package/dist/assets/providers-config-page-CxpTjR81.js +1 -0
  108. package/dist/assets/{quadrantDiagram-ABIIQ3AL-DiBWAzDU.js → quadrantDiagram-ABIIQ3AL-CwE6F-_2.js} +1 -1
  109. package/dist/assets/radar-I7S5WNFK-CEcPKCj8.js +1 -0
  110. package/dist/assets/railroad-3IZDKUUU-CW38eNDs.js +1 -0
  111. package/dist/assets/railroad-abnf-AHOZXSZD-ByrylcXf.js +1 -0
  112. package/dist/assets/railroad-ebnf-EBAXGLYW-CNB6GwP-.js +1 -0
  113. package/dist/assets/railroad-peg-LSFZ7HO6-x6hnqlBG.js +1 -0
  114. package/dist/assets/{railroadDiagram-RFXS5EU6-CP6b3PBI.js → railroadDiagram-RFXS5EU6-xgLekU3B.js} +1 -1
  115. package/dist/assets/react-Bk2ydNTe.js +8 -0
  116. package/dist/assets/{refresh-cw-C2e94pmp.js → refresh-cw-Ba0LZou4.js} +1 -1
  117. package/dist/assets/remote-Dv38PuMV.js +1 -0
  118. package/dist/assets/{requirementDiagram-TGXJPOKE-D8YV0-Jz.js → requirementDiagram-TGXJPOKE-CyVUzEX5.js} +1 -1
  119. package/dist/assets/rotate-cw-IkYVk9JX.js +1 -0
  120. package/dist/assets/runtime-config-page-C0ByyUVr.js +1 -0
  121. package/dist/assets/{sankeyDiagram-HTMAVEWB-C2vA4ojE.js → sankeyDiagram-HTMAVEWB-JK6bFmYB.js} +1 -1
  122. package/dist/assets/{save-CkwDOgvt.js → save-DTOAvqzt.js} +1 -1
  123. package/dist/assets/{search-CLXM2reO.js → search-D4X5DNMe.js} +1 -1
  124. package/dist/assets/search-config-page-Cr6254K5.js +1 -0
  125. package/dist/assets/{secrets-config-page-DQ_Curaj.js → secrets-config-page-W2Hx332d.js} +2 -2
  126. package/dist/assets/security-config-1E8OF4kR.js +1 -0
  127. package/dist/assets/select-CDv0g2Pj.js +41 -0
  128. package/dist/assets/{sequenceDiagram-DBY2YBRQ-B9LBmpUo.js → sequenceDiagram-DBY2YBRQ-BR5IokXV.js} +1 -1
  129. package/dist/assets/{settings-2-B9IT2HGd.js → settings-2-CoxzNABp.js} +1 -1
  130. package/dist/assets/{sizeCapture-X5ZJPWSS-9UIfya9-.js → sizeCapture-X5ZJPWSS-SxG_YnMA.js} +1 -1
  131. package/dist/assets/skeleton-DW018fJv.js +1 -0
  132. package/dist/assets/{src-DKf77Yzo.js → src-vgz8E_-O.js} +1 -1
  133. package/dist/assets/{stateDiagram-2N3HPSRC-oTW44vds.js → stateDiagram-2N3HPSRC-DD4OoYhn.js} +1 -1
  134. package/dist/assets/stateDiagram-v2-6OUMAXLB-ZC6dFORv.js +1 -0
  135. package/dist/assets/{swimlanes-5IMT3BWC-Cf7lcsay.js → swimlanes-5IMT3BWC-BWkFeyCT.js} +2 -2
  136. package/dist/assets/swimlanesDiagram-G3AALYLV-CRkh51Im.js +8 -0
  137. package/dist/assets/{tag-chip-CDkB5smU.js → tag-chip-CjkZEoS2.js} +1 -1
  138. package/dist/assets/{timeline-definition-FHXFAJF6-DoCuWKDJ.js → timeline-definition-FHXFAJF6-VTRPy6KA.js} +1 -1
  139. package/dist/assets/treeView-QDETBFTQ-Bw0DSCH7.js +1 -0
  140. package/dist/assets/treemap-6X3UGDF4-DFWBFcfh.js +1 -0
  141. package/dist/assets/use-confirm-dialog-CavtY1vJ.js +1 -0
  142. package/dist/assets/{vennDiagram-L72KCM5P-CpU0pzGe.js → vennDiagram-L72KCM5P-Bvk42Pek.js} +1 -1
  143. package/dist/assets/wardley-OPB4EBWU-CoWturk0.js +1 -0
  144. package/dist/assets/{wardleyDiagram-EHGQE667-CkN6nn6-.js → wardleyDiagram-EHGQE667-DOFjx2s3.js} +1 -1
  145. package/dist/assets/x-PTXYTEwz.js +1 -0
  146. package/dist/assets/{xychartDiagram-FW5EYKEG-DATpapm2.js → xychartDiagram-FW5EYKEG-DY5yRTUc.js} +1 -1
  147. package/dist/index.html +30 -32
  148. package/index.html +8 -0
  149. package/package.json +8 -8
  150. package/src/app/components/layout/page-layout.tsx +15 -6
  151. package/src/app/components/layout/sidebar-rail.styles.ts +0 -2
  152. package/src/app/components/layout/sidebar.tsx +2 -2
  153. package/src/app/styles/charcoal-theme.css +85 -0
  154. package/src/app/styles/design-system.css +23 -13
  155. package/src/features/agents/components/__tests__/agents-page.test.tsx +36 -24
  156. package/src/features/agents/components/agent-advanced-config-fields.tsx +7 -7
  157. package/src/features/agents/components/agent-details-dialog.tsx +8 -8
  158. package/src/features/agents/components/agent-dialogs.tsx +7 -7
  159. package/src/features/agents/components/agents-page.tsx +42 -62
  160. package/src/features/chat/components/chat-sidebar-list-mode-switch.tsx +2 -2
  161. package/src/features/chat/components/conversation/__tests__/chat-conversation-content.test.tsx +46 -4
  162. package/src/features/chat/components/conversation/__tests__/chat-conversation-header-section.test.tsx +17 -1
  163. package/src/features/chat/components/conversation/__tests__/chat-conversation-panel.test.tsx +8 -22
  164. package/src/features/chat/components/conversation/__tests__/chat-conversation-workspace-section.test.tsx +69 -3
  165. package/src/features/chat/components/conversation/chat-conversation-content.tsx +24 -11
  166. package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +30 -31
  167. package/src/features/chat/components/conversation/chat-conversation-header.tsx +1 -1
  168. package/src/features/chat/components/conversation/chat-conversation-panel.tsx +1 -8
  169. package/src/features/chat/components/conversation/chat-conversation-workspace-section.tsx +16 -4
  170. package/src/features/chat/components/layout/__tests__/chat-page-shell.test.tsx +23 -0
  171. package/src/features/chat/components/layout/__tests__/chat-sidebar-read-state.test.tsx +1 -1
  172. package/src/features/chat/components/layout/__tests__/chat-sidebar-session-area.test.tsx +52 -0
  173. package/src/features/chat/components/layout/__tests__/chat-sidebar-toolbar.test.tsx +6 -0
  174. package/src/features/chat/components/layout/__tests__/chat-sidebar.test.tsx +11 -17
  175. package/src/features/chat/components/layout/chat-page-shell.tsx +7 -15
  176. package/src/features/chat/components/layout/chat-sidebar-desktop-layout.tsx +32 -42
  177. package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +16 -67
  178. package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +1 -4
  179. package/src/features/chat/components/providers/chat-presenter.provider.tsx +2 -0
  180. package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +84 -12
  181. package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +258 -9
  182. package/src/features/chat/features/conversation/components/session-conversation-area.tsx +51 -34
  183. package/src/features/chat/features/conversation/components/session-conversation-input.tsx +50 -39
  184. package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-controller.test.tsx +128 -1
  185. package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-input-state.test.tsx +67 -1
  186. package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-slash-commands.test.tsx +4 -0
  187. package/src/features/chat/features/conversation/hooks/__tests__/use-session-provider-model-catalog.test.tsx +109 -0
  188. package/src/features/chat/features/conversation/hooks/use-chat-composer-reference-intent.ts +46 -0
  189. package/src/features/chat/features/conversation/hooks/use-session-conversation-composer-nodes.ts +26 -0
  190. package/src/features/chat/features/conversation/hooks/use-session-conversation-controller.ts +45 -12
  191. package/src/features/chat/features/conversation/hooks/use-session-conversation-input-attachments.ts +1 -0
  192. package/src/features/chat/features/conversation/hooks/use-session-conversation-input-query.ts +28 -3
  193. package/src/features/chat/features/conversation/hooks/use-session-conversation-input-state.ts +91 -37
  194. package/src/features/chat/features/conversation/hooks/use-session-conversation-recovery-actions.ts +64 -0
  195. package/src/features/chat/features/conversation/hooks/use-session-conversation-slash-commands.ts +2 -0
  196. package/src/features/chat/features/conversation/hooks/use-session-provider-model-catalog.ts +84 -0
  197. package/src/features/chat/features/conversation/utils/__tests__/session-message-composer.utils.test.ts +34 -0
  198. package/src/features/chat/features/conversation/utils/session-conversation-input-toolbar.utils.ts +18 -0
  199. package/src/features/chat/features/conversation/utils/session-message-composer.utils.ts +117 -0
  200. package/src/features/chat/features/conversation/utils/session-queued-input.utils.ts +10 -97
  201. package/src/features/chat/features/input/input-surface-plugins/__tests__/slash-command-plugin.test.ts +2 -1
  202. package/src/features/chat/features/input/input-surface-plugins/slash-command-plugin.utils.ts +3 -1
  203. package/src/features/chat/features/input/utils/__tests__/chat-composer-state.utils.test.ts +22 -1
  204. package/src/features/chat/features/input/utils/__tests__/chat-inline-token.utils.test.ts +23 -0
  205. package/src/features/chat/features/input/utils/__tests__/chat-input-bar.utils.test.ts +105 -0
  206. package/src/features/chat/features/input/utils/chat-composer-state.utils.ts +27 -2
  207. package/src/features/chat/features/input/utils/chat-composer-token-protocol.utils.ts +5 -0
  208. package/src/features/chat/features/input/utils/chat-inline-token.utils.ts +97 -32
  209. package/src/features/chat/features/input/utils/chat-input-bar.utils.ts +1 -1
  210. package/src/features/chat/features/input/utils/chat-input-toolbar.utils.ts +64 -10
  211. package/src/features/chat/features/message/components/__tests__/chat-message-assistant-header.container.test.tsx +149 -0
  212. package/src/features/chat/features/message/components/__tests__/chat-message-inline-editor.test.tsx +59 -0
  213. package/src/features/chat/features/message/components/__tests__/chat-message-list.container.test.tsx +123 -90
  214. package/src/features/chat/features/message/components/__tests__/chat-message-timeline-dividers.test.tsx +43 -0
  215. package/src/features/chat/features/message/components/chat-message-inline-editor.tsx +111 -0
  216. package/src/features/chat/features/message/components/chat-message-list.container.tsx +81 -172
  217. package/src/features/chat/features/message/components/chat-message-timeline-dividers.tsx +75 -0
  218. package/src/features/chat/features/message/hooks/use-chat-inline-token-actions.ts +125 -0
  219. package/src/features/chat/features/message/hooks/use-chat-message-actions.tsx +187 -0
  220. package/src/features/chat/features/message/utils/__tests__/chat-message-action-targets.utils.test.ts +89 -0
  221. package/src/features/chat/features/message/utils/__tests__/chat-message-timeline-compaction.utils.test.ts +194 -0
  222. package/src/features/chat/features/message/utils/__tests__/chat-message-timeline-continuation-compaction.utils.test.ts +167 -0
  223. package/src/features/chat/features/message/utils/__tests__/chat-message-timeline.utils.test.ts +203 -0
  224. package/src/features/chat/features/message/utils/__tests__/chat-message.utils.test.ts +26 -0
  225. package/src/features/chat/features/message/utils/chat-message-action-targets.utils.ts +28 -0
  226. package/src/features/chat/features/message/utils/chat-message-part.utils.ts +38 -0
  227. package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +1 -0
  228. package/src/features/chat/features/message/utils/chat-message-timeline.utils.ts +204 -7
  229. package/src/features/chat/features/ncp/hooks/__tests__/use-ncp-agent-runtime.test.tsx +180 -1
  230. package/src/features/chat/features/ncp/hooks/__tests__/use-ncp-session-conversation.test.tsx +184 -10
  231. package/src/features/chat/features/ncp/hooks/use-hydrated-ncp-agent.integration.test.tsx +57 -0
  232. package/src/features/chat/features/ncp/hooks/use-ncp-session-conversation.ts +90 -1
  233. package/src/features/chat/features/ncp/utils/__tests__/ncp-chat-query-derived.utils.test.ts +110 -0
  234. package/src/features/chat/features/ncp/utils/ncp-chat-query-derived.utils.ts +65 -3
  235. package/src/features/chat/features/session/components/chat-sidebar-session-item.tsx +10 -10
  236. package/src/features/chat/features/session/components/chat-sidebar-session-list.tsx +2 -2
  237. package/src/features/chat/features/session/components/session-header/__tests__/chat-session-header-actions.test.tsx +17 -0
  238. package/src/features/chat/features/session/components/session-header/chat-session-header-actions.tsx +63 -54
  239. package/src/features/chat/features/session/components/session-header/chat-session-header-menu-item.tsx +1 -1
  240. package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx +1 -1
  241. package/src/features/chat/features/session/components/session-header/chat-session-switcher-groups.tsx +1 -1
  242. package/src/features/chat/features/session/components/session-header/chat-session-title-switcher.tsx +1 -1
  243. package/src/features/chat/features/session/hooks/__tests__/use-selected-session-context-window-indicator.test.tsx +87 -0
  244. package/src/features/chat/features/session/utils/__tests__/chat-session-display.utils.test.ts +26 -0
  245. package/src/features/chat/features/session/utils/__tests__/ncp-session-adapter.utils.test.ts +23 -2
  246. package/src/features/chat/features/session/utils/chat-context-window-indicator.utils.ts +44 -5
  247. package/src/features/chat/features/session/utils/chat-session-display.utils.ts +48 -12
  248. package/src/features/chat/features/session/utils/ncp-session-adapter.utils.ts +23 -4
  249. package/src/features/chat/features/session/utils/ncp-session-context-metadata.utils.ts +42 -4
  250. package/src/features/chat/features/welcome/components/__tests__/chat-conversation-welcome.test.tsx +6 -0
  251. package/src/features/chat/features/welcome/components/__tests__/chat-welcome.test.tsx +27 -9
  252. package/src/features/chat/features/welcome/components/chat-welcome-agent-picker.tsx +1 -1
  253. package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +11 -17
  254. package/src/features/chat/features/welcome/components/chat-welcome-prompt-suggestions.tsx +37 -0
  255. package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +1 -1
  256. package/src/features/chat/features/welcome/components/chat-welcome.tsx +35 -33
  257. package/src/features/chat/features/welcome/utils/__tests__/chat-welcome-project-options.utils.test.ts +22 -6
  258. package/src/features/chat/features/welcome/utils/chat-welcome-project-options.utils.ts +13 -0
  259. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel-content.test.tsx +73 -3
  260. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel.test.tsx +22 -2
  261. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-text-selection.test.tsx +75 -0
  262. package/src/features/chat/features/workspace/components/__tests__/workspace-text-selection-menu.test.tsx +102 -0
  263. package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +145 -26
  264. package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +42 -18
  265. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +50 -10
  266. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-nav.tsx +48 -22
  267. package/src/features/chat/features/workspace/components/chat-session-workspace-panel.tsx +13 -2
  268. package/src/features/chat/features/workspace/components/workspace-text-selection-menu.tsx +223 -0
  269. package/src/features/chat/features/workspace/utils/__tests__/chat-workspace-panel-view-model.utils.test.ts +80 -0
  270. package/src/features/chat/features/workspace/utils/__tests__/workspace-text-excerpt.utils.test.ts +54 -0
  271. package/src/features/chat/features/workspace/utils/chat-thread-workspace-session.utils.ts +47 -0
  272. package/src/features/chat/features/workspace/utils/chat-workspace-file-tab.utils.ts +16 -0
  273. package/src/features/chat/features/workspace/utils/chat-workspace-panel-view-model.utils.ts +22 -1
  274. package/src/features/chat/features/workspace/utils/workspace-text-excerpt.utils.ts +53 -0
  275. package/src/features/chat/index.ts +1 -0
  276. package/src/features/chat/managers/__tests__/chat-composer-intent.manager.test.ts +106 -0
  277. package/src/features/chat/managers/__tests__/chat-session-list.manager.test.ts +53 -5
  278. package/src/features/chat/managers/__tests__/chat-thread-workspace.manager.test.ts +93 -1
  279. package/src/features/chat/managers/__tests__/chat-thread.manager.test.ts +3 -10
  280. package/src/features/chat/managers/__tests__/provider-model-catalog-notice.manager.test.ts +57 -0
  281. package/src/features/chat/managers/chat-composer-intent.manager.ts +145 -0
  282. package/src/features/chat/managers/chat-session-list.manager.ts +14 -25
  283. package/src/features/chat/managers/chat-thread.manager.ts +32 -16
  284. package/src/features/chat/managers/provider-model-catalog-notice.manager.ts +121 -0
  285. package/src/features/chat/pages/__tests__/ncp-chat-page.test.tsx +3 -9
  286. package/src/features/chat/pages/ncp-chat-page.tsx +0 -1
  287. package/src/features/chat/presenters/chat.presenter.ts +3 -0
  288. package/src/features/chat/stores/__tests__/chat-composer-draft.store.test.ts +55 -0
  289. package/src/features/chat/stores/chat-composer-draft.store.ts +92 -0
  290. package/src/features/chat/stores/chat-thread.store.ts +2 -4
  291. package/src/features/chat/types/chat-input-bar.types.ts +6 -0
  292. package/src/features/chat/types/chat-input.types.ts +5 -0
  293. package/src/features/chat/types/chat-message.types.ts +5 -0
  294. package/src/features/cron/components/__tests__/cron-config.test.tsx +100 -19
  295. package/src/features/cron/components/cron-config.tsx +19 -33
  296. package/src/features/cron/components/cron-job-detail-dialog.tsx +42 -16
  297. package/src/features/cron/components/cron-job-row.tsx +18 -1
  298. package/src/features/cron/components/cron-task-discovery.tsx +1 -1
  299. package/src/features/inbox/components/inbox-delivery-content.test.tsx +8 -2
  300. package/src/features/inbox/components/inbox-delivery-content.tsx +1 -1
  301. package/src/features/inbox/components/inbox-reader-dialog.test.tsx +10 -4
  302. package/src/features/inbox/components/inbox-reader-dialog.tsx +37 -61
  303. package/src/features/inbox/pages/inbox-page.tsx +90 -98
  304. package/src/features/marketplace/components/marketplace-page-parts.tsx +1 -1
  305. package/src/features/notifications/components/__tests__/app-notification-toast.test.tsx +31 -6
  306. package/src/features/notifications/components/app-notification-toast.tsx +54 -15
  307. package/src/features/notifications/managers/__tests__/app-notification.manager.test.ts +2 -0
  308. package/src/features/notifications/managers/app-notification.manager.ts +3 -0
  309. package/src/features/panel-apps/components/panel-app-list-item.tsx +1 -1
  310. package/src/features/panel-apps/components/panel-app-toolbar.tsx +2 -2
  311. package/src/features/panel-apps/components/panel-apps-list.tsx +4 -4
  312. package/src/features/panel-apps/utils/panel-app-doc-browser.utils.tsx +1 -0
  313. package/src/features/pwa/managers/__tests__/pwa-shell-theme.manager.test.ts +9 -0
  314. package/src/features/pwa/managers/pwa-shell-theme.manager.ts +1 -0
  315. package/src/features/service-apps/components/__tests__/service-apps-panel.test.tsx +5 -4
  316. package/src/features/service-apps/components/service-app-list-item.tsx +470 -0
  317. package/src/features/service-apps/components/service-apps-panel.tsx +76 -490
  318. package/src/features/settings/components/config/__tests__/provider-models-section.test.tsx +239 -0
  319. package/src/features/settings/components/config/provider-auth-section.tsx +90 -59
  320. package/src/features/settings/components/config/provider-form-detail-pane.tsx +307 -0
  321. package/src/features/settings/components/config/provider-form.tsx +149 -367
  322. package/src/features/settings/components/config/provider-model-list.tsx +293 -0
  323. package/src/features/settings/components/config/provider-model-suggestions-panel.tsx +151 -0
  324. package/src/features/settings/components/config/provider-models-section.tsx +178 -149
  325. package/src/features/settings/components/config/provider-status-badge.tsx +4 -2
  326. package/src/features/settings/hooks/__tests__/use-provider-connectivity.test.tsx +98 -0
  327. package/src/features/settings/hooks/__tests__/use-provider-model-suggestions.test.tsx +107 -0
  328. package/src/features/settings/hooks/use-provider-connectivity.ts +132 -0
  329. package/src/features/settings/hooks/use-provider-model-suggestions.ts +51 -0
  330. package/src/features/settings/pages/__tests__/appearance-settings-page.test.tsx +2 -2
  331. package/src/features/settings/pages/__tests__/providers-config-page.test.tsx +12 -0
  332. package/src/features/settings/pages/__tests__/search-config-page.test.tsx +48 -0
  333. package/src/features/settings/pages/providers-config-page.tsx +2 -1
  334. package/src/features/settings/pages/search-config-page.tsx +17 -8
  335. package/src/features/settings/utils/__tests__/provider-form-support.utils.test.ts +42 -0
  336. package/src/features/settings/utils/provider-form-context.utils.ts +2 -0
  337. package/src/features/settings/utils/provider-form-model.utils.ts +25 -0
  338. package/src/features/settings/utils/provider-form-support.utils.ts +21 -5
  339. package/src/index.css +1 -1
  340. package/src/platforms/desktop/types/desktop-update.types.ts +5 -0
  341. package/src/platforms/mobile/components/__tests__/mobile-app-shell.test.tsx +13 -7
  342. package/src/platforms/mobile/components/__tests__/mobile-bottom-nav.test.tsx +18 -20
  343. package/src/shared/components/actions/__tests__/navigation-link.test.tsx +14 -3
  344. package/src/shared/components/actions/navigation-link.tsx +35 -15
  345. package/src/shared/components/common/__tests__/agent-avatar.test.tsx +3 -2
  346. package/src/shared/components/common/agent-avatar.tsx +3 -3
  347. package/src/shared/components/doc-browser/__tests__/doc-browser.test.tsx +66 -0
  348. package/src/shared/components/doc-browser/doc-browser-panel-parts.tsx +5 -2
  349. package/src/shared/components/doc-browser/doc-browser-renderer.types.ts +1 -0
  350. package/src/shared/components/doc-browser/doc-browser.tsx +9 -0
  351. package/src/shared/components/doc-browser/hooks/use-doc-browser-scroll-restoration.ts +126 -0
  352. package/src/shared/components/path-picker/server-path-picker-directory-list.tsx +1 -1
  353. package/src/shared/components/path-picker/server-path-picker-locations.tsx +1 -1
  354. package/src/shared/components/path-picker/server-path-picker-navigation-bar.tsx +3 -3
  355. package/src/shared/components/settings/settings-page.tsx +1 -1
  356. package/src/shared/components/ui/actions/__tests__/icon-action-button.test.tsx +1 -1
  357. package/src/shared/components/ui/actions/icon-action-button.tsx +1 -1
  358. package/src/shared/components/ui/button.tsx +4 -4
  359. package/src/shared/components/ui/context-menu/__tests__/context-menu.test.tsx +103 -0
  360. package/src/shared/components/ui/context-menu/context-menu.tsx +263 -0
  361. package/src/shared/components/ui/dialog.tsx +1 -1
  362. package/src/shared/components/ui/input.tsx +1 -1
  363. package/src/shared/components/ui/scroll-area.tsx +2 -0
  364. package/src/shared/components/ui/select.tsx +1 -1
  365. package/src/shared/components/ui/switch.tsx +1 -1
  366. package/src/shared/components/ui/tab-strip/__tests__/compact-tab-strip.test.tsx +19 -6
  367. package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +28 -67
  368. package/src/shared/components/ui/tabs.tsx +1 -1
  369. package/src/shared/components/ui/textarea.tsx +1 -1
  370. package/src/shared/hooks/use-config.ts +33 -1
  371. package/src/shared/lib/api/__tests__/ncp-session-query-cache.utils.test.ts +26 -0
  372. package/src/shared/lib/api/ncp-session-query-cache.utils.ts +7 -10
  373. package/src/shared/lib/api/ncp-session.types.ts +7 -0
  374. package/src/shared/lib/api/types.ts +38 -1
  375. package/src/shared/lib/api/utils/config.utils.ts +14 -0
  376. package/src/shared/lib/cron/cron-job-view.utils.ts +4 -0
  377. package/src/shared/lib/host-capabilities/__tests__/host-capability.manager.test.ts +26 -0
  378. package/src/shared/lib/host-capabilities/host-capability.manager.ts +28 -0
  379. package/src/shared/lib/i18n/locales/en-US/chat.json +45 -17
  380. package/src/shared/lib/i18n/locales/en-US/core.json +26 -0
  381. package/src/shared/lib/i18n/locales/en-US/doc-browser.json +1 -0
  382. package/src/shared/lib/i18n/locales/en-US/search.json +1 -0
  383. package/src/shared/lib/i18n/locales/zh-CN/chat.json +45 -17
  384. package/src/shared/lib/i18n/locales/zh-CN/core.json +26 -0
  385. package/src/shared/lib/i18n/locales/zh-CN/doc-browser.json +1 -0
  386. package/src/shared/lib/i18n/locales/zh-CN/search.json +1 -0
  387. package/src/shared/lib/provider-models/__tests__/anonymous-provider-configuration.test.ts +40 -0
  388. package/src/shared/lib/provider-models/index.ts +4 -3
  389. package/src/shared/lib/session-project/__tests__/workspace-file-breadcrumb.test.ts +28 -1
  390. package/src/shared/lib/session-project/workspace-file-breadcrumb.utils.ts +23 -0
  391. package/src/shared/lib/theme/index.test.ts +11 -0
  392. package/src/shared/lib/theme/index.ts +2 -0
  393. package/dist/assets/api-CHo2gekJ.js +0 -13
  394. package/dist/assets/app-presenter-provider-2_DmWYT9.js +0 -108
  395. package/dist/assets/app-presenter-provider-D3BuuOyZ.css +0 -1
  396. package/dist/assets/appearance-settings-page-BEy2UE7R.js +0 -1
  397. package/dist/assets/architecture-TIHT7OUA-Cii4JyA2.js +0 -1
  398. package/dist/assets/book-open-BrZL4o9L.js +0 -1
  399. package/dist/assets/card-B5rRLu_6.js +0 -1
  400. package/dist/assets/channel-BSKkTPe8.js +0 -1
  401. package/dist/assets/channels-list-page-C1dnm68I.js +0 -8
  402. package/dist/assets/chat-page-Dz6tvZ91.js +0 -1
  403. package/dist/assets/chunk-2Q5K7J3B-CDMOR1xZ.js +0 -1
  404. package/dist/assets/chunk-VAUOI2AC-BRvqNW76.js +0 -1
  405. package/dist/assets/chunk-XXDRQBXY-CwX_mqJ3.js +0 -1
  406. package/dist/assets/classDiagram-OUVF2IWQ-RzbGxG77.js +0 -1
  407. package/dist/assets/classDiagram-v2-EOCWNBFH-C_gWB7WT.js +0 -1
  408. package/dist/assets/config-split-page-6y6W6dz4.js +0 -1
  409. package/dist/assets/confirm-dialog-q1CpEmR8.js +0 -5
  410. package/dist/assets/cynefin-VYW2F7L2-fSLIS0X3.js +0 -1
  411. package/dist/assets/desktop-update-config-DrdlwP4j.js +0 -1
  412. package/dist/assets/dist-C9EX46wM.js +0 -41
  413. package/dist/assets/doc-browser-BfttDSti.js +0 -1
  414. package/dist/assets/doc-browser-DH-3hDnI.js +0 -1
  415. package/dist/assets/doc-browser-context-TU2heon0.js +0 -1
  416. package/dist/assets/eventmodeling-45OFAUF4-XVcQGgha.js +0 -1
  417. package/dist/assets/eye-B-3dyZNA.js +0 -1
  418. package/dist/assets/flowDiagram-23GEKE2U-BiFSctqz.js +0 -1
  419. package/dist/assets/gitGraph-TEB2WS4Q-C014uXqS.js +0 -1
  420. package/dist/assets/host-capabilities-B-TtABsP.js +0 -1
  421. package/dist/assets/index-CXDPLDFD.css +0 -1
  422. package/dist/assets/index-k_eWScvN.js +0 -2
  423. package/dist/assets/info-DKCQHKI2-CQ2qjGhU.js +0 -1
  424. package/dist/assets/loader-circle-B35NlHTI.js +0 -1
  425. package/dist/assets/logo-badge-DB51c0cS.js +0 -1
  426. package/dist/assets/mcp-marketplace-page-CkPtwPBk.js +0 -1
  427. package/dist/assets/mcp-marketplace-page-DWtsIqml.js +0 -9
  428. package/dist/assets/model-config-page-D6cGNnMM.js +0 -1
  429. package/dist/assets/navigation-link-BSJEUiwD.js +0 -1
  430. package/dist/assets/packet-7NZHBO7P-6IFyydij.js +0 -1
  431. package/dist/assets/pie-RZYD4A2V-spXQC_wr.js +0 -1
  432. package/dist/assets/plus-BRVe5jSJ.js +0 -1
  433. package/dist/assets/popover-Bp9IpE_N.js +0 -1
  434. package/dist/assets/provider-models-CXUgDxGR.js +0 -1
  435. package/dist/assets/provider-scoped-model-input-dk7fz9NL.js +0 -1
  436. package/dist/assets/providers-config-page-DTP2YfxA.js +0 -1
  437. package/dist/assets/radar-I7S5WNFK-DWVA8lvY.js +0 -1
  438. package/dist/assets/railroad-3IZDKUUU-Ce51u8y1.js +0 -1
  439. package/dist/assets/railroad-abnf-AHOZXSZD-D7i7cqI_.js +0 -1
  440. package/dist/assets/railroad-ebnf-EBAXGLYW-BEg2hcPs.js +0 -1
  441. package/dist/assets/railroad-peg-LSFZ7HO6-CxROSzbi.js +0 -1
  442. package/dist/assets/react-D6ShNq95.js +0 -8
  443. package/dist/assets/remote-FllhXW3o.js +0 -1
  444. package/dist/assets/rotate-cw-CTC-Qszi.js +0 -1
  445. package/dist/assets/runtime-config-page-C57OLdPm.js +0 -1
  446. package/dist/assets/search-config-page-tnJXaaSr.js +0 -1
  447. package/dist/assets/security-config-S00DjFfO.js +0 -1
  448. package/dist/assets/select-CNFBf00l.js +0 -1
  449. package/dist/assets/skeleton-Dc06gatK.js +0 -1
  450. package/dist/assets/stateDiagram-v2-6OUMAXLB-Bui4RXQK.js +0 -1
  451. package/dist/assets/swimlanesDiagram-G3AALYLV-DTwUsCBz.js +0 -8
  452. package/dist/assets/tabs-BuNr8LSO.js +0 -1
  453. package/dist/assets/trash-2-GchaJuEM.js +0 -1
  454. package/dist/assets/treeView-QDETBFTQ-D5zsTiuL.js +0 -1
  455. package/dist/assets/treemap-6X3UGDF4-CR3dxqNs.js +0 -1
  456. package/dist/assets/use-config-C69rR15i.js +0 -1
  457. package/dist/assets/use-confirm-dialog-DF_EgPYx.js +0 -1
  458. package/dist/assets/use-viewport-layout-BACNZyMY.js +0 -1
  459. package/dist/assets/wardley-OPB4EBWU-LatRT_Lx.js +0 -1
  460. package/dist/assets/x-BXFquY9e.js +0 -1
  461. package/src/features/chat/features/welcome/components/chat-welcome-capability-grid.tsx +0 -59
  462. /package/dist/assets/{array-CAkJT3no.js → array-NADKd9aU.js} +0 -0
  463. /package/dist/assets/{chunk-KEIR6QF5-BgdDoWEH.js → chunk-KEIR6QF5-BuyuzJJL.js} +0 -0
  464. /package/dist/assets/{chunk-Y2CYZVJY-pTllD0P3.js → chunk-Y2CYZVJY-D_B2ZRNt.js} +0 -0
  465. /package/dist/assets/{config-hints-S3g-UVZb.js → config-hints-BcfVUMij.js} +0 -0
  466. /package/dist/assets/{cytoscape.esm-DmURt-5G.js → cytoscape.esm-BANTlgza.js} +0 -0
  467. /package/dist/assets/{defaultLocale-BKy_KP3O.js → defaultLocale-C4_L0aEs.js} +0 -0
  468. /package/dist/assets/{dist-IgNNB7K9.js → dist-DAPEIJbz.js} +0 -0
  469. /package/dist/assets/{graphlib-xw_TBHyH.js → graphlib-ChqXg0dI.js} +0 -0
  470. /package/dist/assets/{init-C9xlLIAu.js → init-D8wZg9xq.js} +0 -0
  471. /package/dist/assets/{jszip.min-Das2IAnb.js → jszip.min-CkbBfwAQ.js} +0 -0
  472. /package/dist/assets/{katex-DSy1eD2d.js → katex-TZJFa0J_.js} +0 -0
  473. /package/dist/assets/{middleware-Df-a4x-q.js → middleware-B3k-TSmZ.js} +0 -0
  474. /package/dist/assets/{path-DB0USYHi.js → path-DodfxcX7.js} +0 -0
  475. /package/dist/assets/{rough.esm-B1B52ZQS.js → rough.esm-CUaa1Rbe.js} +0 -0
  476. /package/dist/assets/{xlsx-DfjC_iml.js → xlsx-CxByi7bR.js} +0 -0
@@ -3,9 +3,11 @@ import {
3
3
  useEffect,
4
4
  useMemo,
5
5
  useState,
6
+ type ReactElement,
6
7
  type MutableRefObject,
7
8
  } from 'react';
8
9
  import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
10
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
9
11
  import { afterEach, describe, expect, it, vi } from 'vitest';
10
12
  import {
11
13
  createChatComposerTextNode,
@@ -27,9 +29,34 @@ import type {
27
29
  } from '@/features/chat/features/conversation/hooks/use-session-conversation-input-state';
28
30
  import { useSessionConversationInputState } from '@/features/chat/features/conversation/hooks/use-session-conversation-input-state';
29
31
  import { useChatMessageLayoutStore } from '@/features/chat/stores/chat-message-layout.store';
32
+ import { ChatComposerIntentManager } from '@/features/chat/managers/chat-composer-intent.manager';
30
33
 
31
34
  const uploadNcpAssetsMock = vi.hoisted(() => vi.fn());
32
35
 
36
+ function renderInput(input: ReactElement) {
37
+ const queryClient = new QueryClient({
38
+ defaultOptions: { queries: { retry: false } },
39
+ });
40
+ return render(
41
+ <QueryClientProvider client={queryClient}>{input}</QueryClientProvider>,
42
+ );
43
+ }
44
+
45
+ Object.defineProperty(Range.prototype, 'getBoundingClientRect', {
46
+ value: vi.fn(() => ({
47
+ bottom: 0,
48
+ height: 0,
49
+ left: 0,
50
+ right: 0,
51
+ top: 0,
52
+ width: 0,
53
+ x: 0,
54
+ y: 0,
55
+ toJSON: () => ({}),
56
+ })),
57
+ writable: true,
58
+ });
59
+
33
60
  afterEach(() => {
34
61
  useChatMessageLayoutStore.getState().setLayout('card');
35
62
  });
@@ -72,6 +99,14 @@ vi.mock('@/shared/hooks/use-server-path-search', () => ({
72
99
  }),
73
100
  }));
74
101
 
102
+ vi.mock('@/shared/hooks/use-projects', () => ({
103
+ useProjects: () => ({
104
+ data: { projects: [] },
105
+ isFetching: false,
106
+ isLoading: false,
107
+ }),
108
+ }));
109
+
75
110
  vi.mock('@/shared/lib/api', async (importOriginal) => {
76
111
  const actual = await importOriginal();
77
112
  return {
@@ -85,7 +120,9 @@ type StreamingInputControl = {
85
120
  bumpStream: () => void;
86
121
  };
87
122
 
123
+ const chatComposerIntentManager = new ChatComposerIntentManager();
88
124
  const presenter = {
125
+ chatComposerIntentManager,
89
126
  chatThreadManager: {
90
127
  openSideChatDraft: vi.fn(),
91
128
  },
@@ -100,6 +137,7 @@ const controller: SessionConversationInputController = {
100
137
  deleteQueuedInput: vi.fn(),
101
138
  editQueuedInput: vi.fn(),
102
139
  isSending: true,
140
+ primaryAction: 'send',
103
141
  queuedInputs: [],
104
142
  send: vi.fn(),
105
143
  sendDisabled: true,
@@ -109,6 +147,7 @@ const controller: SessionConversationInputController = {
109
147
 
110
148
  function createStreamingInputSnapshot(
111
149
  nodes: readonly ChatComposerNode[],
150
+ sendError: string | null = null,
112
151
  ): SessionConversationInputSnapshot {
113
152
  return {
114
153
  attachments: [],
@@ -120,7 +159,7 @@ function createStreamingInputSnapshot(
120
159
  selectedSessionType: 'default',
121
160
  selectedSkills: [],
122
161
  selectedThinkingLevel: null,
123
- sendError: null,
162
+ sendError,
124
163
  skillRecords: [],
125
164
  text: nodes
126
165
  .map((node) => (node.type === 'text' ? node.text : ''))
@@ -167,12 +206,16 @@ async function insertText(textbox: HTMLElement, text: string): Promise<void> {
167
206
  function StreamingSessionConversationInputHarness({
168
207
  controllerOverride = controller,
169
208
  controlRef,
209
+ initialText = '',
210
+ sendError = null,
170
211
  }: {
171
212
  controllerOverride?: SessionConversationInputController;
172
213
  controlRef: MutableRefObject<StreamingInputControl | null>;
214
+ initialText?: string;
215
+ sendError?: string | null;
173
216
  }) {
174
217
  const [nodes, setNodes] = useState<readonly ChatComposerNode[]>([
175
- createChatComposerTextNode(''),
218
+ createChatComposerTextNode(initialText),
176
219
  ]);
177
220
  const [streamChunk, setStreamChunk] = useState(0);
178
221
  const bumpStream = useCallback(() => setStreamChunk((chunk) => chunk + 1), []);
@@ -184,7 +227,10 @@ function StreamingSessionConversationInputHarness({
184
227
  };
185
228
  }, [bumpStream, controlRef]);
186
229
 
187
- const inputSnapshot = useMemo(() => createStreamingInputSnapshot(nodes), [nodes]);
230
+ const inputSnapshot = useMemo(
231
+ () => createStreamingInputSnapshot(nodes, sendError),
232
+ [nodes, sendError],
233
+ );
188
234
  const inputActions: SessionConversationInputActions = useMemo(() => ({
189
235
  addAttachments: vi.fn(() => []),
190
236
  applyPromptSuggestion: vi.fn(),
@@ -212,13 +258,18 @@ function StreamingSessionConversationInputHarness({
212
258
  },
213
259
  }), []);
214
260
  const inputQuery = useMemo(() => ({
261
+ addDiscoveredModel: vi.fn(async () => null),
262
+ dismissDiscoveredModels: vi.fn(),
215
263
  defaultModel: undefined,
216
264
  defaultProjectRoot: null,
265
+ discoveredModelOptions: [],
217
266
  fallbackPreferredModel: undefined,
218
267
  fallbackPreferredThinking: undefined,
219
268
  isProviderStateResolved: true,
220
269
  isSkillsLoading: false,
221
270
  modelOptions: [],
271
+ providersView: null,
272
+ refreshProviderModelCatalog: vi.fn(),
222
273
  selectedSession: null,
223
274
  selectedSessionKey: null,
224
275
  sessionTypeState: {
@@ -254,7 +305,7 @@ describe('SessionConversationInput streaming stability', () => {
254
305
  useChatMessageLayoutStore.getState().setLayout('flat');
255
306
  const controlRef: MutableRefObject<StreamingInputControl | null> = { current: null };
256
307
 
257
- render(<StreamingSessionConversationInputHarness controlRef={controlRef} />);
308
+ renderInput(<StreamingSessionConversationInputHarness controlRef={controlRef} />);
258
309
 
259
310
  const track = document.querySelector(
260
311
  '[data-chat-conversation-track="flat"][data-chat-conversation-track-width="composer"]',
@@ -266,7 +317,7 @@ describe('SessionConversationInput streaming stability', () => {
266
317
 
267
318
  it('keeps a numbered IME candidate commit stable while streamed output rerenders the owner', async () => {
268
319
  const controlRef: MutableRefObject<StreamingInputControl | null> = { current: null };
269
- render(<StreamingSessionConversationInputHarness controlRef={controlRef} />);
320
+ renderInput(<StreamingSessionConversationInputHarness controlRef={controlRef} />);
270
321
 
271
322
  const textbox = screen.getByRole('textbox');
272
323
  fireEvent.focus(textbox);
@@ -296,11 +347,59 @@ describe('SessionConversationInput streaming stability', () => {
296
347
  await waitFor(() => expect(window.getSelection()?.anchorOffset).toBe(1));
297
348
  });
298
349
 
350
+ it('inserts a project file reference at the saved composer caret', async () => {
351
+ const controlRef: MutableRefObject<StreamingInputControl | null> = { current: null };
352
+ render(
353
+ <StreamingSessionConversationInputHarness
354
+ controlRef={controlRef}
355
+ initialText="Hello"
356
+ />,
357
+ );
358
+
359
+ const textbox = screen.getByRole('textbox');
360
+ fireEvent.focus(textbox);
361
+ expect(textbox.textContent).toBe('Hello');
362
+ const paragraph = textbox.querySelector('p');
363
+ expect(paragraph).toBeTruthy();
364
+ const textNode = document
365
+ .createTreeWalker(paragraph!, NodeFilter.SHOW_TEXT)
366
+ .nextNode();
367
+ expect(textNode).toBeTruthy();
368
+ const range = document.createRange();
369
+ range.setStart(textNode!, 2);
370
+ range.collapse(true);
371
+ const selection = window.getSelection();
372
+ selection?.removeAllRanges();
373
+ selection?.addRange(range);
374
+ fireEvent(document, new Event('selectionchange'));
375
+ await act(async () => Promise.resolve());
376
+
377
+ act(() => {
378
+ chatComposerIntentManager.requestFileReference({
379
+ targetSessionKey: null,
380
+ tokenKey: 'docs/guide.md',
381
+ label: 'guide.md',
382
+ });
383
+ });
384
+
385
+ await waitFor(() => {
386
+ expect(
387
+ textbox.querySelector(
388
+ '[data-composer-token-kind="workspace_file"][data-composer-token-key="docs/guide.md"]',
389
+ ),
390
+ ).toBeTruthy();
391
+ });
392
+ expect(textbox.textContent).toContain('He');
393
+ expect(textbox.textContent).toContain('guide.md');
394
+ expect(textbox.textContent).toContain('llo');
395
+ expect(textbox.textContent).toBe('Heguide.mdllo');
396
+ });
397
+
299
398
  it('renders queued inputs above the composer with edit and delete actions', () => {
300
399
  const controlRef: MutableRefObject<StreamingInputControl | null> = { current: null };
301
400
  const deleteQueuedInput = vi.fn();
302
401
  const editQueuedInput = vi.fn();
303
- render(
402
+ renderInput(
304
403
  <StreamingSessionConversationInputHarness
305
404
  controlRef={controlRef}
306
405
  controllerOverride={{
@@ -327,6 +426,20 @@ describe('SessionConversationInput streaming stability', () => {
327
426
  expect(editQueuedInput).toHaveBeenCalledWith('queued-1');
328
427
  expect(deleteQueuedInput).toHaveBeenCalledWith('queued-2');
329
428
  });
429
+
430
+ it('leaves send-error rendering to the conversation surface', () => {
431
+ const controlRef: MutableRefObject<StreamingInputControl | null> = { current: null };
432
+ const providerError = 'Chat Completions API failed (402): raw provider error';
433
+
434
+ render(
435
+ <StreamingSessionConversationInputHarness
436
+ controlRef={controlRef}
437
+ sendError={providerError}
438
+ />,
439
+ );
440
+
441
+ expect(screen.queryByText(providerError)).toBeNull();
442
+ });
330
443
  });
331
444
 
332
445
  type AttachmentSubmitAgentSend = (envelope: NcpAgentSendEnvelope) => Promise<NcpRunHandle | null>;
@@ -341,11 +454,23 @@ function createAttachmentRunHandle(): NcpRunHandle {
341
454
  };
342
455
  }
343
456
 
344
- function AttachmentSubmitHarness({ send }: { readonly send: AttachmentSubmitAgentSend }) {
345
- const { inputActions, inputSnapshot } = useSessionConversationInputState();
457
+ function AttachmentSubmitHarness({
458
+ initialPrompt,
459
+ send,
460
+ }: {
461
+ readonly initialPrompt?: string;
462
+ readonly send: AttachmentSubmitAgentSend;
463
+ }) {
464
+ const { inputActions, inputSnapshot } = useSessionConversationInputState(
465
+ initialPrompt,
466
+ `attachment-test:${initialPrompt ?? 'empty'}`,
467
+ );
346
468
  const inputQuery = useMemo(() => ({
469
+ addDiscoveredModel: vi.fn(async () => null),
470
+ dismissDiscoveredModels: vi.fn(),
347
471
  defaultModel: 'test-model',
348
472
  defaultProjectRoot: null,
473
+ discoveredModelOptions: [],
349
474
  fallbackPreferredModel: undefined,
350
475
  fallbackPreferredThinking: undefined,
351
476
  isProviderStateResolved: true,
@@ -358,6 +483,8 @@ function AttachmentSubmitHarness({ send }: { readonly send: AttachmentSubmitAgen
358
483
  thinkingCapability: null,
359
484
  },
360
485
  ],
486
+ providersView: null,
487
+ refreshProviderModelCatalog: vi.fn(),
361
488
  selectedSession: null,
362
489
  selectedSessionKey: 'session-attachment',
363
490
  sessionTypeState: {
@@ -373,6 +500,8 @@ function AttachmentSubmitHarness({ send }: { readonly send: AttachmentSubmitAgen
373
500
  }), []);
374
501
  const agent = useMemo(() => ({
375
502
  abort: vi.fn(),
503
+ continueRun: vi.fn(),
504
+ editMessage: vi.fn(),
376
505
  isHydrating: false,
377
506
  isRunning: false,
378
507
  isSending: false,
@@ -414,6 +543,126 @@ function AttachmentSubmitHarness({ send }: { readonly send: AttachmentSubmitAgen
414
543
  }
415
544
 
416
545
  describe('SessionConversationInput attachment submit', () => {
546
+ it('preserves a project file reference in the outgoing user message and AI context', async () => {
547
+ const send = vi.fn<AttachmentSubmitAgentSend>(async () => createAttachmentRunHandle());
548
+
549
+ render(<AttachmentSubmitHarness initialPrompt="这里面有啥" send={send} />);
550
+
551
+ const textbox = screen.getByRole('textbox');
552
+ fireEvent.focus(textbox);
553
+ const textNode = document
554
+ .createTreeWalker(textbox, NodeFilter.SHOW_TEXT)
555
+ .nextNode();
556
+ expect(textNode).toBeTruthy();
557
+ const range = document.createRange();
558
+ range.setStart(textNode!, 0);
559
+ range.collapse(true);
560
+ const selection = window.getSelection();
561
+ selection?.removeAllRanges();
562
+ selection?.addRange(range);
563
+ fireEvent(document, new Event('selectionchange'));
564
+ await act(async () => Promise.resolve());
565
+
566
+ act(() => {
567
+ chatComposerIntentManager.requestFileReference({
568
+ targetSessionKey: 'session-attachment',
569
+ tokenKey: 'docs/guide.md',
570
+ label: 'guide.md',
571
+ });
572
+ });
573
+
574
+ await waitFor(() => {
575
+ expect(
576
+ document.querySelector(
577
+ '[data-composer-token-kind="workspace_file"][data-composer-token-key="docs/guide.md"]',
578
+ ),
579
+ ).toBeTruthy();
580
+ });
581
+
582
+ fireEvent.click(screen.getByRole('button', { name: /Send|发送/ }));
583
+
584
+ await waitFor(() => expect(send).toHaveBeenCalledTimes(1));
585
+ expect(send.mock.calls[0]?.[0].message.parts).toEqual([
586
+ {
587
+ type: 'text',
588
+ text: '这里面有啥 @file:docs%2Fguide.md',
589
+ },
590
+ ]);
591
+ expect(send.mock.calls[0]?.[0].message.metadata).toMatchObject({
592
+ ui_inline_tokens: {
593
+ schemaVersion: 2,
594
+ items: [
595
+ {
596
+ kind: 'workspace_file',
597
+ key: 'docs/guide.md',
598
+ label: 'guide.md',
599
+ rawText: '@file:docs%2Fguide.md',
600
+ },
601
+ ],
602
+ },
603
+ });
604
+ });
605
+
606
+ it('preserves an exact workspace excerpt in the outgoing message metadata', async () => {
607
+ const send = vi.fn<AttachmentSubmitAgentSend>(async () => createAttachmentRunHandle());
608
+ render(<AttachmentSubmitHarness initialPrompt="解释一下" send={send} />);
609
+
610
+ const textbox = screen.getByRole('textbox');
611
+ await waitFor(() => expect(textbox.textContent).toBe('解释一下'));
612
+ fireEvent.focus(textbox);
613
+ const paragraph = textbox.querySelector('p');
614
+ const textNode = document.createTreeWalker(
615
+ paragraph!,
616
+ NodeFilter.SHOW_TEXT,
617
+ ).nextNode();
618
+ const range = document.createRange();
619
+ range.setStart(textNode!, '解释一下'.length);
620
+ range.collapse(true);
621
+ window.getSelection()?.removeAllRanges();
622
+ window.getSelection()?.addRange(range);
623
+ fireEvent(document, new Event('selectionchange'));
624
+ await act(async () => Promise.resolve());
625
+
626
+ act(() => {
627
+ chatComposerIntentManager.requestExcerptReference({
628
+ targetSessionKey: 'session-attachment',
629
+ path: 'docs/guide.md',
630
+ label: 'guide.md',
631
+ excerpt: 'Requests must include an authorization header.',
632
+ startLine: 32,
633
+ endLine: 34,
634
+ });
635
+ });
636
+
637
+ await waitFor(() => expect(document.querySelector(
638
+ '[data-composer-token-kind="workspace_excerpt"]',
639
+ )).toBeTruthy());
640
+ fireEvent.click(screen.getByRole('button', { name: /Send|发送/ }));
641
+
642
+ await waitFor(() => expect(send).toHaveBeenCalledTimes(1));
643
+ const envelope = send.mock.calls[0]?.[0];
644
+ const metadata = envelope.message.metadata?.ui_inline_tokens as {
645
+ items: Array<Record<string, unknown>>;
646
+ };
647
+ expect(metadata.items).toEqual([
648
+ expect.objectContaining({
649
+ kind: 'workspace_excerpt',
650
+ path: 'docs/guide.md',
651
+ label: 'guide.md',
652
+ excerpt: 'Requests must include an authorization header.',
653
+ startLine: 32,
654
+ endLine: 34,
655
+ rawText: expect.stringMatching(/^@excerpt:/),
656
+ }),
657
+ ]);
658
+ expect(envelope.message.parts).toEqual([
659
+ {
660
+ type: 'text',
661
+ text: expect.stringMatching(/^解释一下 @excerpt:/),
662
+ },
663
+ ]);
664
+ });
665
+
417
666
  it('keeps uploaded file attachments in the outgoing send envelope after token insertion', async () => {
418
667
  uploadNcpAssetsMock.mockResolvedValueOnce([
419
668
  {
@@ -427,7 +676,7 @@ describe('SessionConversationInput attachment submit', () => {
427
676
  ]);
428
677
  const send = vi.fn<AttachmentSubmitAgentSend>(async () => createAttachmentRunHandle());
429
678
 
430
- render(<AttachmentSubmitHarness send={send} />);
679
+ renderInput(<AttachmentSubmitHarness send={send} />);
431
680
 
432
681
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement | null;
433
682
  expect(fileInput).toBeTruthy();
@@ -84,11 +84,13 @@ function readChatDraftRouteState(value: unknown): ChatDraftRouteState | null {
84
84
  }
85
85
 
86
86
  function useSessionConversationDraftRouteState(params: {
87
+ readonly applyPromptSuggestion: (prompt: string) => void;
87
88
  readonly sessionKey: string | null;
88
89
  readonly setPendingProjectRoot: (projectRoot: string | null) => void;
89
90
  readonly setPendingSessionType: (sessionType: string) => void;
90
91
  }) {
91
92
  const {
93
+ applyPromptSuggestion,
92
94
  sessionKey,
93
95
  setPendingProjectRoot,
94
96
  setPendingSessionType,
@@ -119,6 +121,9 @@ function useSessionConversationDraftRouteState(params: {
119
121
  ) {
120
122
  setPendingSessionType(draftState.sessionType);
121
123
  }
124
+ if (typeof draftState.prompt === "string" && draftState.prompt.trim()) {
125
+ applyPromptSuggestion(draftState.prompt);
126
+ }
122
127
  setPendingProjectRoot(
123
128
  typeof draftState.projectRoot === "string" &&
124
129
  draftState.projectRoot.trim()
@@ -126,6 +131,7 @@ function useSessionConversationDraftRouteState(params: {
126
131
  : null,
127
132
  );
128
133
  }, [
134
+ applyPromptSuggestion,
129
135
  location.key,
130
136
  location.state,
131
137
  sessionKey,
@@ -194,7 +200,10 @@ export function SessionConversationArea(props: SessionConversationAreaProps) {
194
200
  );
195
201
  const agent = useNcpSessionConversation(sessionKey ?? undefined);
196
202
  const runQueue = useSessionRunQueue(sessionKey);
197
- const { inputActions, inputSnapshot } = useSessionConversationInputState(initialPrompt);
203
+ const { inputActions, inputSnapshot } = useSessionConversationInputState(
204
+ initialPrompt,
205
+ sessionKey,
206
+ );
198
207
  const inputQuery = useSessionConversationInputQuery({
199
208
  sessionKey,
200
209
  inputSnapshot,
@@ -242,6 +251,7 @@ export function SessionConversationArea(props: SessionConversationAreaProps) {
242
251
  inputQuery.sessionTypeState.selectedSessionType,
243
252
  ]);
244
253
  useSessionConversationDraftRouteState({
254
+ applyPromptSuggestion: inputActions.applyPromptSuggestion,
245
255
  sessionKey,
246
256
  setPendingProjectRoot: inputActions.setPendingProjectRoot,
247
257
  setPendingSessionType: inputActions.setPendingSessionType,
@@ -249,8 +259,10 @@ export function SessionConversationArea(props: SessionConversationAreaProps) {
249
259
  const isRuntimeBlocked = isNcpChatRuntimeBlocked(systemStatus);
250
260
  const currentSessionRunning =
251
261
  agent.isRunning || inputQuery.selectedSession?.status === "running";
252
- const rawLastSendError =
253
- agent.hydrateError?.message ?? agent.snapshot.error?.message ?? null;
262
+ const runtimeError = agent.snapshot.error;
263
+ const rawLastSendError = agent.hydrateError?.message
264
+ ?? (runtimeError?.code === "run-interrupted" ? null : runtimeError?.message)
265
+ ?? null;
254
266
  const filteredLastSendError =
255
267
  systemStatus.phase === "ready" &&
256
268
  isNcpAgentStartupUnavailableErrorMessage(rawLastSendError)
@@ -298,6 +310,7 @@ export function SessionConversationArea(props: SessionConversationAreaProps) {
298
310
  editQueuedInput: (id: string) =>
299
311
  controllerRef.current.editQueuedInput(id),
300
312
  isSending: controller.isSending,
313
+ primaryAction: controller.primaryAction,
301
314
  queuedInputs: controller.queuedInputs,
302
315
  send: () => controllerRef.current.send(),
303
316
  sendDisabled: controller.sendDisabled,
@@ -307,6 +320,7 @@ export function SessionConversationArea(props: SessionConversationAreaProps) {
307
320
  [
308
321
  controller.canStopGeneration,
309
322
  controller.isSending,
323
+ controller.primaryAction,
310
324
  controller.queuedInputs,
311
325
  controller.sendDisabled,
312
326
  controller.stopDisabled,
@@ -319,28 +333,23 @@ export function SessionConversationArea(props: SessionConversationAreaProps) {
319
333
  ),
320
334
  [agent.snapshot.contextWindow],
321
335
  );
322
- const displayInputSnapshot = useMemo(
323
- () => ({
324
- ...inputSnapshot,
325
- sendError: lastSendError ?? inputSnapshot.sendError,
326
- }),
327
- [inputSnapshot, lastSendError],
328
- );
329
- const sessionFailurePreview = inputQuery.selectedSession?.activityPreview;
330
- const sessionFailureMessage =
331
- sessionFailurePreview?.state === "failed"
332
- ? sessionFailurePreview.statusText?.trim() ||
333
- sessionFailurePreview.replyText?.trim() ||
334
- null
335
- : null;
336
- const sessionFailureSlot = sessionFailureMessage ? (
337
- <div className="rounded-lg border border-red-200/80 bg-red-50/80 px-3 py-2.5 shadow-sm">
338
- <div className="text-xs font-semibold text-red-800">
339
- {t("chatSessionErrorTitle")}
340
- </div>
341
- <div className="mt-1 whitespace-pre-wrap break-words text-xs leading-5 text-red-700">
342
- {sessionFailureMessage}
343
- </div>
336
+ const { selectedSession } = inputQuery;
337
+ const conversationFailureMessage =
338
+ inputSnapshot.sendError?.trim() ||
339
+ lastSendError?.trim() ||
340
+ (selectedSession?.activityPreview?.state === "failed" &&
341
+ selectedSession.activityPreview.statusKind !== "run-interrupted"
342
+ ? selectedSession.activityPreview.statusText?.trim()
343
+ : null) ||
344
+ null;
345
+ const conversationFailureSlot = conversationFailureMessage ? (
346
+ <div
347
+ className="rounded-lg border-l-2 border-destructive/40 bg-muted/45 px-3 py-2.5"
348
+ role="status"
349
+ >
350
+ <pre className="max-h-32 select-text overflow-auto whitespace-pre-wrap break-words font-mono text-[11px] leading-5 text-muted-foreground">
351
+ {conversationFailureMessage}
352
+ </pre>
344
353
  </div>
345
354
  ) : null;
346
355
  useSessionConversationDraftIntent({
@@ -348,23 +357,24 @@ export function SessionConversationArea(props: SessionConversationAreaProps) {
348
357
  applyPromptSuggestion: inputActions.applyPromptSuggestion,
349
358
  });
350
359
  const renderInput = useCallback(
351
- (surface: "default" | "embedded") => (
360
+ (surface: "default" | "embedded", placeholder?: string) => (
352
361
  <SessionConversationInput
353
362
  contextWindow={contextWindow}
354
363
  controller={inputController}
355
364
  inputActions={inputActions}
356
365
  inputQuery={inputQuery}
357
- inputSnapshot={displayInputSnapshot}
366
+ inputSnapshot={inputSnapshot}
358
367
  onContextCompactingChange={handleContextCompactingChange}
368
+ placeholder={placeholder}
359
369
  surface={surface}
360
370
  />
361
371
  ),
362
372
  [
363
373
  contextWindow,
364
- displayInputSnapshot,
365
374
  inputController,
366
375
  inputActions,
367
376
  inputQuery,
377
+ inputSnapshot,
368
378
  handleContextCompactingChange,
369
379
  ],
370
380
  );
@@ -372,7 +382,8 @@ export function SessionConversationArea(props: SessionConversationAreaProps) {
372
382
  showWelcomeForDraft &&
373
383
  !sessionKey &&
374
384
  agent.visibleMessages.length === 0 &&
375
- !agent.isHydrating;
385
+ !agent.isHydrating &&
386
+ !controller.isSending;
376
387
 
377
388
  return (
378
389
  <>
@@ -380,23 +391,29 @@ export function SessionConversationArea(props: SessionConversationAreaProps) {
380
391
  <ChatConversationContent
381
392
  hasPreviousMessages={agent.hasPreviousMessages}
382
393
  historyError={agent.historyError}
383
- isAwaitingAssistantOutput={
384
- controller.isSending && currentSessionRunning
385
- }
386
394
  isHistoryLoading={agent.isHydrating}
387
395
  isLoadingPreviousMessages={agent.isLoadingPreviousMessages}
388
396
  isSending={controller.isSending}
397
+ canContinue={controller.canContinue}
398
+ messageActionsDisabled={controller.isSending}
389
399
  isContextCompacting={Boolean(
390
400
  sessionKey && compactingSessionIds.has(sessionKey),
391
401
  )}
392
- bottomSlot={sessionFailureSlot}
402
+ bottomSlot={showWelcome ? null : conversationFailureSlot}
393
403
  messages={agent.visibleMessages}
394
404
  sessionKey={sessionKey}
395
405
  showWelcome={showWelcome}
396
406
  onLoadPreviousMessages={agent.loadPreviousMessages}
407
+ onContinueRun={() => controllerRef.current.continueRun()}
408
+ onEditMessage={(payload) => controllerRef.current.editMessage(payload)}
397
409
  welcomeSlot={
398
410
  <ChatConversationWelcome
399
- inputSlot={renderInput("embedded")}
411
+ inputSlot={
412
+ <div className="space-y-2">
413
+ {renderInput("embedded", t("chatWelcomeInputPlaceholder"))}
414
+ {conversationFailureSlot}
415
+ </div>
416
+ }
400
417
  pendingProjectRoot={inputSnapshot.pendingProjectRoot}
401
418
  pendingSessionType={inputSnapshot.pendingSessionType}
402
419
  selectedSessionTypeValue={inputSnapshot.selectedSessionType}