@blade-hq/agent-kit 0.0.0-placeholder.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (763) hide show
  1. package/dist/client.d.ts +16 -0
  2. package/dist/client.d.ts.map +1 -0
  3. package/dist/client.js +75 -0
  4. package/dist/client.js.map +1 -0
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +2 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/internal/core/api/auth-resolve.d.ts +10 -0
  10. package/dist/internal/core/api/auth-resolve.d.ts.map +1 -0
  11. package/dist/internal/core/api/auth-resolve.js +25 -0
  12. package/dist/internal/core/api/auth-resolve.js.map +1 -0
  13. package/dist/internal/core/api/auth.d.ts +22 -0
  14. package/dist/internal/core/api/auth.d.ts.map +1 -0
  15. package/dist/internal/core/api/auth.js +13 -0
  16. package/dist/internal/core/api/auth.js.map +1 -0
  17. package/dist/internal/core/api/client.d.ts +20 -0
  18. package/dist/internal/core/api/client.d.ts.map +1 -0
  19. package/dist/internal/core/api/client.js +135 -0
  20. package/dist/internal/core/api/client.js.map +1 -0
  21. package/dist/internal/core/api/gis-api.d.ts +4 -0
  22. package/dist/internal/core/api/gis-api.d.ts.map +1 -0
  23. package/dist/internal/core/api/gis-api.js +8 -0
  24. package/dist/internal/core/api/gis-api.js.map +1 -0
  25. package/dist/internal/core/api/licenses.d.ts +26 -0
  26. package/dist/internal/core/api/licenses.d.ts.map +1 -0
  27. package/dist/internal/core/api/licenses.js +40 -0
  28. package/dist/internal/core/api/licenses.js.map +1 -0
  29. package/dist/internal/core/api/memories.d.ts +46 -0
  30. package/dist/internal/core/api/memories.d.ts.map +1 -0
  31. package/dist/internal/core/api/memories.js +49 -0
  32. package/dist/internal/core/api/memories.js.map +1 -0
  33. package/dist/internal/core/api/models.d.ts +15 -0
  34. package/dist/internal/core/api/models.d.ts.map +1 -0
  35. package/dist/internal/core/api/models.js +15 -0
  36. package/dist/internal/core/api/models.js.map +1 -0
  37. package/dist/internal/core/api/partner-skill.d.ts +3 -0
  38. package/dist/internal/core/api/partner-skill.d.ts.map +1 -0
  39. package/dist/internal/core/api/partner-skill.js +9 -0
  40. package/dist/internal/core/api/partner-skill.js.map +1 -0
  41. package/dist/internal/core/api/registry.d.ts +272 -0
  42. package/dist/internal/core/api/registry.d.ts.map +1 -0
  43. package/dist/internal/core/api/registry.js +67 -0
  44. package/dist/internal/core/api/registry.js.map +1 -0
  45. package/dist/internal/core/api/scenarios.d.ts +51 -0
  46. package/dist/internal/core/api/scenarios.d.ts.map +1 -0
  47. package/dist/internal/core/api/scenarios.js +30 -0
  48. package/dist/internal/core/api/scenarios.js.map +1 -0
  49. package/dist/internal/core/api/sessions.d.ts +223 -0
  50. package/dist/internal/core/api/sessions.d.ts.map +1 -0
  51. package/dist/internal/core/api/sessions.js +340 -0
  52. package/dist/internal/core/api/sessions.js.map +1 -0
  53. package/dist/internal/core/api/skills.d.ts +19 -0
  54. package/dist/internal/core/api/skills.d.ts.map +1 -0
  55. package/dist/internal/core/api/skills.js +28 -0
  56. package/dist/internal/core/api/skills.js.map +1 -0
  57. package/dist/internal/core/api/socket.d.ts +56 -0
  58. package/dist/internal/core/api/socket.d.ts.map +1 -0
  59. package/dist/internal/core/api/socket.js +824 -0
  60. package/dist/internal/core/api/socket.js.map +1 -0
  61. package/dist/internal/core/api/software-factory.d.ts +126 -0
  62. package/dist/internal/core/api/software-factory.d.ts.map +1 -0
  63. package/dist/internal/core/api/software-factory.js +130 -0
  64. package/dist/internal/core/api/software-factory.js.map +1 -0
  65. package/dist/internal/core/api/solutions.d.ts +5 -0
  66. package/dist/internal/core/api/solutions.d.ts.map +1 -0
  67. package/dist/internal/core/api/solutions.js +21 -0
  68. package/dist/internal/core/api/solutions.js.map +1 -0
  69. package/dist/internal/core/api/user-preferences.d.ts +3 -0
  70. package/dist/internal/core/api/user-preferences.d.ts.map +1 -0
  71. package/dist/internal/core/api/user-preferences.js +12 -0
  72. package/dist/internal/core/api/user-preferences.js.map +1 -0
  73. package/dist/internal/core/api/vibe-coding.d.ts +90 -0
  74. package/dist/internal/core/api/vibe-coding.d.ts.map +1 -0
  75. package/dist/internal/core/api/vibe-coding.js +121 -0
  76. package/dist/internal/core/api/vibe-coding.js.map +1 -0
  77. package/dist/internal/core/asr/VoiceWaveform.d.ts +11 -0
  78. package/dist/internal/core/asr/VoiceWaveform.d.ts.map +1 -0
  79. package/dist/internal/core/asr/VoiceWaveform.js +28 -0
  80. package/dist/internal/core/asr/VoiceWaveform.js.map +1 -0
  81. package/dist/internal/core/asr/use-tiptap-voice-input.d.ts +30 -0
  82. package/dist/internal/core/asr/use-tiptap-voice-input.d.ts.map +1 -0
  83. package/dist/internal/core/asr/use-tiptap-voice-input.js +100 -0
  84. package/dist/internal/core/asr/use-tiptap-voice-input.js.map +1 -0
  85. package/dist/internal/core/asr/use-voice-input.d.ts +18 -0
  86. package/dist/internal/core/asr/use-voice-input.d.ts.map +1 -0
  87. package/dist/internal/core/asr/use-voice-input.js +312 -0
  88. package/dist/internal/core/asr/use-voice-input.js.map +1 -0
  89. package/dist/internal/core/asr/voice-input-support.d.ts +6 -0
  90. package/dist/internal/core/asr/voice-input-support.d.ts.map +1 -0
  91. package/dist/internal/core/asr/voice-input-support.js +35 -0
  92. package/dist/internal/core/asr/voice-input-support.js.map +1 -0
  93. package/dist/internal/core/components/ai-elements/file-tree.d.ts +27 -0
  94. package/dist/internal/core/components/ai-elements/file-tree.d.ts.map +1 -0
  95. package/dist/internal/core/components/ai-elements/file-tree.js +73 -0
  96. package/dist/internal/core/components/ai-elements/file-tree.js.map +1 -0
  97. package/dist/internal/core/components/ai-elements/reasoning.d.ts +33 -0
  98. package/dist/internal/core/components/ai-elements/reasoning.d.ts.map +1 -0
  99. package/dist/internal/core/components/ai-elements/reasoning.js +124 -0
  100. package/dist/internal/core/components/ai-elements/reasoning.js.map +1 -0
  101. package/dist/internal/core/components/ai-elements/shimmer.d.ts +10 -0
  102. package/dist/internal/core/components/ai-elements/shimmer.d.ts.map +1 -0
  103. package/dist/internal/core/components/ai-elements/shimmer.js +29 -0
  104. package/dist/internal/core/components/ai-elements/shimmer.js.map +1 -0
  105. package/dist/internal/core/components/card/CardCodeBlock.d.ts +6 -0
  106. package/dist/internal/core/components/card/CardCodeBlock.d.ts.map +1 -0
  107. package/dist/internal/core/components/card/CardCodeBlock.js +24 -0
  108. package/dist/internal/core/components/card/CardCodeBlock.js.map +1 -0
  109. package/dist/internal/core/components/card/CardContext.d.ts +8 -0
  110. package/dist/internal/core/components/card/CardContext.d.ts.map +1 -0
  111. package/dist/internal/core/components/card/CardContext.js +4 -0
  112. package/dist/internal/core/components/card/CardContext.js.map +1 -0
  113. package/dist/internal/core/components/card/CardRenderer.d.ts +8 -0
  114. package/dist/internal/core/components/card/CardRenderer.d.ts.map +1 -0
  115. package/dist/internal/core/components/card/CardRenderer.js +82 -0
  116. package/dist/internal/core/components/card/CardRenderer.js.map +1 -0
  117. package/dist/internal/core/components/card/CardStates.d.ts +9 -0
  118. package/dist/internal/core/components/card/CardStates.d.ts.map +1 -0
  119. package/dist/internal/core/components/card/CardStates.js +11 -0
  120. package/dist/internal/core/components/card/CardStates.js.map +1 -0
  121. package/dist/internal/core/components/card/cards/attraction-card.d.ts +3 -0
  122. package/dist/internal/core/components/card/cards/attraction-card.d.ts.map +1 -0
  123. package/dist/internal/core/components/card/cards/attraction-card.js +10 -0
  124. package/dist/internal/core/components/card/cards/attraction-card.js.map +1 -0
  125. package/dist/internal/core/components/card/cards/cite-card.d.ts +11 -0
  126. package/dist/internal/core/components/card/cards/cite-card.d.ts.map +1 -0
  127. package/dist/internal/core/components/card/cards/cite-card.js +12 -0
  128. package/dist/internal/core/components/card/cards/cite-card.js.map +1 -0
  129. package/dist/internal/core/components/card/cards/comprehensive-analysis-card.d.ts +3 -0
  130. package/dist/internal/core/components/card/cards/comprehensive-analysis-card.d.ts.map +1 -0
  131. package/dist/internal/core/components/card/cards/comprehensive-analysis-card.js +160 -0
  132. package/dist/internal/core/components/card/cards/comprehensive-analysis-card.js.map +1 -0
  133. package/dist/internal/core/components/card/cards/conflict-detection-card.d.ts +5 -0
  134. package/dist/internal/core/components/card/cards/conflict-detection-card.d.ts.map +1 -0
  135. package/dist/internal/core/components/card/cards/conflict-detection-card.js +46 -0
  136. package/dist/internal/core/components/card/cards/conflict-detection-card.js.map +1 -0
  137. package/dist/internal/core/components/card/cards/counter.d.ts +3 -0
  138. package/dist/internal/core/components/card/cards/counter.d.ts.map +1 -0
  139. package/dist/internal/core/components/card/cards/counter.js +10 -0
  140. package/dist/internal/core/components/card/cards/counter.js.map +1 -0
  141. package/dist/internal/core/components/card/cards/damage-effect-card.d.ts +5 -0
  142. package/dist/internal/core/components/card/cards/damage-effect-card.d.ts.map +1 -0
  143. package/dist/internal/core/components/card/cards/damage-effect-card.js +138 -0
  144. package/dist/internal/core/components/card/cards/damage-effect-card.js.map +1 -0
  145. package/dist/internal/core/components/card/cards/destination-card.d.ts +3 -0
  146. package/dist/internal/core/components/card/cards/destination-card.d.ts.map +1 -0
  147. package/dist/internal/core/components/card/cards/destination-card.js +10 -0
  148. package/dist/internal/core/components/card/cards/destination-card.js.map +1 -0
  149. package/dist/internal/core/components/card/cards/diff-card.d.ts +3 -0
  150. package/dist/internal/core/components/card/cards/diff-card.d.ts.map +1 -0
  151. package/dist/internal/core/components/card/cards/diff-card.js +81 -0
  152. package/dist/internal/core/components/card/cards/diff-card.js.map +1 -0
  153. package/dist/internal/core/components/card/cards/execution-order-card.d.ts +3 -0
  154. package/dist/internal/core/components/card/cards/execution-order-card.d.ts.map +1 -0
  155. package/dist/internal/core/components/card/cards/execution-order-card.js +97 -0
  156. package/dist/internal/core/components/card/cards/execution-order-card.js.map +1 -0
  157. package/dist/internal/core/components/card/cards/experience-card-with-options.d.ts +5 -0
  158. package/dist/internal/core/components/card/cards/experience-card-with-options.d.ts.map +1 -0
  159. package/dist/internal/core/components/card/cards/experience-card-with-options.js +113 -0
  160. package/dist/internal/core/components/card/cards/experience-card-with-options.js.map +1 -0
  161. package/dist/internal/core/components/card/cards/flight-card.d.ts +3 -0
  162. package/dist/internal/core/components/card/cards/flight-card.d.ts.map +1 -0
  163. package/dist/internal/core/components/card/cards/flight-card.js +10 -0
  164. package/dist/internal/core/components/card/cards/flight-card.js.map +1 -0
  165. package/dist/internal/core/components/card/cards/hotel-card.d.ts +3 -0
  166. package/dist/internal/core/components/card/cards/hotel-card.d.ts.map +1 -0
  167. package/dist/internal/core/components/card/cards/hotel-card.js +10 -0
  168. package/dist/internal/core/components/card/cards/hotel-card.js.map +1 -0
  169. package/dist/internal/core/components/card/cards/kill-chain-card.d.ts +3 -0
  170. package/dist/internal/core/components/card/cards/kill-chain-card.d.ts.map +1 -0
  171. package/dist/internal/core/components/card/cards/kill-chain-card.js +230 -0
  172. package/dist/internal/core/components/card/cards/kill-chain-card.js.map +1 -0
  173. package/dist/internal/core/components/card/cards/kill-chain-types.d.ts +158 -0
  174. package/dist/internal/core/components/card/cards/kill-chain-types.d.ts.map +1 -0
  175. package/dist/internal/core/components/card/cards/kill-chain-types.js +9 -0
  176. package/dist/internal/core/components/card/cards/kill-chain-types.js.map +1 -0
  177. package/dist/internal/core/components/card/cards/map-card.d.ts +3 -0
  178. package/dist/internal/core/components/card/cards/map-card.d.ts.map +1 -0
  179. package/dist/internal/core/components/card/cards/map-card.js +60 -0
  180. package/dist/internal/core/components/card/cards/map-card.js.map +1 -0
  181. package/dist/internal/core/components/card/cards/order-status-card.d.ts +3 -0
  182. package/dist/internal/core/components/card/cards/order-status-card.d.ts.map +1 -0
  183. package/dist/internal/core/components/card/cards/order-status-card.js +57 -0
  184. package/dist/internal/core/components/card/cards/order-status-card.js.map +1 -0
  185. package/dist/internal/core/components/card/cards/patch-card.d.ts +16 -0
  186. package/dist/internal/core/components/card/cards/patch-card.d.ts.map +1 -0
  187. package/dist/internal/core/components/card/cards/patch-card.js +47 -0
  188. package/dist/internal/core/components/card/cards/patch-card.js.map +1 -0
  189. package/dist/internal/core/components/card/cards/product-recommendation-card.d.ts +3 -0
  190. package/dist/internal/core/components/card/cards/product-recommendation-card.d.ts.map +1 -0
  191. package/dist/internal/core/components/card/cards/product-recommendation-card.js +18 -0
  192. package/dist/internal/core/components/card/cards/product-recommendation-card.js.map +1 -0
  193. package/dist/internal/core/components/card/cards/reflection-optimization-card.d.ts +3 -0
  194. package/dist/internal/core/components/card/cards/reflection-optimization-card.d.ts.map +1 -0
  195. package/dist/internal/core/components/card/cards/reflection-optimization-card.js +51 -0
  196. package/dist/internal/core/components/card/cards/reflection-optimization-card.js.map +1 -0
  197. package/dist/internal/core/components/card/cards/resolution-modifications-card.d.ts +3 -0
  198. package/dist/internal/core/components/card/cards/resolution-modifications-card.d.ts.map +1 -0
  199. package/dist/internal/core/components/card/cards/resolution-modifications-card.js +85 -0
  200. package/dist/internal/core/components/card/cards/resolution-modifications-card.js.map +1 -0
  201. package/dist/internal/core/components/card/cards/resolution-summary-card.d.ts +3 -0
  202. package/dist/internal/core/components/card/cards/resolution-summary-card.d.ts.map +1 -0
  203. package/dist/internal/core/components/card/cards/resolution-summary-card.js +55 -0
  204. package/dist/internal/core/components/card/cards/resolution-summary-card.js.map +1 -0
  205. package/dist/internal/core/components/card/cards/restaurant-card.d.ts +3 -0
  206. package/dist/internal/core/components/card/cards/restaurant-card.d.ts.map +1 -0
  207. package/dist/internal/core/components/card/cards/restaurant-card.js +10 -0
  208. package/dist/internal/core/components/card/cards/restaurant-card.js.map +1 -0
  209. package/dist/internal/core/components/card/cards/shopping-list-card.d.ts +3 -0
  210. package/dist/internal/core/components/card/cards/shopping-list-card.d.ts.map +1 -0
  211. package/dist/internal/core/components/card/cards/shopping-list-card.js +17 -0
  212. package/dist/internal/core/components/card/cards/shopping-list-card.js.map +1 -0
  213. package/dist/internal/core/components/card/cards/simulation-event-card.d.ts +5 -0
  214. package/dist/internal/core/components/card/cards/simulation-event-card.d.ts.map +1 -0
  215. package/dist/internal/core/components/card/cards/simulation-event-card.js +116 -0
  216. package/dist/internal/core/components/card/cards/simulation-event-card.js.map +1 -0
  217. package/dist/internal/core/components/card/cards/survival-effect-card.d.ts +5 -0
  218. package/dist/internal/core/components/card/cards/survival-effect-card.d.ts.map +1 -0
  219. package/dist/internal/core/components/card/cards/survival-effect-card.js +76 -0
  220. package/dist/internal/core/components/card/cards/survival-effect-card.js.map +1 -0
  221. package/dist/internal/core/components/card/cards/travel-itinerary-card.d.ts +3 -0
  222. package/dist/internal/core/components/card/cards/travel-itinerary-card.d.ts.map +1 -0
  223. package/dist/internal/core/components/card/cards/travel-itinerary-card.js +16 -0
  224. package/dist/internal/core/components/card/cards/travel-itinerary-card.js.map +1 -0
  225. package/dist/internal/core/components/card/register.d.ts +2 -0
  226. package/dist/internal/core/components/card/register.d.ts.map +1 -0
  227. package/dist/internal/core/components/card/register.js +64 -0
  228. package/dist/internal/core/components/card/register.js.map +1 -0
  229. package/dist/internal/core/components/chat/AgentLoopBlock.d.ts +9 -0
  230. package/dist/internal/core/components/chat/AgentLoopBlock.d.ts.map +1 -0
  231. package/dist/internal/core/components/chat/AgentLoopBlock.js +174 -0
  232. package/dist/internal/core/components/chat/AgentLoopBlock.js.map +1 -0
  233. package/dist/internal/core/components/chat/AskUserQuestionBlock.d.ts +33 -0
  234. package/dist/internal/core/components/chat/AskUserQuestionBlock.d.ts.map +1 -0
  235. package/dist/internal/core/components/chat/AskUserQuestionBlock.js +178 -0
  236. package/dist/internal/core/components/chat/AskUserQuestionBlock.js.map +1 -0
  237. package/dist/internal/core/components/chat/AssistantTurnBlock.d.ts +17 -0
  238. package/dist/internal/core/components/chat/AssistantTurnBlock.d.ts.map +1 -0
  239. package/dist/internal/core/components/chat/AssistantTurnBlock.js +181 -0
  240. package/dist/internal/core/components/chat/AssistantTurnBlock.js.map +1 -0
  241. package/dist/internal/core/components/chat/AttachmentPreviewDialog.d.ts +27 -0
  242. package/dist/internal/core/components/chat/AttachmentPreviewDialog.d.ts.map +1 -0
  243. package/dist/internal/core/components/chat/AttachmentPreviewDialog.js +64 -0
  244. package/dist/internal/core/components/chat/AttachmentPreviewDialog.js.map +1 -0
  245. package/dist/internal/core/components/chat/ChatInput.d.ts +65 -0
  246. package/dist/internal/core/components/chat/ChatInput.d.ts.map +1 -0
  247. package/dist/internal/core/components/chat/ChatInput.js +1127 -0
  248. package/dist/internal/core/components/chat/ChatInput.js.map +1 -0
  249. package/dist/internal/core/components/chat/ChatView.d.ts +14 -0
  250. package/dist/internal/core/components/chat/ChatView.d.ts.map +1 -0
  251. package/dist/internal/core/components/chat/ChatView.js +28 -0
  252. package/dist/internal/core/components/chat/ChatView.js.map +1 -0
  253. package/dist/internal/core/components/chat/CompactionCard.d.ts +7 -0
  254. package/dist/internal/core/components/chat/CompactionCard.d.ts.map +1 -0
  255. package/dist/internal/core/components/chat/CompactionCard.js +82 -0
  256. package/dist/internal/core/components/chat/CompactionCard.js.map +1 -0
  257. package/dist/internal/core/components/chat/ConnectionBanner.d.ts +2 -0
  258. package/dist/internal/core/components/chat/ConnectionBanner.d.ts.map +1 -0
  259. package/dist/internal/core/components/chat/ConnectionBanner.js +37 -0
  260. package/dist/internal/core/components/chat/ConnectionBanner.js.map +1 -0
  261. package/dist/internal/core/components/chat/FileCompletionMenu.d.ts +14 -0
  262. package/dist/internal/core/components/chat/FileCompletionMenu.d.ts.map +1 -0
  263. package/dist/internal/core/components/chat/FileCompletionMenu.js +163 -0
  264. package/dist/internal/core/components/chat/FileCompletionMenu.js.map +1 -0
  265. package/dist/internal/core/components/chat/FileSizeLimitDialog.d.ts +10 -0
  266. package/dist/internal/core/components/chat/FileSizeLimitDialog.d.ts.map +1 -0
  267. package/dist/internal/core/components/chat/FileSizeLimitDialog.js +30 -0
  268. package/dist/internal/core/components/chat/FileSizeLimitDialog.js.map +1 -0
  269. package/dist/internal/core/components/chat/ImageLightbox.d.ts +12 -0
  270. package/dist/internal/core/components/chat/ImageLightbox.d.ts.map +1 -0
  271. package/dist/internal/core/components/chat/ImageLightbox.js +140 -0
  272. package/dist/internal/core/components/chat/ImageLightbox.js.map +1 -0
  273. package/dist/internal/core/components/chat/MessageActions.d.ts +7 -0
  274. package/dist/internal/core/components/chat/MessageActions.d.ts.map +1 -0
  275. package/dist/internal/core/components/chat/MessageActions.js +18 -0
  276. package/dist/internal/core/components/chat/MessageActions.js.map +1 -0
  277. package/dist/internal/core/components/chat/MessageContextPills.d.ts +7 -0
  278. package/dist/internal/core/components/chat/MessageContextPills.d.ts.map +1 -0
  279. package/dist/internal/core/components/chat/MessageContextPills.js +8 -0
  280. package/dist/internal/core/components/chat/MessageContextPills.js.map +1 -0
  281. package/dist/internal/core/components/chat/MessageFileAttachmentList.d.ts +14 -0
  282. package/dist/internal/core/components/chat/MessageFileAttachmentList.d.ts.map +1 -0
  283. package/dist/internal/core/components/chat/MessageFileAttachmentList.js +38 -0
  284. package/dist/internal/core/components/chat/MessageFileAttachmentList.js.map +1 -0
  285. package/dist/internal/core/components/chat/MessageList.d.ts +12 -0
  286. package/dist/internal/core/components/chat/MessageList.d.ts.map +1 -0
  287. package/dist/internal/core/components/chat/MessageList.js +315 -0
  288. package/dist/internal/core/components/chat/MessageList.js.map +1 -0
  289. package/dist/internal/core/components/chat/ProgressCircle.d.ts +13 -0
  290. package/dist/internal/core/components/chat/ProgressCircle.d.ts.map +1 -0
  291. package/dist/internal/core/components/chat/ProgressCircle.js +28 -0
  292. package/dist/internal/core/components/chat/ProgressCircle.js.map +1 -0
  293. package/dist/internal/core/components/chat/RenderErrorBoundary.d.ts +20 -0
  294. package/dist/internal/core/components/chat/RenderErrorBoundary.d.ts.map +1 -0
  295. package/dist/internal/core/components/chat/RenderErrorBoundary.js +39 -0
  296. package/dist/internal/core/components/chat/RenderErrorBoundary.js.map +1 -0
  297. package/dist/internal/core/components/chat/ResourceIframe.d.ts +6 -0
  298. package/dist/internal/core/components/chat/ResourceIframe.d.ts.map +1 -0
  299. package/dist/internal/core/components/chat/ResourceIframe.js +124 -0
  300. package/dist/internal/core/components/chat/ResourceIframe.js.map +1 -0
  301. package/dist/internal/core/components/chat/Shimmer.d.ts +7 -0
  302. package/dist/internal/core/components/chat/Shimmer.d.ts.map +1 -0
  303. package/dist/internal/core/components/chat/Shimmer.js +6 -0
  304. package/dist/internal/core/components/chat/Shimmer.js.map +1 -0
  305. package/dist/internal/core/components/chat/SkillCompletionMenu.d.ts +10 -0
  306. package/dist/internal/core/components/chat/SkillCompletionMenu.d.ts.map +1 -0
  307. package/dist/internal/core/components/chat/SkillCompletionMenu.js +65 -0
  308. package/dist/internal/core/components/chat/SkillCompletionMenu.js.map +1 -0
  309. package/dist/internal/core/components/chat/SkillStatusBar.d.ts +7 -0
  310. package/dist/internal/core/components/chat/SkillStatusBar.d.ts.map +1 -0
  311. package/dist/internal/core/components/chat/SkillStatusBar.js +113 -0
  312. package/dist/internal/core/components/chat/SkillStatusBar.js.map +1 -0
  313. package/dist/internal/core/components/chat/StickyStatusBar.d.ts +11 -0
  314. package/dist/internal/core/components/chat/StickyStatusBar.d.ts.map +1 -0
  315. package/dist/internal/core/components/chat/StickyStatusBar.js +115 -0
  316. package/dist/internal/core/components/chat/StickyStatusBar.js.map +1 -0
  317. package/dist/internal/core/components/chat/TextAttachmentPills.d.ts +11 -0
  318. package/dist/internal/core/components/chat/TextAttachmentPills.d.ts.map +1 -0
  319. package/dist/internal/core/components/chat/TextAttachmentPills.js +35 -0
  320. package/dist/internal/core/components/chat/TextAttachmentPills.js.map +1 -0
  321. package/dist/internal/core/components/chat/ToolCallBlock.d.ts +17 -0
  322. package/dist/internal/core/components/chat/ToolCallBlock.d.ts.map +1 -0
  323. package/dist/internal/core/components/chat/ToolCallBlock.js +172 -0
  324. package/dist/internal/core/components/chat/ToolCallBlock.js.map +1 -0
  325. package/dist/internal/core/components/chat/TurnNavRail.d.ts +12 -0
  326. package/dist/internal/core/components/chat/TurnNavRail.d.ts.map +1 -0
  327. package/dist/internal/core/components/chat/TurnNavRail.js +14 -0
  328. package/dist/internal/core/components/chat/TurnNavRail.js.map +1 -0
  329. package/dist/internal/core/components/chat/UserMessageBubble.d.ts +18 -0
  330. package/dist/internal/core/components/chat/UserMessageBubble.d.ts.map +1 -0
  331. package/dist/internal/core/components/chat/UserMessageBubble.js +130 -0
  332. package/dist/internal/core/components/chat/UserMessageBubble.js.map +1 -0
  333. package/dist/internal/core/components/chat/WhatIfUserBubble.d.ts +14 -0
  334. package/dist/internal/core/components/chat/WhatIfUserBubble.d.ts.map +1 -0
  335. package/dist/internal/core/components/chat/WhatIfUserBubble.js +20 -0
  336. package/dist/internal/core/components/chat/WhatIfUserBubble.js.map +1 -0
  337. package/dist/internal/core/components/chat/display-utils.d.ts +36 -0
  338. package/dist/internal/core/components/chat/display-utils.d.ts.map +1 -0
  339. package/dist/internal/core/components/chat/display-utils.js +533 -0
  340. package/dist/internal/core/components/chat/display-utils.js.map +1 -0
  341. package/dist/internal/core/components/chat/extensions/file-mention.d.ts +13 -0
  342. package/dist/internal/core/components/chat/extensions/file-mention.d.ts.map +1 -0
  343. package/dist/internal/core/components/chat/extensions/file-mention.js +52 -0
  344. package/dist/internal/core/components/chat/extensions/file-mention.js.map +1 -0
  345. package/dist/internal/core/components/chat/extensions/skill-mention.d.ts +26 -0
  346. package/dist/internal/core/components/chat/extensions/skill-mention.d.ts.map +1 -0
  347. package/dist/internal/core/components/chat/extensions/skill-mention.js +72 -0
  348. package/dist/internal/core/components/chat/extensions/skill-mention.js.map +1 -0
  349. package/dist/internal/core/components/chat/index.d.ts +15 -0
  350. package/dist/internal/core/components/chat/index.d.ts.map +1 -0
  351. package/dist/internal/core/components/chat/index.js +15 -0
  352. package/dist/internal/core/components/chat/index.js.map +1 -0
  353. package/dist/internal/core/components/chat/tool-renderers/BashRenderer.d.ts +3 -0
  354. package/dist/internal/core/components/chat/tool-renderers/BashRenderer.d.ts.map +1 -0
  355. package/dist/internal/core/components/chat/tool-renderers/BashRenderer.js +52 -0
  356. package/dist/internal/core/components/chat/tool-renderers/BashRenderer.js.map +1 -0
  357. package/dist/internal/core/components/chat/tool-renderers/FileEditRenderer.d.ts +3 -0
  358. package/dist/internal/core/components/chat/tool-renderers/FileEditRenderer.d.ts.map +1 -0
  359. package/dist/internal/core/components/chat/tool-renderers/FileEditRenderer.js +108 -0
  360. package/dist/internal/core/components/chat/tool-renderers/FileEditRenderer.js.map +1 -0
  361. package/dist/internal/core/components/chat/tool-renderers/FileReadRenderer.d.ts +3 -0
  362. package/dist/internal/core/components/chat/tool-renderers/FileReadRenderer.d.ts.map +1 -0
  363. package/dist/internal/core/components/chat/tool-renderers/FileReadRenderer.js +75 -0
  364. package/dist/internal/core/components/chat/tool-renderers/FileReadRenderer.js.map +1 -0
  365. package/dist/internal/core/components/chat/tool-renderers/SearchRenderer.d.ts +3 -0
  366. package/dist/internal/core/components/chat/tool-renderers/SearchRenderer.d.ts.map +1 -0
  367. package/dist/internal/core/components/chat/tool-renderers/SearchRenderer.js +96 -0
  368. package/dist/internal/core/components/chat/tool-renderers/SearchRenderer.js.map +1 -0
  369. package/dist/internal/core/components/chat/tool-renderers/registry.d.ts +10 -0
  370. package/dist/internal/core/components/chat/tool-renderers/registry.d.ts.map +1 -0
  371. package/dist/internal/core/components/chat/tool-renderers/registry.js +21 -0
  372. package/dist/internal/core/components/chat/tool-renderers/registry.js.map +1 -0
  373. package/dist/internal/core/components/chat/tool-renderers/shared.d.ts +27 -0
  374. package/dist/internal/core/components/chat/tool-renderers/shared.d.ts.map +1 -0
  375. package/dist/internal/core/components/chat/tool-renderers/shared.js +116 -0
  376. package/dist/internal/core/components/chat/tool-renderers/shared.js.map +1 -0
  377. package/dist/internal/core/components/chat/whatif-quote-context.d.ts +16 -0
  378. package/dist/internal/core/components/chat/whatif-quote-context.d.ts.map +1 -0
  379. package/dist/internal/core/components/chat/whatif-quote-context.js +16 -0
  380. package/dist/internal/core/components/chat/whatif-quote-context.js.map +1 -0
  381. package/dist/internal/core/components/markdown/MarkdownContent.d.ts +10 -0
  382. package/dist/internal/core/components/markdown/MarkdownContent.d.ts.map +1 -0
  383. package/dist/internal/core/components/markdown/MarkdownContent.js +95 -0
  384. package/dist/internal/core/components/markdown/MarkdownContent.js.map +1 -0
  385. package/dist/internal/core/components/model/ModelSelector.d.ts +10 -0
  386. package/dist/internal/core/components/model/ModelSelector.d.ts.map +1 -0
  387. package/dist/internal/core/components/model/ModelSelector.js +48 -0
  388. package/dist/internal/core/components/model/ModelSelector.js.map +1 -0
  389. package/dist/internal/core/components/plan/PlanSummaryCard.d.ts +9 -0
  390. package/dist/internal/core/components/plan/PlanSummaryCard.d.ts.map +1 -0
  391. package/dist/internal/core/components/plan/PlanSummaryCard.js +75 -0
  392. package/dist/internal/core/components/plan/PlanSummaryCard.js.map +1 -0
  393. package/dist/internal/core/components/plan/PlanVisualization.d.ts +14 -0
  394. package/dist/internal/core/components/plan/PlanVisualization.d.ts.map +1 -0
  395. package/dist/internal/core/components/plan/PlanVisualization.js +82 -0
  396. package/dist/internal/core/components/plan/PlanVisualization.js.map +1 -0
  397. package/dist/internal/core/components/plan/debug-log.d.ts +22 -0
  398. package/dist/internal/core/components/plan/debug-log.d.ts.map +1 -0
  399. package/dist/internal/core/components/plan/debug-log.js +47 -0
  400. package/dist/internal/core/components/plan/debug-log.js.map +1 -0
  401. package/dist/internal/core/components/plan/extract-plan-messages.d.ts +3 -0
  402. package/dist/internal/core/components/plan/extract-plan-messages.d.ts.map +1 -0
  403. package/dist/internal/core/components/plan/extract-plan-messages.js +59 -0
  404. package/dist/internal/core/components/plan/extract-plan-messages.js.map +1 -0
  405. package/dist/internal/core/components/plan/index.d.ts +7 -0
  406. package/dist/internal/core/components/plan/index.d.ts.map +1 -0
  407. package/dist/internal/core/components/plan/index.js +6 -0
  408. package/dist/internal/core/components/plan/index.js.map +1 -0
  409. package/dist/internal/core/components/plan/parse-plan-messages.d.ts +12 -0
  410. package/dist/internal/core/components/plan/parse-plan-messages.d.ts.map +1 -0
  411. package/dist/internal/core/components/plan/parse-plan-messages.js +272 -0
  412. package/dist/internal/core/components/plan/parse-plan-messages.js.map +1 -0
  413. package/dist/internal/core/components/plan/parse-plan-tree.d.ts +17 -0
  414. package/dist/internal/core/components/plan/parse-plan-tree.d.ts.map +1 -0
  415. package/dist/internal/core/components/plan/parse-plan-tree.js +117 -0
  416. package/dist/internal/core/components/plan/parse-plan-tree.js.map +1 -0
  417. package/dist/internal/core/components/plan/phases/PlanMindMap.d.ts +9 -0
  418. package/dist/internal/core/components/plan/phases/PlanMindMap.d.ts.map +1 -0
  419. package/dist/internal/core/components/plan/phases/PlanMindMap.js +42 -0
  420. package/dist/internal/core/components/plan/phases/PlanMindMap.js.map +1 -0
  421. package/dist/internal/core/components/plan/phases/PlanStatusIcon.d.ts +6 -0
  422. package/dist/internal/core/components/plan/phases/PlanStatusIcon.d.ts.map +1 -0
  423. package/dist/internal/core/components/plan/phases/PlanStatusIcon.js +15 -0
  424. package/dist/internal/core/components/plan/phases/PlanStatusIcon.js.map +1 -0
  425. package/dist/internal/core/components/plan/phases/PlanTree.d.ts +9 -0
  426. package/dist/internal/core/components/plan/phases/PlanTree.d.ts.map +1 -0
  427. package/dist/internal/core/components/plan/phases/PlanTree.js +55 -0
  428. package/dist/internal/core/components/plan/phases/PlanTree.js.map +1 -0
  429. package/dist/internal/core/components/plan/phases/SkillAnalysis.d.ts +8 -0
  430. package/dist/internal/core/components/plan/phases/SkillAnalysis.d.ts.map +1 -0
  431. package/dist/internal/core/components/plan/phases/SkillAnalysis.js +22 -0
  432. package/dist/internal/core/components/plan/phases/SkillAnalysis.js.map +1 -0
  433. package/dist/internal/core/components/plan/phases/SkillDiscovery.d.ts +11 -0
  434. package/dist/internal/core/components/plan/phases/SkillDiscovery.d.ts.map +1 -0
  435. package/dist/internal/core/components/plan/phases/SkillDiscovery.js +52 -0
  436. package/dist/internal/core/components/plan/phases/SkillDiscovery.js.map +1 -0
  437. package/dist/internal/core/components/plan/types.d.ts +57 -0
  438. package/dist/internal/core/components/plan/types.d.ts.map +1 -0
  439. package/dist/internal/core/components/plan/types.js +2 -0
  440. package/dist/internal/core/components/plan/types.js.map +1 -0
  441. package/dist/internal/core/components/session/SessionDetail.d.ts +9 -0
  442. package/dist/internal/core/components/session/SessionDetail.d.ts.map +1 -0
  443. package/dist/internal/core/components/session/SessionDetail.js +248 -0
  444. package/dist/internal/core/components/session/SessionDetail.js.map +1 -0
  445. package/dist/internal/core/components/session/SessionList.d.ts +10 -0
  446. package/dist/internal/core/components/session/SessionList.d.ts.map +1 -0
  447. package/dist/internal/core/components/session/SessionList.js +28 -0
  448. package/dist/internal/core/components/session/SessionList.js.map +1 -0
  449. package/dist/internal/core/components/session/SessionListItem.d.ts +9 -0
  450. package/dist/internal/core/components/session/SessionListItem.d.ts.map +1 -0
  451. package/dist/internal/core/components/session/SessionListItem.js +10 -0
  452. package/dist/internal/core/components/session/SessionListItem.js.map +1 -0
  453. package/dist/internal/core/components/session/StatusBadge.d.ts +4 -0
  454. package/dist/internal/core/components/session/StatusBadge.d.ts.map +1 -0
  455. package/dist/internal/core/components/session/StatusBadge.js +47 -0
  456. package/dist/internal/core/components/session/StatusBadge.js.map +1 -0
  457. package/dist/internal/core/components/session/index.d.ts +6 -0
  458. package/dist/internal/core/components/session/index.d.ts.map +1 -0
  459. package/dist/internal/core/components/session/index.js +6 -0
  460. package/dist/internal/core/components/session/index.js.map +1 -0
  461. package/dist/internal/core/components/session/session-utils.d.ts +20 -0
  462. package/dist/internal/core/components/session/session-utils.d.ts.map +1 -0
  463. package/dist/internal/core/components/session/session-utils.js +130 -0
  464. package/dist/internal/core/components/session/session-utils.js.map +1 -0
  465. package/dist/internal/core/components/ui/collapsible.d.ts +6 -0
  466. package/dist/internal/core/components/ui/collapsible.d.ts.map +1 -0
  467. package/dist/internal/core/components/ui/collapsible.js +13 -0
  468. package/dist/internal/core/components/ui/collapsible.js.map +1 -0
  469. package/dist/internal/core/components/workspace/FileTree.d.ts +14 -0
  470. package/dist/internal/core/components/workspace/FileTree.d.ts.map +1 -0
  471. package/dist/internal/core/components/workspace/FileTree.js +521 -0
  472. package/dist/internal/core/components/workspace/FileTree.js.map +1 -0
  473. package/dist/internal/core/components/workspace/WorkspaceFilesPanel.d.ts +20 -0
  474. package/dist/internal/core/components/workspace/WorkspaceFilesPanel.d.ts.map +1 -0
  475. package/dist/internal/core/components/workspace/WorkspaceFilesPanel.js +142 -0
  476. package/dist/internal/core/components/workspace/WorkspaceFilesPanel.js.map +1 -0
  477. package/dist/internal/core/components/workspace/index.d.ts +3 -0
  478. package/dist/internal/core/components/workspace/index.d.ts.map +1 -0
  479. package/dist/internal/core/components/workspace/index.js +3 -0
  480. package/dist/internal/core/components/workspace/index.js.map +1 -0
  481. package/dist/internal/core/devtools/bridge-devtools/BridgeDevtoolsFab.d.ts +2 -0
  482. package/dist/internal/core/devtools/bridge-devtools/BridgeDevtoolsFab.d.ts.map +1 -0
  483. package/dist/internal/core/devtools/bridge-devtools/BridgeDevtoolsFab.js +306 -0
  484. package/dist/internal/core/devtools/bridge-devtools/BridgeDevtoolsFab.js.map +1 -0
  485. package/dist/internal/core/devtools/bridge-devtools/index.d.ts +4 -0
  486. package/dist/internal/core/devtools/bridge-devtools/index.d.ts.map +1 -0
  487. package/dist/internal/core/devtools/bridge-devtools/index.js +3 -0
  488. package/dist/internal/core/devtools/bridge-devtools/index.js.map +1 -0
  489. package/dist/internal/core/devtools/bridge-devtools/mount.d.ts +2 -0
  490. package/dist/internal/core/devtools/bridge-devtools/mount.d.ts.map +1 -0
  491. package/dist/internal/core/devtools/bridge-devtools/mount.js +24 -0
  492. package/dist/internal/core/devtools/bridge-devtools/mount.js.map +1 -0
  493. package/dist/internal/core/devtools/bridge-devtools/store.d.ts +16 -0
  494. package/dist/internal/core/devtools/bridge-devtools/store.d.ts.map +1 -0
  495. package/dist/internal/core/devtools/bridge-devtools/store.js +37 -0
  496. package/dist/internal/core/devtools/bridge-devtools/store.js.map +1 -0
  497. package/dist/internal/core/devtools/bridge-devtools/tap.d.ts +6 -0
  498. package/dist/internal/core/devtools/bridge-devtools/tap.d.ts.map +1 -0
  499. package/dist/internal/core/devtools/bridge-devtools/tap.js +58 -0
  500. package/dist/internal/core/devtools/bridge-devtools/tap.js.map +1 -0
  501. package/dist/internal/core/devtools/bridge-devtools/types.d.ts +30 -0
  502. package/dist/internal/core/devtools/bridge-devtools/types.d.ts.map +1 -0
  503. package/dist/internal/core/devtools/bridge-devtools/types.js +2 -0
  504. package/dist/internal/core/devtools/bridge-devtools/types.js.map +1 -0
  505. package/dist/internal/core/hooks/use-background-tasks.d.ts +8 -0
  506. package/dist/internal/core/hooks/use-background-tasks.d.ts.map +1 -0
  507. package/dist/internal/core/hooks/use-background-tasks.js +23 -0
  508. package/dist/internal/core/hooks/use-background-tasks.js.map +1 -0
  509. package/dist/internal/core/hooks/use-card-state.d.ts +2 -0
  510. package/dist/internal/core/hooks/use-card-state.d.ts.map +1 -0
  511. package/dist/internal/core/hooks/use-card-state.js +22 -0
  512. package/dist/internal/core/hooks/use-card-state.js.map +1 -0
  513. package/dist/internal/core/hooks/use-chat.d.ts +11 -0
  514. package/dist/internal/core/hooks/use-chat.d.ts.map +1 -0
  515. package/dist/internal/core/hooks/use-chat.js +68 -0
  516. package/dist/internal/core/hooks/use-chat.js.map +1 -0
  517. package/dist/internal/core/hooks/use-check-skill-file.d.ts +5 -0
  518. package/dist/internal/core/hooks/use-check-skill-file.d.ts.map +1 -0
  519. package/dist/internal/core/hooks/use-check-skill-file.js +26 -0
  520. package/dist/internal/core/hooks/use-check-skill-file.js.map +1 -0
  521. package/dist/internal/core/hooks/use-context-stats.d.ts +8 -0
  522. package/dist/internal/core/hooks/use-context-stats.d.ts.map +1 -0
  523. package/dist/internal/core/hooks/use-context-stats.js +22 -0
  524. package/dist/internal/core/hooks/use-context-stats.js.map +1 -0
  525. package/dist/internal/core/hooks/use-gis.d.ts +18 -0
  526. package/dist/internal/core/hooks/use-gis.d.ts.map +1 -0
  527. package/dist/internal/core/hooks/use-gis.js +52 -0
  528. package/dist/internal/core/hooks/use-gis.js.map +1 -0
  529. package/dist/internal/core/hooks/use-global-skill-stats.d.ts +7 -0
  530. package/dist/internal/core/hooks/use-global-skill-stats.d.ts.map +1 -0
  531. package/dist/internal/core/hooks/use-global-skill-stats.js +20 -0
  532. package/dist/internal/core/hooks/use-global-skill-stats.js.map +1 -0
  533. package/dist/internal/core/hooks/use-input-history.d.ts +8 -0
  534. package/dist/internal/core/hooks/use-input-history.d.ts.map +1 -0
  535. package/dist/internal/core/hooks/use-input-history.js +90 -0
  536. package/dist/internal/core/hooks/use-input-history.js.map +1 -0
  537. package/dist/internal/core/hooks/use-registry.d.ts +54 -0
  538. package/dist/internal/core/hooks/use-registry.d.ts.map +1 -0
  539. package/dist/internal/core/hooks/use-registry.js +35 -0
  540. package/dist/internal/core/hooks/use-registry.js.map +1 -0
  541. package/dist/internal/core/hooks/use-session.d.ts +11 -0
  542. package/dist/internal/core/hooks/use-session.d.ts.map +1 -0
  543. package/dist/internal/core/hooks/use-session.js +22 -0
  544. package/dist/internal/core/hooks/use-session.js.map +1 -0
  545. package/dist/internal/core/hooks/use-skill-stats.d.ts +8 -0
  546. package/dist/internal/core/hooks/use-skill-stats.d.ts.map +1 -0
  547. package/dist/internal/core/hooks/use-skill-stats.js +24 -0
  548. package/dist/internal/core/hooks/use-skill-stats.js.map +1 -0
  549. package/dist/internal/core/hooks/use-skills.d.ts +7 -0
  550. package/dist/internal/core/hooks/use-skills.d.ts.map +1 -0
  551. package/dist/internal/core/hooks/use-skills.js +11 -0
  552. package/dist/internal/core/hooks/use-skills.js.map +1 -0
  553. package/dist/internal/core/hooks/use-token-pressure.d.ts +7 -0
  554. package/dist/internal/core/hooks/use-token-pressure.d.ts.map +1 -0
  555. package/dist/internal/core/hooks/use-token-pressure.js +28 -0
  556. package/dist/internal/core/hooks/use-token-pressure.js.map +1 -0
  557. package/dist/internal/core/index.d.ts +99 -0
  558. package/dist/internal/core/index.d.ts.map +1 -0
  559. package/dist/internal/core/index.js +83 -0
  560. package/dist/internal/core/index.js.map +1 -0
  561. package/dist/internal/core/lib/analytics.d.ts +8 -0
  562. package/dist/internal/core/lib/analytics.d.ts.map +1 -0
  563. package/dist/internal/core/lib/analytics.js +8 -0
  564. package/dist/internal/core/lib/analytics.js.map +1 -0
  565. package/dist/internal/core/lib/attachment-upload.d.ts +11 -0
  566. package/dist/internal/core/lib/attachment-upload.d.ts.map +1 -0
  567. package/dist/internal/core/lib/attachment-upload.js +26 -0
  568. package/dist/internal/core/lib/attachment-upload.js.map +1 -0
  569. package/dist/internal/core/lib/card-registry.d.ts +36 -0
  570. package/dist/internal/core/lib/card-registry.d.ts.map +1 -0
  571. package/dist/internal/core/lib/card-registry.js +67 -0
  572. package/dist/internal/core/lib/card-registry.js.map +1 -0
  573. package/dist/internal/core/lib/chat.d.ts +49 -0
  574. package/dist/internal/core/lib/chat.d.ts.map +1 -0
  575. package/dist/internal/core/lib/chat.js +172 -0
  576. package/dist/internal/core/lib/chat.js.map +1 -0
  577. package/dist/internal/core/lib/code-highlight.d.ts +9 -0
  578. package/dist/internal/core/lib/code-highlight.d.ts.map +1 -0
  579. package/dist/internal/core/lib/code-highlight.js +153 -0
  580. package/dist/internal/core/lib/code-highlight.js.map +1 -0
  581. package/dist/internal/core/lib/open-session-file.d.ts +3 -0
  582. package/dist/internal/core/lib/open-session-file.d.ts.map +1 -0
  583. package/dist/internal/core/lib/open-session-file.js +14 -0
  584. package/dist/internal/core/lib/open-session-file.js.map +1 -0
  585. package/dist/internal/core/lib/parent-bridge.d.ts +20 -0
  586. package/dist/internal/core/lib/parent-bridge.d.ts.map +1 -0
  587. package/dist/internal/core/lib/parent-bridge.js +135 -0
  588. package/dist/internal/core/lib/parent-bridge.js.map +1 -0
  589. package/dist/internal/core/lib/preview-dispatch.d.ts +25 -0
  590. package/dist/internal/core/lib/preview-dispatch.d.ts.map +1 -0
  591. package/dist/internal/core/lib/preview-dispatch.js +55 -0
  592. package/dist/internal/core/lib/preview-dispatch.js.map +1 -0
  593. package/dist/internal/core/lib/resource-bridge.d.ts +12 -0
  594. package/dist/internal/core/lib/resource-bridge.d.ts.map +1 -0
  595. package/dist/internal/core/lib/resource-bridge.js +51 -0
  596. package/dist/internal/core/lib/resource-bridge.js.map +1 -0
  597. package/dist/internal/core/lib/session-file-preview.d.ts +4 -0
  598. package/dist/internal/core/lib/session-file-preview.d.ts.map +1 -0
  599. package/dist/internal/core/lib/session-file-preview.js +71 -0
  600. package/dist/internal/core/lib/session-file-preview.js.map +1 -0
  601. package/dist/internal/core/lib/step-ranges.d.ts +43 -0
  602. package/dist/internal/core/lib/step-ranges.d.ts.map +1 -0
  603. package/dist/internal/core/lib/step-ranges.js +229 -0
  604. package/dist/internal/core/lib/step-ranges.js.map +1 -0
  605. package/dist/internal/core/lib/tool-preview.d.ts +3 -0
  606. package/dist/internal/core/lib/tool-preview.d.ts.map +1 -0
  607. package/dist/internal/core/lib/tool-preview.js +7 -0
  608. package/dist/internal/core/lib/tool-preview.js.map +1 -0
  609. package/dist/internal/core/lib/ui-meta.d.ts +10 -0
  610. package/dist/internal/core/lib/ui-meta.d.ts.map +1 -0
  611. package/dist/internal/core/lib/ui-meta.js +28 -0
  612. package/dist/internal/core/lib/ui-meta.js.map +1 -0
  613. package/dist/internal/core/lib/utils.d.ts +4 -0
  614. package/dist/internal/core/lib/utils.d.ts.map +1 -0
  615. package/dist/internal/core/lib/utils.js +30 -0
  616. package/dist/internal/core/lib/utils.js.map +1 -0
  617. package/dist/internal/core/lib/whatif-prompt.d.ts +46 -0
  618. package/dist/internal/core/lib/whatif-prompt.d.ts.map +1 -0
  619. package/dist/internal/core/lib/whatif-prompt.js +138 -0
  620. package/dist/internal/core/lib/whatif-prompt.js.map +1 -0
  621. package/dist/internal/core/react/AgentKitProvider.d.ts +20 -0
  622. package/dist/internal/core/react/AgentKitProvider.d.ts.map +1 -0
  623. package/dist/internal/core/react/AgentKitProvider.js +32 -0
  624. package/dist/internal/core/react/AgentKitProvider.js.map +1 -0
  625. package/dist/internal/core/routes.d.ts +2 -0
  626. package/dist/internal/core/routes.d.ts.map +1 -0
  627. package/dist/internal/core/routes.js +2 -0
  628. package/dist/internal/core/routes.js.map +1 -0
  629. package/dist/internal/core/schemas/background.d.ts +12 -0
  630. package/dist/internal/core/schemas/background.d.ts.map +1 -0
  631. package/dist/internal/core/schemas/background.js +2 -0
  632. package/dist/internal/core/schemas/background.js.map +1 -0
  633. package/dist/internal/core/schemas/event.d.ts +46 -0
  634. package/dist/internal/core/schemas/event.d.ts.map +1 -0
  635. package/dist/internal/core/schemas/event.js +2 -0
  636. package/dist/internal/core/schemas/event.js.map +1 -0
  637. package/dist/internal/core/schemas/gis.d.ts +51 -0
  638. package/dist/internal/core/schemas/gis.d.ts.map +1 -0
  639. package/dist/internal/core/schemas/gis.js +2 -0
  640. package/dist/internal/core/schemas/gis.js.map +1 -0
  641. package/dist/internal/core/schemas/message.d.ts +84 -0
  642. package/dist/internal/core/schemas/message.d.ts.map +1 -0
  643. package/dist/internal/core/schemas/message.js +23 -0
  644. package/dist/internal/core/schemas/message.js.map +1 -0
  645. package/dist/internal/core/schemas/partner-skill.d.ts +24 -0
  646. package/dist/internal/core/schemas/partner-skill.d.ts.map +1 -0
  647. package/dist/internal/core/schemas/partner-skill.js +24 -0
  648. package/dist/internal/core/schemas/partner-skill.js.map +1 -0
  649. package/dist/internal/core/schemas/projection.d.ts +88 -0
  650. package/dist/internal/core/schemas/projection.d.ts.map +1 -0
  651. package/dist/internal/core/schemas/projection.js +2 -0
  652. package/dist/internal/core/schemas/projection.js.map +1 -0
  653. package/dist/internal/core/schemas/session.d.ts +101 -0
  654. package/dist/internal/core/schemas/session.d.ts.map +1 -0
  655. package/dist/internal/core/schemas/session.js +27 -0
  656. package/dist/internal/core/schemas/session.js.map +1 -0
  657. package/dist/internal/core/schemas/skill.d.ts +51 -0
  658. package/dist/internal/core/schemas/skill.d.ts.map +1 -0
  659. package/dist/internal/core/schemas/skill.js +8 -0
  660. package/dist/internal/core/schemas/skill.js.map +1 -0
  661. package/dist/internal/core/schemas/studio/agent.d.ts +13 -0
  662. package/dist/internal/core/schemas/studio/agent.d.ts.map +1 -0
  663. package/dist/internal/core/schemas/studio/agent.js +10 -0
  664. package/dist/internal/core/schemas/studio/agent.js.map +1 -0
  665. package/dist/internal/core/schemas/studio/database.d.ts +40 -0
  666. package/dist/internal/core/schemas/studio/database.d.ts.map +1 -0
  667. package/dist/internal/core/schemas/studio/database.js +35 -0
  668. package/dist/internal/core/schemas/studio/database.js.map +1 -0
  669. package/dist/internal/core/schemas/studio/env.d.ts +8 -0
  670. package/dist/internal/core/schemas/studio/env.d.ts.map +1 -0
  671. package/dist/internal/core/schemas/studio/env.js +8 -0
  672. package/dist/internal/core/schemas/studio/env.js.map +1 -0
  673. package/dist/internal/core/schemas/studio/knowledge.d.ts +19 -0
  674. package/dist/internal/core/schemas/studio/knowledge.d.ts.map +1 -0
  675. package/dist/internal/core/schemas/studio/knowledge.js +15 -0
  676. package/dist/internal/core/schemas/studio/knowledge.js.map +1 -0
  677. package/dist/internal/core/schemas/studio/resource-base.d.ts +8 -0
  678. package/dist/internal/core/schemas/studio/resource-base.d.ts.map +1 -0
  679. package/dist/internal/core/schemas/studio/resource-base.js +8 -0
  680. package/dist/internal/core/schemas/studio/resource-base.js.map +1 -0
  681. package/dist/internal/core/schemas/studio/scene.d.ts +13 -0
  682. package/dist/internal/core/schemas/studio/scene.d.ts.map +1 -0
  683. package/dist/internal/core/schemas/studio/scene.js +12 -0
  684. package/dist/internal/core/schemas/studio/scene.js.map +1 -0
  685. package/dist/internal/core/schemas/studio/tool.d.ts +26 -0
  686. package/dist/internal/core/schemas/studio/tool.d.ts.map +1 -0
  687. package/dist/internal/core/schemas/studio/tool.js +21 -0
  688. package/dist/internal/core/schemas/studio/tool.js.map +1 -0
  689. package/dist/internal/core/schemas/task.d.ts +13 -0
  690. package/dist/internal/core/schemas/task.d.ts.map +1 -0
  691. package/dist/internal/core/schemas/task.js +12 -0
  692. package/dist/internal/core/schemas/task.js.map +1 -0
  693. package/dist/internal/core/stores/answer-callback-store.d.ts +9 -0
  694. package/dist/internal/core/stores/answer-callback-store.d.ts.map +1 -0
  695. package/dist/internal/core/stores/answer-callback-store.js +13 -0
  696. package/dist/internal/core/stores/answer-callback-store.js.map +1 -0
  697. package/dist/internal/core/stores/auth-store.d.ts +38 -0
  698. package/dist/internal/core/stores/auth-store.d.ts.map +1 -0
  699. package/dist/internal/core/stores/auth-store.js +137 -0
  700. package/dist/internal/core/stores/auth-store.js.map +1 -0
  701. package/dist/internal/core/stores/background-store.d.ts +11 -0
  702. package/dist/internal/core/stores/background-store.d.ts.map +1 -0
  703. package/dist/internal/core/stores/background-store.js +34 -0
  704. package/dist/internal/core/stores/background-store.js.map +1 -0
  705. package/dist/internal/core/stores/card-state-store.d.ts +10 -0
  706. package/dist/internal/core/stores/card-state-store.d.ts.map +1 -0
  707. package/dist/internal/core/stores/card-state-store.js +22 -0
  708. package/dist/internal/core/stores/card-state-store.js.map +1 -0
  709. package/dist/internal/core/stores/chat-store.d.ts +34 -0
  710. package/dist/internal/core/stores/chat-store.d.ts.map +1 -0
  711. package/dist/internal/core/stores/chat-store.js +470 -0
  712. package/dist/internal/core/stores/chat-store.js.map +1 -0
  713. package/dist/internal/core/stores/connection-store.d.ts +14 -0
  714. package/dist/internal/core/stores/connection-store.d.ts.map +1 -0
  715. package/dist/internal/core/stores/connection-store.js +28 -0
  716. package/dist/internal/core/stores/connection-store.js.map +1 -0
  717. package/dist/internal/core/stores/gis-store.d.ts +19 -0
  718. package/dist/internal/core/stores/gis-store.d.ts.map +1 -0
  719. package/dist/internal/core/stores/gis-store.js +60 -0
  720. package/dist/internal/core/stores/gis-store.js.map +1 -0
  721. package/dist/internal/core/stores/model-preferences-store.d.ts +14 -0
  722. package/dist/internal/core/stores/model-preferences-store.d.ts.map +1 -0
  723. package/dist/internal/core/stores/model-preferences-store.js +62 -0
  724. package/dist/internal/core/stores/model-preferences-store.js.map +1 -0
  725. package/dist/internal/core/stores/runtime-features-store.d.ts +19 -0
  726. package/dist/internal/core/stores/runtime-features-store.d.ts.map +1 -0
  727. package/dist/internal/core/stores/runtime-features-store.js +17 -0
  728. package/dist/internal/core/stores/runtime-features-store.js.map +1 -0
  729. package/dist/internal/core/stores/runtime-store.d.ts +18 -0
  730. package/dist/internal/core/stores/runtime-store.d.ts.map +1 -0
  731. package/dist/internal/core/stores/runtime-store.js +23 -0
  732. package/dist/internal/core/stores/runtime-store.js.map +1 -0
  733. package/dist/internal/core/stores/session-store.d.ts +39 -0
  734. package/dist/internal/core/stores/session-store.d.ts.map +1 -0
  735. package/dist/internal/core/stores/session-store.js +396 -0
  736. package/dist/internal/core/stores/session-store.js.map +1 -0
  737. package/dist/internal/core/stores/task-store.d.ts +9 -0
  738. package/dist/internal/core/stores/task-store.d.ts.map +1 -0
  739. package/dist/internal/core/stores/task-store.js +14 -0
  740. package/dist/internal/core/stores/task-store.js.map +1 -0
  741. package/dist/internal/core/stores/ui-bridge-store.d.ts +31 -0
  742. package/dist/internal/core/stores/ui-bridge-store.d.ts.map +1 -0
  743. package/dist/internal/core/stores/ui-bridge-store.js +116 -0
  744. package/dist/internal/core/stores/ui-bridge-store.js.map +1 -0
  745. package/dist/internal/core/stores/ui-store.d.ts +59 -0
  746. package/dist/internal/core/stores/ui-store.d.ts.map +1 -0
  747. package/dist/internal/core/stores/ui-store.js +109 -0
  748. package/dist/internal/core/stores/ui-store.js.map +1 -0
  749. package/dist/internal/core/types/index.d.ts +8 -0
  750. package/dist/internal/core/types/index.d.ts.map +1 -0
  751. package/dist/internal/core/types/index.js +2 -0
  752. package/dist/internal/core/types/index.js.map +1 -0
  753. package/dist/internal/core/types/solution.d.ts +22 -0
  754. package/dist/internal/core/types/solution.d.ts.map +1 -0
  755. package/dist/internal/core/types/solution.js +7 -0
  756. package/dist/internal/core/types/solution.js.map +1 -0
  757. package/dist/react.d.ts +9 -0
  758. package/dist/react.d.ts.map +1 -0
  759. package/dist/react.js +9 -0
  760. package/dist/react.js.map +1 -0
  761. package/package.json +67 -7
  762. package/README.md +0 -4
  763. package/index.js +0 -1
@@ -0,0 +1,1127 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { EditorContent, useEditor } from "@tiptap/react";
3
+ import StarterKit from "@tiptap/starter-kit";
4
+ import { exitSuggestion, } from "@tiptap/suggestion";
5
+ import { Archive, ChevronDown, File, FileCode2, FileText, Film, FolderUp, CircleHelp, Download, FlaskConical, Import, Lightbulb, Loader2, Mic, MicOff, Music, Paperclip, Plus, Rocket, Scissors, Send, Sparkles, Share2, Square, X, } from "lucide-react";
6
+ import { useQueryClient } from "@tanstack/react-query";
7
+ import { useEffect, useEffectEvent, useMemo, useRef, useState } from "react";
8
+ import { createRoot } from "react-dom/client";
9
+ import { toast } from "sonner";
10
+ import { useTiptapVoiceInput } from "../../asr/use-tiptap-voice-input";
11
+ import { VoiceWaveform } from "../../asr/VoiceWaveform";
12
+ import { ModelSelector } from "../model/ModelSelector";
13
+ import { useRuntimeFeaturesStore } from "../../stores/runtime-features-store";
14
+ import { useModelPreferencesStore } from "../../stores/model-preferences-store";
15
+ import { getAuthedUrl } from "../../api/client";
16
+ import { getSessionTurns, listSessions, uploadFiles, writeFile } from "../../api/sessions";
17
+ import { listSessionSkills, searchSkills } from "../../api/skills";
18
+ import { useInputHistory } from "../../hooks/use-input-history";
19
+ import { ATTACHMENT_SIZE_LIMIT_BYTES, splitFilesBySize, } from "../../lib/attachment-upload";
20
+ import { buildMessageContent, transformSlashCommand } from "../../lib/chat";
21
+ import { skillDisplayName } from "../../schemas/skill";
22
+ import { useConnectionStore } from "../../stores/connection-store";
23
+ import { useSessionStore } from "../../stores/session-store";
24
+ import { useUiBridgeStore } from "../../stores/ui-bridge-store";
25
+ import { FileCompletionMenu, getFileSuggestionItems, } from "./FileCompletionMenu";
26
+ import { SkillCompletionMenu, } from "./SkillCompletionMenu";
27
+ import { FileSizeLimitDialog } from "./FileSizeLimitDialog";
28
+ import { SkillStatusBar } from "./SkillStatusBar";
29
+ import { FileMention, fileMentionSuggestionKey, } from "./extensions/file-mention";
30
+ import { COMMANDS, SkillMention, skillMentionSuggestionKey, } from "./extensions/skill-mention";
31
+ function getEditorText(editor) {
32
+ return editor?.getText({ blockSeparator: "\n" }) ?? "";
33
+ }
34
+ function buildPlainTextDocument(text) {
35
+ return {
36
+ type: "doc",
37
+ content: text.split("\n").map((line) => ({
38
+ type: "paragraph",
39
+ content: line ? [{ type: "text", text: line }] : [],
40
+ })),
41
+ };
42
+ }
43
+ function replaceEditorText(editor, text) {
44
+ if (!editor) {
45
+ return;
46
+ }
47
+ if (!text) {
48
+ editor.commands.clearContent();
49
+ editor.commands.focus("end");
50
+ return;
51
+ }
52
+ editor.commands.setContent(buildPlainTextDocument(text));
53
+ editor.commands.focus("end");
54
+ }
55
+ function getFileCardIcon(attachment) {
56
+ const lowerName = attachment.name.toLowerCase();
57
+ if (attachment.mimeType.startsWith("audio/")) {
58
+ return Music;
59
+ }
60
+ if (attachment.mimeType.startsWith("video/")) {
61
+ return Film;
62
+ }
63
+ if (/\.(zip|rar|7z|tar|gz|bz2|xz)$/.test(lowerName)) {
64
+ return Archive;
65
+ }
66
+ if (/\.(ts|tsx|js|jsx|py|rb|go|rs|java|kt|swift|c|cc|cpp|h|hpp|css|scss|html|json|yaml|yml|toml|md)$/.test(lowerName)) {
67
+ return FileCode2;
68
+ }
69
+ if (attachment.mimeType.startsWith("text/") || /\.(txt|pdf|doc|docx|rtf|odt)$/.test(lowerName)) {
70
+ return FileText;
71
+ }
72
+ return File;
73
+ }
74
+ async function hashFileContent(file) {
75
+ const buffer = await file.arrayBuffer();
76
+ const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
77
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
78
+ return hashArray
79
+ .map((b) => b.toString(16).padStart(2, "0"))
80
+ .join("")
81
+ .slice(0, 12);
82
+ }
83
+ function getFileExtension(file) {
84
+ const name = file.name || "";
85
+ const dotIndex = name.lastIndexOf(".");
86
+ return dotIndex >= 0 ? name.slice(dotIndex) : "";
87
+ }
88
+ function isClipboardPastedFile(file) {
89
+ // Browsers assign generic names like "image.png" for pasted clipboard images
90
+ return /^image\.\w+$/.test(file.name);
91
+ }
92
+ async function getUploadFileName(file) {
93
+ if (file.webkitRelativePath)
94
+ return file.webkitRelativePath;
95
+ if (isClipboardPastedFile(file)) {
96
+ const hash = await hashFileContent(file);
97
+ return `paste_${hash}${getFileExtension(file)}`;
98
+ }
99
+ return file.name || "未命名文件";
100
+ }
101
+ function getImagePreviewUrl(attachment, sessionId, localImageUrls) {
102
+ if (attachment.status === "uploaded" && sessionId && attachment.uploadedPath) {
103
+ return getAuthedUrl(`/api/sessions/${encodeURIComponent(sessionId)}/files/${encodeURIComponent(attachment.uploadedPath)}`);
104
+ }
105
+ return localImageUrls[attachment.id];
106
+ }
107
+ function isMessageContentEmpty(content) {
108
+ if (typeof content === "string") {
109
+ return !content.trim();
110
+ }
111
+ return content.length === 0 || content.every((part) => part.type === "text" && !part.text.trim());
112
+ }
113
+ function isImageAttachment(attachment) {
114
+ return attachment.kind === "file" && attachment.mimeType.startsWith("image/");
115
+ }
116
+ function buildSubmitPayload(text, attachments, pendingContexts, onBeforeSend) {
117
+ const validAttachments = attachments.filter((attachment) => attachment.status !== "failed");
118
+ const payload = buildMessageContent(text, validAttachments);
119
+ const contextParts = pendingContexts.map((context) => ({
120
+ type: "text",
121
+ text: `[上下文: ${context.label}]\n${context.content}`,
122
+ }));
123
+ const mergedPayload = contextParts.length === 0
124
+ ? payload
125
+ : typeof payload === "string"
126
+ ? payload.trim()
127
+ ? [...contextParts, { type: "text", text: payload }]
128
+ : contextParts
129
+ : [...contextParts, ...payload];
130
+ return onBeforeSend ? onBeforeSend(mergedPayload) : mergedPayload;
131
+ }
132
+ function estimateTokenCount(text) {
133
+ const cjkCount = (text.match(/[\u3400-\u9FFF]/g) ?? []).length;
134
+ const visibleCount = text.replace(/\s/g, "").length;
135
+ const otherCount = Math.max(0, visibleCount - cjkCount);
136
+ return Math.max(0, Math.round(cjkCount * 1.2 + otherCount / 4));
137
+ }
138
+ function formatTokenK(text) {
139
+ const tokenCount = estimateTokenCount(text);
140
+ const tokenK = tokenCount / 1000;
141
+ if (tokenK >= 10) {
142
+ return `约 ${tokenK.toFixed(1)}k`;
143
+ }
144
+ return `约 ${tokenK.toFixed(2)}k`;
145
+ }
146
+ function ComposerFilePill({ attachment, onRemove, }) {
147
+ const Icon = getFileCardIcon(attachment);
148
+ const isFile = attachment.kind === "file";
149
+ const isFailed = isFile && attachment.status === "failed";
150
+ const isUploading = isFile && attachment.status === "uploading";
151
+ return (_jsxs("div", { className: `flex shrink-0 items-center gap-1.5 rounded-full border px-2.5 py-1 text-[11px] ${isFailed
152
+ ? "border-red-500/30 bg-red-500/5 text-red-400"
153
+ : "border-[hsl(var(--border))] bg-[hsl(var(--card))] text-[hsl(var(--foreground))]"}`, children: [isUploading ? (_jsx(Loader2, { size: 12, className: "shrink-0 animate-spin text-[hsl(var(--muted-foreground))]" })) : (_jsx(Icon, { size: 12, className: "shrink-0 text-[hsl(var(--muted-foreground))]" })), _jsx("span", { className: "max-w-32 truncate", children: attachment.name }), _jsx("button", { type: "button", onClick: () => onRemove(attachment.id), "aria-label": `移除 ${attachment.name}`, className: "ml-0.5 inline-flex shrink-0 items-center justify-center rounded-full text-[hsl(var(--muted-foreground))] transition hover:text-rose-400", children: _jsx(X, { size: 10 }) })] }));
154
+ }
155
+ function AddContextDialog({ sessionId, onClose, onAdd, }) {
156
+ const CONTEXT_INLINE_THRESHOLD = 200;
157
+ const [label, setLabel] = useState("");
158
+ const [content, setContent] = useState("");
159
+ const [showSessionPicker, setShowSessionPicker] = useState(false);
160
+ const [sessions, setSessions] = useState([]);
161
+ const [loadingSessions, setLoadingSessions] = useState(false);
162
+ const [importingId, setImportingId] = useState(null);
163
+ const [isImportProcessing, setIsImportProcessing] = useState(false);
164
+ const sanitizeContextFolderName = (raw) => {
165
+ const normalized = raw.trim().toLowerCase();
166
+ const safe = normalized.replace(/[^\w\-.\u4e00-\u9fa5]+/g, "_").replace(/^_+|_+$/g, "");
167
+ return safe || "untitled";
168
+ };
169
+ const uploadContextSnippet = async (folder, fileName, fileContent) => {
170
+ const filePath = `context/${folder}/${fileName}`;
171
+ await writeFile(sessionId, filePath, fileContent);
172
+ return filePath;
173
+ };
174
+ const handleLoadSessions = async () => {
175
+ if (showSessionPicker) {
176
+ setShowSessionPicker(false);
177
+ return;
178
+ }
179
+ setLoadingSessions(true);
180
+ setShowSessionPicker(true);
181
+ try {
182
+ const list = await listSessions();
183
+ setSessions(list
184
+ .filter((s) => s.id !== sessionId)
185
+ .map((s) => ({ id: s.id, intent: s.intent || s.id })));
186
+ }
187
+ catch {
188
+ setSessions([]);
189
+ }
190
+ finally {
191
+ setLoadingSessions(false);
192
+ }
193
+ };
194
+ const handleImportSession = async (sid) => {
195
+ setImportingId(sid);
196
+ setIsImportProcessing(false);
197
+ try {
198
+ const turns = await getSessionTurns(sid);
199
+ const session = sessions.find((s) => s.id === sid);
200
+ const nextLabel = session?.intent || "导入的会话";
201
+ const folder = sanitizeContextFolderName(nextLabel);
202
+ let contextFileIndex = 1;
203
+ const pendingUploads = [];
204
+ const segments = [];
205
+ for (const turn of turns.filter((t) => t.role === "user" || t.role === "assistant")) {
206
+ const textParts = turn.blocks
207
+ .filter((b) => b.type === "text")
208
+ .map((b) => (typeof b.content === "string" ? b.content : ""))
209
+ .filter(Boolean);
210
+ const toolParts = [];
211
+ for (const tc of (turn.tool_calls ?? []).filter((item) => item.status === "done")) {
212
+ const rawResultStr = typeof tc.result === "string"
213
+ ? tc.result
214
+ : tc.result != null
215
+ ? JSON.stringify(tc.result, null, 2)
216
+ : "";
217
+ const hasLongResult = rawResultStr.length > CONTEXT_INLINE_THRESHOLD;
218
+ const toolName = (tc.tool_name || "").toLowerCase();
219
+ const looksLikeReadFile = toolName.includes("read") || toolName.includes("file");
220
+ let resultText = rawResultStr;
221
+ if (hasLongResult || (looksLikeReadFile && rawResultStr.length > CONTEXT_INLINE_THRESHOLD)) {
222
+ const fileName = `tool-result-${String(contextFileIndex).padStart(3, "0")}.txt`;
223
+ contextFileIndex += 1;
224
+ const filePath = `context/${folder}/${fileName}`;
225
+ const pendingText = `[处理中: 将转存到工作区文件 ${filePath}]`;
226
+ pendingUploads.push({
227
+ pendingText,
228
+ finalText: `[内容已转存到工作区文件: ${filePath}]`,
229
+ fallbackPrefix: "[转存失败,保留原文片段]",
230
+ fileName,
231
+ rawResultStr,
232
+ });
233
+ resultText = pendingText;
234
+ }
235
+ toolParts.push(`[工具调用: ${tc.display_name || tc.tool_name}]\n参数: ${tc.arguments}\n结果: ${resultText}`);
236
+ }
237
+ segments.push(`[${turn.role}]: ${[...textParts, ...toolParts].join("\n\n")}`);
238
+ }
239
+ const resolvedText = segments.join("\n\n");
240
+ setLabel(nextLabel);
241
+ setContent(resolvedText);
242
+ setShowSessionPicker(false);
243
+ if (pendingUploads.length > 0) {
244
+ setIsImportProcessing(true);
245
+ let finalText = resolvedText;
246
+ for (const upload of pendingUploads) {
247
+ try {
248
+ await uploadContextSnippet(folder, upload.fileName, upload.rawResultStr);
249
+ finalText = finalText.split(upload.pendingText).join(upload.finalText);
250
+ }
251
+ catch (error) {
252
+ const reason = error instanceof Error ? error.message : "unknown error";
253
+ finalText = finalText.split(upload.pendingText).join(`${upload.fallbackPrefix}\n原因: ${reason}\n${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`);
254
+ }
255
+ setContent(finalText);
256
+ }
257
+ setIsImportProcessing(false);
258
+ }
259
+ }
260
+ catch {
261
+ // ignore
262
+ }
263
+ finally {
264
+ setIsImportProcessing(false);
265
+ setImportingId(null);
266
+ }
267
+ };
268
+ return (_jsx("div", { className: "fixed inset-0 z-[60] flex items-center justify-center bg-black/55 p-4", onClick: onClose, onKeyDown: (e) => {
269
+ if (e.key === "Escape")
270
+ onClose();
271
+ }, children: _jsxs("div", { className: "w-full max-w-lg flex flex-col rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-2xl", onClick: (e) => e.stopPropagation(), onKeyDown: (e) => e.stopPropagation(), children: [_jsxs("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-5 py-3", children: [_jsx("h4", { className: "text-sm font-semibold text-[hsl(var(--foreground))]", children: "\u6DFB\u52A0\u4E0A\u4E0B\u6587" }), _jsx("button", { type: "button", onClick: onClose, className: "rounded-md p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]", children: _jsx(X, { size: 14 }) })] }), _jsxs("div", { className: "px-5 py-4 space-y-3", children: [_jsxs("div", { className: "relative", children: [_jsxs("button", { type: "button", onClick: handleLoadSessions, className: "inline-flex items-center gap-1.5 rounded-md border border-[hsl(var(--border))] px-2.5 py-1.5 text-xs text-[hsl(var(--foreground))] transition-colors hover:bg-[hsl(var(--accent))]", children: [_jsx(Import, { size: 12 }), "\u4ECE\u5176\u4ED6\u4F1A\u8BDD\u5BFC\u5165", _jsx(ChevronDown, { size: 10, className: `transition-transform ${showSessionPicker ? "rotate-180" : ""}` })] }), showSessionPicker && (_jsx("div", { className: "absolute left-0 top-full z-10 mt-1 max-h-48 w-full overflow-y-auto rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-lg", children: loadingSessions ? (_jsxs("div", { className: "flex items-center gap-2 px-3 py-2.5 text-xs text-[hsl(var(--muted-foreground))]", children: [_jsx(Loader2, { size: 12, className: "animate-spin" }), "\u52A0\u8F7D\u4F1A\u8BDD\u5217\u8868\u2026"] })) : sessions.length === 0 ? (_jsx("div", { className: "px-3 py-2.5 text-xs text-[hsl(var(--muted-foreground))]", children: "\u6682\u65E0\u5176\u4ED6\u4F1A\u8BDD" })) : (sessions.map((s) => (_jsxs("button", { type: "button", disabled: importingId === s.id, onClick: () => handleImportSession(s.id), className: "flex w-full items-center gap-2 px-3 py-2 text-left text-xs text-[hsl(var(--foreground))] transition-colors hover:bg-[hsl(var(--accent))] disabled:opacity-50", children: [importingId === s.id && _jsx(Loader2, { size: 10, className: "shrink-0 animate-spin" }), _jsx("span", { className: "truncate", children: s.intent })] }, s.id)))) }))] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "ctx-label", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u6807\u7B7E" }), _jsx("input", { id: "ctx-label", value: label, onChange: (e) => setLabel(e.target.value), placeholder: "\u4F8B\u5982\uFF1A\u53C2\u8003\u5BF9\u8BDD\u3001\u80CC\u666F\u8D44\u6599\u2026", className: "w-full rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--background))] px-3 py-1.5 text-xs text-[hsl(var(--foreground))] placeholder:text-[hsl(var(--muted-foreground))] outline-none focus-visible:border-[hsl(var(--ring))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))]" })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "ctx-content", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u5185\u5BB9" }), isImportProcessing && (_jsxs("div", { className: "mb-1.5 flex items-center gap-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [_jsx(Loader2, { size: 11, className: "animate-spin" }), "\u6B63\u5728\u5904\u7406\u5BFC\u5165\u5185\u5BB9\u5E76\u5199\u5165 workspace/context\uFF0C\u5B8C\u6210\u540E\u53EF\u70B9\u51FB\u201C\u786E\u5B9A\u201D"] })), _jsx("textarea", { id: "ctx-content", value: content, onChange: (e) => setContent(e.target.value), placeholder: "\u8F93\u5165\u6216\u4ECE\u5176\u4ED6\u4F1A\u8BDD\u5BFC\u5165\u4E0A\u4E0B\u6587\u5185\u5BB9\u2026", rows: 6, className: "w-full rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--background))] px-3 py-2 font-mono text-[11px] leading-[1.6] text-[hsl(var(--foreground))] placeholder:text-[hsl(var(--muted-foreground))] outline-none focus-visible:border-[hsl(var(--ring))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] resize-y" })] })] }), _jsxs("div", { className: "flex justify-end gap-2 border-t border-[hsl(var(--border))] px-5 py-3", children: [_jsx("button", { type: "button", onClick: onClose, className: "rounded-md border border-[hsl(var(--border))] px-3 py-1.5 text-xs text-[hsl(var(--foreground))] transition-colors hover:bg-[hsl(var(--accent))]", children: "\u53D6\u6D88" }), _jsx("button", { type: "button", onClick: () => {
272
+ if (label.trim() && content.trim()) {
273
+ onAdd(label.trim(), content.trim());
274
+ onClose();
275
+ }
276
+ }, disabled: isImportProcessing || !label.trim() || !content.trim(), className: "rounded-md bg-blue-500 px-3 py-1.5 text-xs text-white transition-colors hover:bg-blue-600 disabled:opacity-50", children: "\u786E\u5B9A" })] })] }) }));
277
+ }
278
+ function ComposerContextPill({ id, label, content, onRemove, }) {
279
+ const [showDetail, setShowDetail] = useState(false);
280
+ const tokenK = formatTokenK(content);
281
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex shrink-0 items-center gap-1.5 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--accent))] px-2.5 py-1 text-[11px] text-[hsl(var(--foreground))]", children: [_jsx("button", { type: "button", onClick: () => setShowDetail(true), className: "max-w-40 truncate hover:text-blue-400 transition-colors", title: "\u70B9\u51FB\u67E5\u770B\u5B8C\u6574\u5185\u5BB9", children: label }), _jsx("span", { className: "shrink-0 rounded bg-[hsl(var(--background))] px-1.5 py-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", title: "\u4E0A\u4E0B\u6587\u5185\u5BB9 token \u4F30\u7B97\u503C", children: tokenK }), _jsx("button", { type: "button", onClick: () => onRemove(id), "aria-label": `移除上下文 ${label}`, className: "ml-0.5 inline-flex shrink-0 items-center justify-center rounded-full text-[hsl(var(--muted-foreground))] transition hover:text-rose-400", children: _jsx(X, { size: 10 }) })] }), showDetail && (_jsx("div", { className: "fixed inset-0 z-[60] flex items-center justify-center bg-black/55 p-6", onClick: () => setShowDetail(false), onKeyDown: (e) => {
282
+ if (e.key === "Escape")
283
+ setShowDetail(false);
284
+ }, children: _jsxs("div", { className: "w-full max-w-4xl max-h-[85vh] flex flex-col rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-2xl", onClick: (e) => e.stopPropagation(), onKeyDown: (e) => e.stopPropagation(), children: [_jsxs("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-6 py-3", children: [_jsx("h4", { className: "text-xs font-semibold text-[hsl(var(--foreground))]", children: label }), _jsx("button", { type: "button", onClick: () => setShowDetail(false), className: "rounded-md p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]", children: _jsx(X, { size: 14 }) })] }), _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-6 py-4", children: _jsx("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] leading-[1.6] text-[hsl(var(--foreground)/0.85)]", children: content }) })] }) }))] }));
285
+ }
286
+ function serializeEditorContent(node) {
287
+ if (!node)
288
+ return "";
289
+ if (node.type === "text") {
290
+ return node.text ?? "";
291
+ }
292
+ if (node.type === "hardBreak") {
293
+ return "\n";
294
+ }
295
+ if (node.type === "fileMention") {
296
+ const path = typeof node.attrs?.path === "string" ? node.attrs.path : "";
297
+ return path ? `\`${path}\`` : "";
298
+ }
299
+ if (node.type === "skillMention") {
300
+ const skillId = typeof node.attrs?.skillId === "string" ? node.attrs.skillId : "";
301
+ return skillId ? `<skill>${skillId}</skill>` : "";
302
+ }
303
+ const children = (node.content ?? []).map((child) => serializeEditorContent(child));
304
+ if (node.type === "doc") {
305
+ return children.join("\n");
306
+ }
307
+ return children.join("");
308
+ }
309
+ function findLeadingSkillMention(node) {
310
+ const result = scanLeadingSkillMention(node, false);
311
+ return result.skillId;
312
+ }
313
+ function scanLeadingSkillMention(node, seenContent) {
314
+ if (!node) {
315
+ return { skillId: null, seenContent };
316
+ }
317
+ if (node.type === "text") {
318
+ return { skillId: null, seenContent: seenContent || /\S/.test(node.text ?? "") };
319
+ }
320
+ if (node.type === "hardBreak" || node.type === "fileMention") {
321
+ return { skillId: null, seenContent: true };
322
+ }
323
+ if (node.type === "skillMention") {
324
+ return {
325
+ skillId: seenContent ? null : (typeof node.attrs?.skillId === "string" ? node.attrs.skillId : null),
326
+ seenContent: true,
327
+ };
328
+ }
329
+ let nextSeenContent = seenContent;
330
+ for (const child of node.content ?? []) {
331
+ const result = scanLeadingSkillMention(child, nextSeenContent);
332
+ if (result.skillId) {
333
+ return result;
334
+ }
335
+ nextSeenContent = result.seenContent;
336
+ }
337
+ return { skillId: null, seenContent: nextSeenContent };
338
+ }
339
+ async function getSkillSuggestionItems(sessionId, query) {
340
+ const loadSessionSkills = async () => {
341
+ if (!sessionId) {
342
+ return [];
343
+ }
344
+ try {
345
+ return await listSessionSkills(sessionId);
346
+ }
347
+ catch {
348
+ return [];
349
+ }
350
+ };
351
+ if (!query) {
352
+ const source = await loadSessionSkills();
353
+ return source.map((s) => ({
354
+ type: "skill",
355
+ skillId: s.skill_id,
356
+ displayName: s.display_name,
357
+ description: s.description,
358
+ local: s.local,
359
+ }));
360
+ }
361
+ const q = query.toLowerCase();
362
+ const sessionSkills = await loadSessionSkills();
363
+ const localMatches = sessionSkills
364
+ .filter((s) => s.skill_id.toLowerCase().includes(q) ||
365
+ s.description.toLowerCase().includes(q))
366
+ .map((s) => ({
367
+ type: "skill",
368
+ skillId: s.skill_id,
369
+ displayName: s.display_name,
370
+ description: s.description,
371
+ local: s.local,
372
+ }));
373
+ try {
374
+ const remoteResults = await searchSkills(query, 10);
375
+ const seen = new Set(localMatches.map((s) => s.skillId));
376
+ const dedupedRemote = remoteResults
377
+ .filter((r) => !seen.has(r.skill_id))
378
+ .map((r) => ({
379
+ type: "skill",
380
+ skillId: r.skill_id,
381
+ displayName: r.display_name,
382
+ description: r.description,
383
+ local: r.local,
384
+ }));
385
+ return [...localMatches, ...dedupedRemote];
386
+ }
387
+ catch {
388
+ return localMatches;
389
+ }
390
+ }
391
+ function updateSuggestionPosition(element, clientRect) {
392
+ const rect = clientRect?.();
393
+ if (!rect) {
394
+ element.style.display = "none";
395
+ return;
396
+ }
397
+ const width = Math.min(420, window.innerWidth - 16);
398
+ const left = Math.min(Math.max(8, rect.left), window.innerWidth - width - 8);
399
+ // Always place above the cursor, anchored to bottom
400
+ const bottom = window.innerHeight - rect.top + 4;
401
+ element.style.display = "block";
402
+ element.style.position = "fixed";
403
+ element.style.left = `${left}px`;
404
+ element.style.top = "";
405
+ element.style.bottom = `${bottom}px`;
406
+ element.style.maxHeight = `${rect.top - 16}px`;
407
+ element.style.width = `${width}px`;
408
+ element.style.zIndex = "60";
409
+ }
410
+ function showVoiceInputErrorToast(error) {
411
+ toast.error(error.title, {
412
+ description: error.description,
413
+ duration: error.description ? 15000 : undefined,
414
+ });
415
+ }
416
+ export function ChatInput({ onSend, onStop, isStreaming, mode = "executing", onToggleMode, renderAttachments, onBeforeSend, ensureSession, onCommand, canShareSession = false, slotAboveTextarea, externalDraft, externalAttachments, maxWidthClassName = "max-w-3xl", onResyncSkills, isResyncingSkills = false, }) {
417
+ const [input, setInputInternal] = useState(externalDraft?.value ?? "");
418
+ // Mirror every setInput into the optional external channel so the caller
419
+ // (e.g. ship-attack's chat-draft-store) can persist the draft across view
420
+ // switches. The internal useState stays the source of truth for tiptap.
421
+ const setInput = useEffectEvent((value) => {
422
+ setInputInternal(value);
423
+ externalDraft?.setValue(value);
424
+ });
425
+ // Reverse sync: when external value changes from the outside (e.g. a sibling
426
+ // ChatInput wrote to the shared store, or the user switched to a session with
427
+ // a different saved draft), pull it back into both this instance's input state
428
+ // AND the tiptap editor.
429
+ //
430
+ // No "non-empty → empty" guard: it used to be here to paper over a race where
431
+ // ship-attack's draft store briefly observed `drafts[newId] === undefined`
432
+ // during createSession → setActiveSession before migrateDraftKey landed. But
433
+ // migrateDraftKey is now invoked synchronously right after setActiveSession
434
+ // in the same React commit, so the race can't happen. Keeping the guard would
435
+ // *break* the legitimate "user switches to a session with no saved draft"
436
+ // case: external goes to "" and the composer would stubbornly keep the
437
+ // previous session's text — which then gets posted into the wrong session on
438
+ // next send, since `send` resolves against the new active session id.
439
+ const externalDraftValue = externalDraft?.value;
440
+ const inputRef = useRef(input);
441
+ inputRef.current = input;
442
+ useEffect(() => {
443
+ if (externalDraftValue == null)
444
+ return;
445
+ // inputRef 读当前 internal 值;updater callback 里做 diff 是 render-phase
446
+ // 副作用,React 19 的 useEffectEvent 检查会把之后同步触发的 editor.onUpdate
447
+ // 判为 "被 render 调用",这里改成 effect 体内直接 diff + 写。
448
+ if (inputRef.current === externalDraftValue)
449
+ return;
450
+ if (editorRef.current) {
451
+ replaceEditorText(editorRef.current, externalDraftValue);
452
+ }
453
+ setInputInternal(externalDraftValue);
454
+ }, [externalDraftValue]);
455
+ const [composerAttachments, setComposerAttachmentsInternal] = useState(externalAttachments?.value ?? []);
456
+ const setComposerAttachments = useEffectEvent((valueOrUpdater) => {
457
+ setComposerAttachmentsInternal((prev) => {
458
+ const next = typeof valueOrUpdater === "function"
459
+ ? valueOrUpdater(prev)
460
+ : valueOrUpdater;
461
+ externalAttachments?.setValue(next);
462
+ return next;
463
+ });
464
+ });
465
+ // Reverse sync for attachments — same reasoning as the draft channel above:
466
+ // no "non-empty → empty" guard, because session switching legitimately needs
467
+ // to clear the previous session's attachments and the migrate path never
468
+ // actually goes through an empty intermediate.
469
+ const externalAttachmentsValue = externalAttachments?.value;
470
+ const composerAttachmentsRef = useRef(composerAttachments);
471
+ composerAttachmentsRef.current = composerAttachments;
472
+ useEffect(() => {
473
+ if (externalAttachmentsValue == null)
474
+ return;
475
+ if (composerAttachmentsRef.current === externalAttachmentsValue)
476
+ return;
477
+ setComposerAttachmentsInternal(externalAttachmentsValue);
478
+ }, [externalAttachmentsValue]);
479
+ const [dragging, setDragging] = useState(false);
480
+ const [isEditorFocused, setIsEditorFocused] = useState(false);
481
+ const [oversizedFiles, setOversizedFiles] = useState([]);
482
+ const [selectedModel, setSelectedModel] = useState("");
483
+ const defaultModel = useModelPreferencesStore((state) => state.defaultModel);
484
+ const initializeModels = useModelPreferencesStore((state) => state.initialize);
485
+ const setPreferredModel = useModelPreferencesStore((state) => state.setPreferredModel);
486
+ const queryClient = useQueryClient();
487
+ const actionMenuRef = useRef(null);
488
+ const fileInputRef = useRef(null);
489
+ const folderInputRef = useRef(null);
490
+ const editorRef = useRef(null);
491
+ const localImageUrlsRef = useRef(new Map());
492
+ const activeSessionId = useSessionStore((state) => state.activeSessionId);
493
+ const sessions = useSessionStore((state) => state.sessions);
494
+ const activeSessionModel = useMemo(() => sessions.find((session) => session.id === activeSessionId)?.model ?? null, [activeSessionId, sessions]);
495
+ const rewindDraft = useSessionStore((state) => activeSessionId ? state.rewindDrafts[activeSessionId] : undefined);
496
+ const patchSession = useSessionStore((state) => state.patchSession);
497
+ const setRewindDraft = useSessionStore((state) => state.setRewindDraft);
498
+ const pendingContexts = useUiBridgeStore((state) => activeSessionId ? state.pendingContexts[activeSessionId] : undefined);
499
+ const draftAppends = useUiBridgeStore((state) => activeSessionId ? state.draftAppends[activeSessionId] : undefined);
500
+ useEffect(() => {
501
+ void initializeModels();
502
+ }, [initializeModels]);
503
+ useEffect(() => {
504
+ setSelectedModel(activeSessionModel || defaultModel);
505
+ }, [activeSessionModel, defaultModel]);
506
+ const sendRequests = useUiBridgeStore((state) => activeSessionId ? state.sendRequests[activeSessionId] : undefined);
507
+ const removePendingContext = useUiBridgeStore((state) => state.removePendingContext);
508
+ const consumePendingContexts = useUiBridgeStore((state) => state.consumePendingContexts);
509
+ const consumeDraftAppends = useUiBridgeStore((state) => state.consumeDraftAppends);
510
+ const consumeSendRequests = useUiBridgeStore((state) => state.consumeSendRequests);
511
+ const connectionStatus = useConnectionStore((state) => state.status);
512
+ const inputHistory = useInputHistory(activeSessionId);
513
+ const getSessionId = useEffectEvent(() => activeSessionId);
514
+ const handleSlashCommand = useEffectEvent((commandId) => onCommand?.(commandId));
515
+ const [localImageUrls, setLocalImageUrls] = useState({});
516
+ useEffect(() => {
517
+ const closeActionMenu = (event) => {
518
+ const menu = actionMenuRef.current;
519
+ if (!menu?.open || menu.contains(event.target)) {
520
+ return;
521
+ }
522
+ menu.removeAttribute("open");
523
+ };
524
+ const closeActionMenuOnEscape = (event) => {
525
+ if (event.key === "Escape") {
526
+ actionMenuRef.current?.removeAttribute("open");
527
+ }
528
+ };
529
+ window.addEventListener("pointerdown", closeActionMenu);
530
+ window.addEventListener("keydown", closeActionMenuOnEscape);
531
+ return () => {
532
+ window.removeEventListener("pointerdown", closeActionMenu);
533
+ window.removeEventListener("keydown", closeActionMenuOnEscape);
534
+ };
535
+ }, []);
536
+ const getMentionSuggestionItems = useEffectEvent(async (query) => {
537
+ const normalizedQuery = query.trim().toLowerCase();
538
+ const commandItems = COMMANDS.filter((item) => {
539
+ if (!normalizedQuery) {
540
+ return true;
541
+ }
542
+ return (item.id.toLowerCase().startsWith(normalizedQuery) ||
543
+ item.label.toLowerCase().startsWith(normalizedQuery));
544
+ });
545
+ const skillItems = await getSkillSuggestionItems(getSessionId(), query);
546
+ return [...commandItems, ...skillItems];
547
+ });
548
+ const appendFiles = async (files) => {
549
+ const { accepted, rejected } = splitFilesBySize(files, ATTACHMENT_SIZE_LIMIT_BYTES);
550
+ if (rejected.length > 0) {
551
+ setOversizedFiles(rejected);
552
+ }
553
+ if (accepted.length === 0) {
554
+ return;
555
+ }
556
+ // Files are always staged as `pending` with the raw File handle; upload happens
557
+ // at submit time so that no-active-session hosts (e.g. ship-attack left panel)
558
+ // can create the session via `ensureSession` and still upload to workdir.
559
+ const pendingFileAttachments = await Promise.all(accepted.map(async (file) => {
560
+ const uploadName = await getUploadFileName(file);
561
+ const id = `${uploadName}-${file.size}-${file.lastModified}-${Math.random().toString(36).slice(2)}`;
562
+ return {
563
+ id,
564
+ kind: "file",
565
+ name: uploadName,
566
+ size: file.size,
567
+ mimeType: file.type,
568
+ status: "pending",
569
+ file,
570
+ };
571
+ }));
572
+ if (pendingFileAttachments.length > 0) {
573
+ setComposerAttachments((prev) => [...prev, ...pendingFileAttachments]);
574
+ }
575
+ };
576
+ const stableAppendFiles = useEffectEvent((files) => appendFiles(files));
577
+ const stableHandleSubmit = useEffectEvent(() => handleSubmit());
578
+ const getEditorState = useEffectEvent(() => ({
579
+ input,
580
+ connectionStatus,
581
+ navigateUp: inputHistory.navigateUp,
582
+ navigateDown: inputHistory.navigateDown,
583
+ isNavigatingHistory: inputHistory.isNavigating,
584
+ handleSubmit: stableHandleSubmit,
585
+ }));
586
+ const syncEditorState = (editorInstance) => {
587
+ const value = getEditorText(editorInstance);
588
+ setInput(value);
589
+ };
590
+ const resetComposer = () => {
591
+ editorRef.current?.commands.clearContent();
592
+ setInput("");
593
+ setComposerAttachments([]);
594
+ };
595
+ const editor = useEditor({
596
+ immediatelyRender: false,
597
+ extensions: [
598
+ StarterKit.configure({
599
+ blockquote: false,
600
+ bulletList: false,
601
+ codeBlock: false,
602
+ dropcursor: false,
603
+ gapcursor: false,
604
+ heading: false,
605
+ horizontalRule: false,
606
+ orderedList: false,
607
+ }),
608
+ FileMention.configure({
609
+ suggestion: {
610
+ char: "@",
611
+ pluginKey: fileMentionSuggestionKey,
612
+ items: async ({ query }) => getFileSuggestionItems(getSessionId(), query),
613
+ command: ({ editor: suggestionEditor, props, range }) => {
614
+ const item = props;
615
+ suggestionEditor
616
+ .chain()
617
+ .focus()
618
+ .insertContentAt(range, [
619
+ {
620
+ type: "fileMention",
621
+ attrs: {
622
+ name: item.name,
623
+ path: item.path,
624
+ },
625
+ },
626
+ {
627
+ type: "text",
628
+ text: " ",
629
+ },
630
+ ])
631
+ .run();
632
+ },
633
+ render: () => {
634
+ let container = null;
635
+ let root = null;
636
+ const menuRef = { current: null };
637
+ const handleExit = () => {
638
+ const view = editorRef.current?.view;
639
+ if (view) {
640
+ exitSuggestion(view, fileMentionSuggestionKey);
641
+ }
642
+ };
643
+ const renderMenu = (props) => {
644
+ if (!container || !root)
645
+ return;
646
+ updateSuggestionPosition(container, props.clientRect);
647
+ root.render(_jsx(FileCompletionMenu, { ref: (instance) => {
648
+ menuRef.current = instance;
649
+ }, ...props, sessionId: getSessionId(), onExit: handleExit }));
650
+ };
651
+ return {
652
+ onStart: (props) => {
653
+ container = document.createElement("div");
654
+ document.body.appendChild(container);
655
+ root = createRoot(container);
656
+ renderMenu(props);
657
+ },
658
+ onUpdate: (props) => {
659
+ renderMenu(props);
660
+ },
661
+ onExit: () => {
662
+ menuRef.current = null;
663
+ root?.unmount();
664
+ container?.remove();
665
+ root = null;
666
+ container = null;
667
+ },
668
+ onKeyDown: ({ event, view }) => {
669
+ if (event.key === "Escape") {
670
+ event.preventDefault();
671
+ exitSuggestion(view, fileMentionSuggestionKey);
672
+ return true;
673
+ }
674
+ return menuRef.current?.onKeyDown(event) ?? false;
675
+ },
676
+ };
677
+ },
678
+ },
679
+ }),
680
+ SkillMention.configure({
681
+ suggestion: {
682
+ char: "/",
683
+ pluginKey: skillMentionSuggestionKey,
684
+ items: ({ query }) => getMentionSuggestionItems(query),
685
+ command: ({ editor: suggestionEditor, props, range }) => {
686
+ const item = props;
687
+ if (item.type === "command") {
688
+ suggestionEditor.chain().focus().deleteRange(range).run();
689
+ void handleSlashCommand(item.id);
690
+ return;
691
+ }
692
+ suggestionEditor
693
+ .chain()
694
+ .focus()
695
+ .insertContentAt(range, [
696
+ {
697
+ type: "skillMention",
698
+ attrs: {
699
+ skillId: item.skillId,
700
+ displayName: skillDisplayName(item),
701
+ description: item.description,
702
+ },
703
+ },
704
+ {
705
+ type: "text",
706
+ text: " ",
707
+ },
708
+ ])
709
+ .run();
710
+ },
711
+ render: () => {
712
+ let container = null;
713
+ let root = null;
714
+ const menuRef = { current: null };
715
+ const renderMenu = (props) => {
716
+ if (!container || !root)
717
+ return;
718
+ updateSuggestionPosition(container, props.clientRect);
719
+ root.render(_jsx(SkillCompletionMenu, { ref: (instance) => {
720
+ menuRef.current = instance;
721
+ }, items: props.items, command: (item) => props.command(item) }));
722
+ };
723
+ return {
724
+ onStart: (props) => {
725
+ container = document.createElement("div");
726
+ document.body.appendChild(container);
727
+ root = createRoot(container);
728
+ renderMenu(props);
729
+ },
730
+ onUpdate: (props) => {
731
+ renderMenu(props);
732
+ },
733
+ onExit: () => {
734
+ menuRef.current = null;
735
+ root?.unmount();
736
+ container?.remove();
737
+ root = null;
738
+ container = null;
739
+ },
740
+ onKeyDown: ({ event, view }) => {
741
+ if (event.key === "Escape") {
742
+ event.preventDefault();
743
+ exitSuggestion(view, skillMentionSuggestionKey);
744
+ return true;
745
+ }
746
+ return menuRef.current?.onKeyDown(event) ?? false;
747
+ },
748
+ };
749
+ },
750
+ },
751
+ }),
752
+ ],
753
+ content: "",
754
+ onCreate: ({ editor: editorInstance }) => {
755
+ editorRef.current = editorInstance;
756
+ syncEditorState(editorInstance);
757
+ },
758
+ onUpdate: ({ editor: editorInstance }) => {
759
+ syncEditorState(editorInstance);
760
+ },
761
+ editorProps: {
762
+ attributes: {
763
+ "aria-label": "输入消息",
764
+ class: "min-h-[40px] max-h-[240px] overflow-y-auto px-4 py-3 text-sm leading-relaxed text-[hsl(var(--foreground))] focus:outline-none [&_.file-mention-pill]:inline-flex [&_.file-mention-pill]:items-center [&_.file-mention-pill]:rounded-full [&_.file-mention-pill]:bg-[hsl(var(--accent))] [&_.file-mention-pill]:px-2 [&_.file-mention-pill]:py-0.5 [&_.file-mention-pill]:font-medium [&_.file-mention-pill]:text-[hsl(var(--primary))] [&_.file-mention-pill]:select-none [&_.file-mention-pill]:whitespace-nowrap [&_.skill-mention-pill]:inline-flex [&_.skill-mention-pill]:items-center [&_.skill-mention-pill]:rounded-full [&_.skill-mention-pill]:bg-[hsl(var(--primary)/0.15)] [&_.skill-mention-pill]:px-2 [&_.skill-mention-pill]:py-0.5 [&_.skill-mention-pill]:font-medium [&_.skill-mention-pill]:text-[hsl(var(--primary))] [&_.skill-mention-pill]:select-none [&_.skill-mention-pill]:whitespace-nowrap [&_p:first-child]:mt-0 [&_p:last-child]:mb-0",
765
+ },
766
+ handleDOMEvents: {
767
+ focus: () => {
768
+ setIsEditorFocused(true);
769
+ return false;
770
+ },
771
+ blur: () => {
772
+ setIsEditorFocused(false);
773
+ return false;
774
+ },
775
+ keydown: (_view, event) => {
776
+ const state = getEditorState();
777
+ const fileMentionState = editorRef.current
778
+ ? fileMentionSuggestionKey.getState(editorRef.current.view.state)
779
+ : undefined;
780
+ if (fileMentionState?.active) {
781
+ return false;
782
+ }
783
+ const skillMentionState = editorRef.current
784
+ ? skillMentionSuggestionKey.getState(editorRef.current.view.state)
785
+ : undefined;
786
+ if (skillMentionState?.active) {
787
+ return false;
788
+ }
789
+ if (!event.isComposing && event.key === "ArrowUp" && (state.input.trim().length === 0 || state.isNavigatingHistory)) {
790
+ const previousEntry = state.navigateUp(state.input);
791
+ if (!previousEntry) {
792
+ return false;
793
+ }
794
+ event.preventDefault();
795
+ replaceEditorText(editorRef.current, previousEntry);
796
+ return true;
797
+ }
798
+ if (!event.isComposing && event.key === "ArrowDown") {
799
+ const nextEntry = state.navigateDown();
800
+ if (nextEntry == null) {
801
+ return false;
802
+ }
803
+ event.preventDefault();
804
+ replaceEditorText(editorRef.current, nextEntry);
805
+ return true;
806
+ }
807
+ if (event.key === "Enter" && !event.shiftKey && !event.isComposing) {
808
+ event.preventDefault();
809
+ if (state.connectionStatus !== "connected") {
810
+ return true;
811
+ }
812
+ void state.handleSubmit();
813
+ return true;
814
+ }
815
+ return false;
816
+ },
817
+ paste: (_view, event) => {
818
+ if (event.clipboardData?.files.length) {
819
+ event.preventDefault();
820
+ void stableAppendFiles(event.clipboardData.files);
821
+ return true;
822
+ }
823
+ return false;
824
+ },
825
+ },
826
+ },
827
+ });
828
+ useEffect(() => {
829
+ if (!editor || !activeSessionId || rewindDraft == null) {
830
+ return;
831
+ }
832
+ editor.commands.clearContent();
833
+ if (rewindDraft) {
834
+ editor.commands.insertContent({ type: "text", text: rewindDraft });
835
+ }
836
+ editor.commands.focus("end");
837
+ setRewindDraft(activeSessionId, null);
838
+ }, [activeSessionId, editor, rewindDraft, setRewindDraft]);
839
+ const submittingRef = useRef(false);
840
+ useEffect(() => {
841
+ let changed = false;
842
+ const nextLocalIds = new Set();
843
+ for (const attachment of composerAttachments) {
844
+ if (!isImageAttachment(attachment) || !attachment.file || attachment.status === "uploaded") {
845
+ continue;
846
+ }
847
+ nextLocalIds.add(attachment.id);
848
+ if (!localImageUrlsRef.current.has(attachment.id)) {
849
+ localImageUrlsRef.current.set(attachment.id, URL.createObjectURL(attachment.file));
850
+ changed = true;
851
+ }
852
+ }
853
+ for (const [attachmentId, url] of localImageUrlsRef.current) {
854
+ if (nextLocalIds.has(attachmentId)) {
855
+ continue;
856
+ }
857
+ URL.revokeObjectURL(url);
858
+ localImageUrlsRef.current.delete(attachmentId);
859
+ changed = true;
860
+ }
861
+ if (changed) {
862
+ setLocalImageUrls(Object.fromEntries(localImageUrlsRef.current));
863
+ }
864
+ }, [composerAttachments]);
865
+ useEffect(() => {
866
+ return () => {
867
+ for (const url of localImageUrlsRef.current.values()) {
868
+ URL.revokeObjectURL(url);
869
+ }
870
+ localImageUrlsRef.current.clear();
871
+ };
872
+ }, []);
873
+ const applyDraftAppends = useEffectEvent(() => {
874
+ if (!activeSessionId || !editor) {
875
+ return;
876
+ }
877
+ const appends = consumeDraftAppends(activeSessionId);
878
+ if (appends.length === 0) {
879
+ return;
880
+ }
881
+ const text = appends.map((append) => append.text).join("");
882
+ if (!text) {
883
+ return;
884
+ }
885
+ editor.chain().focus("end").insertContent(text).run();
886
+ });
887
+ useEffect(() => {
888
+ if (!draftAppends?.length) {
889
+ return;
890
+ }
891
+ applyDraftAppends();
892
+ }, [applyDraftAppends, draftAppends]);
893
+ const applySendRequests = useEffectEvent(() => {
894
+ if (!activeSessionId) {
895
+ return;
896
+ }
897
+ const requests = consumeSendRequests(activeSessionId);
898
+ if (requests.length === 0) {
899
+ return;
900
+ }
901
+ void stableHandleSubmit();
902
+ });
903
+ useEffect(() => {
904
+ if (!sendRequests?.length) {
905
+ return;
906
+ }
907
+ applySendRequests();
908
+ }, [applySendRequests, sendRequests]);
909
+ // ASR 语音输入:partial 实时替换、final 落定;录音中锁定编辑器
910
+ const viteEnv = import.meta.env ?? {};
911
+ const asrEnabled = useRuntimeFeaturesStore((s) => s.asrEnabled);
912
+ const voice = useTiptapVoiceInput({
913
+ editorRef,
914
+ workletUrl: `${viteEnv.BASE_URL ?? "/"}asr/pcm-worklet.js`,
915
+ onError: showVoiceInputErrorToast,
916
+ });
917
+ const { isRecording, level: voiceLevel } = voice;
918
+ const handleMicDisabledClick = () => toast.info("语音输入功能未开启,请在后端 .env 配置 ASR_API_KEY");
919
+ // 流式中 / session 切换 时强制停录音,避免回调打到错会话
920
+ const voiceStopRef = useRef(voice.stop);
921
+ voiceStopRef.current = voice.stop;
922
+ useEffect(() => {
923
+ if (isStreaming && isRecording) {
924
+ void voiceStopRef.current();
925
+ }
926
+ }, [isStreaming, isRecording]);
927
+ const prevSessionIdRef = useRef(activeSessionId);
928
+ useEffect(() => {
929
+ if (prevSessionIdRef.current !== activeSessionId) {
930
+ prevSessionIdRef.current = activeSessionId;
931
+ if (isRecording) {
932
+ void voiceStopRef.current();
933
+ }
934
+ }
935
+ }, [activeSessionId, isRecording]);
936
+ const handleSubmit = async () => {
937
+ if (isStreaming || connectionStatus !== "connected") {
938
+ return;
939
+ }
940
+ if (submittingRef.current) {
941
+ return;
942
+ }
943
+ if (composerAttachments.some((attachment) => attachment.kind === "file" && attachment.status === "uploading")) {
944
+ return;
945
+ }
946
+ submittingRef.current = true;
947
+ try {
948
+ const json = editor?.getJSON();
949
+ const rawText = serializeEditorContent(json);
950
+ const skillName = findLeadingSkillMention(json);
951
+ const text = skillName ? transformSlashCommand(skillName, rawText) : rawText;
952
+ const pendingFiles = composerAttachments.filter((a) => a.kind === "file" && a.status === "pending" && !!a.file);
953
+ let updatedAttachments = composerAttachments;
954
+ let uploadTargetSessionId;
955
+ if (pendingFiles.length > 0) {
956
+ let uploadSessionId = activeSessionId;
957
+ if (!uploadSessionId && ensureSession) {
958
+ try {
959
+ uploadSessionId = await ensureSession(text || "新会话");
960
+ }
961
+ catch {
962
+ setComposerAttachments((prev) => prev.map((a) => a.kind === "file" && a.status === "pending"
963
+ ? { ...a, status: "failed" }
964
+ : a));
965
+ return;
966
+ }
967
+ }
968
+ if (uploadSessionId) {
969
+ uploadTargetSessionId = uploadSessionId;
970
+ if (pendingFiles.length > 0) {
971
+ setComposerAttachments((prev) => prev.map((a) => a.kind === "file" && a.status === "pending"
972
+ ? { ...a, status: "uploading" }
973
+ : a));
974
+ try {
975
+ const result = await uploadFiles(uploadSessionId, ".", pendingFiles.map((a) => ({ file: a.file, name: a.name })));
976
+ // Map pending file id → server result synchronously,
977
+ // so buildSubmitPayload sees the correct server-deduped names.
978
+ const uploadResultById = new Map();
979
+ const failedSet = new Set(result.failed);
980
+ let uploadIdx = 0;
981
+ for (const pf of pendingFiles) {
982
+ if (failedSet.has(pf.name)) {
983
+ failedSet.delete(pf.name);
984
+ uploadResultById.set(pf.id, null);
985
+ }
986
+ else {
987
+ uploadResultById.set(pf.id, result.uploaded[uploadIdx++] ?? null);
988
+ }
989
+ }
990
+ updatedAttachments = composerAttachments.map((a) => {
991
+ if (!uploadResultById.has(a.id))
992
+ return a;
993
+ const uploadedPath = uploadResultById.get(a.id);
994
+ if (!uploadedPath)
995
+ return { ...a, status: "failed" };
996
+ const actualName = uploadedPath.split("/").pop() || a.name;
997
+ return { ...a, name: actualName, status: "uploaded", uploadedPath };
998
+ });
999
+ setComposerAttachments(updatedAttachments);
1000
+ if (result.uploaded.length > 0) {
1001
+ void queryClient.invalidateQueries({ queryKey: ["file-tree", uploadSessionId] });
1002
+ }
1003
+ }
1004
+ catch {
1005
+ setComposerAttachments((prev) => prev.map((a) => a.kind === "file" && a.status === "uploading"
1006
+ ? { ...a, status: "failed" }
1007
+ : a));
1008
+ return;
1009
+ }
1010
+ }
1011
+ }
1012
+ }
1013
+ const activePendingContexts = pendingContexts ?? [];
1014
+ const nextPayload = buildSubmitPayload(text, updatedAttachments, activePendingContexts, onBeforeSend);
1015
+ if (isMessageContentEmpty(nextPayload)) {
1016
+ return;
1017
+ }
1018
+ if (activeSessionId && activePendingContexts.length > 0) {
1019
+ consumePendingContexts(activeSessionId);
1020
+ }
1021
+ onSend(nextPayload, uploadTargetSessionId, selectedModel || null);
1022
+ if (text.trim()) {
1023
+ inputHistory.addEntry(text);
1024
+ }
1025
+ resetComposer();
1026
+ }
1027
+ finally {
1028
+ submittingRef.current = false;
1029
+ }
1030
+ };
1031
+ const removeAttachment = (id) => {
1032
+ setComposerAttachments((prev) => prev.filter((attachment) => attachment.id !== id));
1033
+ };
1034
+ const [showAddContext, setShowAddContext] = useState(false);
1035
+ const isPlanning = mode === "planning";
1036
+ const placeholder = isPlanning ? "规划进行中… 可输入补充需求或等待完成" : "输入消息…";
1037
+ const attachments = renderAttachments?.() ?? null;
1038
+ const hasRenderedAttachments = attachments !== null;
1039
+ const hasPendingContexts = (pendingContexts?.length ?? 0) > 0;
1040
+ const currentSession = useSessionStore((state) => activeSessionId ? state.sessions.find((s) => s.id === activeSessionId) : undefined);
1041
+ const isSkillEditor = currentSession?.solution_id === "skill_editor" ||
1042
+ currentSession?.template_id === "skill_editor";
1043
+ const imageAttachments = composerAttachments.filter(isImageAttachment);
1044
+ const fileAttachments = composerAttachments.filter((attachment) => !isImageAttachment(attachment));
1045
+ const hasUploadingFiles = composerAttachments.some((attachment) => attachment.status === "uploading");
1046
+ const hasValidAttachments = composerAttachments.some((attachment) => attachment.status !== "failed");
1047
+ const isSendDisabled = connectionStatus !== "connected" ||
1048
+ hasUploadingFiles ||
1049
+ (!input.trim() && !hasValidAttachments && !hasRenderedAttachments && !hasPendingContexts);
1050
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "bg-[hsl(var(--background))] px-5 py-3", children: _jsx("div", { className: `mx-auto ${maxWidthClassName}`, children: _jsx("div", { className: "relative", onDragOver: (event) => {
1051
+ event.preventDefault();
1052
+ setDragging(true);
1053
+ }, onDragLeave: () => setDragging(false), onDrop: (event) => {
1054
+ event.preventDefault();
1055
+ setDragging(false);
1056
+ void stableAppendFiles(event.dataTransfer.files);
1057
+ }, children: _jsxs("div", { className: `overflow-visible rounded-2xl border bg-[hsl(var(--card))] transition-[box-shadow,border-color] duration-300 ${isRecording
1058
+ ? "border-emerald-400/70! shadow-[0_0_0_3px_rgba(52,211,153,0.18),0_0_24px_rgba(52,211,153,0.28)]"
1059
+ : dragging
1060
+ ? isPlanning
1061
+ ? "border-amber-400/60"
1062
+ : "border-[hsl(var(--primary)/0.6)]"
1063
+ : isEditorFocused
1064
+ ? isPlanning
1065
+ ? "border-amber-400/60"
1066
+ : "border-[hsl(var(--primary)/0.6)]"
1067
+ : isPlanning
1068
+ ? "border-amber-400/30"
1069
+ : "border-[hsl(var(--border))]"}`, children: [composerAttachments.length > 0 && (_jsxs("div", { className: "flex max-h-40 flex-col gap-2 overflow-y-auto border-b border-[hsl(var(--border))] px-3 py-2", children: [imageAttachments.length > 0 && (_jsx("div", { className: "grid grid-cols-3 gap-2", children: imageAttachments.map((attachment) => (_jsxs("div", { className: "relative overflow-hidden rounded-xl border border-[hsl(var(--border))]", children: [_jsx("img", { src: getImagePreviewUrl(attachment, activeSessionId, localImageUrls), alt: attachment.name || "图片预览", className: "h-24 w-full object-cover" }), _jsx("button", { type: "button", onClick: () => removeAttachment(attachment.id), "aria-label": `移除 ${attachment.name || "图片"}`, className: "absolute right-1.5 top-1.5 flex h-6 w-6 items-center justify-center rounded-full bg-[hsl(var(--background)/0.85)] text-[hsl(var(--foreground))]", children: _jsx(X, { size: 12 }) })] }, attachment.id))) })), fileAttachments.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-1.5", children: fileAttachments.map((attachment) => (_jsx(ComposerFilePill, { attachment: attachment, onRemove: removeAttachment }, attachment.id))) }))] })), (hasPendingContexts || isSkillEditor) ? (_jsxs("div", { className: "flex flex-wrap items-center gap-1.5 border-b border-[hsl(var(--border))] px-3 py-2", children: [pendingContexts?.map((context) => (_jsx(ComposerContextPill, { id: context.id, label: context.label, content: context.content, onRemove: (contextId) => {
1070
+ if (!activeSessionId) {
1071
+ return;
1072
+ }
1073
+ removePendingContext(activeSessionId, contextId);
1074
+ } }, context.id))), isSkillEditor && (_jsx("button", { type: "button", onClick: () => setShowAddContext(true), title: "\u6DFB\u52A0\u4E0A\u4E0B\u6587", className: "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full border border-dashed border-[hsl(var(--border))] text-[hsl(var(--muted-foreground))] transition-colors hover:border-[hsl(var(--ring))] hover:text-[hsl(var(--foreground))]", children: _jsx(Plus, { size: 12 }) }))] })) : null, showAddContext && activeSessionId && (_jsx(AddContextDialog, { sessionId: activeSessionId, onClose: () => setShowAddContext(false), onAdd: (label, content) => {
1075
+ if (activeSessionId) {
1076
+ useUiBridgeStore.getState().addPendingContext(activeSessionId, { label, content });
1077
+ }
1078
+ } })), attachments ? (_jsx("div", { className: "border-b border-[hsl(var(--border))] px-3 py-3", children: attachments })) : null, slotAboveTextarea ? (_jsx("div", { className: "border-b border-[hsl(var(--border))] px-3 py-2", children: slotAboveTextarea })) : null, _jsxs("div", { className: "relative", children: [input.length === 0 && (_jsx("div", { className: "pointer-events-none absolute left-4 top-3 text-sm leading-relaxed text-[hsl(var(--muted-foreground))]", children: placeholder })), _jsx(EditorContent, { editor: editor })] }), _jsxs("div", { className: "flex items-center justify-between border-t border-[hsl(var(--border))] px-3 py-1.5", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { ref: fileInputRef, type: "file", accept: "*/*", multiple: true, onChange: (event) => {
1079
+ if (event.target.files) {
1080
+ void appendFiles(event.target.files);
1081
+ event.target.value = "";
1082
+ }
1083
+ }, className: "hidden" }), _jsx("input", { ref: folderInputRef, type: "file", multiple: true, onChange: (event) => {
1084
+ if (event.target.files) {
1085
+ void appendFiles(event.target.files);
1086
+ event.target.value = "";
1087
+ }
1088
+ }, className: "hidden", ...{ webkitdirectory: "" } }), _jsxs("details", { ref: actionMenuRef, className: "group relative", children: [_jsx("summary", { "aria-label": "\u6DFB\u52A0\u5185\u5BB9", title: "\u6DFB\u52A0\u5185\u5BB9", className: "flex h-7 w-7 shrink-0 cursor-pointer list-none items-center justify-center rounded-lg border border-[hsl(var(--border))] text-[hsl(var(--muted-foreground))] transition-colors hover:border-[hsl(var(--ring))] hover:text-[hsl(var(--foreground))] [&::-webkit-details-marker]:hidden", children: _jsx(Plus, { size: 14 }) }), _jsxs("div", { className: "absolute bottom-full left-0 z-30 mb-2 min-w-36 overflow-visible rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--popover))] py-1 text-[11px] text-[hsl(var(--popover-foreground))] shadow-lg", children: [_jsxs("button", { type: "button", onClick: () => {
1089
+ actionMenuRef.current?.removeAttribute("open");
1090
+ fileInputRef.current?.click();
1091
+ }, className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]", children: [_jsx(Paperclip, { size: 13 }), "\u4E0A\u4F20\u6587\u4EF6"] }), _jsxs("button", { type: "button", onClick: () => {
1092
+ actionMenuRef.current?.removeAttribute("open");
1093
+ folderInputRef.current?.click();
1094
+ }, className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]", children: [_jsx(FolderUp, { size: 13 }), "\u4E0A\u4F20\u6587\u4EF6\u5939"] }), onCommand ? (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: () => {
1095
+ actionMenuRef.current?.removeAttribute("open");
1096
+ void onCommand("compact");
1097
+ }, disabled: isStreaming, className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))] disabled:cursor-not-allowed disabled:opacity-50", children: [isStreaming ? _jsx(Loader2, { size: 13, className: "animate-spin" }) : _jsx(Scissors, { size: 13 }), "\u6574\u7406\u5BF9\u8BDD"] }), _jsxs("button", { type: "button", onClick: () => {
1098
+ actionMenuRef.current?.removeAttribute("open");
1099
+ void onCommand("download_session");
1100
+ }, className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]", children: [_jsx(Download, { size: 13 }), "\u5BFC\u51FA\u4F1A\u8BDD"] }), canShareSession ? (_jsxs("button", { type: "button", onClick: () => {
1101
+ actionMenuRef.current?.removeAttribute("open");
1102
+ void onCommand("share_session");
1103
+ }, className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]", children: [_jsx(Share2, { size: 13 }), "\u5206\u4EAB\u4F1A\u8BDD"] })) : null, _jsxs("button", { type: "button", onClick: () => {
1104
+ actionMenuRef.current?.removeAttribute("open");
1105
+ void onCommand("extract_skill");
1106
+ }, className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]", children: [_jsx(FlaskConical, { size: 13 }), "\u63D0\u53D6\u6280\u80FD"] }), _jsxs("button", { type: "button", onClick: () => {
1107
+ actionMenuRef.current?.removeAttribute("open");
1108
+ void onCommand("generate_app");
1109
+ }, className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]", children: [_jsx(Rocket, { size: 13 }), "\u751F\u6210\u5E94\u7528"] })] })) : null, _jsxs("div", { className: "flex items-center gap-2 px-3 py-2", children: [_jsx(Sparkles, { size: 13 }), _jsx("span", { className: "shrink-0", children: "\u6A21\u578B" }), _jsx(ModelSelector, { value: selectedModel, onValueChange: (model) => {
1110
+ setSelectedModel(model);
1111
+ if (activeSessionId) {
1112
+ patchSession(activeSessionId, { model });
1113
+ }
1114
+ void setPreferredModel(model);
1115
+ }, compact: true, placement: "top" })] })] })] }), _jsx("button", { type: "button", onClick: onToggleMode, disabled: isStreaming || !onToggleMode, "aria-pressed": isPlanning, "aria-label": isPlanning ? "关闭规划模式" : "开启规划模式", title: isPlanning ? "规划模式已开启" : "开启规划模式", className: `flex h-7 w-7 shrink-0 items-center justify-center rounded-lg border transition-colors ${isPlanning
1116
+ ? "border-amber-500/45 bg-amber-500/15 text-amber-400"
1117
+ : "border-[hsl(var(--border))] text-[hsl(var(--muted-foreground))] hover:border-amber-500/35 hover:text-[hsl(var(--foreground))]"} disabled:cursor-not-allowed disabled:opacity-50`, children: _jsx(Lightbulb, { size: 13 }) })] }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs("div", { className: "group/help relative", children: [_jsx("button", { type: "button", "aria-label": "\u67E5\u770B\u8F93\u5165\u63D0\u793A", className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-lg text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]", children: _jsx(CircleHelp, { size: 13 }) }), _jsx("div", { className: "pointer-events-auto absolute bottom-full right-0 z-30 hidden pb-2 group-hover/help:block group-focus-within/help:block", children: _jsxs("div", { className: "min-w-64 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--popover))] p-3 text-left text-[11px] leading-5 text-[hsl(var(--popover-foreground))] shadow-lg", children: [activeSessionId ? (_jsx("div", { className: "mb-2 border-b border-[hsl(var(--border))] pb-2", children: _jsx(SkillStatusBar, { sessionId: activeSessionId, onResync: onResyncSkills, isResyncing: isResyncingSkills, vertical: true }) })) : null, _jsxs("div", { className: "space-y-0.5", children: [_jsx("div", { children: "Shift+Enter \u6362\u884C" }), _jsx("div", { children: "/ \u8C03\u7528\u6280\u80FD" }), _jsx("div", { children: "@ \u5F15\u7528\u6587\u4EF6" })] })] }) })] }), _jsx("button", { type: "button", onClick: asrEnabled ? voice.toggle : handleMicDisabledClick, disabled: isStreaming, "aria-label": !asrEnabled ? "语音输入未开启" : isRecording ? "停止语音输入" : "开始语音输入", title: !asrEnabled ? "语音输入未开启" : isRecording ? "停止语音输入" : "语音输入", className: `flex items-center justify-center rounded-lg border transition-[width,height,border-color,background-color,color,box-shadow] duration-300 disabled:opacity-40 ${!asrEnabled
1118
+ ? "h-7 w-7 border-[hsl(var(--border))] text-[hsl(var(--muted-foreground))]/50 hover:text-[hsl(var(--muted-foreground))]"
1119
+ : isRecording
1120
+ ? "h-9 w-9 border-emerald-400/80! bg-emerald-400/15 text-emerald-400 shadow-[0_0_0_2px_rgba(52,211,153,0.2),0_0_12px_rgba(52,211,153,0.35)]"
1121
+ : "h-7 w-7 border-[hsl(var(--border))] text-[hsl(var(--muted-foreground))] hover:border-[hsl(var(--ring))] hover:text-[hsl(var(--foreground))]"}`, children: !asrEnabled ? (_jsx(MicOff, { size: 13 })) : isRecording ? (_jsx(VoiceWaveform, { level: voiceLevel, size: 18 })) : (_jsx(Mic, { size: 13 })) }), isStreaming ? (_jsx("button", { type: "button", onClick: onStop, "aria-label": "\u505C\u6B62\u751F\u6210", className: "flex h-7 w-7 items-center justify-center rounded-lg bg-[hsl(var(--destructive))] text-[hsl(var(--destructive-foreground))] transition-opacity hover:opacity-80", children: _jsx(Square, { size: 13 }) })) : (_jsx("button", { type: "button", onClick: handleSubmit, disabled: isSendDisabled || isRecording, "aria-label": "\u53D1\u9001\u6D88\u606F", className: "flex h-7 w-7 items-center justify-center rounded-lg bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] transition-opacity hover:opacity-80 disabled:opacity-25", children: _jsx(Send, { size: 13 }) }))] })] })] }) }) }) }), _jsx(FileSizeLimitDialog, { open: oversizedFiles.length > 0, onOpenChange: (open) => {
1122
+ if (!open) {
1123
+ setOversizedFiles([]);
1124
+ }
1125
+ }, files: oversizedFiles, limitBytes: ATTACHMENT_SIZE_LIMIT_BYTES })] }));
1126
+ }
1127
+ //# sourceMappingURL=ChatInput.js.map