@zythum02/fello-server 0.1.51 → 0.1.53

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 (377) hide show
  1. package/out/renderer/assets/{_baseUniq-DdWCC-Go.js → _baseUniq-CJr3HkLS.js} +1 -1
  2. package/out/renderer/assets/_baseUniq-CJr3HkLS.js.br +0 -0
  3. package/out/renderer/assets/_baseUniq-CJr3HkLS.js.gz +0 -0
  4. package/out/renderer/assets/{arc-B_en4gJt.js → arc-POsBroTF.js} +1 -1
  5. package/out/renderer/assets/arc-POsBroTF.js.br +0 -0
  6. package/out/renderer/assets/arc-POsBroTF.js.gz +0 -0
  7. package/out/renderer/assets/{architectureDiagram-Q4EWVU46-W-l3dTvZ.js → architectureDiagram-Q4EWVU46-CmToUhDb.js} +6 -6
  8. package/out/renderer/assets/architectureDiagram-Q4EWVU46-CmToUhDb.js.br +0 -0
  9. package/out/renderer/assets/architectureDiagram-Q4EWVU46-CmToUhDb.js.gz +0 -0
  10. package/out/renderer/assets/{arrow-left-BwbOF_G_.js → arrow-left-CxS1t3f7.js} +1 -1
  11. package/out/renderer/assets/{automation--izxbhlj.js → automation-Cyz3eLWp.js} +7 -8
  12. package/out/renderer/assets/automation-Cyz3eLWp.js.br +0 -0
  13. package/out/renderer/assets/automation-Cyz3eLWp.js.gz +0 -0
  14. package/out/renderer/assets/{blockDiagram-DXYQGD6D-BdxXOr8Y.js → blockDiagram-DXYQGD6D-M2nnTg9f.js} +7 -7
  15. package/out/renderer/assets/blockDiagram-DXYQGD6D-M2nnTg9f.js.br +0 -0
  16. package/out/renderer/assets/blockDiagram-DXYQGD6D-M2nnTg9f.js.gz +0 -0
  17. package/out/renderer/assets/{c4Diagram-AHTNJAMY-C_8XgPtT.js → c4Diagram-AHTNJAMY-CwLtsy_0.js} +3 -3
  18. package/out/renderer/assets/c4Diagram-AHTNJAMY-CwLtsy_0.js.br +0 -0
  19. package/out/renderer/assets/c4Diagram-AHTNJAMY-CwLtsy_0.js.gz +0 -0
  20. package/out/renderer/assets/{channel-BsSLbHzl.js → channel-BUNDMqpH.js} +1 -1
  21. package/out/renderer/assets/{chunk-4BX2VUAB-CADGLBio.js → chunk-4BX2VUAB-B2qXmkDT.js} +1 -1
  22. package/out/renderer/assets/{chunk-4TB4RGXK-C7h57GNs.js → chunk-4TB4RGXK-DXLZpPY5.js} +5 -5
  23. package/out/renderer/assets/chunk-4TB4RGXK-DXLZpPY5.js.br +0 -0
  24. package/out/renderer/assets/chunk-4TB4RGXK-DXLZpPY5.js.gz +0 -0
  25. package/out/renderer/assets/{chunk-55IACEB6-Cw-dv2b3.js → chunk-55IACEB6-CJeyefxI.js} +1 -1
  26. package/out/renderer/assets/{chunk-EDXVE4YY-BPjYyS5o.js → chunk-EDXVE4YY-CNjJEQfY.js} +1 -1
  27. package/out/renderer/assets/chunk-EDXVE4YY-CNjJEQfY.js.br +0 -0
  28. package/out/renderer/assets/chunk-EDXVE4YY-CNjJEQfY.js.gz +0 -0
  29. package/out/renderer/assets/{chunk-FMBD7UC4-DhJ5Z89u.js → chunk-FMBD7UC4-DOAOsjRu.js} +1 -1
  30. package/out/renderer/assets/{chunk-OYMX7WX6-D5Q5ZCl0.js → chunk-OYMX7WX6-BG4B1VQ7.js} +3 -3
  31. package/out/renderer/assets/chunk-OYMX7WX6-BG4B1VQ7.js.br +0 -0
  32. package/out/renderer/assets/chunk-OYMX7WX6-BG4B1VQ7.js.gz +0 -0
  33. package/out/renderer/assets/{chunk-QZHKN3VN-SsM-5KS-.js → chunk-QZHKN3VN-B9zfXYIQ.js} +1 -1
  34. package/out/renderer/assets/{chunk-YZCP3GAM-AbfctYy8.js → chunk-YZCP3GAM-jeoI2tsD.js} +1 -1
  35. package/out/renderer/assets/chunk-YZCP3GAM-jeoI2tsD.js.br +0 -0
  36. package/out/renderer/assets/chunk-YZCP3GAM-jeoI2tsD.js.gz +0 -0
  37. package/out/renderer/assets/{circle-x-CxFDvVH_.js → circle-x-B1kBsMlS.js} +1 -1
  38. package/out/renderer/assets/{classDiagram-v2-HSJHXN6E-7ZGV_42k.js → classDiagram-6PBFFD2Q-DWPFF3Yt.js} +7 -7
  39. package/out/renderer/assets/{classDiagram-6PBFFD2Q-7ZGV_42k.js → classDiagram-v2-HSJHXN6E-DWPFF3Yt.js} +7 -7
  40. package/out/renderer/assets/{clone-D2_BL2Tz.js → clone-Dcvr9oKv.js} +1 -1
  41. package/out/renderer/assets/{code-editor-cp9haQUT.js → code-editor-CEXlC4aV.js} +2 -2
  42. package/out/renderer/assets/code-editor-CEXlC4aV.js.br +0 -0
  43. package/out/renderer/assets/code-editor-CEXlC4aV.js.gz +0 -0
  44. package/out/renderer/assets/{collapsible-BHMUDZxc.js → collapsible-CMuCJUWG.js} +1 -1
  45. package/out/renderer/assets/collapsible-CMuCJUWG.js.br +0 -0
  46. package/out/renderer/assets/collapsible-CMuCJUWG.js.gz +0 -0
  47. package/out/renderer/assets/{cose-bilkent-S5V4N54A-CVcE9aWV.js → cose-bilkent-S5V4N54A-B3bgImVS.js} +2 -2
  48. package/out/renderer/assets/cose-bilkent-S5V4N54A-B3bgImVS.js.br +0 -0
  49. package/out/renderer/assets/cose-bilkent-S5V4N54A-B3bgImVS.js.gz +0 -0
  50. package/out/renderer/assets/{dagre-KV5264BT-zrX-TFsi.js → dagre-KV5264BT-DTbumBA_.js} +7 -7
  51. package/out/renderer/assets/dagre-KV5264BT-DTbumBA_.js.br +0 -0
  52. package/out/renderer/assets/dagre-KV5264BT-DTbumBA_.js.gz +0 -0
  53. package/out/renderer/assets/{diagram-5BDNPKRD-Ct9NrJP9.js → diagram-5BDNPKRD-B34Y6e8q.js} +7 -7
  54. package/out/renderer/assets/diagram-5BDNPKRD-B34Y6e8q.js.br +0 -0
  55. package/out/renderer/assets/diagram-5BDNPKRD-B34Y6e8q.js.gz +0 -0
  56. package/out/renderer/assets/{diagram-G4DWMVQ6-tTGWcCd_.js → diagram-G4DWMVQ6-BBiBmFR4.js} +7 -7
  57. package/out/renderer/assets/diagram-G4DWMVQ6-BBiBmFR4.js.br +0 -0
  58. package/out/renderer/assets/diagram-G4DWMVQ6-BBiBmFR4.js.gz +0 -0
  59. package/out/renderer/assets/{diagram-MMDJMWI5-CpmcnN2B.js → diagram-MMDJMWI5-P-YslDjG.js} +6 -6
  60. package/out/renderer/assets/diagram-MMDJMWI5-P-YslDjG.js.br +0 -0
  61. package/out/renderer/assets/diagram-MMDJMWI5-P-YslDjG.js.gz +0 -0
  62. package/out/renderer/assets/{diagram-TYMM5635-DKTR2xS9.js → diagram-TYMM5635-D_cLard_.js} +6 -6
  63. package/out/renderer/assets/diagram-TYMM5635-D_cLard_.js.br +0 -0
  64. package/out/renderer/assets/diagram-TYMM5635-D_cLard_.js.gz +0 -0
  65. package/out/renderer/assets/{ellipsis-8708fodN.js → ellipsis-D1agTYu1.js} +1 -1
  66. package/out/renderer/assets/{erDiagram-SMLLAGMA-BW13EXAs.js → erDiagram-SMLLAGMA-C1MHqKvC.js} +5 -5
  67. package/out/renderer/assets/erDiagram-SMLLAGMA-C1MHqKvC.js.br +0 -0
  68. package/out/renderer/assets/erDiagram-SMLLAGMA-C1MHqKvC.js.gz +0 -0
  69. package/out/renderer/assets/{field-Be86bgEh.js → field-DR3J0r9e.js} +1 -1
  70. package/out/renderer/assets/field-DR3J0r9e.js.br +0 -0
  71. package/out/renderer/assets/field-DR3J0r9e.js.gz +0 -0
  72. package/out/renderer/assets/{file-text-CMw1QH-C.js → file-text-nGCW6zu1.js} +1 -1
  73. package/out/renderer/assets/{flowDiagram-DWJPFMVM-C3oZAKxX.js → flowDiagram-DWJPFMVM-DprlEc3Z.js} +7 -7
  74. package/out/renderer/assets/flowDiagram-DWJPFMVM-DprlEc3Z.js.br +0 -0
  75. package/out/renderer/assets/flowDiagram-DWJPFMVM-DprlEc3Z.js.gz +0 -0
  76. package/out/renderer/assets/{ganttDiagram-T4ZO3ILL-BARJrpDB.js → ganttDiagram-T4ZO3ILL-CbTdumBm.js} +3 -3
  77. package/out/renderer/assets/ganttDiagram-T4ZO3ILL-CbTdumBm.js.br +0 -0
  78. package/out/renderer/assets/ganttDiagram-T4ZO3ILL-CbTdumBm.js.gz +0 -0
  79. package/out/renderer/assets/{gitGraphDiagram-UUTBAWPF-D0gl3Row.js → gitGraphDiagram-UUTBAWPF-06bme-w8.js} +7 -7
  80. package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-06bme-w8.js.br +0 -0
  81. package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-06bme-w8.js.gz +0 -0
  82. package/out/renderer/assets/{graph-DB7hnlLW.js → graph-BZhxluo9.js} +2 -2
  83. package/out/renderer/assets/graph-BZhxluo9.js.br +0 -0
  84. package/out/renderer/assets/graph-BZhxluo9.js.gz +0 -0
  85. package/out/renderer/assets/{highlighted-body-OFNGDK62-J87DvYBX.js → highlighted-body-OFNGDK62-CvDMJtXf.js} +2 -2
  86. package/out/renderer/assets/{index-Co8mzhyV.js → index-LmYTNvdF.js} +913 -453
  87. package/out/renderer/assets/index-LmYTNvdF.js.br +0 -0
  88. package/out/renderer/assets/index-LmYTNvdF.js.gz +0 -0
  89. package/out/renderer/assets/index-aGJ_yZib.css +382 -0
  90. package/out/renderer/assets/index-aGJ_yZib.css.br +0 -0
  91. package/out/renderer/assets/index-aGJ_yZib.css.gz +0 -0
  92. package/out/renderer/assets/{infoDiagram-42DDH7IO-BrfLG_LC.js → infoDiagram-42DDH7IO-DqivEzWL.js} +5 -5
  93. package/out/renderer/assets/infoDiagram-42DDH7IO-DqivEzWL.js.br +0 -0
  94. package/out/renderer/assets/infoDiagram-42DDH7IO-DqivEzWL.js.gz +0 -0
  95. package/out/renderer/assets/{ishikawaDiagram-UXIWVN3A-CO0cyvTq.js → ishikawaDiagram-UXIWVN3A-BKcg_z4w.js} +2 -2
  96. package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-BKcg_z4w.js.br +0 -0
  97. package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-BKcg_z4w.js.gz +0 -0
  98. package/out/renderer/assets/{item-CvcokSWl.js → item-BHEUMM9H.js} +1 -1
  99. package/out/renderer/assets/item-BHEUMM9H.js.br +0 -0
  100. package/out/renderer/assets/item-BHEUMM9H.js.gz +0 -0
  101. package/out/renderer/assets/{journeyDiagram-VCZTEJTY-D3F2Iu5P.js → journeyDiagram-VCZTEJTY-Bvv8xuxQ.js} +5 -5
  102. package/out/renderer/assets/journeyDiagram-VCZTEJTY-Bvv8xuxQ.js.br +0 -0
  103. package/out/renderer/assets/journeyDiagram-VCZTEJTY-Bvv8xuxQ.js.gz +0 -0
  104. package/out/renderer/assets/{kanban-definition-6JOO6SKY-CC_drlaB.js → kanban-definition-6JOO6SKY-C-gRMpeM.js} +3 -3
  105. package/out/renderer/assets/kanban-definition-6JOO6SKY-C-gRMpeM.js.br +0 -0
  106. package/out/renderer/assets/kanban-definition-6JOO6SKY-C-gRMpeM.js.gz +0 -0
  107. package/out/renderer/assets/{layout-B_3n1To1.js → layout-B4dSyItA.js} +4 -4
  108. package/out/renderer/assets/layout-B4dSyItA.js.br +0 -0
  109. package/out/renderer/assets/layout-B4dSyItA.js.gz +0 -0
  110. package/out/renderer/assets/{linear-AxwRZ_jw.js → linear-CoVhuer7.js} +1 -1
  111. package/out/renderer/assets/linear-CoVhuer7.js.br +0 -0
  112. package/out/renderer/assets/linear-CoVhuer7.js.gz +0 -0
  113. package/out/renderer/assets/{link-2-4A51Gs15.js → link-2-DHUPzNSt.js} +1 -1
  114. package/out/renderer/assets/{mermaid-GHXKKRXX-DFOJYe_t.js → mermaid-GHXKKRXX-CZqkhGx7.js} +54 -54
  115. package/out/renderer/assets/mermaid-GHXKKRXX-CZqkhGx7.js.br +0 -0
  116. package/out/renderer/assets/mermaid-GHXKKRXX-CZqkhGx7.js.gz +0 -0
  117. package/out/renderer/assets/mic-BgSvicCB.js +22 -0
  118. package/out/renderer/assets/{min-Dip7FmOo.js → min-emzuJjmk.js} +2 -2
  119. package/out/renderer/assets/min-emzuJjmk.js.br +0 -0
  120. package/out/renderer/assets/min-emzuJjmk.js.gz +0 -0
  121. package/out/renderer/assets/{mindmap-definition-QFDTVHPH-D9aiLrpe.js → mindmap-definition-QFDTVHPH-DQ4JNECm.js} +4 -4
  122. package/out/renderer/assets/mindmap-definition-QFDTVHPH-DQ4JNECm.js.br +0 -0
  123. package/out/renderer/assets/mindmap-definition-QFDTVHPH-DQ4JNECm.js.gz +0 -0
  124. package/out/renderer/assets/{open-guide-KaWHLGYU.js → open-guide-CfLO-Sdk.js} +1 -1
  125. package/out/renderer/assets/{package-search-CNALSYvi.js → package-search-CrF2Iegl.js} +1 -1
  126. package/out/renderer/assets/{pieDiagram-DEJITSTG-BX_34lAP.js → pieDiagram-DEJITSTG-0H6CGQQt.js} +7 -7
  127. package/out/renderer/assets/pieDiagram-DEJITSTG-0H6CGQQt.js.br +0 -0
  128. package/out/renderer/assets/pieDiagram-DEJITSTG-0H6CGQQt.js.gz +0 -0
  129. package/out/renderer/assets/{plus-DOVKq0d7.js → plus-YNCXW-GD.js} +1 -1
  130. package/out/renderer/assets/{quadrantDiagram-34T5L4WZ-G09qfNO8.js → quadrantDiagram-34T5L4WZ-D0aPKp5z.js} +3 -3
  131. package/out/renderer/assets/quadrantDiagram-34T5L4WZ-D0aPKp5z.js.br +0 -0
  132. package/out/renderer/assets/quadrantDiagram-34T5L4WZ-D0aPKp5z.js.gz +0 -0
  133. package/out/renderer/assets/{refresh-cw-DGB7KSZ3.js → refresh-cw-Bvm578nW.js} +1 -1
  134. package/out/renderer/assets/{requirementDiagram-MS252O5E-sJPY8r9J.js → requirementDiagram-MS252O5E-BkzwapW_.js} +4 -4
  135. package/out/renderer/assets/requirementDiagram-MS252O5E-BkzwapW_.js.br +0 -0
  136. package/out/renderer/assets/requirementDiagram-MS252O5E-BkzwapW_.js.gz +0 -0
  137. package/out/renderer/assets/{resizable-C5jomC3Y.js → resizable-cStzNJ8V.js} +1 -1
  138. package/out/renderer/assets/resizable-cStzNJ8V.js.br +0 -0
  139. package/out/renderer/assets/resizable-cStzNJ8V.js.gz +0 -0
  140. package/out/renderer/assets/{sankeyDiagram-XADWPNL6-DHIS2ISZ.js → sankeyDiagram-XADWPNL6-Dbde7usj.js} +2 -2
  141. package/out/renderer/assets/sankeyDiagram-XADWPNL6-Dbde7usj.js.br +0 -0
  142. package/out/renderer/assets/sankeyDiagram-XADWPNL6-Dbde7usj.js.gz +0 -0
  143. package/out/renderer/assets/{schedule-BoqPUAOI.js → schedule-DNMCsk-G.js} +9 -10
  144. package/out/renderer/assets/schedule-DNMCsk-G.js.br +0 -0
  145. package/out/renderer/assets/schedule-DNMCsk-G.js.gz +0 -0
  146. package/out/renderer/assets/{search-DdqhQVGJ.js → search-BEY9yGF_.js} +1 -1
  147. package/out/renderer/assets/{sequenceDiagram-FGHM5R23-Boc12Em2.js → sequenceDiagram-FGHM5R23-DI8l1pSL.js} +4 -4
  148. package/out/renderer/assets/sequenceDiagram-FGHM5R23-DI8l1pSL.js.br +0 -0
  149. package/out/renderer/assets/sequenceDiagram-FGHM5R23-DI8l1pSL.js.gz +0 -0
  150. package/out/renderer/assets/{session-DgU3TDDV.js → session-Bn5k9ScR.js} +1540 -182
  151. package/out/renderer/assets/session-Bn5k9ScR.js.br +0 -0
  152. package/out/renderer/assets/session-Bn5k9ScR.js.gz +0 -0
  153. package/out/renderer/assets/{setting-dialog-4pmkQ7WP.js → setting-dialog-sqfPfGsy.js} +3 -3
  154. package/out/renderer/assets/setting-dialog-sqfPfGsy.js.br +0 -0
  155. package/out/renderer/assets/setting-dialog-sqfPfGsy.js.gz +0 -0
  156. package/out/renderer/assets/{settings-2-CI8inOtS.js → settings-2-DRhoXOO8.js} +1 -1
  157. package/out/renderer/assets/{settings-agents-C4u0s-iR.js → settings-agents-Bntc31Nn.js} +10 -11
  158. package/out/renderer/assets/settings-agents-Bntc31Nn.js.br +0 -0
  159. package/out/renderer/assets/settings-agents-Bntc31Nn.js.gz +0 -0
  160. package/out/renderer/assets/{settings-general-BkLSJoHB.js → settings-general-DhbLb9cP.js} +2 -2
  161. package/out/renderer/assets/settings-general-DhbLb9cP.js.br +0 -0
  162. package/out/renderer/assets/settings-general-DhbLb9cP.js.gz +0 -0
  163. package/out/renderer/assets/{settings-ilink-6ZrgPpeO.js → settings-ilink-C7nGGjwT.js} +3 -3
  164. package/out/renderer/assets/settings-ilink-C7nGGjwT.js.br +0 -0
  165. package/out/renderer/assets/settings-ilink-C7nGGjwT.js.gz +0 -0
  166. package/out/renderer/assets/{settings-image-generation-B6YIO6o_.js → settings-image-generation-H2dgqG7Y.js} +6 -7
  167. package/out/renderer/assets/settings-image-generation-H2dgqG7Y.js.br +0 -0
  168. package/out/renderer/assets/settings-image-generation-H2dgqG7Y.js.gz +0 -0
  169. package/out/renderer/assets/{settings-layout-Cf7GMXFZ.js → settings-layout-ATto1xpJ.js} +9 -3
  170. package/out/renderer/assets/settings-layout-ATto1xpJ.js.br +0 -0
  171. package/out/renderer/assets/settings-layout-ATto1xpJ.js.gz +0 -0
  172. package/out/renderer/assets/{settings-mcp-CJvL5Siz.js → settings-mcp-DUdMuoJ-.js} +7 -8
  173. package/out/renderer/assets/settings-mcp-DUdMuoJ-.js.br +0 -0
  174. package/out/renderer/assets/settings-mcp-DUdMuoJ-.js.gz +0 -0
  175. package/out/renderer/assets/{settings-memory-CvkppfHy.js → settings-memory-CJLG4aHW.js} +3 -3
  176. package/out/renderer/assets/settings-memory-CJLG4aHW.js.br +0 -0
  177. package/out/renderer/assets/settings-memory-CJLG4aHW.js.gz +0 -0
  178. package/out/renderer/assets/{settings-snippets-CO_jL3O3.js → settings-snippets-B4VcnD5Z.js} +6 -7
  179. package/out/renderer/assets/settings-snippets-B4VcnD5Z.js.br +0 -0
  180. package/out/renderer/assets/settings-snippets-B4VcnD5Z.js.gz +0 -0
  181. package/out/renderer/assets/settings-speech-to-text-DQ7lfkTu.js +1054 -0
  182. package/out/renderer/assets/settings-speech-to-text-DQ7lfkTu.js.br +0 -0
  183. package/out/renderer/assets/settings-speech-to-text-DQ7lfkTu.js.gz +0 -0
  184. package/out/renderer/assets/{settings-webui-5n5mI55N.js → settings-webui-DZf9O-6j.js} +2 -2
  185. package/out/renderer/assets/settings-webui-DZf9O-6j.js.br +0 -0
  186. package/out/renderer/assets/settings-webui-DZf9O-6j.js.gz +0 -0
  187. package/out/renderer/assets/{skills-installed-BqjN4mEl.js → skills-installed-Dp0r_4I-.js} +4 -4
  188. package/out/renderer/assets/skills-installed-Dp0r_4I-.js.br +0 -0
  189. package/out/renderer/assets/skills-installed-Dp0r_4I-.js.gz +0 -0
  190. package/out/renderer/assets/{skills-layout-C8b-pe9X.js → skills-layout-D-5rlY38.js} +2 -2
  191. package/out/renderer/assets/skills-layout-D-5rlY38.js.br +0 -0
  192. package/out/renderer/assets/skills-layout-D-5rlY38.js.gz +0 -0
  193. package/out/renderer/assets/{skills-skills-sh-Bh8KQ3PF.js → skills-skills-sh-CcLoIrSw.js} +4 -4
  194. package/out/renderer/assets/skills-skills-sh-CcLoIrSw.js.br +0 -0
  195. package/out/renderer/assets/skills-skills-sh-CcLoIrSw.js.gz +0 -0
  196. package/out/renderer/assets/{sortable.esm-DARmP-Qe.js → sortable.esm-knFxDx0Y.js} +1 -1
  197. package/out/renderer/assets/sortable.esm-knFxDx0Y.js.br +0 -0
  198. package/out/renderer/assets/sortable.esm-knFxDx0Y.js.gz +0 -0
  199. package/out/renderer/assets/{standard-schema-CtFhVVG9.js → standard-schema-dKXoCekr.js} +1 -1
  200. package/out/renderer/assets/standard-schema-dKXoCekr.js.br +0 -0
  201. package/out/renderer/assets/standard-schema-dKXoCekr.js.gz +0 -0
  202. package/out/renderer/assets/{stateDiagram-FHFEXIEX-Da2gV_KD.js → stateDiagram-FHFEXIEX-DWWz4PMv.js} +9 -9
  203. package/out/renderer/assets/stateDiagram-FHFEXIEX-DWWz4PMv.js.br +0 -0
  204. package/out/renderer/assets/stateDiagram-FHFEXIEX-DWWz4PMv.js.gz +0 -0
  205. package/out/renderer/assets/{stateDiagram-v2-QKLJ7IA2-D44mYiaY.js → stateDiagram-v2-QKLJ7IA2-Dm2qD5bg.js} +5 -5
  206. package/out/renderer/assets/{task-Ca7ur8ku.js → task-C5dyYbfn.js} +11 -12
  207. package/out/renderer/assets/task-C5dyYbfn.js.br +0 -0
  208. package/out/renderer/assets/task-C5dyYbfn.js.gz +0 -0
  209. package/out/renderer/assets/{textarea-BCC4Oh3S.js → textarea-DTqKlQbL.js} +1 -1
  210. package/out/renderer/assets/{timeline-definition-GMOUNBTQ-egFv4rLM.js → timeline-definition-GMOUNBTQ-A1tEoL9d.js} +3 -3
  211. package/out/renderer/assets/timeline-definition-GMOUNBTQ-A1tEoL9d.js.br +0 -0
  212. package/out/renderer/assets/timeline-definition-GMOUNBTQ-A1tEoL9d.js.gz +0 -0
  213. package/out/renderer/assets/{vennDiagram-DHZGUBPP-CnOs99wX.js → vennDiagram-DHZGUBPP-tNdYrJi_.js} +2 -2
  214. package/out/renderer/assets/vennDiagram-DHZGUBPP-tNdYrJi_.js.br +0 -0
  215. package/out/renderer/assets/vennDiagram-DHZGUBPP-tNdYrJi_.js.gz +0 -0
  216. package/out/renderer/assets/{wardley-RL74JXVD-Bb1llXhX.js → wardley-RL74JXVD-BxN5_Sp6.js} +4 -4
  217. package/out/renderer/assets/wardley-RL74JXVD-BxN5_Sp6.js.br +0 -0
  218. package/out/renderer/assets/wardley-RL74JXVD-BxN5_Sp6.js.gz +0 -0
  219. package/out/renderer/assets/{wardleyDiagram-NUSXRM2D-BupfUxsI.js → wardleyDiagram-NUSXRM2D-B_3jA8zU.js} +6 -6
  220. package/out/renderer/assets/wardleyDiagram-NUSXRM2D-B_3jA8zU.js.br +0 -0
  221. package/out/renderer/assets/wardleyDiagram-NUSXRM2D-B_3jA8zU.js.gz +0 -0
  222. package/out/renderer/assets/{wrench-Dj1S5dhM.js → wrench-7r-g9MUq.js} +1 -1
  223. package/out/renderer/assets/wrench-7r-g9MUq.js.br +0 -0
  224. package/out/renderer/assets/wrench-7r-g9MUq.js.gz +0 -0
  225. package/out/renderer/assets/{xlsx-view-DIarHecR.js → xlsx-view-Bv0YhA5m.js} +10 -10
  226. package/out/renderer/assets/xlsx-view-Bv0YhA5m.js.br +0 -0
  227. package/out/renderer/assets/xlsx-view-Bv0YhA5m.js.gz +0 -0
  228. package/out/renderer/assets/{xychartDiagram-5P7HB3ND-CtPNxvT_.js → xychartDiagram-5P7HB3ND-NNVuzC4j.js} +3 -3
  229. package/out/renderer/assets/xychartDiagram-5P7HB3ND-NNVuzC4j.js.br +0 -0
  230. package/out/renderer/assets/xychartDiagram-5P7HB3ND-NNVuzC4j.js.gz +0 -0
  231. package/out/renderer/index.html +2 -2
  232. package/out/renderer/index.html.br +0 -0
  233. package/out/renderer/index.html.gz +0 -0
  234. package/out/server/main.js +602 -68
  235. package/package.json +3 -1
  236. package/resources/tree-sitter-wasm/tree-sitter-dart.wasm +0 -0
  237. package/out/renderer/assets/_baseUniq-DdWCC-Go.js.br +0 -0
  238. package/out/renderer/assets/_baseUniq-DdWCC-Go.js.gz +0 -0
  239. package/out/renderer/assets/arc-B_en4gJt.js.br +0 -0
  240. package/out/renderer/assets/arc-B_en4gJt.js.gz +0 -0
  241. package/out/renderer/assets/architectureDiagram-Q4EWVU46-W-l3dTvZ.js.br +0 -0
  242. package/out/renderer/assets/architectureDiagram-Q4EWVU46-W-l3dTvZ.js.gz +0 -0
  243. package/out/renderer/assets/automation--izxbhlj.js.br +0 -0
  244. package/out/renderer/assets/automation--izxbhlj.js.gz +0 -0
  245. package/out/renderer/assets/blockDiagram-DXYQGD6D-BdxXOr8Y.js.br +0 -0
  246. package/out/renderer/assets/blockDiagram-DXYQGD6D-BdxXOr8Y.js.gz +0 -0
  247. package/out/renderer/assets/c4Diagram-AHTNJAMY-C_8XgPtT.js.br +0 -0
  248. package/out/renderer/assets/c4Diagram-AHTNJAMY-C_8XgPtT.js.gz +0 -0
  249. package/out/renderer/assets/chunk-4TB4RGXK-C7h57GNs.js.br +0 -0
  250. package/out/renderer/assets/chunk-4TB4RGXK-C7h57GNs.js.gz +0 -0
  251. package/out/renderer/assets/chunk-EDXVE4YY-BPjYyS5o.js.br +0 -0
  252. package/out/renderer/assets/chunk-EDXVE4YY-BPjYyS5o.js.gz +0 -0
  253. package/out/renderer/assets/chunk-OYMX7WX6-D5Q5ZCl0.js.br +0 -0
  254. package/out/renderer/assets/chunk-OYMX7WX6-D5Q5ZCl0.js.gz +0 -0
  255. package/out/renderer/assets/chunk-YZCP3GAM-AbfctYy8.js.br +0 -0
  256. package/out/renderer/assets/chunk-YZCP3GAM-AbfctYy8.js.gz +0 -0
  257. package/out/renderer/assets/clipboard-D6ZpW5GH.js +0 -15
  258. package/out/renderer/assets/code-editor-cp9haQUT.js.br +0 -0
  259. package/out/renderer/assets/code-editor-cp9haQUT.js.gz +0 -0
  260. package/out/renderer/assets/collapsible-BHMUDZxc.js.br +0 -0
  261. package/out/renderer/assets/collapsible-BHMUDZxc.js.gz +0 -0
  262. package/out/renderer/assets/context-menu-K6z5uSmg.js +0 -282
  263. package/out/renderer/assets/context-menu-K6z5uSmg.js.br +0 -0
  264. package/out/renderer/assets/context-menu-K6z5uSmg.js.gz +0 -0
  265. package/out/renderer/assets/cose-bilkent-S5V4N54A-CVcE9aWV.js.br +0 -0
  266. package/out/renderer/assets/cose-bilkent-S5V4N54A-CVcE9aWV.js.gz +0 -0
  267. package/out/renderer/assets/dagre-KV5264BT-zrX-TFsi.js.br +0 -0
  268. package/out/renderer/assets/dagre-KV5264BT-zrX-TFsi.js.gz +0 -0
  269. package/out/renderer/assets/diagram-5BDNPKRD-Ct9NrJP9.js.br +0 -0
  270. package/out/renderer/assets/diagram-5BDNPKRD-Ct9NrJP9.js.gz +0 -0
  271. package/out/renderer/assets/diagram-G4DWMVQ6-tTGWcCd_.js.br +0 -0
  272. package/out/renderer/assets/diagram-G4DWMVQ6-tTGWcCd_.js.gz +0 -0
  273. package/out/renderer/assets/diagram-MMDJMWI5-CpmcnN2B.js.br +0 -0
  274. package/out/renderer/assets/diagram-MMDJMWI5-CpmcnN2B.js.gz +0 -0
  275. package/out/renderer/assets/diagram-TYMM5635-DKTR2xS9.js.br +0 -0
  276. package/out/renderer/assets/diagram-TYMM5635-DKTR2xS9.js.gz +0 -0
  277. package/out/renderer/assets/erDiagram-SMLLAGMA-BW13EXAs.js.br +0 -0
  278. package/out/renderer/assets/erDiagram-SMLLAGMA-BW13EXAs.js.gz +0 -0
  279. package/out/renderer/assets/field-Be86bgEh.js.br +0 -0
  280. package/out/renderer/assets/field-Be86bgEh.js.gz +0 -0
  281. package/out/renderer/assets/flowDiagram-DWJPFMVM-C3oZAKxX.js.br +0 -0
  282. package/out/renderer/assets/flowDiagram-DWJPFMVM-C3oZAKxX.js.gz +0 -0
  283. package/out/renderer/assets/ganttDiagram-T4ZO3ILL-BARJrpDB.js.br +0 -0
  284. package/out/renderer/assets/ganttDiagram-T4ZO3ILL-BARJrpDB.js.gz +0 -0
  285. package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-D0gl3Row.js.br +0 -0
  286. package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-D0gl3Row.js.gz +0 -0
  287. package/out/renderer/assets/graph-DB7hnlLW.js.br +0 -0
  288. package/out/renderer/assets/graph-DB7hnlLW.js.gz +0 -0
  289. package/out/renderer/assets/index-Co8mzhyV.js.br +0 -0
  290. package/out/renderer/assets/index-Co8mzhyV.js.gz +0 -0
  291. package/out/renderer/assets/index-iHYS74sQ.css +0 -382
  292. package/out/renderer/assets/index-iHYS74sQ.css.br +0 -0
  293. package/out/renderer/assets/index-iHYS74sQ.css.gz +0 -0
  294. package/out/renderer/assets/infoDiagram-42DDH7IO-BrfLG_LC.js.br +0 -0
  295. package/out/renderer/assets/infoDiagram-42DDH7IO-BrfLG_LC.js.gz +0 -0
  296. package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-CO0cyvTq.js.br +0 -0
  297. package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-CO0cyvTq.js.gz +0 -0
  298. package/out/renderer/assets/item-CvcokSWl.js.br +0 -0
  299. package/out/renderer/assets/item-CvcokSWl.js.gz +0 -0
  300. package/out/renderer/assets/journeyDiagram-VCZTEJTY-D3F2Iu5P.js.br +0 -0
  301. package/out/renderer/assets/journeyDiagram-VCZTEJTY-D3F2Iu5P.js.gz +0 -0
  302. package/out/renderer/assets/kanban-definition-6JOO6SKY-CC_drlaB.js.br +0 -0
  303. package/out/renderer/assets/kanban-definition-6JOO6SKY-CC_drlaB.js.gz +0 -0
  304. package/out/renderer/assets/layout-B_3n1To1.js.br +0 -0
  305. package/out/renderer/assets/layout-B_3n1To1.js.gz +0 -0
  306. package/out/renderer/assets/linear-AxwRZ_jw.js.br +0 -0
  307. package/out/renderer/assets/linear-AxwRZ_jw.js.gz +0 -0
  308. package/out/renderer/assets/mermaid-GHXKKRXX-DFOJYe_t.js.br +0 -0
  309. package/out/renderer/assets/mermaid-GHXKKRXX-DFOJYe_t.js.gz +0 -0
  310. package/out/renderer/assets/min-Dip7FmOo.js.br +0 -0
  311. package/out/renderer/assets/min-Dip7FmOo.js.gz +0 -0
  312. package/out/renderer/assets/mindmap-definition-QFDTVHPH-D9aiLrpe.js.br +0 -0
  313. package/out/renderer/assets/mindmap-definition-QFDTVHPH-D9aiLrpe.js.gz +0 -0
  314. package/out/renderer/assets/pieDiagram-DEJITSTG-BX_34lAP.js.br +0 -0
  315. package/out/renderer/assets/pieDiagram-DEJITSTG-BX_34lAP.js.gz +0 -0
  316. package/out/renderer/assets/quadrantDiagram-34T5L4WZ-G09qfNO8.js.br +0 -0
  317. package/out/renderer/assets/quadrantDiagram-34T5L4WZ-G09qfNO8.js.gz +0 -0
  318. package/out/renderer/assets/requirementDiagram-MS252O5E-sJPY8r9J.js.br +0 -0
  319. package/out/renderer/assets/requirementDiagram-MS252O5E-sJPY8r9J.js.gz +0 -0
  320. package/out/renderer/assets/resizable-C5jomC3Y.js.br +0 -0
  321. package/out/renderer/assets/resizable-C5jomC3Y.js.gz +0 -0
  322. package/out/renderer/assets/sankeyDiagram-XADWPNL6-DHIS2ISZ.js.br +0 -0
  323. package/out/renderer/assets/sankeyDiagram-XADWPNL6-DHIS2ISZ.js.gz +0 -0
  324. package/out/renderer/assets/schedule-BoqPUAOI.js.br +0 -0
  325. package/out/renderer/assets/schedule-BoqPUAOI.js.gz +0 -0
  326. package/out/renderer/assets/sequenceDiagram-FGHM5R23-Boc12Em2.js.br +0 -0
  327. package/out/renderer/assets/sequenceDiagram-FGHM5R23-Boc12Em2.js.gz +0 -0
  328. package/out/renderer/assets/session-DgU3TDDV.js.br +0 -0
  329. package/out/renderer/assets/session-DgU3TDDV.js.gz +0 -0
  330. package/out/renderer/assets/setting-dialog-4pmkQ7WP.js.br +0 -0
  331. package/out/renderer/assets/setting-dialog-4pmkQ7WP.js.gz +0 -0
  332. package/out/renderer/assets/settings-agents-C4u0s-iR.js.br +0 -0
  333. package/out/renderer/assets/settings-agents-C4u0s-iR.js.gz +0 -0
  334. package/out/renderer/assets/settings-general-BkLSJoHB.js.br +0 -0
  335. package/out/renderer/assets/settings-general-BkLSJoHB.js.gz +0 -0
  336. package/out/renderer/assets/settings-ilink-6ZrgPpeO.js.br +0 -0
  337. package/out/renderer/assets/settings-ilink-6ZrgPpeO.js.gz +0 -0
  338. package/out/renderer/assets/settings-image-generation-B6YIO6o_.js.br +0 -0
  339. package/out/renderer/assets/settings-image-generation-B6YIO6o_.js.gz +0 -0
  340. package/out/renderer/assets/settings-layout-Cf7GMXFZ.js.br +0 -0
  341. package/out/renderer/assets/settings-layout-Cf7GMXFZ.js.gz +0 -0
  342. package/out/renderer/assets/settings-mcp-CJvL5Siz.js.br +0 -0
  343. package/out/renderer/assets/settings-mcp-CJvL5Siz.js.gz +0 -0
  344. package/out/renderer/assets/settings-memory-CvkppfHy.js.br +0 -0
  345. package/out/renderer/assets/settings-memory-CvkppfHy.js.gz +0 -0
  346. package/out/renderer/assets/settings-snippets-CO_jL3O3.js.br +0 -0
  347. package/out/renderer/assets/settings-snippets-CO_jL3O3.js.gz +0 -0
  348. package/out/renderer/assets/settings-webui-5n5mI55N.js.br +0 -0
  349. package/out/renderer/assets/settings-webui-5n5mI55N.js.gz +0 -0
  350. package/out/renderer/assets/skills-installed-BqjN4mEl.js.br +0 -0
  351. package/out/renderer/assets/skills-installed-BqjN4mEl.js.gz +0 -0
  352. package/out/renderer/assets/skills-layout-C8b-pe9X.js.br +0 -0
  353. package/out/renderer/assets/skills-layout-C8b-pe9X.js.gz +0 -0
  354. package/out/renderer/assets/skills-skills-sh-Bh8KQ3PF.js.br +0 -0
  355. package/out/renderer/assets/skills-skills-sh-Bh8KQ3PF.js.gz +0 -0
  356. package/out/renderer/assets/sortable.esm-DARmP-Qe.js.br +0 -0
  357. package/out/renderer/assets/sortable.esm-DARmP-Qe.js.gz +0 -0
  358. package/out/renderer/assets/standard-schema-CtFhVVG9.js.br +0 -0
  359. package/out/renderer/assets/standard-schema-CtFhVVG9.js.gz +0 -0
  360. package/out/renderer/assets/stateDiagram-FHFEXIEX-Da2gV_KD.js.br +0 -0
  361. package/out/renderer/assets/stateDiagram-FHFEXIEX-Da2gV_KD.js.gz +0 -0
  362. package/out/renderer/assets/task-Ca7ur8ku.js.br +0 -0
  363. package/out/renderer/assets/task-Ca7ur8ku.js.gz +0 -0
  364. package/out/renderer/assets/timeline-definition-GMOUNBTQ-egFv4rLM.js.br +0 -0
  365. package/out/renderer/assets/timeline-definition-GMOUNBTQ-egFv4rLM.js.gz +0 -0
  366. package/out/renderer/assets/vennDiagram-DHZGUBPP-CnOs99wX.js.br +0 -0
  367. package/out/renderer/assets/vennDiagram-DHZGUBPP-CnOs99wX.js.gz +0 -0
  368. package/out/renderer/assets/wardley-RL74JXVD-Bb1llXhX.js.br +0 -0
  369. package/out/renderer/assets/wardley-RL74JXVD-Bb1llXhX.js.gz +0 -0
  370. package/out/renderer/assets/wardleyDiagram-NUSXRM2D-BupfUxsI.js.br +0 -0
  371. package/out/renderer/assets/wardleyDiagram-NUSXRM2D-BupfUxsI.js.gz +0 -0
  372. package/out/renderer/assets/wrench-Dj1S5dhM.js.br +0 -0
  373. package/out/renderer/assets/wrench-Dj1S5dhM.js.gz +0 -0
  374. package/out/renderer/assets/xlsx-view-DIarHecR.js.br +0 -0
  375. package/out/renderer/assets/xlsx-view-DIarHecR.js.gz +0 -0
  376. package/out/renderer/assets/xychartDiagram-5P7HB3ND-CtPNxvT_.js.br +0 -0
  377. package/out/renderer/assets/xychartDiagram-5P7HB3ND-CtPNxvT_.js.gz +0 -0
@@ -1,38 +1,37 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./code-editor-cp9haQUT.js","./index-Co8mzhyV.js","./index-iHYS74sQ.css","./mermaid-GHXKKRXX-DFOJYe_t.js","./code-editor-BwxubRqT.css"])))=>i.map(i=>d[i]);
2
- import { c as createLucideIcon, r as reactExports, aC as formatErrorMessage, bB as ReactStore, bC as popupStoreSelectors, bD as triggerHover, ap as triggerPress, bE as escapeKey, bF as attachPreventUnmountOnClose, bG as closePress, bH as PATIENT_CLICK_THRESHOLD, aw as reactDomExports, bI as focusOut, bJ as setPopupOpenState, bK as createInitialPopupStoreState, bL as createPopupFloatingRootContext, bM as Timeout, bN as PopupTriggerMap, j as jsxRuntimeExports, bO as FloatingTree, bP as usePopupRootSync, bQ as useImplicitActiveTrigger, bR as useOpenStateTransitions, an as createChangeEventDetails, bS as imperativeAction, bT as PopupHandleAttachment, bU as usePopupRootStore, bV as useDismiss, bW as usePopupInteractionProps, bX as usePopupHandleStore, aA as useBaseUiId, bY as useTriggerDataForwarding, bZ as useHoverReferenceInteraction, b_ as safePolygon, b$ as useClick, c0 as useOpenMethodTriggerProps, aF as useButton, c1 as useTriggerFocusGuards, ah as useRenderElement, c2 as CLICK_TRIGGER_IDENTIFIER, c3 as FocusGuard, ak as pressableTriggerOpenStateMapping, c4 as triggerOpenStateMapping, c5 as FloatingPortal, c6 as POPUP_COLLISION_AVOIDANCE, c7 as useFloatingNodeId, aI as useAnimationsFinished, c8 as useAnchorPositioning, aJ as useIsoLayoutEffect, c9 as useAnchoredPopupScrollLock, ca as usePositioner, cb as InternalBackdrop, cc as inertValue, cd as FloatingNode, aB as useStableCallback, ce as useToolbarRootContext, aK as useOpenChangeComplete, cf as useHoverFloatingInteraction, cg as createDefaultInitialFocus, ch as FOCUSABLE_POPUP_PROPS, bl as COMPOSITE_KEYS, ci as getDisabledMountTransitionStyles, cj as FloatingFocusManager, ck as isHTMLElement, cl as popupTransitionStateMapping, u as useTranslation, b as useMessage, Q as useNavigate, a as useAppStore, V as Badge, cm as formatUpdatedTime, f as request, K as electron, a6 as ALL_FEATURES, a7 as FEATURE_I18N_KEYS, F as cn$1, d as Switch, B as Button, H as LoaderCircle, i as isWebUI, J as FolderOpen, C as Check, e as Copy, g as extractErrorMessage, aU as reduceFlushStreaming, aT as reduceSessionNotification, h as copyText, av as React, cn as Tooltip, co as TooltipTrigger, cp as TooltipContent, S as ScrollArea, a0 as Bot, cq as formatDuration, ax as getDefaultExportFromCjs, cr as ReactDOM, cs as v$2, A as generateUUID, ct as HoverCard, cu as HoverCardTrigger, cv as HoverCardContent, cw as X$1, aW as Folder, L as Library, v as DropdownMenu, w as DropdownMenuTrigger, cx as ChevronDown, x as DropdownMenuContent, y as DropdownMenuItem, cy as DropdownMenuSub, cz as DropdownMenuSubTrigger, cA as DropdownMenuSubContent, cB as CircleQuestionMark, cC as ChevronUp, aV as Clock, aP as Tabs, aQ as TabsList, aR as TabsTrigger, cD as z$1, X as CircleCheck, cE as __vitePreload, I as Input, cF as Code, bv as EDITOR_LABELS, aS as webUIBaseUrl, R as subscribe, cG as FolderPlus, a5 as ChevronRight, P as Pencil, T as Trash2, cH as useProjectState, cI as clientId, cJ as TabsContent } from "./index-Co8mzhyV.js";
3
- import { S as Settings2 } from "./settings-2-CI8inOtS.js";
4
- import { i as isValidMessageToDisplay, M as MessageBubble, A as ArrowUpToLine, S as Square, j as jsonToPrettyYamlExports, p as parseFileReference, c as CodeCompareView, r as resolveFileUrl, I as ImageView, P as PdfView, D as DocxView, a as PptxView, X as XlsxView, R as RotateCcw, F as Folders } from "./xlsx-view-DIarHecR.js";
5
- import { I as Image, W as Wrench } from "./wrench-Dj1S5dhM.js";
6
- import { F as FileText } from "./file-text-CMw1QH-C.js";
7
- import { C as Clipboard } from "./clipboard-D6ZpW5GH.js";
8
- import { A as ArrowLeft } from "./arrow-left-BwbOF_G_.js";
9
- import { aQ as CodeView, S as StreamMarkdown, aR as FileIcon } from "./mermaid-GHXKKRXX-DFOJYe_t.js";
10
- import { b as ContextMenuContent, c as ContextMenuItem, d as ContextMenuSeparator, C as ContextMenu, a as ContextMenuTrigger } from "./context-menu-K6z5uSmg.js";
11
- import { S as Search } from "./search-DdqhQVGJ.js";
12
- import { E as ExternalLink } from "./link-2-4A51Gs15.js";
13
- import { R as RefreshCw } from "./refresh-cw-DGB7KSZ3.js";
14
- import { P as Plus } from "./plus-DOVKq0d7.js";
15
- import { R as ResizablePanelGroup, a as ResizablePanel, b as ResizableHandle } from "./resizable-C5jomC3Y.js";
16
- import "./collapsible-BHMUDZxc.js";
17
- import "./item-CvcokSWl.js";
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./code-editor-CEXlC4aV.js","./index-LmYTNvdF.js","./index-aGJ_yZib.css","./mermaid-GHXKKRXX-CZqkhGx7.js","./code-editor-BwxubRqT.css"])))=>i.map(i=>d[i]);
2
+ import { h as createLucideIcon, r as reactExports, am as formatErrorMessage, bq as ReactStore, br as popupStoreSelectors, bs as triggerHover, al as triggerPress, bt as escapeKey, bu as attachPreventUnmountOnClose, bv as closePress, bw as PATIENT_CLICK_THRESHOLD, ae as reactDomExports, bx as focusOut, by as setPopupOpenState, bz as createInitialPopupStoreState, bA as createPopupFloatingRootContext, bB as Timeout, bC as PopupTriggerMap, j as jsxRuntimeExports, bD as FloatingTree, bE as usePopupRootSync, bF as useImplicitActiveTrigger, bG as useOpenStateTransitions, ak as createChangeEventDetails, bH as imperativeAction, bI as PopupHandleAttachment, bJ as usePopupRootStore, bK as useDismiss, bL as usePopupInteractionProps, bM as usePopupHandleStore, ai as useBaseUiId, bN as useTriggerDataForwarding, bO as useHoverReferenceInteraction, bP as safePolygon, bQ as useClick, bR as useOpenMethodTriggerProps, aq as useButton, bS as useTriggerFocusGuards, ap as useRenderElement, bT as CLICK_TRIGGER_IDENTIFIER, bU as FocusGuard, bV as pressableTriggerOpenStateMapping, bW as triggerOpenStateMapping, bX as FloatingPortal, bY as POPUP_COLLISION_AVOIDANCE, bZ as useFloatingNodeId, at as useAnimationsFinished, b_ as useAnchorPositioning, au as useIsoLayoutEffect, b$ as useAnchoredPopupScrollLock, c0 as usePositioner, c1 as InternalBackdrop, c2 as inertValue, c3 as FloatingNode, aj as useStableCallback, c4 as useToolbarRootContext, av as useOpenChangeComplete, c5 as useHoverFloatingInteraction, c6 as createDefaultInitialFocus, c7 as FOCUSABLE_POPUP_PROPS, ba as COMPOSITE_KEYS, c8 as getDisabledMountTransitionStyles, c9 as FloatingFocusManager, ca as isHTMLElement, cb as popupTransitionStateMapping, u as useTranslation, b as useMessage, X as useNavigate, a as useAppStore, _ as Badge, cc as formatUpdatedTime, e as request, V as electron, ab as ALL_FEATURES, ac as FEATURE_I18N_KEYS, M as cn$1, c as Switch, B as Button, R as LoaderCircle, cd as buttonVariants, i as isWebUI, U as FolderOpen, C as Check, d as Copy, f as extractErrorMessage, aG as reduceFlushStreaming, aF as reduceSessionNotification, g as copyText, ad as React, ce as Tooltip, cf as TooltipTrigger, cg as TooltipContent, S as ScrollArea, a5 as Bot, ch as formatDuration, af as getDefaultExportFromCjs, ci as ReactDOM, Y as subscribe, cj as clientId, A as DropdownMenu, E as DropdownMenuTrigger, ck as ChevronDown, F as DropdownMenuContent, G as DropdownMenuItem, cl as v$2, J as generateUUID, cm as HoverCard, cn as HoverCardTrigger, co as HoverCardContent, cp as X$1, aI as Folder, L as Library, cq as DropdownMenuSub, cr as DropdownMenuSubTrigger, cs as DropdownMenuSubContent, ct as CircleQuestionMark, cu as ChevronUp, aH as Clock, aB as Tabs, aC as TabsList, aD as TabsTrigger, cv as z$1, a0 as CircleCheck, cw as __vitePreload, I as Input, m as ContextMenuContent, n as ContextMenuItem, o as ContextMenuSeparator, cx as Code, bk as EDITOR_LABELS, k as ContextMenu, l as ContextMenuTrigger, aE as webUIBaseUrl, aa as ChevronRight, cy as MessageSquare, cz as FolderPlus, P as Pencil, T as Trash2, cA as useProjectState, cB as TabsContent } from "./index-LmYTNvdF.js";
3
+ import { S as Settings2 } from "./settings-2-DRhoXOO8.js";
4
+ import { i as isValidMessageToDisplay, M as MessageBubble, A as ArrowUpToLine, S as Square, j as jsonToPrettyYamlExports, p as parseFileReference, c as CodeCompareView, r as resolveFileUrl, I as ImageView, P as PdfView, D as DocxView, a as PptxView, X as XlsxView, R as RotateCcw, F as Folders } from "./xlsx-view-Bv0YhA5m.js";
5
+ import { M as Mic, C as Clipboard } from "./mic-BgSvicCB.js";
6
+ import { I as Image, W as Wrench } from "./wrench-7r-g9MUq.js";
7
+ import { F as FileText } from "./file-text-nGCW6zu1.js";
8
+ import { A as ArrowLeft } from "./arrow-left-CxS1t3f7.js";
9
+ import { aQ as CodeView, S as StreamMarkdown, aR as FileIcon } from "./mermaid-GHXKKRXX-CZqkhGx7.js";
10
+ import { S as Search } from "./search-BEY9yGF_.js";
11
+ import { E as ExternalLink } from "./link-2-DHUPzNSt.js";
12
+ import { R as RefreshCw } from "./refresh-cw-Bvm578nW.js";
13
+ import { P as Plus } from "./plus-YNCXW-GD.js";
14
+ import { R as ResizablePanelGroup, a as ResizablePanel, b as ResizableHandle } from "./resizable-cStzNJ8V.js";
15
+ import "./collapsible-CMuCJUWG.js";
16
+ import "./item-BHEUMM9H.js";
18
17
  import "./schemas-c0X-G5_P.js";
19
- import "./ellipsis-8708fodN.js";
20
- const __iconNode$h = [
18
+ import "./ellipsis-D1agTYu1.js";
19
+ const __iconNode$k = [
21
20
  ["path", { d: "M12 5v14", key: "s699le" }],
22
21
  ["path", { d: "m19 12-7 7-7-7", key: "1idqje" }]
23
22
  ];
24
- const ArrowDown = createLucideIcon("arrow-down", __iconNode$h);
25
- const __iconNode$g = [
23
+ const ArrowDown = createLucideIcon("arrow-down", __iconNode$k);
24
+ const __iconNode$j = [
26
25
  ["path", { d: "M5 12h14", key: "1ays0h" }],
27
26
  ["path", { d: "m12 5 7 7-7 7", key: "xquz4c" }]
28
27
  ];
29
- const ArrowRight = createLucideIcon("arrow-right", __iconNode$g);
30
- const __iconNode$f = [
28
+ const ArrowRight = createLucideIcon("arrow-right", __iconNode$j);
29
+ const __iconNode$i = [
31
30
  ["path", { d: "m5 12 7-7 7 7", key: "hav0vg" }],
32
31
  ["path", { d: "M12 19V5", key: "x0mq9r" }]
33
32
  ];
34
- const ArrowUp = createLucideIcon("arrow-up", __iconNode$f);
35
- const __iconNode$e = [
33
+ const ArrowUp = createLucideIcon("arrow-up", __iconNode$i);
34
+ const __iconNode$h = [
36
35
  [
37
36
  "path",
38
37
  {
@@ -41,20 +40,20 @@ const __iconNode$e = [
41
40
  }
42
41
  ]
43
42
  ];
44
- const Astroid = createLucideIcon("astroid", __iconNode$e);
45
- const __iconNode$d = [
43
+ const Astroid = createLucideIcon("astroid", __iconNode$h);
44
+ const __iconNode$g = [
46
45
  ["circle", { cx: "12", cy: "12", r: "4", key: "4exip2" }],
47
46
  ["path", { d: "M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-4 8", key: "7n84p3" }]
48
47
  ];
49
- const AtSign = createLucideIcon("at-sign", __iconNode$d);
50
- const __iconNode$c = [["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]];
51
- const Circle = createLucideIcon("circle", __iconNode$c);
52
- const __iconNode$b = [
48
+ const AtSign = createLucideIcon("at-sign", __iconNode$g);
49
+ const __iconNode$f = [["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]];
50
+ const Circle = createLucideIcon("circle", __iconNode$f);
51
+ const __iconNode$e = [
53
52
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
54
53
  ["path", { d: "M12 2a7 7 0 1 0 10 10", key: "1yuj32" }]
55
54
  ];
56
- const Eclipse = createLucideIcon("eclipse", __iconNode$b);
57
- const __iconNode$a = [
55
+ const Eclipse = createLucideIcon("eclipse", __iconNode$e);
56
+ const __iconNode$d = [
58
57
  [
59
58
  "path",
60
59
  {
@@ -66,34 +65,58 @@ const __iconNode$a = [
66
65
  ["path", { d: "M9 15h6", key: "cctwl0" }],
67
66
  ["path", { d: "M12 18v-6", key: "17g6i2" }]
68
67
  ];
69
- const FilePlus = createLucideIcon("file-plus", __iconNode$a);
70
- const __iconNode$9 = [
68
+ const FilePlus = createLucideIcon("file-plus", __iconNode$d);
69
+ const __iconNode$c = [
71
70
  ["path", { d: "m12 14 4-4", key: "9kzdfg" }],
72
71
  ["path", { d: "M3.34 19a10 10 0 1 1 17.32 0", key: "19p75a" }]
73
72
  ];
74
- const Gauge = createLucideIcon("gauge", __iconNode$9);
75
- const __iconNode$8 = [
73
+ const Gauge = createLucideIcon("gauge", __iconNode$c);
74
+ const __iconNode$b = [
76
75
  ["path", { d: "M15 6a9 9 0 0 0-9 9V3", key: "1cii5b" }],
77
76
  ["circle", { cx: "18", cy: "6", r: "3", key: "1h7g24" }],
78
77
  ["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }]
79
78
  ];
80
- const GitBranch = createLucideIcon("git-branch", __iconNode$8);
81
- const __iconNode$7 = [
79
+ const GitBranch = createLucideIcon("git-branch", __iconNode$b);
80
+ const __iconNode$a = [
82
81
  ["line", { x1: "4", x2: "20", y1: "9", y2: "9", key: "4lhtct" }],
83
82
  ["line", { x1: "4", x2: "20", y1: "15", y2: "15", key: "vyu0kd" }],
84
83
  ["line", { x1: "10", x2: "8", y1: "3", y2: "21", key: "1ggp8o" }],
85
84
  ["line", { x1: "16", x2: "14", y1: "3", y2: "21", key: "weycgp" }]
86
85
  ];
87
- const Hash = createLucideIcon("hash", __iconNode$7);
88
- const __iconNode$6 = [
86
+ const Hash = createLucideIcon("hash", __iconNode$a);
87
+ const __iconNode$9 = [
88
+ [
89
+ "path",
90
+ {
91
+ d: "M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",
92
+ key: "zw3jo"
93
+ }
94
+ ],
95
+ [
96
+ "path",
97
+ {
98
+ d: "M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12",
99
+ key: "1wduqc"
100
+ }
101
+ ],
102
+ [
103
+ "path",
104
+ {
105
+ d: "M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17",
106
+ key: "kqbvx6"
107
+ }
108
+ ]
109
+ ];
110
+ const Layers = createLucideIcon("layers", __iconNode$9);
111
+ const __iconNode$8 = [
89
112
  ["path", { d: "M3 5h8", key: "18g2rq" }],
90
113
  ["path", { d: "M3 12h8", key: "1xfjp6" }],
91
114
  ["path", { d: "M3 19h8", key: "fpbke4" }],
92
115
  ["path", { d: "m15 5 3 3 3-3", key: "1t4thf" }],
93
116
  ["path", { d: "m15 19 3-3 3 3", key: "y4ckd2" }]
94
117
  ];
95
- const ListChevronsDownUp = createLucideIcon("list-chevrons-down-up", __iconNode$6);
96
- const __iconNode$5 = [
118
+ const ListChevronsDownUp = createLucideIcon("list-chevrons-down-up", __iconNode$8);
119
+ const __iconNode$7 = [
97
120
  [
98
121
  "path",
99
122
  {
@@ -104,8 +127,25 @@ const __iconNode$5 = [
104
127
  ["path", { d: "M12 8v6", key: "1ib9pf" }],
105
128
  ["path", { d: "M9 11h6", key: "1fldmi" }]
106
129
  ];
107
- const MessageSquarePlus = createLucideIcon("message-square-plus", __iconNode$5);
108
- const __iconNode$4 = [
130
+ const MessageSquarePlus = createLucideIcon("message-square-plus", __iconNode$7);
131
+ const __iconNode$6 = [
132
+ [
133
+ "path",
134
+ {
135
+ d: "M16 10a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 14.286V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z",
136
+ key: "1n2ejm"
137
+ }
138
+ ],
139
+ [
140
+ "path",
141
+ {
142
+ d: "M20 9a2 2 0 0 1 2 2v10.286a.71.71 0 0 1-1.212.502l-2.202-2.202A2 2 0 0 0 17.172 19H10a2 2 0 0 1-2-2v-1",
143
+ key: "1qfcsi"
144
+ }
145
+ ]
146
+ ];
147
+ const MessagesSquare = createLucideIcon("messages-square", __iconNode$6);
148
+ const __iconNode$5 = [
109
149
  [
110
150
  "path",
111
151
  {
@@ -114,8 +154,8 @@ const __iconNode$4 = [
114
154
  }
115
155
  ]
116
156
  ];
117
- const Paperclip = createLucideIcon("paperclip", __iconNode$4);
118
- const __iconNode$3 = [
157
+ const Paperclip = createLucideIcon("paperclip", __iconNode$5);
158
+ const __iconNode$4 = [
119
159
  ["path", { d: "M10 7v10a5 5 0 0 0 5-5", key: "1blmz7" }],
120
160
  ["path", { d: "m14 8-6 3", key: "2tb98i" }],
121
161
  [
@@ -126,13 +166,13 @@ const __iconNode$3 = [
126
166
  }
127
167
  ]
128
168
  ];
129
- const ReceiptTurkishLira = createLucideIcon("receipt-turkish-lira", __iconNode$3);
130
- const __iconNode$2 = [
169
+ const ReceiptTurkishLira = createLucideIcon("receipt-turkish-lira", __iconNode$4);
170
+ const __iconNode$3 = [
131
171
  ["path", { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8", key: "1p45f6" }],
132
172
  ["path", { d: "M21 3v5h-5", key: "1q7to0" }]
133
173
  ];
134
- const RotateCw = createLucideIcon("rotate-cw", __iconNode$2);
135
- const __iconNode$1 = [
174
+ const RotateCw = createLucideIcon("rotate-cw", __iconNode$3);
175
+ const __iconNode$2 = [
136
176
  [
137
177
  "path",
138
178
  {
@@ -143,13 +183,23 @@ const __iconNode$1 = [
143
183
  ["path", { d: "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7", key: "1ydtos" }],
144
184
  ["path", { d: "M7 3v4a1 1 0 0 0 1 1h7", key: "t51u73" }]
145
185
  ];
146
- const Save = createLucideIcon("save", __iconNode$1);
147
- const __iconNode = [
186
+ const Save = createLucideIcon("save", __iconNode$2);
187
+ const __iconNode$1 = [
148
188
  ["path", { d: "m7 11 2-2-2-2", key: "1lz0vl" }],
149
189
  ["path", { d: "M11 13h4", key: "1p7l4v" }],
150
190
  ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }]
151
191
  ];
152
- const SquareTerminal = createLucideIcon("square-terminal", __iconNode);
192
+ const SquareTerminal = createLucideIcon("square-terminal", __iconNode$1);
193
+ const __iconNode = [
194
+ [
195
+ "path",
196
+ {
197
+ d: "M15.914 4a1.5 1.5 0 00-2.474-1.561l-9 9A1.5 1.5 0 005.5 14h4.002a.5.5 0 01.471.666L8.086 20a1.5 1.5 0 002.475 1.56l9-9A1.5 1.5 0 0018.5 10h-3.997a.5.5 0 01-.472-.667z",
198
+ key: "1v7up4"
199
+ }
200
+ ]
201
+ ];
202
+ const Zap = createLucideIcon("zap", __iconNode);
153
203
  const PopoverRootContext = /* @__PURE__ */ reactExports.createContext(void 0);
154
204
  function usePopoverRootContext(optional) {
155
205
  const context = reactExports.useContext(PopoverRootContext);
@@ -626,6 +676,12 @@ function useClosePartCount() {
626
676
  hasClosePart: closePartCount > 0
627
677
  };
628
678
  }
679
+ function useClosePartRegistration() {
680
+ const context = reactExports.useContext(ClosePartContext);
681
+ useIsoLayoutEffect(() => {
682
+ return context?.register();
683
+ }, [context]);
684
+ }
629
685
  const PopoverPopup = /* @__PURE__ */ reactExports.forwardRef(function PopoverPopup2(componentProps, forwardedRef) {
630
686
  const {
631
687
  render,
@@ -716,6 +772,35 @@ const PopoverPopup = /* @__PURE__ */ reactExports.forwardRef(function PopoverPop
716
772
  })
717
773
  });
718
774
  });
775
+ const PopoverClose = /* @__PURE__ */ reactExports.forwardRef(function PopoverClose2(componentProps, forwardedRef) {
776
+ const {
777
+ render,
778
+ className,
779
+ style,
780
+ disabled = false,
781
+ nativeButton = true,
782
+ ...elementProps
783
+ } = componentProps;
784
+ const {
785
+ buttonRef,
786
+ getButtonProps
787
+ } = useButton({
788
+ disabled,
789
+ focusableWhenDisabled: false,
790
+ native: nativeButton
791
+ });
792
+ const store = usePopoverRootContext();
793
+ useClosePartRegistration();
794
+ const element = useRenderElement("button", componentProps, {
795
+ ref: [forwardedRef, buttonRef],
796
+ props: [{
797
+ onClick(event) {
798
+ store.setOpen(false, createChangeEventDetails(closePress, event.nativeEvent));
799
+ }
800
+ }, elementProps, getButtonProps]
801
+ });
802
+ return element;
803
+ });
719
804
  function ChatHeader({ session }) {
720
805
  const { t } = useTranslation();
721
806
  const { toast } = useMessage();
@@ -836,20 +921,34 @@ function ChatHeader({ session }) {
836
921
  children: [
837
922
  /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverTrigger, { className: "flex size-7 items-center justify-center rounded-md text-sidebar-foreground/45 hover:bg-sidebar-accent/30 hover:text-sidebar-foreground/70 outline-none transition-colors data-pressed:bg-sidebar-accent/40", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Settings2, { className: "size-4" }) }),
838
923
  /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverPortal, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverPositioner, { side: "bottom", align: "end", sideOffset: 4, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(PopoverPopup, { className: "z-10 min-w-96 rounded-lg border border-border bg-popover text-popover-foreground shadow-lg outline-none p-1.5 origin-(--transform-origin) data-ending-style:scale-90 data-starting-style:scale-90 data-ending-style:opacity-0 data-starting-style:opacity-0 transition-[transform,opacity] duration-100", children: [
839
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-2 py-1.5 space-y-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
840
- CopyableRow,
841
- {
842
- label: t("chatHeader.sessionId", "Session"),
843
- value: session.id,
844
- openFolderTitle: t("chatHeader.openSessionFolder", "Open Session Folder"),
845
- onOpenFolder: async () => {
846
- const dirPath = await request.getSessionDataSystemPath({
847
- sessionId: session.id
848
- });
849
- if (dirPath) electron.revealInFinder(dirPath);
924
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1 py-1", children: [
925
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
926
+ CopyableRow,
927
+ {
928
+ label: t("chatHeader.sessionId", "Session"),
929
+ value: session.id,
930
+ openFolderTitle: t("chatHeader.openSessionFolder", "Open Session Folder"),
931
+ onOpenFolder: async () => {
932
+ const dirPath = await request.getSessionDataSystemPath({
933
+ sessionId: session.id
934
+ });
935
+ if (dirPath) electron.revealInFinder(dirPath);
936
+ }
850
937
  }
851
- }
852
- ) }),
938
+ ) }),
939
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
940
+ CopyableRow,
941
+ {
942
+ label: t("chatHeader.projectId", "Project"),
943
+ value: currentProjectInfo?.cwd ?? session.projectTitle,
944
+ openFolderTitle: t("chatHeader.openProjectFolder", "Open Project Folder"),
945
+ onOpenFolder: async () => {
946
+ const dirPath = currentProjectInfo?.cwd;
947
+ if (dirPath) electron.revealInFinder(dirPath);
948
+ }
949
+ }
950
+ ) })
951
+ ] }),
853
952
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-t border-border/50 my-1" }),
854
953
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-2 py-1 text-xs font-semibold text-foreground/80", children: t("constant.feature.title", "Features") }),
855
954
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: ALL_FEATURES.length >= 2 ? "grid grid-cols-2 gap-0.5" : "", children: ALL_FEATURES.map((feature) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
@@ -961,7 +1060,11 @@ function ChatHeader({ session }) {
961
1060
  }
962
1061
  function UsageButton({ session }) {
963
1062
  const { t } = useTranslation();
1063
+ const configuredAgents = useAppStore((s15) => s15.configuredAgents);
964
1064
  const { lastTurnUsage, usage } = session;
1065
+ const isApiAgent = configuredAgents.some(
1066
+ (agent) => agent.id === session.agentId && agent.type === "api"
1067
+ );
965
1068
  const hasData = usage || lastTurnUsage;
966
1069
  if (!hasData) return null;
967
1070
  const pct = usage?.size ? usage.used / usage.size * 100 : 0;
@@ -1022,7 +1125,21 @@ function UsageButton({ session }) {
1022
1125
  }
1023
1126
  )
1024
1127
  ] })
1025
- ] }) })
1128
+ ] }) }),
1129
+ isApiAgent && /* @__PURE__ */ jsxRuntimeExports.jsx(
1130
+ PopoverClose,
1131
+ {
1132
+ className: buttonVariants({
1133
+ variant: "outline",
1134
+ size: "xs",
1135
+ className: "w-full py-3 font-normal border-border!"
1136
+ }),
1137
+ onClick: () => {
1138
+ document.dispatchEvent(new CustomEvent("fello-open-token-usage"));
1139
+ },
1140
+ children: t("chatHeader.viewBreakdown", "View Breakdown")
1141
+ }
1142
+ )
1026
1143
  ] }) }) }) })
1027
1144
  ] });
1028
1145
  }
@@ -4210,109 +4327,642 @@ function nodesToMentionText(nodes) {
4210
4327
  return `@[${prefix}${n.name}](${n.id})`;
4211
4328
  }).join(" ");
4212
4329
  }
4213
- function readFileAsBase64(file) {
4214
- return new Promise((resolve, reject) => {
4215
- const reader = new FileReader();
4216
- reader.onload = () => {
4217
- const result = reader.result;
4218
- resolve(result.split(",")[1]);
4219
- };
4220
- reader.onerror = reject;
4221
- reader.readAsDataURL(file);
4222
- });
4330
+ const TARGET_SAMPLE_RATE = 16e3;
4331
+ const FRAME_SAMPLES = 320;
4332
+ const workletSource = `
4333
+ class FelloPcmProcessor extends AudioWorkletProcessor {
4334
+ constructor() {
4335
+ super();
4336
+ this.buffer = [];
4337
+ this.position = 0;
4338
+ this.output = [];
4339
+ this.ratio = sampleRate / ${TARGET_SAMPLE_RATE};
4340
+ }
4341
+ process(inputs, outputs) {
4342
+ const input = inputs[0] && inputs[0][0];
4343
+ if (input) {
4344
+ for (let i = 0; i < input.length; i++) this.buffer.push(input[i]);
4345
+ while (this.position + 1 < this.buffer.length) {
4346
+ const index = Math.floor(this.position);
4347
+ const fraction = this.position - index;
4348
+ const sample = this.buffer[index] * (1 - fraction) + this.buffer[index + 1] * fraction;
4349
+ const clamped = Math.max(-1, Math.min(1, sample));
4350
+ this.output.push(clamped < 0 ? clamped * 32768 : clamped * 32767);
4351
+ this.position += this.ratio;
4352
+ if (this.output.length >= ${FRAME_SAMPLES}) {
4353
+ const pcm = new Int16Array(${FRAME_SAMPLES});
4354
+ for (let i = 0; i < ${FRAME_SAMPLES}; i++) pcm[i] = this.output[i];
4355
+ this.output = this.output.slice(${FRAME_SAMPLES});
4356
+ this.port.postMessage(pcm.buffer, [pcm.buffer]);
4357
+ }
4358
+ }
4359
+ const remove = Math.max(0, Math.floor(this.position));
4360
+ if (remove > 0) {
4361
+ this.buffer = this.buffer.slice(remove);
4362
+ this.position -= remove;
4363
+ }
4364
+ }
4365
+ const output = outputs[0] && outputs[0][0];
4366
+ if (output) output.fill(0);
4367
+ return true;
4368
+ }
4223
4369
  }
4224
- async function addFileAsAttachment(file, type, updateSessionState) {
4225
- const data = await readFileAsBase64(file);
4226
- updateSessionState((s15) => ({
4227
- draftAttachments: [
4228
- ...s15.draftAttachments,
4229
- { id: generateUUID(), filename: file.name, mimeType: file.type, type, data }
4230
- ]
4231
- }));
4370
+ registerProcessor("fello-pcm-processor", FelloPcmProcessor);
4371
+ `;
4372
+ function arrayBufferToBase64(buffer) {
4373
+ const bytes = new Uint8Array(buffer);
4374
+ let binary = "";
4375
+ const chunkSize = 32768;
4376
+ for (let offset = 0; offset < bytes.length; offset += chunkSize) {
4377
+ binary += String.fromCharCode(...bytes.subarray(offset, offset + chunkSize));
4378
+ }
4379
+ return btoa(binary);
4232
4380
  }
4233
- function buildAttachmentBlocks(attachments) {
4234
- return attachments.map((att) => {
4235
- if (att.type === "image") {
4236
- return {
4237
- type: "image",
4238
- mimeType: att.mimeType,
4239
- data: att.data
4240
- };
4381
+ function errorMessage(error) {
4382
+ return error instanceof Error ? error.message : String(error);
4383
+ }
4384
+ function useRealtimeAsr(options) {
4385
+ const { onTranscript, onError, onRecordingChange } = options;
4386
+ const configured = useAppStore((state) => state.speechToText.some((provider) => provider.active));
4387
+ const [recording, setRecording] = reactExports.useState(false);
4388
+ const [audioLevel, setAudioLevel] = reactExports.useState(0);
4389
+ const [inputDevices, setInputDevices] = reactExports.useState([]);
4390
+ const asrSessionIdRef = reactExports.useRef(null);
4391
+ const streamRef = reactExports.useRef(null);
4392
+ const audioContextRef = reactExports.useRef(null);
4393
+ const sourceRef = reactExports.useRef(null);
4394
+ const nodeRef = reactExports.useRef(null);
4395
+ const stoppedRef = reactExports.useRef(false);
4396
+ const stoppingRef = reactExports.useRef(false);
4397
+ const recordingRef = reactExports.useRef(false);
4398
+ const audioLevelValueRef = reactExports.useRef(0);
4399
+ const audioLevelFrameRef = reactExports.useRef(null);
4400
+ const stopRef = reactExports.useRef(async () => {
4401
+ });
4402
+ const callbacksRef = reactExports.useRef({ onTranscript, onError, onRecordingChange });
4403
+ callbacksRef.current = { onTranscript, onError, onRecordingChange };
4404
+ const setRecordingState = reactExports.useCallback((value) => {
4405
+ recordingRef.current = value;
4406
+ setRecording(value);
4407
+ callbacksRef.current.onRecordingChange?.(value);
4408
+ }, []);
4409
+ reactExports.useEffect(() => {
4410
+ const handleTranscript = (event) => {
4411
+ if (event.clientId !== clientId || event.asrSessionId !== asrSessionIdRef.current) return;
4412
+ callbacksRef.current.onTranscript?.({
4413
+ text: event.text,
4414
+ isFinal: event.isFinal,
4415
+ id: event.id,
4416
+ index: event.index
4417
+ });
4418
+ };
4419
+ const handleError = (event) => {
4420
+ if (event.clientId !== clientId || event.asrSessionId !== asrSessionIdRef.current) return;
4421
+ callbacksRef.current.onError?.(event.message);
4422
+ };
4423
+ const handleClosed = (event) => {
4424
+ if (event.clientId !== clientId || event.asrSessionId !== asrSessionIdRef.current) return;
4425
+ if (recordingRef.current && !stoppingRef.current) {
4426
+ callbacksRef.current.onError?.("实时语音识别连接已关闭。");
4427
+ void stopRef.current();
4428
+ }
4429
+ };
4430
+ subscribe.on("asr-transcript", handleTranscript);
4431
+ subscribe.on("asr-error", handleError);
4432
+ subscribe.on("asr-closed", handleClosed);
4433
+ return () => {
4434
+ subscribe.off("asr-transcript", handleTranscript);
4435
+ subscribe.off("asr-error", handleError);
4436
+ subscribe.off("asr-closed", handleClosed);
4437
+ };
4438
+ }, [setRecordingState]);
4439
+ const updateAudioLevel = reactExports.useCallback((buffer) => {
4440
+ const samples = new Int16Array(buffer);
4441
+ if (samples.length === 0) return;
4442
+ let sumSquares = 0;
4443
+ for (const sample of samples) {
4444
+ const normalized = sample / 32768;
4445
+ sumSquares += normalized * normalized;
4446
+ }
4447
+ const rms = Math.sqrt(sumSquares / samples.length);
4448
+ audioLevelValueRef.current = Math.min(1, rms * 4);
4449
+ if (audioLevelFrameRef.current !== null) return;
4450
+ audioLevelFrameRef.current = requestAnimationFrame(() => {
4451
+ audioLevelFrameRef.current = null;
4452
+ setAudioLevel(audioLevelValueRef.current);
4453
+ });
4454
+ }, []);
4455
+ const cleanupAudio = reactExports.useCallback(async () => {
4456
+ if (audioLevelFrameRef.current !== null) {
4457
+ cancelAnimationFrame(audioLevelFrameRef.current);
4458
+ audioLevelFrameRef.current = null;
4459
+ }
4460
+ audioLevelValueRef.current = 0;
4461
+ setAudioLevel(0);
4462
+ nodeRef.current?.disconnect();
4463
+ sourceRef.current?.disconnect();
4464
+ streamRef.current?.getTracks().forEach((track) => track.stop());
4465
+ streamRef.current = null;
4466
+ nodeRef.current = null;
4467
+ sourceRef.current = null;
4468
+ const context = audioContextRef.current;
4469
+ audioContextRef.current = null;
4470
+ await context?.close().catch(() => void 0);
4471
+ }, []);
4472
+ const refreshInputDevices = reactExports.useCallback(async () => {
4473
+ if (!navigator.mediaDevices?.enumerateDevices) return [];
4474
+ try {
4475
+ let devices = await navigator.mediaDevices.enumerateDevices();
4476
+ if (devices.length > 0 && devices.every((device) => !device.label)) {
4477
+ try {
4478
+ const permissionStream = await navigator.mediaDevices.getUserMedia({ audio: true });
4479
+ permissionStream.getTracks().forEach((track) => track.stop());
4480
+ devices = await navigator.mediaDevices.enumerateDevices();
4481
+ } catch {
4482
+ }
4483
+ }
4484
+ const audioInputs = devices.filter((device) => device.kind === "audioinput").map((device, index) => ({
4485
+ deviceId: device.deviceId,
4486
+ label: device.label || `Microphone ${index + 1}`
4487
+ }));
4488
+ setInputDevices(audioInputs);
4489
+ return audioInputs;
4490
+ } catch (error) {
4491
+ callbacksRef.current.onError?.(errorMessage(error));
4492
+ return [];
4241
4493
  }
4242
- return {
4243
- type: "resource",
4244
- resource: {
4245
- uri: `file://${att.filename}`,
4246
- text: att.data
4494
+ }, []);
4495
+ const start = reactExports.useCallback(
4496
+ async (deviceId = "default") => {
4497
+ if (recordingRef.current || !configured) return;
4498
+ const asrSessionId = `asr_${Date.now()}_${Math.random().toString(36).slice(2)}`;
4499
+ asrSessionIdRef.current = asrSessionId;
4500
+ stoppedRef.current = false;
4501
+ stoppingRef.current = false;
4502
+ try {
4503
+ const stream = await navigator.mediaDevices.getUserMedia({
4504
+ audio: {
4505
+ channelCount: 1,
4506
+ echoCancellation: true,
4507
+ noiseSuppression: true,
4508
+ ...deviceId !== "default" ? { deviceId: { exact: deviceId } } : {}
4509
+ }
4510
+ });
4511
+ streamRef.current = stream;
4512
+ const audioContext = new AudioContext();
4513
+ audioContextRef.current = audioContext;
4514
+ await audioContext.resume();
4515
+ const workletUrl = URL.createObjectURL(
4516
+ new Blob([workletSource], { type: "application/javascript" })
4517
+ );
4518
+ try {
4519
+ await audioContext.audioWorklet.addModule(workletUrl);
4520
+ } finally {
4521
+ URL.revokeObjectURL(workletUrl);
4522
+ }
4523
+ const source = audioContext.createMediaStreamSource(stream);
4524
+ const node = new AudioWorkletNode(audioContext, "fello-pcm-processor");
4525
+ const silentGain = audioContext.createGain();
4526
+ silentGain.gain.value = 0;
4527
+ node.port.onmessage = (message) => {
4528
+ if (stoppedRef.current || asrSessionIdRef.current !== asrSessionId) return;
4529
+ updateAudioLevel(message.data);
4530
+ void request.sendRealtimeAsrFrame({
4531
+ clientId,
4532
+ asrSessionId,
4533
+ audioB64: arrayBufferToBase64(message.data)
4534
+ }).catch((error) => callbacksRef.current.onError?.(errorMessage(error)));
4535
+ };
4536
+ sourceRef.current = source;
4537
+ nodeRef.current = node;
4538
+ await request.startRealtimeAsr({ clientId, asrSessionId });
4539
+ source.connect(node);
4540
+ node.connect(silentGain);
4541
+ silentGain.connect(audioContext.destination);
4542
+ setRecordingState(true);
4543
+ } catch (error) {
4544
+ await cleanupAudio();
4545
+ await request.stopRealtimeAsr({ clientId, asrSessionId }).catch(() => void 0);
4546
+ asrSessionIdRef.current = null;
4547
+ callbacksRef.current.onError?.(errorMessage(error));
4548
+ setRecordingState(false);
4247
4549
  }
4550
+ },
4551
+ [cleanupAudio, configured, setRecordingState, updateAudioLevel]
4552
+ );
4553
+ const stop = reactExports.useCallback(async () => {
4554
+ const asrSessionId = asrSessionIdRef.current;
4555
+ if (!asrSessionId) return;
4556
+ stoppedRef.current = true;
4557
+ stoppingRef.current = true;
4558
+ await cleanupAudio();
4559
+ await request.stopRealtimeAsr({ clientId, asrSessionId }).catch((error) => {
4560
+ callbacksRef.current.onError?.(errorMessage(error));
4561
+ });
4562
+ asrSessionIdRef.current = null;
4563
+ stoppingRef.current = false;
4564
+ setRecordingState(false);
4565
+ }, [cleanupAudio, setRecordingState]);
4566
+ stopRef.current = stop;
4567
+ reactExports.useEffect(() => {
4568
+ return () => {
4569
+ stoppedRef.current = true;
4570
+ void stopRef.current();
4248
4571
  };
4249
- });
4572
+ }, []);
4573
+ const toggle = reactExports.useCallback(() => {
4574
+ void (recordingRef.current ? stop() : start());
4575
+ }, [start, stop]);
4576
+ return {
4577
+ recording,
4578
+ audioLevel,
4579
+ configured,
4580
+ inputDevices,
4581
+ refreshInputDevices,
4582
+ start,
4583
+ stop,
4584
+ toggle
4585
+ };
4250
4586
  }
4251
- function ChatInput({ session }) {
4587
+ const ASR_WAVEFORM_BARS = [0.35, 0.65, 0.95, 0.55, 0.8, 0.45, 0.9, 0.6, 0.38];
4588
+ const DEFAULT_MAX_DURATION = 5 * 60 * 1e3;
4589
+ const VOICE_INPUT_DEVICE_STORAGE_KEY = "fello.voice-input.device-id";
4590
+ function getInputCursor(input) {
4591
+ return input.selectionStart ?? input.value.length;
4592
+ }
4593
+ function VoiceInputButton({
4594
+ inputRef,
4595
+ disabled = false,
4596
+ className,
4597
+ maxDuration = DEFAULT_MAX_DURATION,
4598
+ ref
4599
+ }) {
4252
4600
  const { t } = useTranslation();
4253
- const navigate = useNavigate();
4254
4601
  const { toast } = useMessage();
4255
- const [isDragOver, setIsDragOver] = reactExports.useState(false);
4256
- const containerRef = reactExports.useRef(null);
4257
- const dragLeaveTimer = reactExports.useRef(null);
4258
- const { addMessage, updateSession } = useAppStore();
4259
- const snippets = useAppStore((s15) => s15.snippets);
4260
- const isStreaming = session.isStreaming;
4261
- const availableModels = reactExports.useMemo(
4262
- () => session.models?.availableModels ?? [],
4263
- [session.models?.availableModels]
4264
- );
4265
- const currentModelId = session.models?.currentModelId ?? null;
4266
- const groupedModels = reactExports.useMemo(() => {
4267
- const groups = /* @__PURE__ */ new Map();
4268
- for (const m of availableModels) {
4269
- const slashIdx = m.name.indexOf("/");
4270
- const key = slashIdx > 0 ? m.name.slice(0, slashIdx) : "";
4271
- if (!groups.has(key)) groups.set(key, []);
4272
- groups.get(key).push(m);
4273
- }
4274
- return groups;
4275
- }, [availableModels]);
4276
- const handleModelChange = reactExports.useCallback(
4277
- async (modelId) => {
4278
- const sid = session.id;
4279
- if (!sid) return;
4280
- useAppStore.getState().updateSession({
4281
- ...session,
4282
- models: { ...session.models, currentModelId: modelId }
4283
- });
4602
+ const asrApplyingRef = reactExports.useRef(false);
4603
+ const asrSegmentsRef = reactExports.useRef(/* @__PURE__ */ new Map());
4604
+ const asrTailRef = reactExports.useRef(0);
4605
+ const asrCurrentKeyRef = reactExports.useRef(null);
4606
+ const asrSequenceRef = reactExports.useRef(0);
4607
+ const freezeAsrSegments = reactExports.useCallback(() => {
4608
+ asrSegmentsRef.current.clear();
4609
+ asrCurrentKeyRef.current = null;
4610
+ const textarea = inputRef.current;
4611
+ if (textarea) asrTailRef.current = getInputCursor(textarea);
4612
+ }, [inputRef]);
4613
+ const applyAsrTranscript = reactExports.useCallback(
4614
+ (transcript) => {
4615
+ const textarea = inputRef.current;
4616
+ if (!textarea) return;
4617
+ const key = transcript.id ? `id:${transcript.id}` : transcript.index !== void 0 ? `index:${transcript.index}` : asrCurrentKeyRef.current ?? `stream:${asrSequenceRef.current++}`;
4618
+ let segment = asrSegmentsRef.current.get(key);
4619
+ if (!segment) {
4620
+ segment = { start: asrTailRef.current, length: 0 };
4621
+ asrSegmentsRef.current.set(key, segment);
4622
+ asrCurrentKeyRef.current = key;
4623
+ }
4624
+ textarea.focus();
4625
+ textarea.setSelectionRange(segment.start, segment.start + segment.length);
4626
+ asrApplyingRef.current = true;
4284
4627
  try {
4285
- await request.setModel({ sessionId: sid, modelId });
4286
- } catch (err) {
4287
- console.error("Failed to set model:", err);
4288
- useAppStore.getState().updateSession(session);
4628
+ document.execCommand("insertText", false, transcript.text);
4629
+ } finally {
4630
+ asrApplyingRef.current = false;
4631
+ }
4632
+ textarea.ownerDocument.dispatchEvent(new Event("selectionchange"));
4633
+ segment.length = transcript.text.length;
4634
+ asrTailRef.current = segment.start + segment.length;
4635
+ if (transcript.isFinal) {
4636
+ asrSegmentsRef.current.delete(key);
4637
+ asrCurrentKeyRef.current = null;
4289
4638
  }
4290
4639
  },
4291
- [session]
4640
+ [inputRef]
4292
4641
  );
4293
- const handleModeChange = reactExports.useCallback(
4294
- async (modeId) => {
4295
- const sid = session.id;
4296
- if (!sid) return;
4297
- useAppStore.getState().updateSession({
4298
- ...session,
4299
- modes: { ...session.modes, currentModeId: modeId }
4300
- });
4301
- try {
4302
- await request.setMode({ sessionId: sid, modeId });
4303
- } catch (err) {
4304
- console.error("Failed to set mode:", err);
4305
- useAppStore.getState().updateSession(session);
4642
+ const asr = useRealtimeAsr({
4643
+ onTranscript: applyAsrTranscript,
4644
+ onError: (message) => toast.error(message),
4645
+ onRecordingChange: (recording) => {
4646
+ if (!recording) freezeAsrSegments();
4647
+ }
4648
+ });
4649
+ const { start: startAsr, stop: stopAsr, refreshInputDevices } = asr;
4650
+ const handleStop = reactExports.useCallback(async () => {
4651
+ await stopAsr();
4652
+ }, [stopAsr]);
4653
+ reactExports.useImperativeHandle(
4654
+ ref,
4655
+ () => ({
4656
+ stop: handleStop
4657
+ }),
4658
+ [handleStop]
4659
+ );
4660
+ const handleStart = reactExports.useCallback(
4661
+ async (deviceId) => {
4662
+ const textarea = inputRef.current;
4663
+ if (!textarea) return;
4664
+ textarea.focus();
4665
+ const cursorPosition = getInputCursor(textarea);
4666
+ const before = textarea.value.slice(0, cursorPosition);
4667
+ if (before.length > 0 && !/\s$/.test(before)) {
4668
+ asrApplyingRef.current = true;
4669
+ try {
4670
+ document.execCommand("insertText", false, " ");
4671
+ } finally {
4672
+ asrApplyingRef.current = false;
4673
+ }
4306
4674
  }
4675
+ asrSegmentsRef.current.clear();
4676
+ asrCurrentKeyRef.current = null;
4677
+ asrTailRef.current = getInputCursor(textarea);
4678
+ await startAsr(deviceId);
4307
4679
  },
4308
- [session]
4680
+ [startAsr, inputRef]
4309
4681
  );
4310
- const handleThoughtLevelChange = reactExports.useCallback(
4311
- async (thoughtLevelId) => {
4312
- const sid = session.id;
4313
- if (!sid) return;
4314
- useAppStore.getState().updateSession({
4315
- ...session,
4682
+ const [savedDeviceId, setSavedDeviceId] = reactExports.useState(() => {
4683
+ try {
4684
+ return localStorage.getItem(VOICE_INPUT_DEVICE_STORAGE_KEY);
4685
+ } catch {
4686
+ return null;
4687
+ }
4688
+ });
4689
+ const [deviceMenuOpen, setDeviceMenuOpen] = reactExports.useState(false);
4690
+ const rememberDevice = reactExports.useCallback((deviceId) => {
4691
+ setSavedDeviceId(deviceId);
4692
+ try {
4693
+ localStorage.setItem(VOICE_INPUT_DEVICE_STORAGE_KEY, deviceId);
4694
+ } catch {
4695
+ }
4696
+ }, []);
4697
+ const handleSelectDevice = reactExports.useCallback(
4698
+ (deviceId) => {
4699
+ rememberDevice(deviceId);
4700
+ setDeviceMenuOpen(false);
4701
+ },
4702
+ [rememberDevice]
4703
+ );
4704
+ const handleMicClick = reactExports.useCallback(async () => {
4705
+ const devices = await refreshInputDevices();
4706
+ const hasSavedDevice = savedDeviceId != null && devices.some((device) => device.deviceId === savedDeviceId);
4707
+ if (hasSavedDevice) {
4708
+ await handleStart(savedDeviceId);
4709
+ } else {
4710
+ setDeviceMenuOpen(true);
4711
+ }
4712
+ }, [refreshInputDevices, handleStart, savedDeviceId]);
4713
+ const handleDeviceMenuChange = reactExports.useCallback(
4714
+ (open) => {
4715
+ setDeviceMenuOpen(open);
4716
+ if (open) void refreshInputDevices();
4717
+ },
4718
+ [refreshInputDevices]
4719
+ );
4720
+ reactExports.useEffect(() => {
4721
+ const textarea = inputRef.current;
4722
+ if (!textarea) return;
4723
+ const handleInput = () => {
4724
+ if (!asrApplyingRef.current && asr.recording) freezeAsrSegments();
4725
+ };
4726
+ textarea.addEventListener("input", handleInput);
4727
+ return () => textarea.removeEventListener("input", handleInput);
4728
+ }, [asr.recording, freezeAsrSegments, inputRef]);
4729
+ reactExports.useEffect(() => {
4730
+ if (disabled && asr.recording) void handleStop();
4731
+ }, [asr.recording, disabled, handleStop]);
4732
+ reactExports.useEffect(() => {
4733
+ if (!asr.recording || maxDuration <= 0 || !Number.isFinite(maxDuration)) return;
4734
+ const timer = setTimeout(() => void handleStop(), maxDuration);
4735
+ return () => clearTimeout(timer);
4736
+ }, [asr.recording, handleStop, maxDuration]);
4737
+ if (!asr.configured) return null;
4738
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
4739
+ "div",
4740
+ {
4741
+ className: cn$1(
4742
+ "relative inline-flex h-7 transition-[width] duration-300 ease-out",
4743
+ asr.recording ? "w-18" : "w-12.5",
4744
+ className
4745
+ ),
4746
+ children: [
4747
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
4748
+ "div",
4749
+ {
4750
+ className: cn$1(
4751
+ "absolute inset-0 transition-[opacity,transform,visibility] duration-300 ease-out",
4752
+ asr.recording ? "visible scale-100 opacity-100" : "pointer-events-none invisible scale-90 opacity-0"
4753
+ ),
4754
+ "aria-hidden": !asr.recording,
4755
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
4756
+ Button,
4757
+ {
4758
+ variant: "default",
4759
+ size: "sm",
4760
+ className: "h-full w-full rounded-lg bg-muted hover:bg-input border border-input text-amber-300/50 hover:text-amber-200",
4761
+ onClick: () => void handleStop(),
4762
+ "aria-label": t("chatInput.stopVoiceInput", "Stop voice input"),
4763
+ "aria-pressed": "true",
4764
+ title: t("chatInput.stopVoiceInput", "Stop voice input"),
4765
+ children: [
4766
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Mic, { className: "size-3.5 shrink-0 animate-pulse" }),
4767
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
4768
+ "span",
4769
+ {
4770
+ className: "flex h-4 flex-1 items-center justify-center gap-0.5 overflow-hidden",
4771
+ "aria-hidden": "true",
4772
+ children: ASR_WAVEFORM_BARS.map((scale, index) => /* @__PURE__ */ jsxRuntimeExports.jsx(
4773
+ "span",
4774
+ {
4775
+ className: "border-l rounded-full bg-amber-300 transition-[height] duration-75",
4776
+ style: {
4777
+ height: `${Math.max(2, Math.round(2 + asr.audioLevel * 16 * scale))}px`
4778
+ }
4779
+ },
4780
+ index
4781
+ ))
4782
+ }
4783
+ )
4784
+ ]
4785
+ }
4786
+ )
4787
+ }
4788
+ ),
4789
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
4790
+ "div",
4791
+ {
4792
+ className: cn$1(
4793
+ "absolute inset-0 transition-[opacity,transform,visibility] duration-300 ease-out",
4794
+ asr.recording ? "pointer-events-none invisible scale-90 opacity-0" : "visible scale-100 opacity-100"
4795
+ ),
4796
+ "aria-hidden": asr.recording,
4797
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenu, { open: deviceMenuOpen, onOpenChange: handleDeviceMenuChange, children: [
4798
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-full items-stretch", children: [
4799
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
4800
+ Button,
4801
+ {
4802
+ size: "sm",
4803
+ className: "h-full w-8 rounded-r-none border-r-0 bg-muted hover:bg-input border border-input text-amber-300/50 hover:text-amber-200",
4804
+ onClick: () => void handleMicClick(),
4805
+ disabled: disabled || !asr.configured,
4806
+ "aria-label": t("chatInput.voiceInput", "Voice input"),
4807
+ title: asr.configured ? t("chatInput.voiceInput", "Voice input") : t("chatInput.voiceInputNotConfigured", "Configure voice input in Settings"),
4808
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Mic, { className: "size-3.5" })
4809
+ }
4810
+ ),
4811
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
4812
+ DropdownMenuTrigger,
4813
+ {
4814
+ render: /* @__PURE__ */ jsxRuntimeExports.jsx(
4815
+ Button,
4816
+ {
4817
+ size: "icon",
4818
+ className: "h-full w-4.5 rounded-l-none bg-muted hover:bg-input border border-input border-l-0 px-0 text-amber-300/50 hover:text-amber-200",
4819
+ disabled: disabled || !asr.configured,
4820
+ "aria-label": t("chatInput.selectVoiceInputDevice", "Select microphone"),
4821
+ title: t("chatInput.selectVoiceInputDevice", "Select microphone")
4822
+ }
4823
+ ),
4824
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3" })
4825
+ }
4826
+ )
4827
+ ] }),
4828
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
4829
+ DropdownMenuContent,
4830
+ {
4831
+ side: "top",
4832
+ align: "center",
4833
+ className: "w-auto! max-w-72 min-w-(--anchor-width)",
4834
+ children: asr.inputDevices.length > 0 ? asr.inputDevices.map((device) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
4835
+ DropdownMenuItem,
4836
+ {
4837
+ onClick: () => handleSelectDevice(device.deviceId),
4838
+ className: "gap-2",
4839
+ children: [
4840
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
4841
+ Check,
4842
+ {
4843
+ className: cn$1(
4844
+ "size-3 shrink-0",
4845
+ device.deviceId === savedDeviceId ? "opacity-100" : "opacity-0"
4846
+ )
4847
+ }
4848
+ ),
4849
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex min-w-0 flex-col gap-0.5 pr-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: device.label }) })
4850
+ ]
4851
+ },
4852
+ device.deviceId
4853
+ )) : /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuItem, { disabled: true, children: t("chatInput.noAudioInputDevices", "No audio input devices found") })
4854
+ }
4855
+ )
4856
+ ] })
4857
+ }
4858
+ )
4859
+ ]
4860
+ }
4861
+ );
4862
+ }
4863
+ function readFileAsBase64(file) {
4864
+ return new Promise((resolve, reject) => {
4865
+ const reader = new FileReader();
4866
+ reader.onload = () => {
4867
+ const result = reader.result;
4868
+ resolve(result.split(",")[1]);
4869
+ };
4870
+ reader.onerror = reject;
4871
+ reader.readAsDataURL(file);
4872
+ });
4873
+ }
4874
+ async function addFileAsAttachment(file, type, updateSessionState) {
4875
+ const data = await readFileAsBase64(file);
4876
+ updateSessionState((s15) => ({
4877
+ draftAttachments: [
4878
+ ...s15.draftAttachments,
4879
+ { id: generateUUID(), filename: file.name, mimeType: file.type, type, data }
4880
+ ]
4881
+ }));
4882
+ }
4883
+ function buildAttachmentBlocks(attachments) {
4884
+ return attachments.map((att) => {
4885
+ if (att.type === "image") {
4886
+ return {
4887
+ type: "image",
4888
+ mimeType: att.mimeType,
4889
+ data: att.data
4890
+ };
4891
+ }
4892
+ return {
4893
+ type: "resource",
4894
+ resource: {
4895
+ uri: `file://${att.filename}`,
4896
+ text: att.data
4897
+ }
4898
+ };
4899
+ });
4900
+ }
4901
+ function ChatInput({ session }) {
4902
+ const { t } = useTranslation();
4903
+ const navigate = useNavigate();
4904
+ const { toast } = useMessage();
4905
+ const [isDragOver, setIsDragOver] = reactExports.useState(false);
4906
+ const containerRef = reactExports.useRef(null);
4907
+ const dragLeaveTimer = reactExports.useRef(null);
4908
+ const { addMessage, updateSession } = useAppStore();
4909
+ const snippets = useAppStore((s15) => s15.snippets);
4910
+ const isStreaming = session.isStreaming;
4911
+ const availableModels = reactExports.useMemo(
4912
+ () => session.models?.availableModels ?? [],
4913
+ [session.models?.availableModels]
4914
+ );
4915
+ const currentModelId = session.models?.currentModelId ?? null;
4916
+ const groupedModels = reactExports.useMemo(() => {
4917
+ const groups = /* @__PURE__ */ new Map();
4918
+ for (const m of availableModels) {
4919
+ const slashIdx = m.name.indexOf("/");
4920
+ const key = slashIdx > 0 ? m.name.slice(0, slashIdx) : "";
4921
+ if (!groups.has(key)) groups.set(key, []);
4922
+ groups.get(key).push(m);
4923
+ }
4924
+ return groups;
4925
+ }, [availableModels]);
4926
+ const handleModelChange = reactExports.useCallback(
4927
+ async (modelId) => {
4928
+ const sid = session.id;
4929
+ if (!sid) return;
4930
+ useAppStore.getState().updateSession({
4931
+ ...session,
4932
+ models: { ...session.models, currentModelId: modelId }
4933
+ });
4934
+ try {
4935
+ await request.setModel({ sessionId: sid, modelId });
4936
+ } catch (err) {
4937
+ console.error("Failed to set model:", err);
4938
+ useAppStore.getState().updateSession(session);
4939
+ }
4940
+ },
4941
+ [session]
4942
+ );
4943
+ const handleModeChange = reactExports.useCallback(
4944
+ async (modeId) => {
4945
+ const sid = session.id;
4946
+ if (!sid) return;
4947
+ useAppStore.getState().updateSession({
4948
+ ...session,
4949
+ modes: { ...session.modes, currentModeId: modeId }
4950
+ });
4951
+ try {
4952
+ await request.setMode({ sessionId: sid, modeId });
4953
+ } catch (err) {
4954
+ console.error("Failed to set mode:", err);
4955
+ useAppStore.getState().updateSession(session);
4956
+ }
4957
+ },
4958
+ [session]
4959
+ );
4960
+ const handleThoughtLevelChange = reactExports.useCallback(
4961
+ async (thoughtLevelId) => {
4962
+ const sid = session.id;
4963
+ if (!sid) return;
4964
+ useAppStore.getState().updateSession({
4965
+ ...session,
4316
4966
  thoughtLevels: { ...session.thoughtLevels, currentThoughtLevelId: thoughtLevelId }
4317
4967
  });
4318
4968
  try {
@@ -4343,10 +4993,9 @@ function ChatInput({ session }) {
4343
4993
  const promptCapabilities = initializeInfo?.agentCapabilities?.promptCapabilities;
4344
4994
  const supportsImage = promptCapabilities?.image ?? false;
4345
4995
  const supportsEmbedded = promptCapabilities?.embeddedContext ?? false;
4346
- const getTextarea = reactExports.useCallback(
4347
- () => containerRef.current?.querySelector("textarea"),
4348
- []
4349
- );
4996
+ const textareaRef = reactExports.useRef(null);
4997
+ const voiceInputRef = reactExports.useRef(null);
4998
+ const getTextarea = reactExports.useCallback(() => textareaRef.current, []);
4350
4999
  const insertTriggerChar = reactExports.useCallback(
4351
5000
  (char) => {
4352
5001
  const textarea = getTextarea();
@@ -4513,6 +5162,7 @@ function ChatInput({ session }) {
4513
5162
  [localInput, availableCommands]
4514
5163
  );
4515
5164
  const handleSubmit = reactExports.useCallback(async () => {
5165
+ await voiceInputRef.current?.stop();
4516
5166
  v$2();
4517
5167
  const state = useAppStore.getState().getSessionState(session.id);
4518
5168
  const currentAttachments = state.draftAttachments;
@@ -4807,7 +5457,10 @@ function ChatInput({ session }) {
4807
5457
  MentionsInput$1,
4808
5458
  {
4809
5459
  value: localInput,
4810
- onChange: (_e3, newValue) => setLocalInput(newValue),
5460
+ inputRef: textareaRef,
5461
+ onChange: (_e3, newValue) => {
5462
+ setLocalInput(newValue);
5463
+ },
4811
5464
  onBlur: handleBlur,
4812
5465
  onKeyDown: handleKeyDown,
4813
5466
  placeholder: disabled ? t("chatInput.placeholderDisabled") : t("chatInput.placeholderActive"),
@@ -5186,6 +5839,14 @@ function ChatInput({ session }) {
5186
5839
  }
5187
5840
  )
5188
5841
  ] }),
5842
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
5843
+ VoiceInputButton,
5844
+ {
5845
+ ref: voiceInputRef,
5846
+ inputRef: textareaRef,
5847
+ disabled
5848
+ }
5849
+ ),
5189
5850
  isStreaming ? /* @__PURE__ */ jsxRuntimeExports.jsx(
5190
5851
  Button,
5191
5852
  {
@@ -5418,13 +6079,12 @@ function AskUserOptions({
5418
6079
  const [highlightedIndex, setHighlightedIndex] = reactExports.useState(null);
5419
6080
  const [isDragOver, setIsDragOver] = reactExports.useState(false);
5420
6081
  const inputContainerRef = reactExports.useRef(null);
6082
+ const textareaRef = reactExports.useRef(null);
6083
+ const voiceInputRef = reactExports.useRef(null);
5421
6084
  const navigate = useNavigate();
5422
6085
  const snippets = useAppStore((s15) => s15.snippets);
5423
6086
  const fileInputRef = reactExports.useRef(null);
5424
- const getTextarea = reactExports.useCallback(
5425
- () => inputContainerRef.current?.querySelector("textarea"),
5426
- []
5427
- );
6087
+ const getTextarea = reactExports.useCallback(() => textareaRef.current, []);
5428
6088
  const insertTriggerChar = reactExports.useCallback(
5429
6089
  (char) => {
5430
6090
  const textarea = getTextarea();
@@ -5489,7 +6149,7 @@ function AskUserOptions({
5489
6149
  }
5490
6150
  if (paths.length === 0) return;
5491
6151
  void (async () => {
5492
- const textarea = inputContainerRef.current?.querySelector("textarea");
6152
+ const textarea = textareaRef.current;
5493
6153
  if (!textarea) return;
5494
6154
  textarea.focus();
5495
6155
  const tags = await Promise.all(
@@ -5575,7 +6235,8 @@ function AskUserOptions({
5575
6235
  window.addEventListener("keydown", handler);
5576
6236
  return () => window.removeEventListener("keydown", handler);
5577
6237
  }, [mode, hasOptions, request$1.options, handleSelectOption]);
5578
- const handleSubmitInput = () => {
6238
+ const handleSubmitInput = async () => {
6239
+ await voiceInputRef.current?.stop();
5579
6240
  const trimmed = resolveMentions(inputValue).trim();
5580
6241
  request.respondAskUser({
5581
6242
  sessionId: request$1.sessionId,
@@ -5589,12 +6250,12 @@ function AskUserOptions({
5589
6250
  if (e.nativeEvent.isComposing) return;
5590
6251
  if (e.key === "Enter" && !e.shiftKey) {
5591
6252
  e.preventDefault();
5592
- handleSubmitInput();
6253
+ void handleSubmitInput();
5593
6254
  }
5594
6255
  };
5595
6256
  reactExports.useEffect(() => {
5596
6257
  if (mode === "input") {
5597
- inputContainerRef.current?.querySelector("textarea")?.focus();
6258
+ textareaRef.current?.focus();
5598
6259
  }
5599
6260
  }, [mode]);
5600
6261
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
@@ -5663,6 +6324,7 @@ function AskUserOptions({
5663
6324
  MentionsInput$1,
5664
6325
  {
5665
6326
  value: inputValue,
6327
+ inputRef: textareaRef,
5666
6328
  onChange: (_e3, newValue) => setInputValue(newValue),
5667
6329
  onKeyDown: handleKeyDown,
5668
6330
  placeholder: t("askUser.inputPlaceholder", "Type your response... (Enter to send)"),
@@ -5803,16 +6465,19 @@ function AskUserOptions({
5803
6465
  )) : /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuItem, { onClick: () => navigate("/settings/snippets"), children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground", children: t("chatInput.snippetsEmpty", "No snippets. Click to add in Settings.") }) }) })
5804
6466
  ] })
5805
6467
  ] }),
5806
- /* @__PURE__ */ jsxRuntimeExports.jsx(
5807
- Button,
5808
- {
5809
- size: "icon",
5810
- className: "size-7 rounded-lg",
5811
- onClick: handleSubmitInput,
5812
- "aria-label": t("askUser.submit", "Submit"),
5813
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowUp, { className: "size-3.5" })
5814
- }
5815
- )
6468
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
6469
+ /* @__PURE__ */ jsxRuntimeExports.jsx(VoiceInputButton, { ref: voiceInputRef, inputRef: textareaRef }),
6470
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
6471
+ Button,
6472
+ {
6473
+ size: "icon",
6474
+ className: "size-7 rounded-lg",
6475
+ onClick: handleSubmitInput,
6476
+ "aria-label": t("askUser.submit", "Submit"),
6477
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowUp, { className: "size-3.5" })
6478
+ }
6479
+ )
6480
+ ] })
5816
6481
  ] })
5817
6482
  ]
5818
6483
  }
@@ -6024,7 +6689,7 @@ function useFile(projectId, file, options = {}) {
6024
6689
  };
6025
6690
  }
6026
6691
  const CodeEditor = reactExports.lazy(
6027
- () => __vitePreload(() => import("./code-editor-cp9haQUT.js"), true ? __vite__mapDeps([0,1,2,3,4]) : void 0, import.meta.url).then((m) => ({ default: m.CodeEditor }))
6692
+ () => __vitePreload(() => import("./code-editor-CEXlC4aV.js"), true ? __vite__mapDeps([0,1,2,3,4]) : void 0, import.meta.url).then((m) => ({ default: m.CodeEditor }))
6028
6693
  );
6029
6694
  const MAX_EDIT_SIZE = 1024 * 1024;
6030
6695
  const EditPanel = reactExports.forwardRef(function EditPanel2({ projectId, filePath, content, loading = false, onCancel, onSaved }, ref) {
@@ -15883,7 +16548,689 @@ function TerminalDetail({ terminalId, projectId, onClose }) {
15883
16548
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "relative min-h-0 flex-1 bg-neutral-900", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: containerRef, className: "h-full w-full px-2 py-1" }) })
15884
16549
  ] });
15885
16550
  }
15886
- function Detail({ detailType, projectId, file, terminalId, onClose }) {
16551
+ function TokenUsageDetail({ session, onClose }) {
16552
+ const { t } = useTranslation();
16553
+ const [records, setRecords] = reactExports.useState([]);
16554
+ const [loading, setLoading] = reactExports.useState(true);
16555
+ reactExports.useEffect(() => {
16556
+ let cancelled = false;
16557
+ let refreshTimer;
16558
+ const load = (silent = false) => {
16559
+ if (!silent) setLoading(true);
16560
+ request.getSessionTokenUsage({ sessionId: session.id }).then((res) => {
16561
+ if (!cancelled) {
16562
+ setRecords(parseTokenUsageRecords(res.records));
16563
+ }
16564
+ }).catch(() => {
16565
+ if (!cancelled) setRecords([]);
16566
+ }).finally(() => {
16567
+ if (!cancelled) setLoading(false);
16568
+ });
16569
+ };
16570
+ load();
16571
+ const handlePromptEnd = (payload) => {
16572
+ if (payload.sessionId !== session.id) return;
16573
+ if (refreshTimer) clearTimeout(refreshTimer);
16574
+ refreshTimer = setTimeout(() => {
16575
+ if (!cancelled) load(true);
16576
+ }, 500);
16577
+ };
16578
+ subscribe.on("prompt-end", handlePromptEnd);
16579
+ return () => {
16580
+ cancelled = true;
16581
+ if (refreshTimer) clearTimeout(refreshTimer);
16582
+ subscribe.off("prompt-end", handlePromptEnd);
16583
+ };
16584
+ }, [session.id]);
16585
+ const liveRecord = createLiveRecord(session.lastTurnUsage, session.updatedAt);
16586
+ const displayRecords = mergeLiveRecord(records, liveRecord);
16587
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col h-full min-h-0", children: [
16588
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
16589
+ "div",
16590
+ {
16591
+ className: "h-12 shrink-0 border-b border-border flex items-center justify-between gap-2 px-3 bg-background/95",
16592
+ style: { WebkitAppRegion: "drag" },
16593
+ children: [
16594
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 min-w-0", children: [
16595
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex size-4 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3.5 text-amber-500/80" }) }),
16596
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-foreground/60", children: [
16597
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-semibold truncate", children: t("tokenUsage.title", "Token Usage Breakdown") }),
16598
+ displayRecords.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "rounded-full bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground tabular-nums shrink-0", children: t("tokenUsage.promptCount", "{{count}} prompts", {
16599
+ count: displayRecords.length
16600
+ }) })
16601
+ ] }) })
16602
+ ] }),
16603
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
16604
+ "button",
16605
+ {
16606
+ type: "button",
16607
+ onClick: onClose,
16608
+ className: "flex size-6 shrink-0 items-center justify-center rounded hover:bg-muted-foreground/10 text-muted-foreground hover:text-foreground transition-colors",
16609
+ style: { WebkitAppRegion: "no-drag" },
16610
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X$1, { className: "size-3.5" })
16611
+ }
16612
+ )
16613
+ ]
16614
+ }
16615
+ ),
16616
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 min-h-0", viewportClassName: "p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-32 items-center justify-center text-xs text-muted-foreground", children: t("tokenUsage.loading", "Loading…") }) : displayRecords.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full items-center justify-center text-xs text-muted-foreground", children: t("tokenUsage.noData", "No token breakdown data available") }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
16617
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SessionSummary, { records: displayRecords }),
16618
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: displayRecords.map((record, index) => ({ record, index })).reverse().map(({ record, index }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
16619
+ PromptUsageItem,
16620
+ {
16621
+ record,
16622
+ promptNumber: index + 1,
16623
+ defaultExpanded: index === displayRecords.length - 1
16624
+ },
16625
+ `${record.timestamp}-${index}`
16626
+ )) })
16627
+ ] }) }) })
16628
+ ] });
16629
+ }
16630
+ function PromptUsageItem({
16631
+ record,
16632
+ promptNumber,
16633
+ defaultExpanded
16634
+ }) {
16635
+ const { t } = useTranslation();
16636
+ const [expanded, setExpanded] = reactExports.useState(defaultExpanded);
16637
+ const breakdown = getBreakdown(record.usage);
16638
+ const stepCount = breakdown?.steps.length ?? breakdown?.stepCount ?? 0;
16639
+ const toolCount = breakdown?.steps.reduce((total, step) => total + step.toolCalls.length, 0) ?? 0;
16640
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border-b border-border/50 transition-colors first:border-t", children: [
16641
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
16642
+ "button",
16643
+ {
16644
+ type: "button",
16645
+ onClick: () => setExpanded((current) => !current),
16646
+ className: "w-full flex items-center p-2 text-left hover:bg-muted/30 transition-colors",
16647
+ children: [
16648
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex size-5 shrink-0 items-center justify-center text-primary -ml-2.5", children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3.5" }) }),
16649
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-3 shrink-0 text-muted-foreground ml-0.5" }),
16650
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex flex-1 ml-2 truncate", children: [
16651
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mr-1", children: [
16652
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] font-semibold", children: t("tokenUsage.promptLabel", "Prompt #{{count}}", { count: promptNumber }) }),
16653
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground/60 tabular-nums mo", children: formatTimestamp(record.timestamp) })
16654
+ ] }),
16655
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 text-[10px] text-muted-foreground ml-2", children: [
16656
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-baseline shrink-0 gap-1", children: [
16657
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[10px] font-semibold tabular-nums text-foreground/85", children: stepCount }),
16658
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground/60", children: t("tokenUsage.steps", "steps") })
16659
+ ] }),
16660
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-baseline shrink-0 gap-1", children: [
16661
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[10px] font-semibold tabular-nums text-foreground/85", children: toolCount }),
16662
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground/60", children: t("tokenUsage.toolCalls", "tool calls") })
16663
+ ] })
16664
+ ] })
16665
+ ] }),
16666
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-baseline shrink-0 ml-2 gap-1", children: [
16667
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[10px] font-semibold tabular-nums text-foreground/85", children: record.usage.totalTokens.toLocaleString() }),
16668
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground/60", children: t("tokenUsage.tokens", "tokens") })
16669
+ ] })
16670
+ ]
16671
+ }
16672
+ ),
16673
+ expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-border/50 py-2.5 space-y-3", children: [
16674
+ /* @__PURE__ */ jsxRuntimeExports.jsx(PromptSummary, { usage: record.usage }),
16675
+ breakdown ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
16676
+ /* @__PURE__ */ jsxRuntimeExports.jsx(UserMessageSection, { text: breakdown.inputComposition.userMessageText }),
16677
+ /* @__PURE__ */ jsxRuntimeExports.jsx(InputCompositionSection, { composition: breakdown.inputComposition }),
16678
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ToolsBreakdownSection, { tools: breakdown.inputComposition.toolsDefinition }),
16679
+ /* @__PURE__ */ jsxRuntimeExports.jsx(StepsSection, { steps: breakdown.steps }),
16680
+ /* @__PURE__ */ jsxRuntimeExports.jsx(PerformanceSection, { performance: breakdown.performance, steps: breakdown.steps })
16681
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md border border-border/60 bg-muted/30 px-2.5 py-2 text-[11px] text-muted-foreground", children: t("tokenUsage.noBreakdown", "No detailed breakdown available for this prompt") })
16682
+ ] })
16683
+ ] });
16684
+ }
16685
+ function PromptSummary({ usage }) {
16686
+ const { t } = useTranslation();
16687
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-3 gap-1.5", children: [
16688
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
16689
+ MetricCard,
16690
+ {
16691
+ label: t("tokenUsage.input", "Input"),
16692
+ value: usage.inputTokens.toLocaleString()
16693
+ }
16694
+ ),
16695
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
16696
+ MetricCard,
16697
+ {
16698
+ label: t("tokenUsage.output", "Output"),
16699
+ value: usage.outputTokens.toLocaleString()
16700
+ }
16701
+ ),
16702
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
16703
+ MetricCard,
16704
+ {
16705
+ label: t("tokenUsage.totalTokens", "Total"),
16706
+ value: usage.totalTokens.toLocaleString()
16707
+ }
16708
+ ),
16709
+ usage.thoughtTokens != null && usage.thoughtTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
16710
+ MetricCard,
16711
+ {
16712
+ label: t("tokenUsage.thought", "Thought"),
16713
+ value: usage.thoughtTokens.toLocaleString()
16714
+ }
16715
+ ),
16716
+ usage.cachedReadTokens != null && usage.cachedReadTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
16717
+ MetricCard,
16718
+ {
16719
+ label: t("tokenUsage.cacheRead", "Cache Read"),
16720
+ value: usage.cachedReadTokens.toLocaleString()
16721
+ }
16722
+ ),
16723
+ usage.cachedWriteTokens != null && usage.cachedWriteTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
16724
+ MetricCard,
16725
+ {
16726
+ label: t("tokenUsage.cacheWrite", "Cache Write"),
16727
+ value: usage.cachedWriteTokens.toLocaleString()
16728
+ }
16729
+ )
16730
+ ] });
16731
+ }
16732
+ function SessionSummary({ records }) {
16733
+ const { t } = useTranslation();
16734
+ const totalInput = records.reduce((sum, record) => sum + record.usage.inputTokens, 0);
16735
+ const totalOutput = records.reduce((sum, record) => sum + record.usage.outputTokens, 0);
16736
+ const totalThought = records.reduce((sum, record) => sum + (record.usage.thoughtTokens ?? 0), 0);
16737
+ const totalCached = records.reduce(
16738
+ (sum, record) => sum + (record.usage.cachedReadTokens ?? 0),
16739
+ 0
16740
+ );
16741
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "pb-3", children: [
16742
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
16743
+ SectionHeader,
16744
+ {
16745
+ icon: MessagesSquare,
16746
+ title: t("tokenUsage.sessionTotal", "Session Total"),
16747
+ badge: t("tokenUsage.promptCount", "{{count}} prompts", {
16748
+ count: records.length
16749
+ })
16750
+ }
16751
+ ),
16752
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 grid grid-cols-3 gap-1.5", children: [
16753
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { label: t("tokenUsage.input", "Input"), value: totalInput.toLocaleString() }),
16754
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MetricCard, { label: t("tokenUsage.output", "Output"), value: totalOutput.toLocaleString() }),
16755
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
16756
+ MetricCard,
16757
+ {
16758
+ label: t("tokenUsage.totalTokens", "Total"),
16759
+ value: (totalInput + totalOutput).toLocaleString()
16760
+ }
16761
+ ),
16762
+ totalThought > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
16763
+ MetricCard,
16764
+ {
16765
+ label: t("tokenUsage.thought", "Thought"),
16766
+ value: totalThought.toLocaleString()
16767
+ }
16768
+ ),
16769
+ totalCached > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
16770
+ MetricCard,
16771
+ {
16772
+ label: t("tokenUsage.cached", "Cached"),
16773
+ value: totalCached.toLocaleString()
16774
+ }
16775
+ )
16776
+ ] })
16777
+ ] });
16778
+ }
16779
+ function InputCompositionSection({ composition }) {
16780
+ const { t } = useTranslation();
16781
+ const parts = [
16782
+ {
16783
+ label: t("tokenUsage.systemPrompt", "System Prompt"),
16784
+ value: composition.systemPrompt,
16785
+ color: "bg-blue-500/80"
16786
+ },
16787
+ {
16788
+ label: t("tokenUsage.tools", "Tools"),
16789
+ value: composition.toolsDefinition.total,
16790
+ color: "bg-amber-500/80"
16791
+ },
16792
+ {
16793
+ label: t("tokenUsage.history", "History"),
16794
+ value: composition.history,
16795
+ color: "bg-emerald-500/80"
16796
+ },
16797
+ {
16798
+ label: t("tokenUsage.userMessage", "User Message"),
16799
+ value: composition.userMessage,
16800
+ color: "bg-purple-500/80"
16801
+ }
16802
+ ];
16803
+ const total = composition.estimatedTotal || parts.reduce((sum, part) => sum + part.value, 0);
16804
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border-t border-border/50 pt-3", children: [
16805
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionHeader, { icon: Layers, title: t("tokenUsage.inputComposition", "Input Composition") }),
16806
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-2.5 w-full rounded-full bg-muted/80 overflow-hidden flex mt-2.5 ring-1 ring-border/30", children: parts.map(
16807
+ (part) => part.value > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
16808
+ "div",
16809
+ {
16810
+ className: cn$1("h-full", part.color),
16811
+ style: { width: `${total > 0 ? part.value / total * 100 : 0}%` }
16812
+ },
16813
+ part.label
16814
+ )
16815
+ ) }),
16816
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "my-3 grid grid-cols-2 gap-x-4 gap-y-1 text-[10px]", children: parts.map((part) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
16817
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 min-w-0", children: [
16818
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn$1("size-2 rounded-sm shrink-0", part.color) }),
16819
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground truncate", children: part.label })
16820
+ ] }),
16821
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums text-muted-foreground shrink-0", children: part.value.toLocaleString() })
16822
+ ] }, part.label)) }),
16823
+ composition.delta !== 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1.5 text-[10px] text-muted-foreground/60", children: [
16824
+ t("tokenUsage.delta", "Estimation delta"),
16825
+ ": ",
16826
+ composition.delta > 0 ? "+" : "",
16827
+ composition.delta.toLocaleString(),
16828
+ " ",
16829
+ t("tokenUsage.tokens", "tokens")
16830
+ ] })
16831
+ ] });
16832
+ }
16833
+ function UserMessageSection({ text }) {
16834
+ const { t } = useTranslation();
16835
+ if (!text) return null;
16836
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border-t border-border/50 pt-3", children: [
16837
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionHeader, { icon: MessageSquare, title: t("tokenUsage.userMessage", "User Message") }),
16838
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { viewportClassName: "mt-2 max-h-40 rounded-md border border-border/60 bg-muted/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "whitespace-pre-wrap wrap-break-word px-2 py-1.5 text-[10px] leading-relaxed text-foreground/70 font-mono", children: text }) })
16839
+ ] });
16840
+ }
16841
+ function ToolsBreakdownSection({ tools }) {
16842
+ const { t } = useTranslation();
16843
+ const [expanded, setExpanded] = reactExports.useState(false);
16844
+ if (tools.perTool.length === 0) return null;
16845
+ const sorted = [...tools.perTool].sort((a, b2) => b2.tokens - a.tokens);
16846
+ const topCount = expanded ? sorted.length : 8;
16847
+ const topTools = sorted.slice(0, topCount);
16848
+ const rest = sorted.slice(topCount);
16849
+ const restTotal = rest.reduce((sum, tool) => sum + tool.tokens, 0);
16850
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border-t border-border/50 pt-3", children: [
16851
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
16852
+ SectionHeader,
16853
+ {
16854
+ icon: Wrench,
16855
+ title: t("tokenUsage.toolsDefinition", "Tools Definition"),
16856
+ badge: t("tokenUsage.toolsCount", "{{count}} tools · {{tokens}} tokens", {
16857
+ count: tools.perTool.length,
16858
+ tokens: tools.total.toLocaleString()
16859
+ })
16860
+ }
16861
+ ),
16862
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 space-y-1 text-[10px]", children: [
16863
+ topTools.map((tool) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
16864
+ "div",
16865
+ {
16866
+ className: "flex items-center gap-2 rounded px-1 -mx-1 py-0.5 hover:bg-muted/40 transition-colors",
16867
+ children: [
16868
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0 truncate font-mono text-muted-foreground", children: tool.name }),
16869
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums font-medium text-foreground/75 shrink-0", children: tool.tokens.toLocaleString() }),
16870
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-16 h-1 rounded-full bg-muted overflow-hidden shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
16871
+ "div",
16872
+ {
16873
+ className: "h-full bg-amber-500/60 rounded-full",
16874
+ style: { width: `${tool.tokens / (sorted[0]?.tokens || 1) * 100}%` }
16875
+ }
16876
+ ) })
16877
+ ]
16878
+ },
16879
+ tool.name
16880
+ )),
16881
+ rest.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
16882
+ "div",
16883
+ {
16884
+ className: "flex items-center gap-2 text-muted-foreground/60 hover:underline cursor-default",
16885
+ onClick: () => setExpanded(true),
16886
+ children: [
16887
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1", children: t("tokenUsage.more", "+{{count}} more", { count: rest.length }) }),
16888
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums shrink-0", children: restTotal.toLocaleString() }),
16889
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-16 shrink-0" })
16890
+ ]
16891
+ }
16892
+ )
16893
+ ] })
16894
+ ] });
16895
+ }
16896
+ function StepsSection({ steps }) {
16897
+ const { t } = useTranslation();
16898
+ const [expandedSteps, setExpandedSteps] = reactExports.useState(() => /* @__PURE__ */ new Set());
16899
+ if (steps.length === 0) return null;
16900
+ const toggleStep = (stepNumber) => {
16901
+ setExpandedSteps((current) => {
16902
+ const next = new Set(current);
16903
+ if (next.has(stepNumber)) next.delete(stepNumber);
16904
+ else next.add(stepNumber);
16905
+ return next;
16906
+ });
16907
+ };
16908
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border-t border-border/50 pt-3", children: [
16909
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
16910
+ SectionHeader,
16911
+ {
16912
+ icon: Layers,
16913
+ title: t("tokenUsage.steps", "Steps"),
16914
+ badge: t("tokenUsage.stepsCount", "{{count}} steps", { count: steps.length })
16915
+ }
16916
+ ),
16917
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2", children: steps.map((step) => {
16918
+ const expanded = expandedSteps.has(step.stepNumber);
16919
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
16920
+ "div",
16921
+ {
16922
+ className: "transition-colors border-b border-border/70 last:border-transparent",
16923
+ children: [
16924
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
16925
+ "button",
16926
+ {
16927
+ type: "button",
16928
+ onClick: () => toggleStep(step.stepNumber),
16929
+ className: "w-full flex items-center py-1.5 text-left hover:bg-muted/30 transition-colors px-1",
16930
+ children: [
16931
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex size-5 shrink-0 items-center justify-center text-primary -ml-2", children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3" }) }),
16932
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 items-center ml-0.5", children: [
16933
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center justify-center text-[11px] font-semibold text-muted-foreground shrink-0", children: [
16934
+ "#",
16935
+ step.stepNumber
16936
+ ] }),
16937
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
16938
+ "span",
16939
+ {
16940
+ className: cn$1(
16941
+ "rounded-full px-1.5 py-0.5 text-[10px] font-medium uppercase truncate",
16942
+ finishReasonBadge(step.finishReason)
16943
+ ),
16944
+ children: step.finishReason
16945
+ }
16946
+ )
16947
+ ] }),
16948
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-4 ml-auto font-mono text-[10px] tabular-nums text-muted-foreground shrink-0", children: [
16949
+ step.toolCalls.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-baseline shrink-0 gap-1", children: [
16950
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: step.toolCalls.length }),
16951
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground/70", children: t("tokenUsage.toolCalls", "tool calls") })
16952
+ ] }),
16953
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1", children: [
16954
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: step.inputTokens.toLocaleString() }),
16955
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground/70", children: t("tokenUsage.inputShort", "in") })
16956
+ ] }),
16957
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1", children: [
16958
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: step.outputTokens.toLocaleString() }),
16959
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground/70", children: t("tokenUsage.outputShort", "out") })
16960
+ ] })
16961
+ ] })
16962
+ ]
16963
+ }
16964
+ ),
16965
+ expanded && /* @__PURE__ */ jsxRuntimeExports.jsx(StepDetails, { step })
16966
+ ]
16967
+ },
16968
+ step.stepNumber
16969
+ );
16970
+ }) })
16971
+ ] });
16972
+ }
16973
+ function StepDetails({ step }) {
16974
+ const { t } = useTranslation();
16975
+ const { inputDetails, outputDetails, performance: performance2 } = step;
16976
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-border/40", children: [
16977
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-1 py-1", children: [
16978
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
16979
+ DetailMetric,
16980
+ {
16981
+ label: t("tokenUsage.input", "Input"),
16982
+ value: step.inputTokens.toLocaleString()
16983
+ }
16984
+ ),
16985
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
16986
+ DetailMetric,
16987
+ {
16988
+ label: t("tokenUsage.output", "Output"),
16989
+ value: step.outputTokens.toLocaleString()
16990
+ }
16991
+ )
16992
+ ] }),
16993
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-[10px] space-y-1", children: [
16994
+ inputDetails.cacheReadTokens != null && inputDetails.cacheReadTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
16995
+ MetricRow,
16996
+ {
16997
+ label: t("tokenUsage.cacheRead", "Cache Read"),
16998
+ value: inputDetails.cacheReadTokens.toLocaleString()
16999
+ }
17000
+ ),
17001
+ inputDetails.cacheWriteTokens != null && inputDetails.cacheWriteTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
17002
+ MetricRow,
17003
+ {
17004
+ label: t("tokenUsage.cacheWrite", "Cache Write"),
17005
+ value: inputDetails.cacheWriteTokens.toLocaleString()
17006
+ }
17007
+ ),
17008
+ inputDetails.noCacheTokens != null && inputDetails.noCacheTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
17009
+ MetricRow,
17010
+ {
17011
+ label: t("tokenUsage.noCache", "No Cache"),
17012
+ value: inputDetails.noCacheTokens.toLocaleString()
17013
+ }
17014
+ ),
17015
+ outputDetails.textTokens != null && outputDetails.textTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
17016
+ MetricRow,
17017
+ {
17018
+ label: t("tokenUsage.text", "Text"),
17019
+ value: outputDetails.textTokens.toLocaleString()
17020
+ }
17021
+ ),
17022
+ outputDetails.reasoningTokens != null && outputDetails.reasoningTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
17023
+ MetricRow,
17024
+ {
17025
+ label: t("tokenUsage.thought", "Thought"),
17026
+ value: outputDetails.reasoningTokens.toLocaleString()
17027
+ }
17028
+ ),
17029
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
17030
+ MetricRow,
17031
+ {
17032
+ label: t("tokenUsage.stepTime", "Step Time"),
17033
+ value: formatMs(performance2.stepTimeMs)
17034
+ }
17035
+ ),
17036
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
17037
+ MetricRow,
17038
+ {
17039
+ label: t("tokenUsage.responseTime", "Response Time"),
17040
+ value: formatMs(performance2.responseTimeMs)
17041
+ }
17042
+ )
17043
+ ] }),
17044
+ step.toolCalls.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pt-1 mt-3 border-t border-border/40", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1", children: step.toolCalls.map((toolCall, index) => /* @__PURE__ */ jsxRuntimeExports.jsx(ToolCallRow, { toolCall }, `${toolCall.toolName}-${index}`)) }) })
17045
+ ] });
17046
+ }
17047
+ function ToolCallRow({ toolCall }) {
17048
+ const { t } = useTranslation();
17049
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-4 border-t border-border/40 first:border-transparent -mt-px", children: [
17050
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 min-w-0", children: [
17051
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-3 shrink-0 text-foreground/80" }),
17052
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[10px] font-medium text-foreground/80 truncate", children: shortToolName(toolCall.toolName) }),
17053
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-auto max-w-[45%] truncate text-[10px] text-muted-foreground/50 font-mono", children: toolCall.toolName })
17054
+ ] }),
17055
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-3 gap-1 -mb-2", children: [
17056
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
17057
+ DetailMetric,
17058
+ {
17059
+ label: t("tokenUsage.arguments", "Arguments"),
17060
+ value: `${toolCall.argumentsOutputTokens.toLocaleString()} ${t("tokenUsage.token", "token")}`
17061
+ }
17062
+ ),
17063
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
17064
+ DetailMetric,
17065
+ {
17066
+ label: t("tokenUsage.result", "Result"),
17067
+ value: `${toolCall.resultInputTokens.toLocaleString()} ${t("tokenUsage.token", "token")}`
17068
+ }
17069
+ ),
17070
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
17071
+ DetailMetric,
17072
+ {
17073
+ label: t("tokenUsage.execution", "Execution"),
17074
+ value: toolCall.executionMs != null ? formatMs(toolCall.executionMs) : "—"
17075
+ }
17076
+ )
17077
+ ] }),
17078
+ toolCall.args && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2", children: [
17079
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground/70 mb-1", children: t("tokenUsage.arguments", "Arguments") }),
17080
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { viewportClassName: "max-h-32 rounded-md border border-border/60 bg-muted/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "whitespace-pre-wrap wrap-break-word px-2 py-1.5 text-[10px] leading-relaxed text-foreground/70 font-mono", children: formatToolArgs(toolCall.args) }) })
17081
+ ] })
17082
+ ] });
17083
+ }
17084
+ function PerformanceSection({
17085
+ performance: performance2,
17086
+ steps
17087
+ }) {
17088
+ const { t } = useTranslation();
17089
+ const ttft = steps[0]?.performance.timeToFirstOutputMs;
17090
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border-t border-border/50 pt-3", children: [
17091
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionHeader, { icon: Gauge, title: t("tokenUsage.performance", "Performance") }),
17092
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 grid grid-cols-3 gap-1.5", children: [
17093
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
17094
+ DetailMetric,
17095
+ {
17096
+ label: t("tokenUsage.totalTime", "Total Time"),
17097
+ value: formatMs(performance2.totalTimeMs)
17098
+ }
17099
+ ),
17100
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
17101
+ DetailMetric,
17102
+ {
17103
+ label: t("tokenUsage.outputSpeed", "Output Speed"),
17104
+ value: `${Math.round(performance2.effectiveOutputTokensPerSecond)} ${t("tokenUsage.tokensPerSecond", "token/s")}`
17105
+ }
17106
+ ),
17107
+ ttft != null && /* @__PURE__ */ jsxRuntimeExports.jsx(DetailMetric, { label: t("tokenUsage.firstToken", "First Token"), value: formatMs(ttft) })
17108
+ ] })
17109
+ ] });
17110
+ }
17111
+ function MetricCard({ label, value }) {
17112
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-2", children: [
17113
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground/70", children: label }),
17114
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 font-mono text-sm font-semibold tabular-nums text-foreground/70 truncate", children: value })
17115
+ ] });
17116
+ }
17117
+ function DetailMetric({ label, value }) {
17118
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-2", children: [
17119
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-medium uppercase tracking-wide truncate text-muted-foreground/70", children: label }),
17120
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1.5 font-mono text-xs font-medium tabular-nums text-foreground/70 truncate", children: value })
17121
+ ] });
17122
+ }
17123
+ function SectionHeader({
17124
+ icon: Icon,
17125
+ title,
17126
+ badge
17127
+ }) {
17128
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [
17129
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { className: "size-3 text-muted-foreground" }),
17130
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-semibold text-foreground/80", children: title }),
17131
+ badge && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground/60 ml-auto", children: badge })
17132
+ ] });
17133
+ }
17134
+ function MetricRow({ label, value }) {
17135
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between min-w-0 gap-2 hover:bg-accent/60 px-1 py-0.5 -mx-1 rounded-sm", children: [
17136
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground truncate", children: label }),
17137
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums text-foreground/80 shrink-0", children: value })
17138
+ ] });
17139
+ }
17140
+ function isRecord(value) {
17141
+ return typeof value === "object" && value !== null;
17142
+ }
17143
+ function parseTokenUsageRecords(records) {
17144
+ const parsed = [];
17145
+ for (const record of records) {
17146
+ if (isTokenUsageRecord(record)) parsed.push(record);
17147
+ }
17148
+ return parsed;
17149
+ }
17150
+ function isTokenUsageRecord(value) {
17151
+ if (!isRecord(value) || typeof value.timestamp !== "number" || !isRecord(value.usage)) {
17152
+ return false;
17153
+ }
17154
+ return typeof value.usage.totalTokens === "number" && typeof value.usage.inputTokens === "number" && typeof value.usage.outputTokens === "number";
17155
+ }
17156
+ function isTokenBreakdown(value) {
17157
+ if (!isRecord(value)) return false;
17158
+ const composition = value.inputComposition;
17159
+ return typeof value.stepCount === "number" && Array.isArray(value.steps) && isRecord(composition) && isRecord(composition.toolsDefinition) && Array.isArray(composition.toolsDefinition.perTool) && isRecord(value.performance);
17160
+ }
17161
+ function getBreakdown(usage) {
17162
+ const breakdown = usage._meta?.fello?.tokenBreakdown;
17163
+ return isTokenBreakdown(breakdown) ? breakdown : void 0;
17164
+ }
17165
+ function createLiveRecord(usage, timestamp) {
17166
+ if (!usage) return null;
17167
+ const breakdown = getBreakdownFromUnknownUsage(usage);
17168
+ if (!breakdown) return null;
17169
+ return {
17170
+ timestamp,
17171
+ usage: {
17172
+ totalTokens: usage.totalTokens,
17173
+ inputTokens: usage.inputTokens,
17174
+ outputTokens: usage.outputTokens,
17175
+ thoughtTokens: usage.thoughtTokens,
17176
+ cachedReadTokens: usage.cachedReadTokens,
17177
+ cachedWriteTokens: usage.cachedWriteTokens,
17178
+ _meta: { fello: { tokenBreakdown: breakdown } }
17179
+ }
17180
+ };
17181
+ }
17182
+ function finishReasonBadge(reason) {
17183
+ if (reason === "stop" || reason === "end_turn") {
17184
+ return "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400";
17185
+ }
17186
+ if (reason === "tool_calls" || reason === "tool_call") {
17187
+ return "bg-amber-500/10 text-amber-600 dark:text-amber-400";
17188
+ }
17189
+ if (reason === "length" || reason === "max_tokens") {
17190
+ return "bg-orange-500/10 text-orange-600 dark:text-orange-400";
17191
+ }
17192
+ return "bg-muted text-muted-foreground";
17193
+ }
17194
+ function getBreakdownFromUnknownUsage(usage) {
17195
+ if (!isRecord(usage) || !isRecord(usage._meta) || !isRecord(usage._meta.fello)) {
17196
+ return void 0;
17197
+ }
17198
+ return isTokenBreakdown(usage._meta.fello.tokenBreakdown) ? usage._meta.fello.tokenBreakdown : void 0;
17199
+ }
17200
+ function mergeLiveRecord(records, liveRecord) {
17201
+ if (!liveRecord) return records;
17202
+ const lastRecord = records[records.length - 1];
17203
+ if (lastRecord && getUsageFingerprint(lastRecord.usage) === getUsageFingerprint(liveRecord.usage)) {
17204
+ return records;
17205
+ }
17206
+ return [...records, liveRecord];
17207
+ }
17208
+ function getUsageFingerprint(usage) {
17209
+ return JSON.stringify(usage) ?? "";
17210
+ }
17211
+ function shortToolName(name) {
17212
+ const parts = name.split("__");
17213
+ return parts[parts.length - 1] || name;
17214
+ }
17215
+ function formatToolArgs(args) {
17216
+ try {
17217
+ return JSON.stringify(JSON.parse(args), null, 2);
17218
+ } catch {
17219
+ return args;
17220
+ }
17221
+ }
17222
+ function formatTimestamp(timestamp) {
17223
+ return new Date(timestamp).toLocaleTimeString([], {
17224
+ hour: "2-digit",
17225
+ minute: "2-digit",
17226
+ second: "2-digit"
17227
+ });
17228
+ }
17229
+ function formatMs(ms2) {
17230
+ if (ms2 < 1e3) return `${Math.round(ms2)}ms`;
17231
+ return `${(ms2 / 1e3).toFixed(1)}s`;
17232
+ }
17233
+ function Detail({ detailType, projectId, file, terminalId, session, onClose }) {
15887
17234
  const { t } = useTranslation();
15888
17235
  if (!detailType) return null;
15889
17236
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col h-full min-h-0 overflow-hidden bg-background", children: [
@@ -15897,7 +17244,8 @@ function Detail({ detailType, projectId, file, terminalId, onClose }) {
15897
17244
  },
15898
17245
  terminalId
15899
17246
  ),
15900
- (!detailType || detailType === "file" && (!projectId || !file) || detailType === "terminal" && (!projectId || !terminalId)) && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full items-center justify-center text-xs text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("detail.noContent", "No content") }) })
17247
+ detailType === "token-usage" && session && /* @__PURE__ */ jsxRuntimeExports.jsx(TokenUsageDetail, { session, onClose }),
17248
+ (!detailType || detailType === "file" && (!projectId || !file) || detailType === "terminal" && (!projectId || !terminalId) || detailType === "token-usage" && !session) && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full items-center justify-center text-xs text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("detail.noContent", "No content") }) })
15901
17249
  ] });
15902
17250
  }
15903
17251
  const GIT_FOLDER_STATUS = {
@@ -17550,6 +18898,15 @@ function Session({ session }) {
17550
18898
  document.addEventListener("fello-preview-file", handlePreviewFileEvent);
17551
18899
  return () => document.removeEventListener("fello-preview-file", handlePreviewFileEvent);
17552
18900
  }, [currentProjectId, handlePreviewFile]);
18901
+ reactExports.useEffect(() => {
18902
+ const handleOpenTokenUsage = () => {
18903
+ setDetailType("token-usage");
18904
+ setDetailFile(null);
18905
+ setDetailTerminalId(null);
18906
+ };
18907
+ document.addEventListener("fello-open-token-usage", handleOpenTokenUsage);
18908
+ return () => document.removeEventListener("fello-open-token-usage", handleOpenTokenUsage);
18909
+ }, []);
17553
18910
  const fetchingRef = reactExports.useRef(null);
17554
18911
  const [connectionError, setConnectionError] = reactExports.useState(false);
17555
18912
  reactExports.useEffect(() => {
@@ -17655,6 +19012,7 @@ function Session({ session }) {
17655
19012
  projectId: currentProjectId,
17656
19013
  file: detailFile,
17657
19014
  terminalId: detailTerminalId,
19015
+ session,
17658
19016
  onClose: handleDetailClose
17659
19017
  }
17660
19018
  ) })