@nextclaw/ui 0.17.1 → 0.18.0

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 (236) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/assets/{abnfDiagram-VRR7QNED-BcFJp_1X.js → abnfDiagram-VRR7QNED-DvTjgVMf.js} +1 -1
  3. package/dist/assets/{aiden0z-pptx-renderer.es-Dp2ezlQn.js → aiden0z-pptx-renderer.es-C1nfBAXR.js} +1 -1
  4. package/dist/assets/{api-DJ6ZKWFY.js → api-BJioGtWS.js} +3 -3
  5. package/dist/assets/{appearance-settings-page-B-juoJ6F.js → appearance-settings-page-DAF1fd14.js} +1 -1
  6. package/dist/assets/{arc-CkgyPMyW.js → arc-BvhODBXv.js} +1 -1
  7. package/dist/assets/architecture-TIHT7OUA-Bjp9jf0h.js +1 -0
  8. package/dist/assets/{architectureDiagram-ZJ3FMSHR-CMd4cIjI.js → architectureDiagram-ZJ3FMSHR-BKO9RgNS.js} +1 -1
  9. package/dist/assets/{blockDiagram-677ZJIJ3-Bz3tbhet.js → blockDiagram-677ZJIJ3-DHpDXy7D.js} +1 -1
  10. package/dist/assets/book-open-aDv6R1av.js +1 -0
  11. package/dist/assets/{c4Diagram-LMCZKHZV-D9hFNAGv.js → c4Diagram-LMCZKHZV-BG_iQnDr.js} +1 -1
  12. package/dist/assets/channel-5T3pdR-s.js +1 -0
  13. package/dist/assets/{channels-list-page-mVHYa7xW.js → channels-list-page-Dubt8r9S.js} +2 -2
  14. package/dist/assets/{chat-page-DsMYGNee.js → chat-page-JbwjeUo4.js} +1 -1
  15. package/dist/assets/chunk-2Q5K7J3B-DTZ3tGfE.js +1 -0
  16. package/dist/assets/{chunk-32BRIVSS-7NrjEITq.js → chunk-32BRIVSS-DR9M0LLx.js} +1 -1
  17. package/dist/assets/{chunk-52WLFC77-viIcqj9q.js → chunk-52WLFC77-698iC3BB.js} +1 -1
  18. package/dist/assets/{chunk-5FCAYU7R-Vsu4J-VM.js → chunk-5FCAYU7R-DikTj9Ey.js} +1 -1
  19. package/dist/assets/{chunk-5HE753X5-C-w6CQZK.js → chunk-5HE753X5-ko0o7_q0.js} +1 -1
  20. package/dist/assets/{chunk-5JV3BV7I-CuKgJQ4W.js → chunk-5JV3BV7I-CEHufhgo.js} +1 -1
  21. package/dist/assets/{chunk-5TONJI2A-CYeiWZKb.js → chunk-5TONJI2A-CGgno1cu.js} +1 -1
  22. package/dist/assets/{chunk-5VM5RSS4-DRCbfwIn.js → chunk-5VM5RSS4-DkiB4cUQ.js} +1 -1
  23. package/dist/assets/{chunk-7BUUIJ7U-BvydOcm3.js → chunk-7BUUIJ7U-DzptcytQ.js} +1 -1
  24. package/dist/assets/{chunk-BIQX33UG-RlppOXKo.js → chunk-BIQX33UG-DMRSQJvT.js} +1 -1
  25. package/dist/assets/{chunk-C7G6YPKG-DAizzYwr.js → chunk-C7G6YPKG-Bw1BwwuY.js} +1 -1
  26. package/dist/assets/{chunk-CQNSW5MT-5eChJHca.js → chunk-CQNSW5MT-C0z6eHBk.js} +1 -1
  27. package/dist/assets/{chunk-CYSBUYHQ-YHPr53fv.js → chunk-CYSBUYHQ-ByPyAouO.js} +1 -1
  28. package/dist/assets/{chunk-EMLP6XTP-CK4D7Hz5.js → chunk-EMLP6XTP-CJlAXWZg.js} +1 -1
  29. package/dist/assets/{chunk-EX3LRPZG-BmlDFIRW.js → chunk-EX3LRPZG-Dqq4zKJu.js} +1 -1
  30. package/dist/assets/{chunk-FWX5IMBZ-D0ksHZZ9.js → chunk-FWX5IMBZ-B0SNoCmi.js} +2 -2
  31. package/dist/assets/{chunk-HOUHSVGY-DPkq8FCm.js → chunk-HOUHSVGY-DG_GJih_.js} +1 -1
  32. package/dist/assets/{chunk-ICXQ74PX-FAatv5fC.js → chunk-ICXQ74PX-Drxk_6bE.js} +1 -1
  33. package/dist/assets/{chunk-JG7HCLWE-DLkIi4F7.js → chunk-JG7HCLWE-DdLFPpnd.js} +1 -1
  34. package/dist/assets/{chunk-JWPE2WC7-DawOjNE3.js → chunk-JWPE2WC7-B8M4G76F.js} +1 -1
  35. package/dist/assets/{chunk-MOJQB5TN-Di52TorW.js → chunk-MOJQB5TN-XP6FJHY_.js} +1 -1
  36. package/dist/assets/{chunk-MOZMSUNE-PfyK9w1-.js → chunk-MOZMSUNE-C_6x18Qw.js} +1 -1
  37. package/dist/assets/{chunk-OGEWGWER-C3jdH3Ty.js → chunk-OGEWGWER-N25BzCmG.js} +1 -1
  38. package/dist/assets/{chunk-OSBZ3O6U-CecHo-f0.js → chunk-OSBZ3O6U-ASDEm7y0.js} +1 -1
  39. package/dist/assets/{chunk-PUDLZKDR-f3IJh3sN.js → chunk-PUDLZKDR-CTlvAcn7.js} +1 -1
  40. package/dist/assets/{chunk-Q4XR5HBZ-DQFeUPxZ.js → chunk-Q4XR5HBZ-Da9BWfB6.js} +1 -1
  41. package/dist/assets/{chunk-QBLGF6JB-BhUeG0y2.js → chunk-QBLGF6JB-Bi6RpTJO.js} +1 -1
  42. package/dist/assets/{chunk-R7FJI6CG-C3XpZ-2u.js → chunk-R7FJI6CG-DkMsSPvK.js} +1 -1
  43. package/dist/assets/{chunk-RYQCIY6F-CAqa5klQ.js → chunk-RYQCIY6F-DZp0eU-j.js} +1 -1
  44. package/dist/assets/{chunk-U6XO7XAA-D_WXezeD.js → chunk-U6XO7XAA-vfinDSrj.js} +1 -1
  45. package/dist/assets/{chunk-V7JOEXUC-CZ70oOtp.js → chunk-V7JOEXUC-C9Nksccs.js} +1 -1
  46. package/dist/assets/chunk-VAUOI2AC-HLGIHQ6k.js +1 -0
  47. package/dist/assets/{chunk-VR4S4FIN-B7AHEYYk.js → chunk-VR4S4FIN-Xv6zfwXs.js} +1 -1
  48. package/dist/assets/{chunk-WYO6CB5R-Dn9To_OI.js → chunk-WYO6CB5R-mOJNzbWl.js} +2 -2
  49. package/dist/assets/chunk-XXDRQBXY-Dl0m6Ni-.js +1 -0
  50. package/dist/assets/{chunk-YOTPTUD7-BYEgRBk3.js → chunk-YOTPTUD7-1-aKSu4o.js} +1 -1
  51. package/dist/assets/{chunk-ZGVPDNZ5-C6YtZDU0.js → chunk-ZGVPDNZ5-OJ8veMpK.js} +1 -1
  52. package/dist/assets/{chunk-ZIRB5QZD-DMuYtnHF.js → chunk-ZIRB5QZD-SR_Nq_PP.js} +1 -1
  53. package/dist/assets/classDiagram-OUVF2IWQ-DcDnzGNX.js +1 -0
  54. package/dist/assets/classDiagram-v2-EOCWNBFH-BKXKMzKM.js +1 -0
  55. package/dist/assets/{config-split-page-BaqLcRxk.js → config-split-page-Bs1wArsX.js} +1 -1
  56. package/dist/assets/{confirm-dialog-DasFoaCT.js → confirm-dialog-BFatCZUq.js} +1 -1
  57. package/dist/assets/{cose-bilkent-JH36ORCC-Bc2Ex5Y3.js → cose-bilkent-JH36ORCC-NjVgz2Bw.js} +1 -1
  58. package/dist/assets/cynefin-VYW2F7L2-BWg7U2UD.js +1 -0
  59. package/dist/assets/{cynefinDiagram-TSTJHNR4-DVysQoGz.js → cynefinDiagram-TSTJHNR4-B_17LDqD.js} +1 -1
  60. package/dist/assets/{dagre-CMhQ1cAG.js → dagre-CMe101gk.js} +1 -1
  61. package/dist/assets/{dagre-VKFMJZFB-RYyWpPJZ.js → dagre-VKFMJZFB-qo8nLb3B.js} +1 -1
  62. package/dist/assets/{desktop-update-config-CoEvKrpB.js → desktop-update-config-DFefhK96.js} +1 -1
  63. package/dist/assets/{diagram-FQU43EPY-BD6KONdF.js → diagram-FQU43EPY-Ba3XIklC.js} +1 -1
  64. package/dist/assets/{diagram-G47NLZAW-CGB2ptRR.js → diagram-G47NLZAW-CG45TcUx.js} +1 -1
  65. package/dist/assets/{diagram-NH7WQ7WH-DnkOI6cU.js → diagram-NH7WQ7WH-2F2HrwV-.js} +1 -1
  66. package/dist/assets/{diagram-OA4YK3LP-DF82RZ7P.js → diagram-OA4YK3LP-CXfWH9NZ.js} +1 -1
  67. package/dist/assets/{diagram-WEI45ONY-Be2v7Ck9.js → diagram-WEI45ONY-CH_4yepc.js} +1 -1
  68. package/dist/assets/{dist-C741xUwt.js → dist-CV9wIyME.js} +1 -1
  69. package/dist/assets/{dist-zOKNc7QQ.js → dist-D1I3blO_.js} +1 -1
  70. package/dist/assets/doc-browser-BFfstBoh.js +1 -0
  71. package/dist/assets/doc-browser-DEdoMb3X.js +1 -0
  72. package/dist/assets/{doc-browser-context-BT8NWQyM.js → doc-browser-context-BcwcVwX_.js} +1 -1
  73. package/dist/assets/{docx-preview-BqwAjrj3.js → docx-preview-CoM4JK7_.js} +1 -1
  74. package/dist/assets/{ebnfDiagram-CCIWWBDH-CP98OYk8.js → ebnfDiagram-CCIWWBDH-BwiG4Ea1.js} +1 -1
  75. package/dist/assets/{erDiagram-Q63AITRT-ZLlx8xfs.js → erDiagram-Q63AITRT-BML3hpnQ.js} +1 -1
  76. package/dist/assets/eventmodeling-45OFAUF4-SB-J4tpq.js +1 -0
  77. package/dist/assets/flowDiagram-23GEKE2U-BQ_u-eLM.js +1 -0
  78. package/dist/assets/{form-actions-BcukaMyR.js → form-actions-YSnn7q_U.js} +1 -1
  79. package/dist/assets/{ganttDiagram-NO4QXBWP-DXCDjHR2.js → ganttDiagram-NO4QXBWP-80enfWbD.js} +1 -1
  80. package/dist/assets/gitGraph-TEB2WS4Q-DPxNwsFd.js +1 -0
  81. package/dist/assets/{gitGraphDiagram-IHSO6WYX-l2HWrTJp.js → gitGraphDiagram-IHSO6WYX-CVLqXr-b.js} +1 -1
  82. package/dist/assets/index-Bsoscjk7.css +1 -0
  83. package/dist/assets/index-L58BO782.js +109 -0
  84. package/dist/assets/info-DKCQHKI2-DNlNGH90.js +1 -0
  85. package/dist/assets/{infoDiagram-FWYZ7A6U-D-DjX-bn.js → infoDiagram-FWYZ7A6U-Dyvs2t0i.js} +1 -1
  86. package/dist/assets/{ishikawaDiagram-FXEZZL3T-y_Xy128F.js → ishikawaDiagram-FXEZZL3T-sSnxDKfh.js} +1 -1
  87. package/dist/assets/{journeyDiagram-5HDEW3XC-DJn5xYcQ.js → journeyDiagram-5HDEW3XC-D22V71Mf.js} +1 -1
  88. package/dist/assets/{kanban-definition-HUTT4EX6-DJVIOR21.js → kanban-definition-HUTT4EX6-D3ds0p-g.js} +1 -1
  89. package/dist/assets/{line-Cos7PIOj.js → line-CbyFs065.js} +1 -1
  90. package/dist/assets/{linear-BtDLqtzF.js → linear-4DKtnZBS.js} +1 -1
  91. package/dist/assets/loader-circle-CsNiT6VM.js +1 -0
  92. package/dist/assets/{map-BKnQyvd0.js → map-CcZzEoz6.js} +1 -1
  93. package/dist/assets/mcp-marketplace-page-DfUCF-L5.js +1 -0
  94. package/dist/assets/mcp-marketplace-page-ZTHpQTvi.js +9 -0
  95. package/dist/assets/{mermaid-parser.core-XUNZhr2W.js → mermaid-parser.core-DPmMOjXD.js} +2 -2
  96. package/dist/assets/{mermaid.core-ySrvolIe.js → mermaid.core-BSf-ddRa.js} +3 -3
  97. package/dist/assets/{mindmap-definition-LN4V7U3C-BypL9tei.js → mindmap-definition-LN4V7U3C-BUTwWPyx.js} +1 -1
  98. package/dist/assets/model-config-page-jYCwpq4U.js +1 -0
  99. package/dist/assets/{navigation-link-BoMNAKyw.js → navigation-link-7oSjAC9R.js} +1 -1
  100. package/dist/assets/{ordinal-CxxVWxYU.js → ordinal-BgLYtOZE.js} +1 -1
  101. package/dist/assets/packet-7NZHBO7P-BpeiqkBZ.js +1 -0
  102. package/dist/assets/{pegDiagram-2B236MQR-D-U2KBGv.js → pegDiagram-2B236MQR-BEu_ZBjc.js} +1 -1
  103. package/dist/assets/pie-RZYD4A2V-Cy1yxsPd.js +1 -0
  104. package/dist/assets/{pieDiagram-ENE6RG2P-CBi3GusJ.js → pieDiagram-ENE6RG2P-CAwAwuBd.js} +1 -1
  105. package/dist/assets/plus-D6UN8XN5.js +1 -0
  106. package/dist/assets/{provider-scoped-model-input-CB-vojwC.js → provider-scoped-model-input-C1CUHVJx.js} +1 -1
  107. package/dist/assets/{providers-config-page-C80nti5H.js → providers-config-page-CMvI4R1e.js} +1 -1
  108. package/dist/assets/{quadrantDiagram-ABIIQ3AL-H0ZuvnZL.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-D7Y2EqSd.js → railroadDiagram-RFXS5EU6-xgLekU3B.js} +1 -1
  115. package/dist/assets/react-7zG0fz1I.js +8 -0
  116. package/dist/assets/{refresh-cw-DZ_Y89ld.js → refresh-cw-BUg7hI3u.js} +1 -1
  117. package/dist/assets/remote-BYPq49kD.js +1 -0
  118. package/dist/assets/{requirementDiagram-TGXJPOKE-BiXNX1NN.js → requirementDiagram-TGXJPOKE-CyVUzEX5.js} +1 -1
  119. package/dist/assets/rotate-cw-B3qmXtfJ.js +1 -0
  120. package/dist/assets/runtime-config-page-DYuYv5yM.js +1 -0
  121. package/dist/assets/{sankeyDiagram-HTMAVEWB-qzDeLztW.js → sankeyDiagram-HTMAVEWB-JK6bFmYB.js} +1 -1
  122. package/dist/assets/{save-BgMfxs5u.js → save-CTCYuZqu.js} +1 -1
  123. package/dist/assets/{search-C7ruoV7u.js → search-CfFUpaf7.js} +1 -1
  124. package/dist/assets/{search-config-page-BTjfOZ6q.js → search-config-page-GUtGbk6i.js} +1 -1
  125. package/dist/assets/{secrets-config-page-BFjiSz73.js → secrets-config-page-Delo8ab0.js} +2 -2
  126. package/dist/assets/security-config-DoVoel5I.js +1 -0
  127. package/dist/assets/{select-BMX2ooE-.js → select-MSvkWmPP.js} +1 -1
  128. package/dist/assets/{sequenceDiagram-DBY2YBRQ-BtRbPQtL.js → sequenceDiagram-DBY2YBRQ-BR5IokXV.js} +1 -1
  129. package/dist/assets/{settings-2-BNQF6hed.js → settings-2-DXUfAWgg.js} +1 -1
  130. package/dist/assets/{sizeCapture-X5ZJPWSS-CMYvM3SL.js → sizeCapture-X5ZJPWSS-SxG_YnMA.js} +1 -1
  131. package/dist/assets/skeleton-DDFivi9Y.js +1 -0
  132. package/dist/assets/{src-Bw-mzbQb.js → src-vgz8E_-O.js} +1 -1
  133. package/dist/assets/{stateDiagram-2N3HPSRC-BJ-mFeOz.js → stateDiagram-2N3HPSRC-DD4OoYhn.js} +1 -1
  134. package/dist/assets/stateDiagram-v2-6OUMAXLB-ZC6dFORv.js +1 -0
  135. package/dist/assets/{swimlanes-5IMT3BWC-BsucVOO2.js → swimlanes-5IMT3BWC-BWkFeyCT.js} +2 -2
  136. package/dist/assets/swimlanesDiagram-G3AALYLV-CRkh51Im.js +8 -0
  137. package/dist/assets/{tag-chip-BL-UXlVO.js → tag-chip-u8g0b0Nf.js} +1 -1
  138. package/dist/assets/{timeline-definition-FHXFAJF6-Bicewlzo.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/{vennDiagram-L72KCM5P-BxOOnO9x.js → vennDiagram-L72KCM5P-Bvk42Pek.js} +1 -1
  142. package/dist/assets/wardley-OPB4EBWU-CoWturk0.js +1 -0
  143. package/dist/assets/{wardleyDiagram-EHGQE667-Cl7NltMv.js → wardleyDiagram-EHGQE667-DOFjx2s3.js} +1 -1
  144. package/dist/assets/x-DdOEUmR4.js +1 -0
  145. package/dist/assets/{xychartDiagram-FW5EYKEG-DiMIxQ7N.js → xychartDiagram-FW5EYKEG-DY5yRTUc.js} +1 -1
  146. package/dist/index.html +22 -21
  147. package/package.json +9 -9
  148. package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +2 -0
  149. package/src/features/chat/features/conversation/components/session-conversation-area.tsx +2 -0
  150. package/src/features/chat/features/conversation/components/session-conversation-input.tsx +2 -0
  151. package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-controller.test.tsx +46 -0
  152. package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-slash-commands.test.tsx +20 -0
  153. package/src/features/chat/features/conversation/hooks/use-session-conversation-controller.ts +138 -54
  154. package/src/features/chat/features/conversation/hooks/use-session-conversation-slash-commands.ts +25 -2
  155. package/src/features/chat/features/message/utils/__tests__/chat-message-show-content-tool-card.utils.test.ts +46 -0
  156. package/src/features/chat/features/message/utils/chat-message-part.utils.ts +2 -0
  157. package/src/features/chat/features/message/utils/chat-message-tool-card.utils.ts +52 -2
  158. package/src/features/chat/features/ncp/hooks/__tests__/use-hydrated-ncp-agent.test.tsx +97 -10
  159. package/src/features/chat/features/ncp/hooks/use-ncp-session-conversation.ts +4 -0
  160. package/src/features/chat/features/ncp/hooks/use-ncp-session-queries.ts +10 -0
  161. package/src/features/chat/features/session/utils/__tests__/ncp-session-adapter.utils.test.ts +27 -0
  162. package/src/features/chat/features/session/utils/ncp-session-adapter.utils.ts +2 -1
  163. package/src/features/chat/features/workspace/components/__tests__/chat-session-child-sessions.test.tsx +51 -0
  164. package/src/features/chat/features/workspace/components/__tests__/chat-session-token-usage.test.tsx +90 -0
  165. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel-content.test.tsx +9 -17
  166. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +4 -45
  167. package/src/features/chat/features/workspace/components/child-sessions/chat-session-child-sessions.tsx +66 -0
  168. package/src/features/chat/features/workspace/components/overview/chat-session-token-usage.tsx +171 -0
  169. package/src/features/chat/types/chat-message.types.ts +5 -0
  170. package/src/shared/components/doc-browser/__tests__/doc-browser-tab-strip.test.tsx +78 -0
  171. package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +71 -3
  172. package/src/shared/components/ui/tab-strip/__tests__/compact-tab-strip.test.tsx +78 -1
  173. package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +97 -44
  174. package/src/shared/lib/api/__tests__/ncp-session-query-cache.utils.test.ts +2 -0
  175. package/src/shared/lib/api/ncp-session-query-cache.utils.ts +4 -0
  176. package/src/shared/lib/api/ncp-session.types.ts +3 -0
  177. package/src/shared/lib/api/types.ts +1 -0
  178. package/src/shared/lib/api/utils/ncp-session.utils.ts +8 -0
  179. package/src/shared/lib/i18n/locales/en-US/chat.json +23 -0
  180. package/src/shared/lib/i18n/locales/zh-CN/chat.json +24 -1
  181. package/dist/assets/architecture-TIHT7OUA-DO2x53FK.js +0 -1
  182. package/dist/assets/channel-nBvMaVyP.js +0 -1
  183. package/dist/assets/chunk-2Q5K7J3B-CJgqFDS4.js +0 -1
  184. package/dist/assets/chunk-VAUOI2AC-BGvh3yIx.js +0 -1
  185. package/dist/assets/chunk-XXDRQBXY-DaBxG5gs.js +0 -1
  186. package/dist/assets/classDiagram-OUVF2IWQ-P6N03G2R.js +0 -1
  187. package/dist/assets/classDiagram-v2-EOCWNBFH-B1_uLvMv.js +0 -1
  188. package/dist/assets/cynefin-VYW2F7L2-B-H8Qp-n.js +0 -1
  189. package/dist/assets/doc-browser-BbirIYbj.js +0 -1
  190. package/dist/assets/doc-browser-Crqog5cn.js +0 -1
  191. package/dist/assets/eventmodeling-45OFAUF4-YVtShyFA.js +0 -1
  192. package/dist/assets/flowDiagram-23GEKE2U-BeKXabVO.js +0 -1
  193. package/dist/assets/gitGraph-TEB2WS4Q-jTSiBj-p.js +0 -1
  194. package/dist/assets/index-1f4Pv2q3.css +0 -1
  195. package/dist/assets/index-BYWLjYFQ.js +0 -109
  196. package/dist/assets/info-DKCQHKI2-BIporNWb.js +0 -1
  197. package/dist/assets/loader-circle-LVHz84Xj.js +0 -1
  198. package/dist/assets/mcp-marketplace-page-2SsrbaiQ.js +0 -1
  199. package/dist/assets/mcp-marketplace-page-XgYLOAkK.js +0 -9
  200. package/dist/assets/model-config-page-DL8ljJK-.js +0 -1
  201. package/dist/assets/packet-7NZHBO7P-CuFMADV0.js +0 -1
  202. package/dist/assets/pie-RZYD4A2V-XUeIXhM9.js +0 -1
  203. package/dist/assets/plus-BeGZHC3f.js +0 -1
  204. package/dist/assets/radar-I7S5WNFK-D-NNGh1k.js +0 -1
  205. package/dist/assets/railroad-3IZDKUUU-C67_uDaM.js +0 -1
  206. package/dist/assets/railroad-abnf-AHOZXSZD-BZ8Yflnd.js +0 -1
  207. package/dist/assets/railroad-ebnf-EBAXGLYW-B7zO7RoK.js +0 -1
  208. package/dist/assets/railroad-peg-LSFZ7HO6-R63PTgLz.js +0 -1
  209. package/dist/assets/react-DND3vEAM.js +0 -8
  210. package/dist/assets/remote-Codkr9SX.js +0 -1
  211. package/dist/assets/rotate-cw-CP3pQ4R8.js +0 -1
  212. package/dist/assets/runtime-config-page-Um1XDqXJ.js +0 -1
  213. package/dist/assets/security-config-Dx-wMb4q.js +0 -1
  214. package/dist/assets/skeleton-CWZ0IO2D.js +0 -1
  215. package/dist/assets/stateDiagram-v2-6OUMAXLB-BE-HqxOK.js +0 -1
  216. package/dist/assets/swimlanesDiagram-G3AALYLV-Dr1H9LJH.js +0 -8
  217. package/dist/assets/treeView-QDETBFTQ-npJ5dbqS.js +0 -1
  218. package/dist/assets/treemap-6X3UGDF4-pYrBx6oa.js +0 -1
  219. package/dist/assets/wardley-OPB4EBWU-CmSRKLR8.js +0 -1
  220. package/dist/assets/x-BSu1xwPK.js +0 -1
  221. /package/dist/assets/{array-BQVzeGRt.js → array-NADKd9aU.js} +0 -0
  222. /package/dist/assets/{chunk-KEIR6QF5-f9psyCXK.js → chunk-KEIR6QF5-BuyuzJJL.js} +0 -0
  223. /package/dist/assets/{chunk-Y2CYZVJY-D1mAU_Po.js → chunk-Y2CYZVJY-D_B2ZRNt.js} +0 -0
  224. /package/dist/assets/{config-hints-nV5HPOvq.js → config-hints-BcfVUMij.js} +0 -0
  225. /package/dist/assets/{cytoscape.esm-0uDtdD0l.js → cytoscape.esm-BANTlgza.js} +0 -0
  226. /package/dist/assets/{defaultLocale-DSWXGgt0.js → defaultLocale-C4_L0aEs.js} +0 -0
  227. /package/dist/assets/{dist--ta5rX12.js → dist-DAPEIJbz.js} +0 -0
  228. /package/dist/assets/{graphlib-CQ6QV4yP.js → graphlib-ChqXg0dI.js} +0 -0
  229. /package/dist/assets/{host-capabilities-Tk038i04.js → host-capabilities-D9C4CBK5.js} +0 -0
  230. /package/dist/assets/{init-Y6h9jGtZ.js → init-D8wZg9xq.js} +0 -0
  231. /package/dist/assets/{jszip.min-8hyJpgpx.js → jszip.min-CkbBfwAQ.js} +0 -0
  232. /package/dist/assets/{katex-ARhY9PS1.js → katex-TZJFa0J_.js} +0 -0
  233. /package/dist/assets/{middleware-DXsbf9xI.js → middleware-B3k-TSmZ.js} +0 -0
  234. /package/dist/assets/{path-10BjdyLh.js → path-DodfxcX7.js} +0 -0
  235. /package/dist/assets/{rough.esm-DxgC_14r.js → rough.esm-CUaa1Rbe.js} +0 -0
  236. /package/dist/assets/{xlsx-DrDuDNAa.js → xlsx-CxByi7bR.js} +0 -0
@@ -1,13 +1,18 @@
1
- import type { PointerEvent } from "react";
1
+ import { useState, type PointerEvent } from "react";
2
2
  import {
3
+ AppWindow,
3
4
  ArrowLeft,
4
5
  ArrowRight,
6
+ BookOpen,
7
+ Boxes,
8
+ Github,
5
9
  PanelRightOpen,
6
10
  PictureInPicture2,
7
11
  Pin,
8
12
  PinOff,
9
13
  Plus,
10
14
  X,
15
+ type LucideIcon,
11
16
  } from "lucide-react";
12
17
  import type { DocBrowserDockState, DocBrowserTab } from "./doc-browser-context";
13
18
  import type { ContextMenuGroup } from "@/shared/components/ui/context-menu/context-menu";
@@ -39,6 +44,68 @@ type DocBrowserTabStripProps = {
39
44
  getTabMenuGroups?: (tab: DocBrowserTab) => readonly ContextMenuGroup[] | undefined;
40
45
  };
41
46
 
47
+ const DOC_BROWSER_BUILTIN_TAB_ICONS: Record<string, LucideIcon> = {
48
+ apps: Boxes,
49
+ docs: BookOpen,
50
+ github: Github,
51
+ "new-tab": Plus,
52
+ "panel-app": AppWindow,
53
+ "service-apps": AppWindow,
54
+ };
55
+
56
+ function DocBrowserUrlTabIcon({
57
+ fallbackIcon: FallbackIcon,
58
+ url,
59
+ }: {
60
+ fallbackIcon: LucideIcon;
61
+ url: string;
62
+ }) {
63
+ const [loadFailed, setLoadFailed] = useState(false);
64
+ return loadFailed ? (
65
+ <FallbackIcon className="h-3.5 w-3.5 text-muted-foreground" aria-hidden="true" />
66
+ ) : (
67
+ <img
68
+ src={url}
69
+ alt=""
70
+ className="h-3.5 w-3.5 rounded-sm object-cover"
71
+ onError={() => setLoadFailed(true)}
72
+ />
73
+ );
74
+ }
75
+
76
+ function DocBrowserTabIcon({ tab }: { tab: DocBrowserTab }) {
77
+ const { dockIcon } = tab;
78
+ const fallbackIcon = tab.kind === "docs"
79
+ ? BookOpen
80
+ : tab.kind === "home"
81
+ ? Plus
82
+ : tab.kind === "apps"
83
+ ? Boxes
84
+ : AppWindow;
85
+ const Icon = dockIcon?.type === "builtin"
86
+ ? (DOC_BROWSER_BUILTIN_TAB_ICONS[dockIcon.name] ?? fallbackIcon)
87
+ : fallbackIcon;
88
+
89
+ if (dockIcon?.type === "url") {
90
+ return (
91
+ <DocBrowserUrlTabIcon
92
+ key={dockIcon.url}
93
+ fallbackIcon={fallbackIcon}
94
+ url={dockIcon.url}
95
+ />
96
+ );
97
+ }
98
+ if (dockIcon?.type === "text") {
99
+ return (
100
+ <span className="max-w-3.5 truncate text-[10px] font-semibold leading-none" aria-hidden="true">
101
+ {dockIcon.value}
102
+ </span>
103
+ );
104
+ }
105
+
106
+ return <Icon className="h-3.5 w-3.5 text-muted-foreground" aria-hidden="true" />;
107
+ }
108
+
42
109
  function shouldBlockHeaderDrag(target: EventTarget | null): boolean {
43
110
  return target instanceof Element && Boolean(
44
111
  target.closest("button, a, input, textarea, select, [data-compact-tab-item]"),
@@ -80,8 +147,9 @@ export function DocBrowserTabStrip({
80
147
  label: tab.title || t("docBrowserTabUntitled"),
81
148
  active: tab.id === activeTabId,
82
149
  tooltip: tab.title,
150
+ leadingIcon: <DocBrowserTabIcon tab={tab} />,
83
151
  closeLabel: closeTabLabel,
84
- closePlacement: "trailing",
152
+ closePlacement: "leading-hover",
85
153
  onSelect: () => onSetActiveTab(tab.id),
86
154
  onClose: () => onCloseTab(tab.id),
87
155
  menuLabel: t("docBrowserTabMoreActions"),
@@ -132,7 +200,7 @@ export function DocBrowserTabStrip({
132
200
  tabsClassName="items-center gap-0.5"
133
201
  actionsClassName="h-full items-center gap-0.5"
134
202
  actionButtonClassName="rounded-md p-1.5 text-muted-foreground hover:bg-muted/60 hover:text-foreground disabled:opacity-50"
135
- tabBaseClassName="group inline-flex min-w-0 cursor-pointer items-center gap-0.5 h-7 px-2 rounded-md text-xs max-w-[220px] shrink-0 transition-colors"
203
+ tabBaseClassName="inline-flex cursor-pointer items-center gap-0.5 h-7 px-2 rounded-md text-xs max-w-[220px] shrink-0 transition-colors"
136
204
  activeTabClassName="bg-muted/80 text-foreground"
137
205
  inactiveTabClassName="text-muted-foreground hover:bg-muted/45 hover:text-foreground"
138
206
  labelClassName="px-0.5 text-xs font-normal"
@@ -113,7 +113,7 @@ describe("CompactTabStrip", () => {
113
113
  active: false,
114
114
  closeLabel: "Close preview",
115
115
  closePlacement: "leading-hover",
116
- leadingIcon: <span />,
116
+ leadingIcon: <span data-testid="preview-tab-icon" />,
117
117
  onClose,
118
118
  onSelect,
119
119
  },
@@ -126,6 +126,83 @@ describe("CompactTabStrip", () => {
126
126
 
127
127
  expect(onClose).toHaveBeenCalledTimes(1);
128
128
  expect(onSelect).not.toHaveBeenCalled();
129
+ expect(
130
+ screen.getByTestId("preview-tab-icon").parentElement?.className,
131
+ ).toContain("group-hover:opacity-0");
132
+ });
133
+
134
+ it("overlays the close action at the start without changing the tab width on hover", () => {
135
+ render(
136
+ <CompactTabStrip
137
+ tabs={[
138
+ {
139
+ key: "marketplace",
140
+ label: "NextClaw Marketplace",
141
+ active: true,
142
+ closeLabel: "Close tab",
143
+ closePlacement: "leading-hover",
144
+ menuLabel: "More tab actions",
145
+ menuGroups: [{ key: "tab", items: [{ key: "close", label: "Close", onSelect: vi.fn() }] }],
146
+ onClose: vi.fn(),
147
+ onSelect: vi.fn(),
148
+ },
149
+ ]}
150
+ actions={[]}
151
+ />,
152
+ );
153
+
154
+ const tabItem = screen.getByRole("button", { name: "NextClaw Marketplace" })
155
+ .closest("[data-compact-tab-item]");
156
+ const leadingActions = tabItem?.querySelector(
157
+ '[data-compact-tab-leading-actions=""]',
158
+ );
159
+ const trailingActions = tabItem?.querySelector(
160
+ '[data-compact-tab-trailing-actions=""]',
161
+ );
162
+ const trailingSpacer = tabItem?.querySelector(
163
+ '[data-compact-tab-trailing-spacer=""]',
164
+ );
165
+ const leadingSlot = tabItem?.querySelector(
166
+ '[data-compact-tab-leading-slot=""]',
167
+ );
168
+
169
+ expect(tabItem?.className).toContain("relative");
170
+ expect(tabItem?.className).toContain("max-w-[180px]");
171
+ expect(tabItem?.className).not.toContain("min-w-[");
172
+ expect(leadingSlot?.className).toContain("w-3.5");
173
+ expect(leadingSlot?.className).toContain("shrink-0");
174
+ expect(leadingActions?.className).toContain("absolute");
175
+ expect(leadingActions?.className).toContain("left-1");
176
+ expect(leadingActions?.className).toContain("opacity-0");
177
+ expect(leadingActions?.className).toContain("pointer-events-none");
178
+ expect(leadingActions?.className).not.toContain("bg-inherit");
179
+ expect(leadingActions?.className).toContain("group-hover:opacity-100");
180
+ expect(leadingActions?.className).toContain("group-focus-within:opacity-100");
181
+ expect(trailingActions?.className).toContain("absolute");
182
+ expect(trailingActions?.className).toContain("opacity-0");
183
+ expect(trailingActions?.className).toContain("pointer-events-none");
184
+ expect(trailingActions?.className).not.toContain("bg-inherit");
185
+ expect(trailingActions?.className).toContain("group-hover:opacity-100");
186
+ expect(trailingActions?.className).toContain("group-focus-within:opacity-100");
187
+ expect(trailingActions?.className).not.toContain("w-0");
188
+ expect(trailingActions?.className).not.toContain("transition-[width");
189
+ expect(trailingSpacer?.className).toContain("w-6");
190
+ expect(trailingSpacer?.className).toContain("shrink-0");
191
+ const closeButton = leadingActions?.querySelector<HTMLButtonElement>(
192
+ '[aria-label="Close tab"]',
193
+ );
194
+ const menuButton = trailingActions?.querySelector<HTMLButtonElement>(
195
+ '[aria-label="More tab actions"]',
196
+ );
197
+ expect(closeButton).toBeTruthy();
198
+ expect(menuButton).toBeTruthy();
199
+ expect(closeButton?.className).toBe(menuButton?.className);
200
+ expect(closeButton?.className).toContain("h-6");
201
+ expect(closeButton?.className).toContain("w-6");
202
+ expect(closeButton?.className).toContain("rounded-md");
203
+ expect(
204
+ trailingActions?.querySelector('[aria-label="Close tab"]'),
205
+ ).toBeNull();
129
206
  });
130
207
 
131
208
  it("opens a tab action menu without selecting the tab or restoring stale focus after an action", async () => {
@@ -1,6 +1,9 @@
1
1
  import * as React from "react";
2
2
  import { MoreVertical, X } from "lucide-react";
3
- import { IconActionButton } from "@/shared/components/ui/actions/icon-action-button";
3
+ import {
4
+ IconActionButton,
5
+ type IconActionButtonProps,
6
+ } from "@/shared/components/ui/actions/icon-action-button";
4
7
  import {
5
8
  ContextMenu,
6
9
  ContextMenuTrigger,
@@ -63,28 +66,94 @@ function closeCompactTab(event: React.MouseEvent<HTMLButtonElement>, onClose: ()
63
66
  onClose();
64
67
  }
65
68
 
69
+ function CompactTabActionButton(props: IconActionButtonProps) {
70
+ return <IconActionButton {...props} size="sm" tone="strong" />;
71
+ }
72
+
66
73
  function CompactTabMenu({ tab }: { tab: CompactTabStripTab }) {
67
74
  if (!tab.menuGroups?.some((group) => group.items.length > 0)) {
68
75
  return null;
69
76
  }
70
77
 
71
78
  const menuLabel = tab.menuLabel ?? tab.label;
79
+ return (
80
+ <div className="flex shrink-0">
81
+ <ContextMenuTrigger>
82
+ <CompactTabActionButton
83
+ icon={<MoreVertical className="h-3.5 w-3.5" />}
84
+ label={menuLabel}
85
+ />
86
+ </ContextMenuTrigger>
87
+ </div>
88
+ );
89
+ }
90
+
91
+ function CompactTabTrailingActions({ tab }: { tab: CompactTabStripTab }) {
92
+ const hasMenu = tab.menuGroups?.some((group) => group.items.length > 0) ?? false;
93
+ const hasTrailingClose = Boolean(
94
+ tab.onClose && tab.closePlacement !== "leading-hover",
95
+ );
96
+ const close = hasTrailingClose ? (
97
+ <CompactTabActionButton
98
+ icon={<X className="h-3.5 w-3.5" />}
99
+ label={tab.closeLabel ?? ""}
100
+ tooltip={tab.closeLabel ?? null}
101
+ onClick={(event) => closeCompactTab(event, tab.onClose!)}
102
+ />
103
+ ) : null;
104
+
105
+ if (!hasMenu && !hasTrailingClose) {
106
+ return null;
107
+ }
108
+
109
+ return (
110
+ <>
111
+ <span
112
+ aria-hidden="true"
113
+ data-compact-tab-trailing-spacer=""
114
+ className={cn(
115
+ "shrink-0",
116
+ hasMenu && hasTrailingClose
117
+ ? "w-[50px]"
118
+ : hasMenu
119
+ ? "w-6"
120
+ : "w-6",
121
+ )}
122
+ />
123
+ <div
124
+ data-compact-tab-trailing-actions=""
125
+ className={cn(
126
+ "pointer-events-none absolute inset-y-0 right-1 z-10 flex items-center gap-0.5 opacity-0",
127
+ "group-hover:pointer-events-auto group-hover:opacity-100 group-focus-within:pointer-events-auto group-focus-within:opacity-100",
128
+ "group-data-[context-menu-open]:pointer-events-auto group-data-[context-menu-open]:opacity-100",
129
+ )}
130
+ >
131
+ {hasMenu ? <CompactTabMenu tab={tab} /> : null}
132
+ {close}
133
+ </div>
134
+ </>
135
+ );
136
+ }
137
+
138
+ function CompactTabLeadingCloseOverlay({ tab }: { tab: CompactTabStripTab }) {
139
+ if (!tab.onClose || tab.closePlacement !== "leading-hover") {
140
+ return null;
141
+ }
142
+
72
143
  return (
73
144
  <div
145
+ data-compact-tab-leading-actions=""
74
146
  className={cn(
75
- "-ml-1.5 flex w-0 shrink-0 overflow-hidden opacity-0 transition-[width,margin,opacity] group-hover:ml-0 group-hover:w-5 group-hover:opacity-100 group-focus-within:ml-0 group-focus-within:w-5 group-focus-within:opacity-100",
76
- "group-data-[context-menu-open]:ml-0 group-data-[context-menu-open]:w-5 group-data-[context-menu-open]:opacity-100",
147
+ "pointer-events-none absolute inset-y-0 left-1 z-10 flex items-center opacity-0",
148
+ "group-hover:pointer-events-auto group-hover:opacity-100 group-focus-within:pointer-events-auto group-focus-within:opacity-100",
77
149
  )}
78
150
  >
79
- <ContextMenuTrigger>
80
- <button
81
- type="button"
82
- aria-label={menuLabel}
83
- className="inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-md text-gray-400 transition-colors hover:bg-gray-200 hover:text-gray-700 focus-visible:bg-gray-200 focus-visible:text-gray-700 focus-visible:outline-none"
84
- >
85
- <MoreVertical className="h-3.5 w-3.5" />
86
- </button>
87
- </ContextMenuTrigger>
151
+ <CompactTabActionButton
152
+ icon={<X className="h-3.5 w-3.5" />}
153
+ label={tab.closeLabel ?? ""}
154
+ tooltip={tab.closeLabel ?? null}
155
+ onClick={(event) => closeCompactTab(event, tab.onClose!)}
156
+ />
88
157
  </div>
89
158
  );
90
159
  }
@@ -96,9 +165,9 @@ function CompactTabLabelButton({
96
165
  labelClassName?: string;
97
166
  tab: CompactTabStripTab;
98
167
  }) {
99
- const leadingIcon = tab.onClose && tab.closePlacement === "leading-hover"
100
- ? null
101
- : tab.leadingIcon;
168
+ const hasLeadingClose = Boolean(
169
+ tab.onClose && tab.closePlacement === "leading-hover",
170
+ );
102
171
  const button = (
103
172
  <button
104
173
  type="button"
@@ -106,9 +175,15 @@ function CompactTabLabelButton({
106
175
  aria-label={tab.label}
107
176
  className="flex min-w-0 flex-1 items-center gap-1.5 text-left"
108
177
  >
109
- {leadingIcon ? (
110
- <span className="inline-flex shrink-0 items-center justify-center">
111
- {leadingIcon}
178
+ {tab.leadingIcon || hasLeadingClose ? (
179
+ <span
180
+ data-compact-tab-leading-slot=""
181
+ className={cn(
182
+ "inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center",
183
+ hasLeadingClose && "group-hover:opacity-0 group-focus-within:opacity-0",
184
+ )}
185
+ >
186
+ {tab.leadingIcon}
112
187
  </span>
113
188
  ) : null}
114
189
  <span className={cn("min-w-0 truncate text-[12px] font-medium", labelClassName, tab.labelClassName)}>
@@ -150,7 +225,6 @@ function CompactTabItem({
150
225
  | "labelClassName"
151
226
  | "tabBaseClassName"
152
227
  > & { itemRef?: React.Ref<HTMLDivElement>; tab: CompactTabStripTab }) {
153
- const leadingClose = tab.onClose && tab.closePlacement === "leading-hover";
154
228
  const item = (
155
229
  <div
156
230
  ref={itemRef}
@@ -158,38 +232,17 @@ function CompactTabItem({
158
232
  onClick={(event) => event.target === event.currentTarget && tab.onSelect()}
159
233
  className={cn(
160
234
  tabBaseClassName ??
161
- "group flex max-w-[180px] min-w-0 cursor-pointer items-center gap-1.5 border-r border-gray-200/70 border-b-2 px-2.5 py-2 transition-colors",
235
+ "flex max-w-[180px] cursor-pointer items-center gap-1.5 border-r border-gray-200/70 border-b-2 px-2.5 py-2 transition-colors",
236
+ "group relative",
162
237
  tab.active
163
238
  ? (activeTabClassName ?? "border-b-primary bg-white text-gray-900")
164
239
  : (inactiveTabClassName ??
165
240
  "border-b-transparent bg-gray-50/85 text-gray-500 hover:bg-gray-100"),
166
241
  )}
167
242
  >
168
- {leadingClose ? (
169
- <button
170
- type="button"
171
- onClick={(event) => closeCompactTab(event, tab.onClose!)}
172
- className="relative inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-md text-gray-400 transition-colors hover:bg-gray-200 hover:text-gray-700"
173
- aria-label={tab.closeLabel}
174
- >
175
- <span className="flex items-center justify-center group-hover:hidden">
176
- {tab.leadingIcon}
177
- </span>
178
- <X className="hidden h-3.5 w-3.5 group-hover:block" />
179
- </button>
180
- ) : null}
181
243
  <CompactTabLabelButton tab={tab} labelClassName={labelClassName} />
182
- <CompactTabMenu tab={tab} />
183
- {tab.onClose && tab.closePlacement !== "leading-hover" ? (
184
- <IconActionButton
185
- size="sm"
186
- tone="strong"
187
- icon={<X className="h-3 w-3" />}
188
- label={tab.closeLabel ?? ""}
189
- tooltip={tab.closeLabel ?? null}
190
- onClick={(event) => closeCompactTab(event, tab.onClose!)}
191
- />
192
- ) : null}
244
+ <CompactTabLeadingCloseOverlay tab={tab} />
245
+ <CompactTabTrailingActions tab={tab} />
193
246
  </div>
194
247
  );
195
248
 
@@ -183,6 +183,7 @@ describe('ncp-session-query-cache', () => {
183
183
  it('applies realtime upsert/delete events to every ncp-sessions query cache entry', () => {
184
184
  const queryClient = new QueryClient();
185
185
  queryClient.setQueryData(['ncp-sessions', 200], createSessionsList());
186
+ queryClient.setQueryData(['ncp-session-token-usage', 'session-3'], { runCount: 1 });
186
187
 
187
188
  applyNcpSessionRealtimeEvent(queryClient, {
188
189
  type: 'session.run-status',
@@ -212,6 +213,7 @@ describe('ncp-session-query-cache', () => {
212
213
  expect(
213
214
  queryClient.getQueryData<NcpSessionsListView>(['ncp-sessions', 200])?.sessions.map((session) => session.sessionId)
214
215
  ).toEqual(['session-3', 'session-1', 'session-2']);
216
+ expect(queryClient.getQueryState(['ncp-session-token-usage', 'session-3'])?.isInvalidated).toBe(true);
215
217
 
216
218
  applyNcpSessionRealtimeEvent(queryClient, {
217
219
  type: 'session.summary.delete',
@@ -155,6 +155,10 @@ export function applyNcpSessionRealtimeEvent(
155
155
  }
156
156
  if (event.type === 'session.summary.upsert') {
157
157
  upsertNcpSessionSummaryInQueryClient(queryClient, event.payload.summary);
158
+ void queryClient?.invalidateQueries({
159
+ queryKey: ['ncp-session-token-usage', event.payload.summary.sessionId],
160
+ exact: true,
161
+ });
158
162
  return;
159
163
  }
160
164
 
@@ -4,6 +4,7 @@ import type {
4
4
  NcpSessionStatus,
5
5
  NcpSessionSummary,
6
6
  } from "@nextclaw/ncp";
7
+ import type { UiNcpSessionTokenUsageView } from "@nextclaw/client-sdk";
7
8
  import type { ThinkingLevel } from "./types";
8
9
 
9
10
  export type SessionTypeIconView = {
@@ -114,3 +115,5 @@ export type NcpSessionMessagesView = {
114
115
  total: number;
115
116
  pageInfo: NcpSessionMessagePageInfo;
116
117
  };
118
+
119
+ export type NcpSessionTokenUsageView = UiNcpSessionTokenUsageView;
@@ -24,6 +24,7 @@ export type {
24
24
  NcpSessionsListView,
25
25
  NcpMessageView,
26
26
  NcpSessionMessagesView,
27
+ NcpSessionTokenUsageView,
27
28
  SessionContextWindowView,
28
29
  } from './ncp-session.types';
29
30
 
@@ -1,6 +1,7 @@
1
1
  import { nextclawClient } from "@/shared/lib/api/managers/client.manager";
2
2
  import type {
3
3
  NcpSessionMessagesView,
4
+ NcpSessionTokenUsageView,
4
5
  NcpSessionSkillsView,
5
6
  NcpSessionsListView,
6
7
  NcpSessionSummaryView,
@@ -26,6 +27,13 @@ export async function fetchNcpSessionMessages(
26
27
  )) as NcpSessionMessagesView;
27
28
  }
28
29
 
30
+ // GET /api/ncp/sessions/:sessionId/usage
31
+ export async function fetchNcpSessionTokenUsage(
32
+ sessionId: string,
33
+ ): Promise<NcpSessionTokenUsageView> {
34
+ return (await nextclawClient.sessions.getUsage(sessionId)) as NcpSessionTokenUsageView;
35
+ }
36
+
29
37
  // GET /api/ncp/sessions/:sessionId/skills
30
38
  export async function fetchNcpSessionSkills(
31
39
  sessionId: string,
@@ -49,8 +49,27 @@
49
49
  "chatWorkspaceClosePanel": "Close workspace panel",
50
50
  "chatWorkspaceOverview": "Overview",
51
51
  "chatWorkspaceOverviewDescription": "Open this session's related conversations, scheduled work, and project files.",
52
+ "chatWorkspaceTokenUsage": "Token usage",
53
+ "chatWorkspaceTokenUsageDescription": "Counts this session's own AI runs. Cached input is included in input tokens; the hit rate is cached reads divided by all input.",
54
+ "chatWorkspaceTokenUsageLoading": "Calculating token usage…",
55
+ "chatWorkspaceTokenUsageLoadFailed": "Couldn’t load token usage.",
56
+ "chatWorkspaceTokenUsageRetry": "Retry",
57
+ "chatWorkspaceTokenUsageEmpty": "This session has no token usage to show yet. Some models and older runs may not report usage.",
58
+ "chatWorkspaceTokenUsageTotal": "Total tokens",
59
+ "chatWorkspaceTokenUsageInput": "Input",
60
+ "chatWorkspaceTokenUsageOutput": "Output",
61
+ "chatWorkspaceTokenUsageCachedInput": "Cached input",
62
+ "chatWorkspaceTokenUsageCacheHitRate": "Cache hit rate",
63
+ "chatWorkspaceTokenUsageRuns": "AI runs",
64
+ "chatWorkspaceTokenUsageByModel": "By model",
65
+ "chatWorkspaceTokenUsageModelRunCount": "Runs: {count}",
66
+ "chatWorkspaceTokenUsageModelCacheHitRate": "Cache hit rate: {rate}",
67
+ "chatWorkspaceTokenUsageReported": "Usage reported",
68
+ "chatWorkspaceTokenUsagePartial": "Partial usage",
69
+ "chatWorkspaceTokenUsageUnavailable": "Usage unavailable",
52
70
  "chatWorkspaceChildSessionsDescription": "Review the child sessions created from this conversation.",
53
71
  "chatWorkspaceChildSessionsEmpty": "No child sessions yet.",
72
+ "chatWorkspaceCreateChildSession": "New child session",
54
73
  "chatWorkspaceSessionCronJobsDescription": "Review scheduled tasks associated with this session.",
55
74
  "chatWorkspaceProjectFiles": "Project files",
56
75
  "chatWorkspaceShowProjectFiles": "Show project files",
@@ -277,6 +296,10 @@
277
296
  "chatSlashCommandCompactContextDetail": "Keeps the latest turn and the active task available for continuation.",
278
297
  "chatSlashCommandCompactContextSuccess": "Context compacted",
279
298
  "chatSlashCommandCompactContextFailed": "Couldn't compact context",
299
+ "chatSlashCommandUpdateSessionTitleTitle": "Update session title",
300
+ "chatSlashCommandUpdateSessionTitleDescription": "Ask AI to create a concise title from this conversation and update the session.",
301
+ "chatSlashCommandUpdateSessionTitleDetail": "Sends a message automatically without replacing your current draft.",
302
+ "chatSlashCommandUpdateSessionTitlePrompt": "Create a concise, accurate title based on this conversation, then use the sessions_update tool to update the current session title now. Do not only suggest a title.",
280
303
  "chatSlashPanelAppHint": "Press Enter to open this panel app on the right.",
281
304
  "chatSlashSkillHint": "Press Enter to add this skill for the next turn.",
282
305
  "chatPanelAppReferenceLoading": "Loading panel apps...",
@@ -49,8 +49,27 @@
49
49
  "chatWorkspaceClosePanel": "关闭工作区侧栏",
50
50
  "chatWorkspaceOverview": "概览",
51
51
  "chatWorkspaceOverviewDescription": "查看与当前会话相关的子会话、定时任务和项目文件。",
52
+ "chatWorkspaceTokenUsage": "Token 用量",
53
+ "chatWorkspaceTokenUsageDescription": "统计当前会话自身的 AI 运行。缓存输入已包含在输入 Token 中;命中率为缓存读取占全部输入的比例。",
54
+ "chatWorkspaceTokenUsageLoading": "正在统计 Token 用量…",
55
+ "chatWorkspaceTokenUsageLoadFailed": "Token 用量加载失败。",
56
+ "chatWorkspaceTokenUsageRetry": "重试",
57
+ "chatWorkspaceTokenUsageEmpty": "当前会话还没有可统计的 Token 用量。部分模型或旧运行可能不会报告用量。",
58
+ "chatWorkspaceTokenUsageTotal": "总 Token",
59
+ "chatWorkspaceTokenUsageInput": "输入",
60
+ "chatWorkspaceTokenUsageOutput": "输出",
61
+ "chatWorkspaceTokenUsageCachedInput": "缓存输入",
62
+ "chatWorkspaceTokenUsageCacheHitRate": "缓存命中率",
63
+ "chatWorkspaceTokenUsageRuns": "AI 运行",
64
+ "chatWorkspaceTokenUsageByModel": "按模型",
65
+ "chatWorkspaceTokenUsageModelRunCount": "{count} 次运行",
66
+ "chatWorkspaceTokenUsageModelCacheHitRate": "缓存命中率 {rate}",
67
+ "chatWorkspaceTokenUsageReported": "用量已报告",
68
+ "chatWorkspaceTokenUsagePartial": "部分用量",
69
+ "chatWorkspaceTokenUsageUnavailable": "用量不可用",
52
70
  "chatWorkspaceChildSessionsDescription": "查看从当前会话创建的子会话。",
53
71
  "chatWorkspaceChildSessionsEmpty": "当前还没有子会话。",
72
+ "chatWorkspaceCreateChildSession": "新建子会话",
54
73
  "chatWorkspaceSessionCronJobsDescription": "查看与当前会话关联的定时任务。",
55
74
  "chatWorkspaceProjectFiles": "项目文件",
56
75
  "chatWorkspaceShowProjectFiles": "展开项目文件",
@@ -59,7 +78,7 @@
59
78
  "chatWorkspaceProjectFilesDescription": "浏览已选项目目录中的文件。",
60
79
  "chatWorkspaceProjectFilesUnavailable": "请先选择项目目录,再浏览其中的文件。",
61
80
  "chatWorkspaceSideChatDraftTitle": "侧边对话",
62
- "chatWorkspaceSideChatDraftSubtitle": "发送第一条消息后,会继承父会话上下文并创建真实 child 会话。",
81
+ "chatWorkspaceSideChatDraftSubtitle": "发送第一条消息后,会继承父会话上下文并创建真实子会话。",
63
82
  "chatWorkspaceChildSessions": "子会话",
64
83
  "chatWorkspaceOpen": "打开",
65
84
  "chatWorkspaceOpenFiles": "打开的文件",
@@ -277,6 +296,10 @@
277
296
  "chatSlashCommandCompactContextDetail": "保留最近一轮和当前任务,供后续继续处理。",
278
297
  "chatSlashCommandCompactContextSuccess": "上下文已压缩",
279
298
  "chatSlashCommandCompactContextFailed": "无法压缩上下文",
299
+ "chatSlashCommandUpdateSessionTitleTitle": "更新会话标题",
300
+ "chatSlashCommandUpdateSessionTitleDescription": "让 AI 根据当前会话内容生成简洁标题并完成更新。",
301
+ "chatSlashCommandUpdateSessionTitleDetail": "命令会自动发送一条消息,不会覆盖输入框中的草稿。",
302
+ "chatSlashCommandUpdateSessionTitlePrompt": "请根据当前会话内容生成一个简洁、准确的标题,然后立即使用 sessions_update 工具更新当前会话标题。不要只给出标题建议。",
280
303
  "chatSlashPanelAppHint": "回车在右侧打开这个面板应用。",
281
304
  "chatSlashSkillHint": "回车把该技能加入本轮请求。",
282
305
  "chatPanelAppReferenceLoading": "加载面板应用中…",
@@ -1 +0,0 @@
1
- import"./chunk-KEIR6QF5-f9psyCXK.js";import{n as e}from"./chunk-MOZMSUNE-PfyK9w1-.js";export{e as createArchitectureServices};
@@ -1 +0,0 @@
1
- import{at as e,ot as t}from"./chunk-WYO6CB5R-Dn9To_OI.js";var n=(n,r)=>t.lang.round(e.parse(n)[r]);export{n as t};
@@ -1 +0,0 @@
1
- import{n as e}from"./chunk-Y2CYZVJY-D1mAU_Po.js";var t=class{constructor(e){this.init=e,this.records=this.init()}static{e(this,`ImperativeState`)}reset(){this.records=this.init()}};export{t};
@@ -1 +0,0 @@
1
- import{n as e}from"./chunk-Y2CYZVJY-D1mAU_Po.js";import{p as t}from"./src-Bw-mzbQb.js";import{x as n}from"./chunk-WYO6CB5R-Dn9To_OI.js";var r=e(e=>{let{securityLevel:r}=n(),i=t(`body`);return r===`sandbox`&&(i=t((t(`#i${e}`).node()?.contentDocument??document).body)),i.select(`#${e}`)},`selectSvgElement`);export{r as t};
@@ -1 +0,0 @@
1
- import{n as e}from"./chunk-Y2CYZVJY-D1mAU_Po.js";import{p as t}from"./src-Bw-mzbQb.js";var n=e((e,n)=>{let r;return n===`sandbox`&&(r=t(`#i`+e)),t(n===`sandbox`?r.nodes()[0].contentDocument.body:`body`).select(`[id="${e}"]`)},`getDiagramElement`);export{n as t};
@@ -1 +0,0 @@
1
- import{n as e}from"./chunk-Y2CYZVJY-D1mAU_Po.js";import"./src-Bw-mzbQb.js";import"./chunk-WYO6CB5R-Dn9To_OI.js";import"./chunk-ICXQ74PX-FAatv5fC.js";import"./chunk-HOUHSVGY-DPkq8FCm.js";import"./chunk-Q4XR5HBZ-DQFeUPxZ.js";import"./chunk-7BUUIJ7U-BvydOcm3.js";import"./chunk-OGEWGWER-C3jdH3Ty.js";import"./chunk-32BRIVSS-7NrjEITq.js";import"./chunk-XXDRQBXY-DaBxG5gs.js";import"./chunk-VR4S4FIN-B7AHEYYk.js";import"./chunk-C7G6YPKG-DAizzYwr.js";import"./chunk-ZGVPDNZ5-C6YtZDU0.js";import"./chunk-52WLFC77-viIcqj9q.js";import"./chunk-FWX5IMBZ-D0ksHZZ9.js";import{i as t,n,r,t as i}from"./chunk-V7JOEXUC-CZ70oOtp.js";var a={parser:n,get db(){return new i},renderer:r,styles:t,init:e(e=>{e.class||={},e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};
@@ -1 +0,0 @@
1
- import{n as e}from"./chunk-Y2CYZVJY-D1mAU_Po.js";import"./src-Bw-mzbQb.js";import"./chunk-WYO6CB5R-Dn9To_OI.js";import"./chunk-ICXQ74PX-FAatv5fC.js";import"./chunk-HOUHSVGY-DPkq8FCm.js";import"./chunk-Q4XR5HBZ-DQFeUPxZ.js";import"./chunk-7BUUIJ7U-BvydOcm3.js";import"./chunk-OGEWGWER-C3jdH3Ty.js";import"./chunk-32BRIVSS-7NrjEITq.js";import"./chunk-XXDRQBXY-DaBxG5gs.js";import"./chunk-VR4S4FIN-B7AHEYYk.js";import"./chunk-C7G6YPKG-DAizzYwr.js";import"./chunk-ZGVPDNZ5-C6YtZDU0.js";import"./chunk-52WLFC77-viIcqj9q.js";import"./chunk-FWX5IMBZ-D0ksHZZ9.js";import{i as t,n,r,t as i}from"./chunk-V7JOEXUC-CZ70oOtp.js";var a={parser:n,get db(){return new i},renderer:r,styles:t,init:e(e=>{e.class||={},e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};
@@ -1 +0,0 @@
1
- import"./chunk-KEIR6QF5-f9psyCXK.js";import{n as e}from"./chunk-OSBZ3O6U-CecHo-f0.js";export{e as createCynefinServices};
@@ -1 +0,0 @@
1
- import{t as e}from"./doc-browser-Crqog5cn.js";export{e as DocBrowser};