@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
@@ -15,19 +15,58 @@ function formatTokenCount(value: number): string {
15
15
  export function buildChatContextWindowIndicator(
16
16
  contextWindow: SessionContextWindowView | null | undefined
17
17
  ): ChatContextWindowIndicator | null {
18
- if (!contextWindow || contextWindow.totalContextTokens <= 0) {
18
+ if (
19
+ !contextWindow ||
20
+ contextWindow.completeInputBudget !== true ||
21
+ !contextWindow.fixedInputTokens ||
22
+ contextWindow.totalContextTokens <= 0
23
+ ) {
19
24
  return null;
20
25
  }
21
- const ratio = contextWindow.usedContextTokens / contextWindow.totalContextTokens;
26
+ const triggerContextTokens = contextWindow.triggerContextTokens ?? contextWindow.totalContextTokens;
27
+ const ratio = contextWindow.usedContextTokens / Math.max(1, triggerContextTokens);
22
28
  const clampedRatio = Math.max(0, Math.min(1, ratio));
23
29
  const percentLabel = `${Math.round(clampedRatio * 100)}%`;
24
30
  const tone: ChatContextWindowIndicator['tone'] =
25
31
  clampedRatio >= 0.9 ? 'danger' : clampedRatio >= 0.75 ? 'warning' : 'neutral';
26
32
  const details: ChatContextWindowIndicator['details'] = [
27
- { label: t('chatContextWindowUsed'), value: formatTokenCount(contextWindow.usedContextTokens) },
28
- { label: t('chatContextWindowTotal'), value: formatTokenCount(contextWindow.totalContextTokens) },
29
- { label: t('chatContextWindowAvailable'), value: formatTokenCount(contextWindow.availableContextTokens) }
33
+ { label: t('chatContextWindowUsed'), value: formatTokenCount(contextWindow.usedContextTokens) }
30
34
  ];
35
+ if (contextWindow.triggerContextTokens !== undefined) {
36
+ details.push({
37
+ label: t('chatContextWindowTrigger'),
38
+ value: formatTokenCount(contextWindow.triggerContextTokens)
39
+ });
40
+ }
41
+ details.push(contextWindow.availableBeforeCompactionTokens === undefined
42
+ ? { label: t('chatContextWindowAvailable'), value: formatTokenCount(contextWindow.availableContextTokens) }
43
+ : {
44
+ label: t('chatContextWindowAvailableBeforeCompaction'),
45
+ value: formatTokenCount(contextWindow.availableBeforeCompactionTokens)
46
+ });
47
+ if (contextWindow.fixedInputTokens !== undefined) {
48
+ details.push({
49
+ label: t('chatContextWindowFixed'),
50
+ value: formatTokenCount(contextWindow.fixedInputTokens),
51
+ dividerBefore: true
52
+ });
53
+ }
54
+ if (contextWindow.dynamicInputTokens !== undefined) {
55
+ details.push({
56
+ label: t('chatContextWindowDynamic'),
57
+ value: formatTokenCount(contextWindow.dynamicInputTokens)
58
+ });
59
+ }
60
+ if (contextWindow.reservedContextTokens !== undefined) {
61
+ details.push({
62
+ label: t('chatContextWindowReserve'),
63
+ value: formatTokenCount(contextWindow.reservedContextTokens)
64
+ });
65
+ }
66
+ details.push({
67
+ label: t('chatContextWindowTotal'),
68
+ value: formatTokenCount(contextWindow.totalContextTokens)
69
+ });
31
70
  if (contextWindow.prunedUsedContextTokens !== contextWindow.usedContextTokens) {
32
71
  details.push({
33
72
  label: t('chatContextWindowPruned'),
@@ -1,6 +1,17 @@
1
- import type { SessionEntryView } from '@/shared/lib/api';
1
+ import type { SessionActivityPreviewView, SessionEntryView } from '@/shared/lib/api';
2
2
  import { getLanguage, getLocale, t, type I18nLanguage } from '@/shared/lib/i18n';
3
3
 
4
+ const LEGACY_ACTIVITY_STATUS_LABELS: Array<[
5
+ string,
6
+ NonNullable<SessionActivityPreviewView['statusKind']>
7
+ ]> = [
8
+ ['Thinking', 'thinking'],
9
+ ['Calling tool', 'tool-running'],
10
+ ['Tool call completed', 'tool-completed'],
11
+ ['Run failed', 'run-failed'],
12
+ ['Run interrupted', 'run-interrupted']
13
+ ];
14
+
4
15
  export function sessionDisplayName(session: SessionEntryView): string {
5
16
  const label = session.label?.trim();
6
17
  if (label) {
@@ -10,21 +21,46 @@ export function sessionDisplayName(session: SessionEntryView): string {
10
21
  return chunks[chunks.length - 1] || session.key;
11
22
  }
12
23
 
13
- export function sessionActivityPreviewText(session: SessionEntryView): string | null {
14
- const preview = session.activityPreview;
15
- if (!preview) {
16
- return null;
24
+ function formatSessionActivityStatus(
25
+ preview: SessionActivityPreviewView,
26
+ lang: I18nLanguage
27
+ ): string | null {
28
+ const detail = preview.statusText?.trim();
29
+ const legacyStatus = preview.statusKind || !detail
30
+ ? undefined
31
+ : LEGACY_ACTIVITY_STATUS_LABELS.find(([label]) => detail === label || detail.startsWith(`${label}: `));
32
+ const statusKind = preview.statusKind ?? legacyStatus?.[1];
33
+ const localizedDetail = legacyStatus
34
+ ? detail?.slice(legacyStatus[0].length).replace(/^:\s*/, '') || undefined
35
+ : detail;
36
+ switch (statusKind) {
37
+ case 'thinking':
38
+ return t('chatTyping', lang);
39
+ case 'tool-running':
40
+ return [t('chatToolCall', lang), t('chatToolStatusRunning', lang), localizedDetail].filter(Boolean).join(' · ');
41
+ case 'tool-completed':
42
+ return [t('chatToolCall', lang), t('chatToolStatusCompleted', lang), localizedDetail].filter(Boolean).join(' · ');
43
+ case 'run-failed':
44
+ return [t('chatToolStatusFailed', lang), localizedDetail].filter(Boolean).join(' · ');
45
+ case 'run-interrupted':
46
+ return t('chatSessionActivityInterrupted', lang);
47
+ default:
48
+ return localizedDetail ?? null;
17
49
  }
18
- if (preview.state === 'cancelled') {
50
+ }
51
+
52
+ export function sessionActivityPreviewText(
53
+ session: SessionEntryView,
54
+ lang: I18nLanguage = getLanguage()
55
+ ): string | null {
56
+ const preview = session.activityPreview;
57
+ if (!preview || preview.state === 'cancelled') {
19
58
  return null;
20
59
  }
21
- if (preview.state === 'failed' || preview.state === 'running') {
22
- return preview.statusText ?? preview.replyText ?? null;
23
- }
24
- if (preview.state === 'completed') {
25
- return preview.replyText ?? preview.statusText ?? null;
60
+ if (preview.state === 'completed' && preview.replyText) {
61
+ return preview.replyText;
26
62
  }
27
- return preview.statusText ?? preview.replyText ?? null;
63
+ return formatSessionActivityStatus(preview, lang) ?? preview.replyText ?? null;
28
64
  }
29
65
 
30
66
  function startOfLocalDate(date: Date): number {
@@ -21,6 +21,13 @@ const SESSION_ACTIVITY_PREVIEW_STATE_SET = new Set<SessionActivityPreviewView['s
21
21
  'cancelled',
22
22
  'idle'
23
23
  ]);
24
+ const SESSION_ACTIVITY_PREVIEW_STATUS_KIND_SET = new Set<NonNullable<SessionActivityPreviewView['statusKind']>>([
25
+ 'thinking',
26
+ 'tool-running',
27
+ 'tool-completed',
28
+ 'run-failed',
29
+ 'run-interrupted'
30
+ ]);
24
31
 
25
32
  function stringifyUnknown(value: unknown): string {
26
33
  if (typeof value === 'string') {
@@ -66,13 +73,15 @@ function readNcpSessionActivityPreview(summary: NcpSessionSummaryView): SessionA
66
73
  if (!SESSION_ACTIVITY_PREVIEW_STATE_SET.has(state as SessionActivityPreviewView['state']) || !timestamp) {
67
74
  return null;
68
75
  }
69
- const statusText = readOptionalString(previewRecord.statusText);
70
- const replyText = readOptionalString(previewRecord.replyText);
76
+ const rawStatusKind = readOptionalString(previewRecord.statusKind);
71
77
  return {
72
78
  state: state as SessionActivityPreviewView['state'],
73
79
  timestamp,
74
- ...(statusText ? { statusText } : {}),
75
- ...(replyText ? { replyText } : {})
80
+ statusKind: SESSION_ACTIVITY_PREVIEW_STATUS_KIND_SET.has(rawStatusKind as NonNullable<SessionActivityPreviewView['statusKind']>)
81
+ ? rawStatusKind as NonNullable<SessionActivityPreviewView['statusKind']>
82
+ : undefined,
83
+ statusText: readOptionalString(previewRecord.statusText) ?? undefined,
84
+ replyText: readOptionalString(previewRecord.replyText) ?? undefined
76
85
  };
77
86
  }
78
87
 
@@ -283,6 +292,16 @@ function toUiParts(parts: NcpMessagePart[]): UIMessage['parts'] {
283
292
  return uiParts;
284
293
  }
285
294
 
295
+ export type NcpChatMessagePart =
296
+ | UIMessage['parts'][number]
297
+ | Extract<NcpMessagePart, { type: 'extension' }>;
298
+
299
+ export function adaptNcpMessagePartsForChat(parts: NcpMessagePart[]): NcpChatMessagePart[] {
300
+ return parts.flatMap<NcpChatMessagePart>((part) =>
301
+ part.type === 'extension' ? [part] : toUiParts([part]),
302
+ );
303
+ }
304
+
286
305
  function normalizeRole(role: NcpMessageView['role']): UIMessage['role'] {
287
306
  if (role === 'service') {
288
307
  return 'system';
@@ -37,11 +37,24 @@ export function readNcpContextWindowValue(value: unknown): SessionContextWindowV
37
37
  return null;
38
38
  }
39
39
  const compactedUsedContextTokens = readNonNegativeInteger(contextWindow.compactedUsedContextTokens);
40
+ const fixedInputTokens = readNonNegativeInteger(contextWindow.fixedInputTokens);
41
+ const dynamicInputTokens = readNonNegativeInteger(contextWindow.dynamicInputTokens);
42
+ const reservedContextTokens = readNonNegativeInteger(contextWindow.reservedContextTokens);
43
+ const triggerContextTokens = readNonNegativeInteger(contextWindow.triggerContextTokens);
44
+ const availableBeforeCompactionTokens = readNonNegativeInteger(
45
+ contextWindow.availableBeforeCompactionTokens,
46
+ );
40
47
  return {
48
+ completeInputBudget: readBoolean(contextWindow.completeInputBudget),
41
49
  usedContextTokens,
42
50
  totalContextTokens,
43
51
  prunedUsedContextTokens,
44
52
  availableContextTokens: readNonNegativeInteger(contextWindow.availableContextTokens) ?? Math.max(0, totalContextTokens - usedContextTokens),
53
+ ...(fixedInputTokens !== null ? { fixedInputTokens } : {}),
54
+ ...(dynamicInputTokens !== null ? { dynamicInputTokens } : {}),
55
+ ...(reservedContextTokens !== null ? { reservedContextTokens } : {}),
56
+ ...(triggerContextTokens !== null ? { triggerContextTokens } : {}),
57
+ ...(availableBeforeCompactionTokens !== null ? { availableBeforeCompactionTokens } : {}),
45
58
  droppedHistoryCount: readNonNegativeInteger(contextWindow.droppedHistoryCount) ?? 0,
46
59
  truncatedToolResultCount: readNonNegativeInteger(contextWindow.truncatedToolResultCount) ?? 0,
47
60
  truncatedSystemPrompt: readBoolean(contextWindow.truncatedSystemPrompt),
@@ -63,7 +76,10 @@ export const CONTEXT_COMPACTION_TIMELINE_KIND = 'context_compaction';
63
76
 
64
77
  export type ContextCompactionTimelineView = {
65
78
  id: string;
66
- status: 'compressing' | 'compressed';
79
+ status: 'compressing' | 'compressed' | 'failed' | 'cancelled';
80
+ phase?: 'pre-run' | 'mid-run';
81
+ continuationMessageId?: string;
82
+ continuationMessageCoveredPartCount?: number;
67
83
  summary: string;
68
84
  coveredMessageCount: number;
69
85
  coveredSessionMessageCount: number;
@@ -86,8 +102,25 @@ export function readContextCompactionTimeline(message: Pick<NcpMessageView, 'met
86
102
  return null;
87
103
  }
88
104
  const id = readOptionalString(rawCheckpoint.id);
89
- const status = rawCheckpoint.status === 'compressing' ? 'compressing' : rawCheckpoint.status === 'compressed' ? 'compressed' : null;
90
- const summary = readOptionalString(rawCheckpoint.summary);
105
+ const status = rawCheckpoint.status === 'compressing'
106
+ ? 'compressing'
107
+ : rawCheckpoint.status === 'compressed'
108
+ ? 'compressed'
109
+ : rawCheckpoint.status === 'failed'
110
+ ? 'failed'
111
+ : rawCheckpoint.status === 'cancelled'
112
+ ? 'cancelled'
113
+ : null;
114
+ const phase = rawCheckpoint.phase === 'pre-run'
115
+ ? 'pre-run'
116
+ : rawCheckpoint.phase === 'mid-run'
117
+ ? 'mid-run'
118
+ : null;
119
+ const continuationMessageId = readOptionalString(rawCheckpoint.continuationMessageId);
120
+ const continuationMessageCoveredPartCount = readNonNegativeInteger(
121
+ rawCheckpoint.continuationMessageCoveredPartCount,
122
+ );
123
+ const summary = typeof rawCheckpoint.summary === 'string' ? rawCheckpoint.summary : null;
91
124
  const coveredMessageCount = readNonNegativeInteger(rawCheckpoint.coveredMessageCount);
92
125
  const coveredSessionMessageCount = readNonNegativeInteger(rawCheckpoint.coveredSessionMessageCount);
93
126
  const originalEstimatedTokens = readNonNegativeInteger(rawCheckpoint.originalEstimatedTokens);
@@ -97,7 +130,7 @@ export function readContextCompactionTimeline(message: Pick<NcpMessageView, 'met
97
130
  if (
98
131
  !id ||
99
132
  !status ||
100
- !summary ||
133
+ summary === null ||
101
134
  coveredMessageCount === null ||
102
135
  coveredSessionMessageCount === null ||
103
136
  originalEstimatedTokens === null ||
@@ -110,6 +143,11 @@ export function readContextCompactionTimeline(message: Pick<NcpMessageView, 'met
110
143
  return {
111
144
  id,
112
145
  status,
146
+ ...(phase ? { phase } : {}),
147
+ ...(continuationMessageId ? { continuationMessageId } : {}),
148
+ ...(continuationMessageCoveredPartCount !== null
149
+ ? { continuationMessageCoveredPartCount }
150
+ : {}),
113
151
  summary,
114
152
  coveredMessageCount,
115
153
  coveredSessionMessageCount,
@@ -79,6 +79,12 @@ vi.mock("@/shared/hooks/use-agents", () => ({
79
79
  }),
80
80
  }));
81
81
 
82
+ vi.mock("@/shared/hooks/use-projects", () => ({
83
+ useProjects: () => ({
84
+ data: { projects: [] },
85
+ }),
86
+ }));
87
+
82
88
  function createFetchedQuery<TData>(data: TData) {
83
89
  return {
84
90
  data,
@@ -50,21 +50,24 @@ describe('ChatWelcome', () => {
50
50
  expect(screen.queryByText('Current Agent:')).toBeNull();
51
51
  });
52
52
 
53
- it('uses an adaptive capability grid for narrow docked layouts', () => {
53
+ it('renders a single-purpose welcome surface with compact prompt suggestions', () => {
54
54
  renderWelcome({ agents: [{ id: 'main', displayName: 'Main' }] });
55
55
 
56
- expect(
57
- screen.getByRole('button', { name: /Smart Conversations/ }).parentElement
58
- ?.className,
59
- ).toContain('auto-fit');
56
+ expect(screen.getByRole('heading', { name: 'What would you like to get done?' })).toBeTruthy();
57
+ expect(screen.queryByText(/Describe the goal/)).toBeNull();
58
+ expect(screen.getByRole('group', { name: 'Task context' })).toBeTruthy();
59
+ const suggestion = screen.getByRole('button', { name: 'Review this project' });
60
+ expect(suggestion.className).toContain('rounded-full');
61
+ expect(suggestion.className).not.toContain('border');
62
+ expect(suggestion.parentElement?.className).toContain('flex-wrap');
60
63
  });
61
64
 
62
- it('fills the composer with a prompt suggestion when clicking a capability card', () => {
65
+ it('fills the composer with a prompt suggestion when clicking a suggestion', () => {
63
66
  const onSelectPrompt = vi.fn();
64
67
 
65
68
  renderWelcome({ onSelectPrompt });
66
69
 
67
- fireEvent.click(screen.getByRole('button', { name: /Smart Conversations/ }));
70
+ fireEvent.click(screen.getByRole('button', { name: 'Review this project' }));
68
71
 
69
72
  expect(onSelectPrompt).toHaveBeenCalledWith(
70
73
  expect.stringContaining('next three concrete things'),
@@ -89,10 +92,17 @@ describe('ChatWelcome', () => {
89
92
  defaultProjectRoot: '/Users/demo/.nextclaw/workspace',
90
93
  onSelectProjectRoot,
91
94
  projectOptions: [
95
+ {
96
+ projectRoot: '/Users/demo/.nextclaw/workspace',
97
+ projectName: 'workspace',
98
+ sessionCount: 0,
99
+ isDefault: true,
100
+ },
92
101
  {
93
102
  projectRoot: '/tmp/project-alpha',
94
103
  projectName: 'project-alpha',
95
104
  sessionCount: 3,
105
+ isDefault: false,
96
106
  },
97
107
  ],
98
108
  });
@@ -100,7 +110,8 @@ describe('ChatWelcome', () => {
100
110
  fireEvent.click(
101
111
  screen.getByRole('button', { name: 'Choose working directory' }),
102
112
  );
103
- expect(screen.getByText('Recent projects')).toBeTruthy();
113
+ expect(screen.getByText('Working directories')).toBeTruthy();
114
+ expect(screen.getByText('Default')).toBeTruthy();
104
115
  expect(screen.getByText('/tmp/project-alpha')).toBeTruthy();
105
116
  expect(screen.getByText('Open folder')).toBeTruthy();
106
117
  expect(screen.getByText('/tmp/project-alpha').closest('.overflow-y-auto'))
@@ -110,7 +121,14 @@ describe('ChatWelcome', () => {
110
121
 
111
122
  expect(onSelectProjectRoot).toHaveBeenCalledWith('/tmp/project-alpha');
112
123
  await waitFor(() => {
113
- expect(screen.queryByText('Recent projects')).toBeNull();
124
+ expect(screen.queryByText('Working directories')).toBeNull();
114
125
  });
126
+
127
+ fireEvent.click(
128
+ screen.getByRole('button', { name: 'Choose working directory' }),
129
+ );
130
+ fireEvent.click(screen.getByText('/Users/demo/.nextclaw/workspace'));
131
+
132
+ expect(onSelectProjectRoot).toHaveBeenLastCalledWith(null);
115
133
  });
116
134
  });
@@ -28,7 +28,7 @@ export function ChatWelcomeAgentPicker({
28
28
  <Select value={selectedAgentId} onValueChange={onSelectAgent}>
29
29
  <SelectTrigger
30
30
  aria-label={t('chatDraftAgentTitle')}
31
- className="h-auto w-auto min-w-0 gap-1 rounded-lg border-0 bg-transparent px-2 py-1.5 text-muted-foreground shadow-none hover:bg-accent hover:text-accent-foreground focus:ring-0"
31
+ className="h-auto w-auto min-w-0 gap-1 rounded-lg border-0 bg-transparent px-2 py-1.5 text-muted-foreground shadow-none hover:bg-[var(--interaction-hover)] hover:text-accent-foreground focus:ring-0"
32
32
  >
33
33
  <span className="sr-only">{t('chatDraftAgentTitle')}</span>
34
34
  <div className="flex min-w-0 items-center gap-1.5">
@@ -11,19 +11,17 @@ import { t } from '@/shared/lib/i18n';
11
11
  import { getSessionProjectName } from '@/shared/lib/session-project';
12
12
 
13
13
  type ChatWelcomeProjectPickerProps = {
14
- defaultProjectRoot?: string | null;
15
14
  isSaving: boolean;
16
15
  projectOptions: readonly ChatWelcomeProjectOption[];
17
16
  projectRoot: string | null;
18
17
  selectable: boolean;
19
18
  onOpenProjectDialog: () => void;
20
- onSelectProjectRoot: (projectRoot: string) => Promise<void> | void;
19
+ onSelectProjectRoot: (projectRoot: string | null) => Promise<void> | void;
21
20
  };
22
21
 
23
22
  const PROJECT_PICKER_MAX_HEIGHT = createPopoverAvailableHeightLimit('20rem');
24
23
 
25
24
  export function ChatWelcomeProjectPicker({
26
- defaultProjectRoot,
27
25
  isSaving,
28
26
  projectOptions,
29
27
  projectRoot,
@@ -34,12 +32,8 @@ export function ChatWelcomeProjectPicker({
34
32
  const [isOpen, setIsOpen] = useState(false);
35
33
  const projectLabel =
36
34
  getSessionProjectName(projectRoot) ?? t('chatWelcomeProjectPickerPlaceholder');
37
- const isDefaultProject =
38
- defaultProjectRoot !== null &&
39
- defaultProjectRoot !== undefined &&
40
- projectRoot === defaultProjectRoot;
41
35
 
42
- const selectProjectRoot = async (nextProjectRoot: string) => {
36
+ const selectProjectRoot = async (nextProjectRoot: string | null) => {
43
37
  setIsOpen(false);
44
38
  await onSelectProjectRoot(nextProjectRoot);
45
39
  };
@@ -49,18 +43,13 @@ export function ChatWelcomeProjectPicker({
49
43
  <PopoverTrigger asChild>
50
44
  <button
51
45
  type="button"
52
- className="inline-flex min-w-0 max-w-full items-center gap-1.5 rounded-lg px-2 py-1.5 text-left font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
46
+ className="inline-flex min-w-0 max-w-full items-center gap-1.5 rounded-lg px-2 py-1.5 text-left font-medium text-muted-foreground transition-colors hover:bg-[var(--interaction-hover)] hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
53
47
  title={projectRoot ?? undefined}
54
48
  aria-label={t('chatWelcomeProjectPickerLabel')}
55
49
  disabled={!selectable || isSaving}
56
50
  >
57
51
  <FolderOpen className="h-4 w-4 shrink-0" />
58
52
  <span className="truncate">{projectLabel}</span>
59
- {isDefaultProject ? (
60
- <span className="shrink-0 text-xs font-normal text-muted-foreground/70">
61
- {t('chatWelcomeProjectDefaultBadge')}
62
- </span>
63
- ) : null}
64
53
  <ChevronDown className="h-3.5 w-3.5 shrink-0 text-muted-foreground/70" />
65
54
  </button>
66
55
  </PopoverTrigger>
@@ -78,10 +67,10 @@ export function ChatWelcomeProjectPicker({
78
67
  <button
79
68
  key={option.projectRoot}
80
69
  type="button"
81
- className="flex w-full min-w-0 items-start gap-2 rounded-xl px-2 py-2 text-left transition-colors hover:bg-accent"
70
+ className="flex w-full min-w-0 items-start gap-2 rounded-xl px-2 py-2 text-left transition-colors hover:bg-[var(--interaction-hover)]"
82
71
  title={option.projectRoot}
83
72
  onClick={() => {
84
- void selectProjectRoot(option.projectRoot);
73
+ void selectProjectRoot(option.isDefault ? null : option.projectRoot);
85
74
  }}
86
75
  >
87
76
  <FolderOpen className="mt-0.5 h-4 w-4 shrink-0 text-muted-foreground/70" />
@@ -90,6 +79,11 @@ export function ChatWelcomeProjectPicker({
90
79
  <span className="truncate text-[13px] font-semibold text-foreground">
91
80
  {option.projectName}
92
81
  </span>
82
+ {option.isDefault ? (
83
+ <span className="shrink-0 rounded-full bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground">
84
+ {t('chatWelcomeProjectDefaultBadge')}
85
+ </span>
86
+ ) : null}
93
87
  </span>
94
88
  <span className="block truncate text-[11px] leading-4 text-muted-foreground">
95
89
  {option.projectRoot}
@@ -111,7 +105,7 @@ export function ChatWelcomeProjectPicker({
111
105
  <div className="shrink-0 border-t border-border p-1.5">
112
106
  <button
113
107
  type="button"
114
- className="flex w-full items-center gap-2 rounded-xl px-2.5 py-2 text-left text-[13px] font-semibold text-foreground transition-colors hover:bg-accent"
108
+ className="flex w-full items-center gap-2 rounded-xl px-2.5 py-2 text-left text-[13px] font-semibold text-foreground transition-colors hover:bg-[var(--interaction-hover)]"
115
109
  onClick={() => {
116
110
  setIsOpen(false);
117
111
  onOpenProjectDialog();
@@ -0,0 +1,37 @@
1
+ import { t } from '@/shared/lib/i18n';
2
+
3
+ const WELCOME_PROMPT_SUGGESTIONS = [
4
+ {
5
+ labelKey: 'chatWelcomeSuggestion1Label' as const,
6
+ promptKey: 'chatWelcomeSuggestion1Prompt' as const,
7
+ },
8
+ {
9
+ labelKey: 'chatWelcomeSuggestion2Label' as const,
10
+ promptKey: 'chatWelcomeSuggestion2Prompt' as const,
11
+ },
12
+ {
13
+ labelKey: 'chatWelcomeSuggestion3Label' as const,
14
+ promptKey: 'chatWelcomeSuggestion3Prompt' as const,
15
+ },
16
+ ];
17
+
18
+ export function ChatWelcomePromptSuggestions({
19
+ onSelectPrompt,
20
+ }: {
21
+ onSelectPrompt: (prompt: string) => void;
22
+ }) {
23
+ return (
24
+ <div className="mt-5 flex flex-wrap justify-center gap-2">
25
+ {WELCOME_PROMPT_SUGGESTIONS.map((suggestion) => (
26
+ <button
27
+ key={suggestion.labelKey}
28
+ type="button"
29
+ onClick={() => onSelectPrompt(t(suggestion.promptKey))}
30
+ className="rounded-full bg-muted/55 px-3.5 py-2 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
31
+ >
32
+ {t(suggestion.labelKey)}
33
+ </button>
34
+ ))}
35
+ </div>
36
+ );
37
+ }
@@ -39,7 +39,7 @@ export function ChatWelcomeSessionTypePicker({
39
39
  <PopoverTrigger asChild>
40
40
  <button
41
41
  type="button"
42
- className="inline-flex min-w-0 max-w-full items-center gap-1.5 rounded-lg px-2 py-1.5 text-left font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
42
+ className="inline-flex min-w-0 max-w-full items-center gap-1.5 rounded-lg px-2 py-1.5 text-left font-medium text-muted-foreground transition-colors hover:bg-[var(--interaction-hover)] hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
43
43
  aria-label={t('chatWelcomeSessionTypePickerLabel')}
44
44
  >
45
45
  {selectedOption.icon?.src ? (
@@ -2,7 +2,7 @@ import type { ReactNode } from 'react';
2
2
  import { useState } from 'react';
3
3
  import { ChatSessionProjectDialog } from '@/features/chat/features/session/components/session-header/chat-session-project-dialog';
4
4
  import { ChatWelcomeAgentPicker } from '@/features/chat/features/welcome/components/chat-welcome-agent-picker';
5
- import { ChatWelcomeCapabilityGrid } from '@/features/chat/features/welcome/components/chat-welcome-capability-grid';
5
+ import { ChatWelcomePromptSuggestions } from '@/features/chat/features/welcome/components/chat-welcome-prompt-suggestions';
6
6
  import { ChatWelcomeProjectPicker } from '@/features/chat/features/welcome/components/chat-welcome-project-picker';
7
7
  import { ChatWelcomeSessionTypePicker } from '@/features/chat/features/welcome/components/chat-welcome-session-type-picker';
8
8
  import type { ChatWelcomeProjectOption } from '@/features/chat/features/welcome/utils/chat-welcome-project-options.utils';
@@ -23,7 +23,7 @@ type ChatWelcomeProps = {
23
23
  sessionTypeOptions: readonly SessionTypeOption[];
24
24
  onSelectAgent: (agentId: string) => void;
25
25
  onSelectPrompt: (prompt: string) => void;
26
- onSelectProjectRoot?: (projectRoot: string) => Promise<void> | void;
26
+ onSelectProjectRoot?: (projectRoot: string | null) => Promise<void> | void;
27
27
  onSelectSessionType: (sessionType: string) => void;
28
28
  };
29
29
 
@@ -46,7 +46,7 @@ export function ChatWelcome({
46
46
  const [isProjectSaving, setIsProjectSaving] = useState(false);
47
47
  const resolvedProjectRoot = selectedProjectRoot ?? defaultProjectRoot ?? null;
48
48
 
49
- const saveProjectRoot = async (projectRoot: string) => {
49
+ const saveProjectRoot = async (projectRoot: string | null) => {
50
50
  if (!onSelectProjectRoot) {
51
51
  return;
52
52
  }
@@ -61,45 +61,47 @@ export function ChatWelcome({
61
61
  const selectableProjectRoot = Boolean(onSelectProjectRoot);
62
62
 
63
63
  return (
64
- <div className="flex min-h-full items-center justify-center px-4 py-8 sm:p-8">
65
- <div className="min-w-0 w-full max-w-[min(760px,100%)]">
64
+ <div className="flex min-h-full items-center justify-center px-4 py-10 sm:p-8">
65
+ <div className="w-full min-w-0 max-w-[min(680px,100%)]">
66
66
  <div className="text-center">
67
- <h2 className="text-2xl font-semibold text-foreground sm:text-3xl">
67
+ <h2 className="text-2xl font-semibold leading-tight text-foreground sm:text-[2rem]">
68
68
  {t('chatWelcomeTitle')}
69
69
  </h2>
70
- <p className="mt-3 text-sm font-medium text-muted-foreground sm:text-base">
71
- {t('chatWelcomeSubtitle')}
72
- </p>
73
70
  </div>
74
71
 
75
- {inputSlot ? <div className="mt-8">{inputSlot}</div> : null}
72
+ {inputSlot ? <div className="mt-6">{inputSlot}</div> : null}
76
73
 
77
- <div className="mt-3 flex flex-wrap items-center gap-2 px-1 text-sm text-muted-foreground">
78
- {onSelectProjectRoot ? (
79
- <ChatWelcomeProjectPicker
80
- defaultProjectRoot={defaultProjectRoot}
81
- isSaving={isProjectSaving}
82
- projectOptions={projectOptions}
83
- projectRoot={resolvedProjectRoot}
84
- selectable={selectableProjectRoot}
85
- onOpenProjectDialog={() => setIsProjectDialogOpen(true)}
86
- onSelectProjectRoot={saveProjectRoot}
74
+ <div className="mt-2 flex justify-center px-1">
75
+ <div
76
+ role="group"
77
+ aria-label={t('chatWelcomeContextLabel')}
78
+ className="flex min-w-0 max-w-full flex-wrap items-center justify-center gap-0.5 rounded-xl bg-muted/40 p-1 text-sm text-muted-foreground"
79
+ >
80
+ {onSelectProjectRoot ? (
81
+ <ChatWelcomeProjectPicker
82
+ isSaving={isProjectSaving}
83
+ projectOptions={projectOptions}
84
+ projectRoot={resolvedProjectRoot}
85
+ selectable={selectableProjectRoot}
86
+ onOpenProjectDialog={() => setIsProjectDialogOpen(true)}
87
+ onSelectProjectRoot={saveProjectRoot}
88
+ />
89
+ ) : null}
90
+ <ChatWelcomeAgentPicker
91
+ agents={agents}
92
+ selectedAgent={selectedAgent}
93
+ selectedAgentId={selectedAgentId}
94
+ onSelectAgent={onSelectAgent}
87
95
  />
88
- ) : null}
89
- <ChatWelcomeAgentPicker
90
- agents={agents}
91
- selectedAgent={selectedAgent}
92
- selectedAgentId={selectedAgentId}
93
- onSelectAgent={onSelectAgent}
94
- />
95
- <ChatWelcomeSessionTypePicker
96
- options={sessionTypeOptions}
97
- selectedSessionType={selectedSessionType}
98
- onSelectSessionType={onSelectSessionType}
99
- />
96
+ <ChatWelcomeSessionTypePicker
97
+ options={sessionTypeOptions}
98
+ selectedSessionType={selectedSessionType}
99
+ onSelectSessionType={onSelectSessionType}
100
+ />
101
+ </div>
100
102
  </div>
101
103
 
102
- <ChatWelcomeCapabilityGrid onSelectPrompt={onSelectPrompt} />
104
+ <ChatWelcomePromptSuggestions onSelectPrompt={onSelectPrompt} />
103
105
  </div>
104
106
 
105
107
  {onSelectProjectRoot ? (