agentstudio 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (371) hide show
  1. package/bin/agentstudio.js +44 -4
  2. package/bin/agentstudio.js.map +1 -1
  3. package/bin/serviceManager.d.ts.map +1 -1
  4. package/bin/serviceManager.js +312 -28
  5. package/bin/serviceManager.js.map +1 -1
  6. package/config/engineConfig.d.ts +96 -0
  7. package/config/engineConfig.d.ts.map +1 -0
  8. package/config/engineConfig.js +429 -0
  9. package/config/engineConfig.js.map +1 -0
  10. package/engines/claude/__tests__/supportedModels.test.d.ts +10 -0
  11. package/engines/claude/__tests__/supportedModels.test.d.ts.map +1 -0
  12. package/engines/claude/__tests__/supportedModels.test.js +89 -0
  13. package/engines/claude/__tests__/supportedModels.test.js.map +1 -0
  14. package/engines/claude/aguiAdapter.d.ts +101 -0
  15. package/engines/claude/aguiAdapter.d.ts.map +1 -0
  16. package/engines/claude/aguiAdapter.js +382 -0
  17. package/engines/claude/aguiAdapter.js.map +1 -0
  18. package/engines/claude/claudeEngine.d.ts +42 -0
  19. package/engines/claude/claudeEngine.d.ts.map +1 -0
  20. package/engines/claude/claudeEngine.js +325 -0
  21. package/engines/claude/claudeEngine.js.map +1 -0
  22. package/engines/claude/index.d.ts +8 -0
  23. package/engines/claude/index.d.ts.map +1 -0
  24. package/engines/claude/index.js +14 -0
  25. package/engines/claude/index.js.map +1 -0
  26. package/engines/cursor/__tests__/a2aAdapter.test.d.ts +6 -0
  27. package/engines/cursor/__tests__/a2aAdapter.test.d.ts.map +1 -0
  28. package/engines/cursor/__tests__/a2aAdapter.test.js +376 -0
  29. package/engines/cursor/__tests__/a2aAdapter.test.js.map +1 -0
  30. package/engines/cursor/a2aAdapter.d.ts +180 -0
  31. package/engines/cursor/a2aAdapter.d.ts.map +1 -0
  32. package/engines/cursor/a2aAdapter.js +405 -0
  33. package/engines/cursor/a2aAdapter.js.map +1 -0
  34. package/engines/cursor/aguiAdapter.d.ts +97 -0
  35. package/engines/cursor/aguiAdapter.d.ts.map +1 -0
  36. package/engines/cursor/aguiAdapter.js +507 -0
  37. package/engines/cursor/aguiAdapter.js.map +1 -0
  38. package/engines/cursor/cursorEngine.d.ts +68 -0
  39. package/engines/cursor/cursorEngine.d.ts.map +1 -0
  40. package/engines/cursor/cursorEngine.js +465 -0
  41. package/engines/cursor/cursorEngine.js.map +1 -0
  42. package/engines/cursor/index.d.ts +11 -0
  43. package/engines/cursor/index.d.ts.map +1 -0
  44. package/engines/cursor/index.js +21 -0
  45. package/engines/cursor/index.js.map +1 -0
  46. package/engines/engineManager.d.ts +80 -0
  47. package/engines/engineManager.d.ts.map +1 -0
  48. package/engines/engineManager.js +137 -0
  49. package/engines/engineManager.js.map +1 -0
  50. package/engines/index.d.ts +26 -0
  51. package/engines/index.d.ts.map +1 -0
  52. package/engines/index.js +81 -0
  53. package/engines/index.js.map +1 -0
  54. package/engines/types.d.ts +319 -0
  55. package/engines/types.d.ts.map +1 -0
  56. package/engines/types.js +69 -0
  57. package/engines/types.js.map +1 -0
  58. package/index.d.ts.map +1 -1
  59. package/index.js +178 -25
  60. package/index.js.map +1 -1
  61. package/middleware/auth.d.ts.map +1 -1
  62. package/middleware/auth.js +4 -0
  63. package/middleware/auth.js.map +1 -1
  64. package/package.json +7 -1
  65. package/public/assets/AgentsPage-D462iGRy.js +10 -0
  66. package/public/assets/{Button-BoiVlafj.js → Button-B_6lGF64.js} +1 -1
  67. package/public/assets/ChatPage-NjuRQPaL.js +478 -0
  68. package/public/assets/{CommandForm-Se4iemMp.js → CommandForm-DwGvE9A_.js} +1 -1
  69. package/public/assets/CommandsPage-DeUS8fhJ.js +1 -0
  70. package/public/assets/CursorConfigPage-Bl1Blrbr.js +1 -0
  71. package/public/assets/{DashboardPage-DbCVzPKz.js → DashboardPage-DH-2iuqf.js} +1 -1
  72. package/public/assets/EngineGate-DxTYx9wb.js +1 -0
  73. package/public/assets/{FileBrowser-DcoBWzKK.js → FileBrowser-CeGsJnUL.js} +5 -5
  74. package/public/assets/{FileExplorer-B41BB0LM.js → FileExplorer-x5R0Tcmk.js} +1 -1
  75. package/public/assets/GeneralSettingsPage-lhNEJQD_.js +1 -0
  76. package/public/assets/HooksPage-9fingjdz.js +1 -0
  77. package/public/assets/LandingPage-BAzi8PDo.js +1 -0
  78. package/public/assets/LoginPage-kQ_NWy8p.js +16 -0
  79. package/public/assets/McpAdminSettingsPage-DQHpWHRC.js +7 -0
  80. package/public/assets/McpPage-DLHfmhSJ.js +20 -0
  81. package/public/assets/{MemorySettingsPage-DYSuz-hU.js → MemorySettingsPage-CRIPja9X.js} +1 -1
  82. package/public/assets/ModelsPage-Bb5vSsuc.js +1 -0
  83. package/public/assets/PluginsPage-BhKM7gV7.js +12 -0
  84. package/public/assets/ProjectSelector-Cbct6pnn.js +1 -0
  85. package/public/assets/ProjectsPage-lQo7-7dt.js +21 -0
  86. package/public/assets/RulesPage-BRnB7__3.js +1 -0
  87. package/public/assets/ScheduledTasksPage-CZiABTSb.js +1 -0
  88. package/public/assets/SettingsLayout-BfG7ftoT.js +1 -0
  89. package/public/assets/SkillsPage-CL6MKxQ9.js +18 -0
  90. package/public/assets/{SubagentForm-C0R084ja.js → SubagentForm-BzzeWg0W.js} +2 -2
  91. package/public/assets/{SubagentsPage-BKFNmqxg.js → SubagentsPage-DhFP2kDE.js} +1 -1
  92. package/public/assets/SystemInfoPage-CFHUN3j8.js +1 -0
  93. package/public/assets/{TelemetrySettingsPage-Ck2btMol.js → TelemetrySettingsPage-BcZFVBXN.js} +1 -1
  94. package/public/assets/{ToastTestPage-B79DFhqI.js → ToastTestPage-BtGnZdyk.js} +1 -1
  95. package/public/assets/{ToolsList-Kfxwp80g.js → ToolsList-CTsQr53G.js} +1 -1
  96. package/public/assets/{UnifiedToolSelector-CkafUbz3.js → UnifiedToolSelector-BP6fuyzG.js} +1 -1
  97. package/public/assets/VersionSettingsPage-DjOjyL3X.js +5 -0
  98. package/public/assets/VoiceSettingsPage-d3l9AWBn.js +1 -0
  99. package/public/assets/WebSocketTunnelPage-CfHtJR9r.js +1 -0
  100. package/public/assets/_basePickBy-Bac3af5O.js +1 -0
  101. package/public/assets/{_baseUniq-COj5YnAO.js → _baseUniq-Dvh9sZ-T.js} +1 -1
  102. package/public/assets/{agents-3mB536QF.js → agents-KlPdWQ8K.js} +1 -1
  103. package/public/assets/arc-CRR5EPpK.js +1 -0
  104. package/public/assets/{architectureDiagram-VXUJARFQ-DD1BwT1T.js → architectureDiagram-VXUJARFQ-Ct1p8kmV.js} +1 -1
  105. package/public/assets/{blockDiagram-VD42YOAC-DFKUIZc6.js → blockDiagram-VD42YOAC-CX_8YiYn.js} +1 -1
  106. package/public/assets/{c4Diagram-YG6GDRKO-B0VVIIvh.js → c4Diagram-YG6GDRKO-BIBVWIY4.js} +1 -1
  107. package/public/assets/channel-CPs-2Y_m.js +1 -0
  108. package/public/assets/{chunk-4BX2VUAB-DM8J7YO9.js → chunk-4BX2VUAB-CQNNXsb5.js} +1 -1
  109. package/public/assets/{chunk-55IACEB6-BjhdmGlM.js → chunk-55IACEB6-N_ZrGhOu.js} +1 -1
  110. package/public/assets/{chunk-B4BG7PRW-1RJ6n2xv.js → chunk-B4BG7PRW-CI6DkhbM.js} +1 -1
  111. package/public/assets/{chunk-DI55MBZ5-1-EHSO67.js → chunk-DI55MBZ5-Dgj-Eo9U.js} +1 -1
  112. package/public/assets/{chunk-FMBD7UC4-DV3SMJK_.js → chunk-FMBD7UC4-o4B0HzSK.js} +1 -1
  113. package/public/assets/{chunk-QN33PNHL-IlsCTdDq.js → chunk-QN33PNHL-DXlfdPIk.js} +1 -1
  114. package/public/assets/{chunk-QZHKN3VN-DJXs-Fqo.js → chunk-QZHKN3VN-ZCBUGD7e.js} +1 -1
  115. package/public/assets/{chunk-TZMSLE5B-BxHO9wa1.js → chunk-TZMSLE5B-N3lZ106d.js} +1 -1
  116. package/public/assets/classDiagram-2ON5EDUG-DCwNRxvC.js +1 -0
  117. package/public/assets/classDiagram-v2-WZHVMYZB-DCwNRxvC.js +1 -0
  118. package/public/assets/clone-C3DcKvhB.js +1 -0
  119. package/public/assets/{cose-bilkent-S5V4N54A-BVJXoW_K.js → cose-bilkent-S5V4N54A-Crc39J9q.js} +1 -1
  120. package/public/assets/{dagre-6UL2VRFP-DHDnVshA.js → dagre-6UL2VRFP-nC3WLCf7.js} +1 -1
  121. package/public/assets/{diagram-PSM6KHXK-40qGxDeg.js → diagram-PSM6KHXK-B5DQIDQ3.js} +1 -1
  122. package/public/assets/diagram-QEK2KX5R-BccDOQuz.js +43 -0
  123. package/public/assets/{diagram-S2PKOQOG-D7AX72a5.js → diagram-S2PKOQOG-D-Cv16WE.js} +1 -1
  124. package/public/assets/{erDiagram-Q2GNP2WA-BHsgeBpL.js → erDiagram-Q2GNP2WA-Dr0ZgvnS.js} +1 -1
  125. package/public/assets/{flowDiagram-NV44I4VS-BYqChOSE.js → flowDiagram-NV44I4VS-DGbbfVi5.js} +1 -1
  126. package/public/assets/{ganttDiagram-LVOFAZNH-CZFFSLKX.js → ganttDiagram-LVOFAZNH-C-3Wnf96.js} +1 -1
  127. package/public/assets/{gitGraphDiagram-NY62KEGX-C5Bgrf0J.js → gitGraphDiagram-NY62KEGX--Q8whT5z.js} +1 -1
  128. package/public/assets/{graph-BP5lFRBg.js → graph-CO1DMS2E.js} +1 -1
  129. package/public/assets/{index-BEPv9Bqe.js → index-B5hSSnK3.js} +58 -58
  130. package/public/assets/index-gbHlIp96.css +1 -0
  131. package/public/assets/infoDiagram-F6ZHWCRC-DSR9cM2B.js +2 -0
  132. package/public/assets/{journeyDiagram-XKPGCS4Q--abC1RHz.js → journeyDiagram-XKPGCS4Q-Cc00zHNt.js} +1 -1
  133. package/public/assets/{kanban-definition-3W4ZIXB7-BJeChfWu.js → kanban-definition-3W4ZIXB7-BF_gHshF.js} +6 -6
  134. package/public/assets/{layout-DjAix4WK.js → layout-BxoLV88o.js} +1 -1
  135. package/public/assets/{linear-Cw0z8VNY.js → linear-Y8e2e012.js} +1 -1
  136. package/public/assets/{mindmap-definition-VGOIOE7T-U_T9xIUk.js → mindmap-definition-VGOIOE7T-CzpuQA4p.js} +1 -1
  137. package/public/assets/{pieDiagram-ADFJNKIX-B0mT9OgH.js → pieDiagram-ADFJNKIX-B22MhIcy.js} +2 -2
  138. package/public/assets/{quadrantDiagram-AYHSOK5B-BWdlgO0u.js → quadrantDiagram-AYHSOK5B-CTT9bIA8.js} +1 -1
  139. package/public/assets/{requirementDiagram-UZGBJVZJ-B-8LxsGB.js → requirementDiagram-UZGBJVZJ-B_vjXDH9.js} +1 -1
  140. package/public/assets/{sankeyDiagram-TZEHDZUN-OXuxkgGA.js → sankeyDiagram-TZEHDZUN-CKfZ4633.js} +1 -1
  141. package/public/assets/{sequenceDiagram-WL72ISMW-Bt5twlzi.js → sequenceDiagram-WL72ISMW-BmTPN6j6.js} +1 -1
  142. package/public/assets/{stateDiagram-FKZM4ZOC-Dmph7TeW.js → stateDiagram-FKZM4ZOC-y2fQE1C7.js} +1 -1
  143. package/public/assets/stateDiagram-v2-4FDKWEC3-C4CM6z52.js +1 -0
  144. package/public/assets/{table-DjMdAdjH.js → table-BJUz-ck5.js} +1 -1
  145. package/public/assets/{timeline-definition-IT6M3QCI-CcV8nyIH.js → timeline-definition-IT6M3QCI-DsXlR68n.js} +1 -1
  146. package/public/assets/{tools-BAI9XHGS.js → tools-BZTR2NP1.js} +1 -1
  147. package/public/assets/{treemap-KMMF4GRG-DBuwkj4f.js → treemap-KMMF4GRG-Cecs9uxX.js} +1 -1
  148. package/public/assets/{ui-components-DaGtjl0g.js → ui-components-DjgDPiqV.js} +153 -128
  149. package/public/assets/useAgents-8KXN6U61.js +2 -0
  150. package/public/assets/{useClaudeVersions-Cy71v4HE.js → useClaudeVersions-DicHLV6A.js} +1 -1
  151. package/public/assets/useCommands-DbSH48ba.js +1 -0
  152. package/public/assets/{useProjects-XgfgISgV.js → useProjects-Bbh6hJMM.js} +1 -1
  153. package/public/assets/{useSessions-CQgq4d84.js → useSessions-DOa4-xiB.js} +1 -1
  154. package/public/assets/{xychartDiagram-PRI3JC2R-Bo9K-U2S.js → xychartDiagram-PRI3JC2R-C2IWhyM7.js} +1 -1
  155. package/public/index.html +5 -5
  156. package/routes/a2a.d.ts +7 -0
  157. package/routes/a2a.d.ts.map +1 -1
  158. package/routes/a2a.js +193 -21
  159. package/routes/a2a.js.map +1 -1
  160. package/routes/agents.d.ts.map +1 -1
  161. package/routes/agents.js +45 -2
  162. package/routes/agents.js.map +1 -1
  163. package/routes/agui.d.ts +16 -0
  164. package/routes/agui.d.ts.map +1 -0
  165. package/routes/agui.js +520 -0
  166. package/routes/agui.js.map +1 -0
  167. package/routes/commands.d.ts.map +1 -1
  168. package/routes/commands.js +35 -3
  169. package/routes/commands.js.map +1 -1
  170. package/routes/cursorA2a.d.ts +18 -0
  171. package/routes/cursorA2a.d.ts.map +1 -0
  172. package/routes/cursorA2a.js +393 -0
  173. package/routes/cursorA2a.js.map +1 -0
  174. package/routes/engine.d.ts +12 -0
  175. package/routes/engine.d.ts.map +1 -0
  176. package/routes/engine.js +178 -0
  177. package/routes/engine.js.map +1 -0
  178. package/routes/gitVersions.d.ts +10 -0
  179. package/routes/gitVersions.d.ts.map +1 -0
  180. package/routes/gitVersions.js +147 -0
  181. package/routes/gitVersions.js.map +1 -0
  182. package/routes/hooks.d.ts +11 -0
  183. package/routes/hooks.d.ts.map +1 -0
  184. package/routes/hooks.js +303 -0
  185. package/routes/hooks.js.map +1 -0
  186. package/routes/mcp.d.ts.map +1 -1
  187. package/routes/mcp.js +28 -3
  188. package/routes/mcp.js.map +1 -1
  189. package/routes/plugins.d.ts.map +1 -1
  190. package/routes/plugins.js +317 -4
  191. package/routes/plugins.js.map +1 -1
  192. package/routes/rules.d.ts +9 -0
  193. package/routes/rules.d.ts.map +1 -0
  194. package/routes/rules.js +470 -0
  195. package/routes/rules.js.map +1 -0
  196. package/routes/sessions.d.ts.map +1 -1
  197. package/routes/sessions.js +68 -32
  198. package/routes/sessions.js.map +1 -1
  199. package/routes/speechToText.d.ts +8 -0
  200. package/routes/speechToText.d.ts.map +1 -0
  201. package/routes/speechToText.js +216 -0
  202. package/routes/speechToText.js.map +1 -0
  203. package/schemas/a2a.d.ts +2 -2
  204. package/services/__tests__/agentImporter.test.d.ts +5 -0
  205. package/services/__tests__/agentImporter.test.d.ts.map +1 -0
  206. package/services/__tests__/agentImporter.test.js +379 -0
  207. package/services/__tests__/agentImporter.test.js.map +1 -0
  208. package/services/__tests__/marketplaceUpdateService.test.d.ts +5 -0
  209. package/services/__tests__/marketplaceUpdateService.test.d.ts.map +1 -0
  210. package/services/__tests__/marketplaceUpdateService.test.js +227 -0
  211. package/services/__tests__/marketplaceUpdateService.test.js.map +1 -0
  212. package/services/__tests__/pluginInstaller.test.js +172 -0
  213. package/services/__tests__/pluginInstaller.test.js.map +1 -1
  214. package/services/__tests__/projectMetadataStorage.test.js +19 -4
  215. package/services/__tests__/projectMetadataStorage.test.js.map +1 -1
  216. package/services/a2a/__tests__/agentCardService.test.js +224 -0
  217. package/services/a2a/__tests__/agentCardService.test.js.map +1 -1
  218. package/services/a2a/__tests__/cursorA2aService.test.d.ts +6 -0
  219. package/services/a2a/__tests__/cursorA2aService.test.d.ts.map +1 -0
  220. package/services/a2a/__tests__/cursorA2aService.test.js +359 -0
  221. package/services/a2a/__tests__/cursorA2aService.test.js.map +1 -0
  222. package/services/a2a/agentCardService.d.ts +22 -0
  223. package/services/a2a/agentCardService.d.ts.map +1 -1
  224. package/services/a2a/agentCardService.js +246 -0
  225. package/services/a2a/agentCardService.js.map +1 -1
  226. package/services/a2a/cursorA2aService.d.ts +126 -0
  227. package/services/a2a/cursorA2aService.d.ts.map +1 -0
  228. package/services/a2a/cursorA2aService.js +336 -0
  229. package/services/a2a/cursorA2aService.js.map +1 -0
  230. package/services/agentImporter.d.ts +62 -0
  231. package/services/agentImporter.d.ts.map +1 -0
  232. package/services/agentImporter.js +335 -0
  233. package/services/agentImporter.js.map +1 -0
  234. package/services/cursorConfigService.d.ts +75 -0
  235. package/services/cursorConfigService.d.ts.map +1 -0
  236. package/services/cursorConfigService.js +538 -0
  237. package/services/cursorConfigService.js.map +1 -0
  238. package/services/gitVersionService.d.ts +52 -0
  239. package/services/gitVersionService.d.ts.map +1 -0
  240. package/services/gitVersionService.js +377 -0
  241. package/services/gitVersionService.js.map +1 -0
  242. package/services/marketplaceUpdateService.d.ts +66 -0
  243. package/services/marketplaceUpdateService.d.ts.map +1 -0
  244. package/services/marketplaceUpdateService.js +364 -0
  245. package/services/marketplaceUpdateService.js.map +1 -0
  246. package/services/mcpAdmin/__tests__/scheduledTaskTools.test.d.ts +5 -0
  247. package/services/mcpAdmin/__tests__/scheduledTaskTools.test.d.ts.map +1 -0
  248. package/services/mcpAdmin/__tests__/scheduledTaskTools.test.js +429 -0
  249. package/services/mcpAdmin/__tests__/scheduledTaskTools.test.js.map +1 -0
  250. package/services/mcpAdmin/tools/index.d.ts +1 -0
  251. package/services/mcpAdmin/tools/index.d.ts.map +1 -1
  252. package/services/mcpAdmin/tools/index.js +5 -1
  253. package/services/mcpAdmin/tools/index.js.map +1 -1
  254. package/services/mcpAdmin/tools/scheduledTaskTools.d.ts +64 -0
  255. package/services/mcpAdmin/tools/scheduledTaskTools.d.ts.map +1 -0
  256. package/services/mcpAdmin/tools/scheduledTaskTools.js +1002 -0
  257. package/services/mcpAdmin/tools/scheduledTaskTools.js.map +1 -0
  258. package/services/mcpAdmin/types.d.ts +1 -1
  259. package/services/mcpAdmin/types.d.ts.map +1 -1
  260. package/services/pluginInstaller.d.ts +55 -1
  261. package/services/pluginInstaller.d.ts.map +1 -1
  262. package/services/pluginInstaller.js +437 -13
  263. package/services/pluginInstaller.js.map +1 -1
  264. package/services/projectMetadataStorage.d.ts.map +1 -1
  265. package/services/projectMetadataStorage.js +4 -2
  266. package/services/projectMetadataStorage.js.map +1 -1
  267. package/services/sessionEventBus.d.ts +67 -0
  268. package/services/sessionEventBus.d.ts.map +1 -0
  269. package/services/sessionEventBus.js +106 -0
  270. package/services/sessionEventBus.js.map +1 -0
  271. package/services/sessionManager.d.ts.map +1 -1
  272. package/services/sessionManager.js +4 -2
  273. package/services/sessionManager.js.map +1 -1
  274. package/services/speechToText/__tests__/speechToText.test.d.ts +5 -0
  275. package/services/speechToText/__tests__/speechToText.test.d.ts.map +1 -0
  276. package/services/speechToText/__tests__/speechToText.test.js +208 -0
  277. package/services/speechToText/__tests__/speechToText.test.js.map +1 -0
  278. package/services/speechToText/index.d.ts +25 -0
  279. package/services/speechToText/index.d.ts.map +1 -0
  280. package/services/speechToText/index.js +228 -0
  281. package/services/speechToText/index.js.map +1 -0
  282. package/services/speechToText/providers/aliyun.d.ts +22 -0
  283. package/services/speechToText/providers/aliyun.d.ts.map +1 -0
  284. package/services/speechToText/providers/aliyun.js +185 -0
  285. package/services/speechToText/providers/aliyun.js.map +1 -0
  286. package/services/speechToText/providers/google.d.ts +24 -0
  287. package/services/speechToText/providers/google.d.ts.map +1 -0
  288. package/services/speechToText/providers/google.js +205 -0
  289. package/services/speechToText/providers/google.js.map +1 -0
  290. package/services/speechToText/providers/openaiCompatible.d.ts +22 -0
  291. package/services/speechToText/providers/openaiCompatible.d.ts.map +1 -0
  292. package/services/speechToText/providers/openaiCompatible.js +198 -0
  293. package/services/speechToText/providers/openaiCompatible.js.map +1 -0
  294. package/services/speechToText/providers/tencent.d.ts +23 -0
  295. package/services/speechToText/providers/tencent.d.ts.map +1 -0
  296. package/services/speechToText/providers/tencent.js +215 -0
  297. package/services/speechToText/providers/tencent.js.map +1 -0
  298. package/services/speechToText/types.d.ts +102 -0
  299. package/services/speechToText/types.d.ts.map +1 -0
  300. package/services/speechToText/types.js +43 -0
  301. package/services/speechToText/types.js.map +1 -0
  302. package/services/taskExecutor/__tests__/mcp-tools-integration.test.d.ts +8 -2
  303. package/services/taskExecutor/__tests__/mcp-tools-integration.test.d.ts.map +1 -1
  304. package/services/taskExecutor/__tests__/mcp-tools-integration.test.js +215 -72
  305. package/services/taskExecutor/__tests__/mcp-tools-integration.test.js.map +1 -1
  306. package/services/taskExecutor/taskWorker.js +9 -1
  307. package/services/taskExecutor/taskWorker.js.map +1 -1
  308. package/services/telemetry.js +1 -1
  309. package/types/a2a.d.ts +20 -0
  310. package/types/a2a.d.ts.map +1 -1
  311. package/types/engine.d.ts +314 -0
  312. package/types/engine.d.ts.map +1 -0
  313. package/types/engine.js +14 -0
  314. package/types/engine.js.map +1 -0
  315. package/types/hooks.d.ts +45 -0
  316. package/types/hooks.d.ts.map +1 -0
  317. package/types/hooks.js +9 -0
  318. package/types/hooks.js.map +1 -0
  319. package/types/plugins.d.ts +86 -2
  320. package/types/plugins.d.ts.map +1 -1
  321. package/types/plugins.js +1 -0
  322. package/types/plugins.js.map +1 -1
  323. package/types/rules.d.ts +51 -0
  324. package/types/rules.d.ts.map +1 -0
  325. package/types/rules.js +9 -0
  326. package/types/rules.js.map +1 -0
  327. package/utils/__tests__/cursorIdeAgentParser.test.d.ts +7 -0
  328. package/utils/__tests__/cursorIdeAgentParser.test.d.ts.map +1 -0
  329. package/utils/__tests__/cursorIdeAgentParser.test.js +289 -0
  330. package/utils/__tests__/cursorIdeAgentParser.test.js.map +1 -0
  331. package/utils/claudeUtils.d.ts +3 -1
  332. package/utils/claudeUtils.d.ts.map +1 -1
  333. package/utils/claudeUtils.js +26 -12
  334. package/utils/claudeUtils.js.map +1 -1
  335. package/utils/cursorCliHistoryParser.d.ts +58 -0
  336. package/utils/cursorCliHistoryParser.d.ts.map +1 -0
  337. package/utils/cursorCliHistoryParser.js +664 -0
  338. package/utils/cursorCliHistoryParser.js.map +1 -0
  339. package/utils/cursorIdeAgentParser.d.ts +49 -0
  340. package/utils/cursorIdeAgentParser.d.ts.map +1 -0
  341. package/utils/cursorIdeAgentParser.js +332 -0
  342. package/utils/cursorIdeAgentParser.js.map +1 -0
  343. package/public/assets/AgentsPage-gSnkPp2k.js +0 -10
  344. package/public/assets/ChatPage-BMrfVkpt.js +0 -471
  345. package/public/assets/CommandsPage-B6u4IO7L.js +0 -1
  346. package/public/assets/GeneralSettingsPage-BbEbWJUQ.js +0 -1
  347. package/public/assets/LandingPage-DFPm2d4Y.js +0 -1
  348. package/public/assets/LoginPage-D5kZJqhk.js +0 -16
  349. package/public/assets/McpAdminSettingsPage-D32iUEjH.js +0 -7
  350. package/public/assets/McpPage-QT4qs391.js +0 -20
  351. package/public/assets/PluginsPage-BotzuK9f.js +0 -1
  352. package/public/assets/ProjectSelector-DujNObqr.js +0 -1
  353. package/public/assets/ProjectsPage-CRWe6HPl.js +0 -21
  354. package/public/assets/ScheduledTasksPage-Beeurg-w.js +0 -1
  355. package/public/assets/SettingsLayout-BfkBUyI_.js +0 -1
  356. package/public/assets/SkillsPage-B59bAr6W.js +0 -18
  357. package/public/assets/SystemInfoPage-D89s7PjE.js +0 -1
  358. package/public/assets/VersionSettingsPage-CaB4PH6h.js +0 -5
  359. package/public/assets/WebSocketTunnelPage-Cbru_-hL.js +0 -1
  360. package/public/assets/_basePickBy-5fAM04Ra.js +0 -1
  361. package/public/assets/arc-C2gTU2ZR.js +0 -1
  362. package/public/assets/channel-DcVTcy-S.js +0 -1
  363. package/public/assets/classDiagram-2ON5EDUG-BXVT6Q7h.js +0 -1
  364. package/public/assets/classDiagram-v2-WZHVMYZB-BXVT6Q7h.js +0 -1
  365. package/public/assets/clone-Bp6orjIq.js +0 -1
  366. package/public/assets/diagram-QEK2KX5R-BfMGeeRo.js +0 -43
  367. package/public/assets/index-BgR-BTTw.css +0 -1
  368. package/public/assets/infoDiagram-F6ZHWCRC-C6OApgqf.js +0 -2
  369. package/public/assets/stateDiagram-v2-4FDKWEC3-DyE8O3Kx.js +0 -1
  370. package/public/assets/useAgents-D5EDAc_E.js +0 -2
  371. package/public/assets/useCommands-BgoCfyuu.js +0 -1
@@ -0,0 +1,664 @@
1
+ "use strict";
2
+ /**
3
+ * Cursor CLI Agent History Parser
4
+ *
5
+ * Parses Cursor CLI agent sessions from ~/.cursor/chats/<workspace-hash>/<session-uuid>/store.db
6
+ * CLI sessions are stored in SQLite databases with blobs containing JSON messages.
7
+ *
8
+ * Note: IDE Agent sessions are stored separately in ~/.cursor/projects/<path>/agent-transcripts/*.txt
9
+ * and are handled by cursorIdeAgentParser.ts (formerly cursorHistoryParser.ts)
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.readCursorCliSessions = readCursorCliSessions;
46
+ exports.readCursorCliSession = readCursorCliSession;
47
+ const fs = __importStar(require("fs"));
48
+ const path = __importStar(require("path"));
49
+ const os = __importStar(require("os"));
50
+ const crypto = __importStar(require("crypto"));
51
+ const child_process_1 = require("child_process");
52
+ /**
53
+ * Extract image references from message content and load image data
54
+ * Looks for @.agentstudio-images/xxx.png patterns and reads the actual files
55
+ *
56
+ * @param content - Message content that may contain @path references
57
+ * @param projectPath - Project path where .agentstudio-images directory is located
58
+ * @returns Array of image data objects
59
+ */
60
+ function extractAndLoadImages(content, projectPath) {
61
+ const images = [];
62
+ // Match @.agentstudio-images/imageN_timestamp.ext patterns
63
+ const imagePathRegex = /@(\.agentstudio-images\/image\d+_\d+\.(png|jpg|jpeg|gif|webp))/gi;
64
+ let match;
65
+ let index = 0;
66
+ while ((match = imagePathRegex.exec(content)) !== null) {
67
+ const relativePath = match[1];
68
+ const fullPath = path.join(projectPath, relativePath);
69
+ try {
70
+ if (fs.existsSync(fullPath)) {
71
+ const imageBuffer = fs.readFileSync(fullPath);
72
+ const base64Data = imageBuffer.toString('base64');
73
+ const ext = path.extname(fullPath).toLowerCase().slice(1);
74
+ // Map extension to media type
75
+ const mediaTypeMap = {
76
+ 'png': 'image/png',
77
+ 'jpg': 'image/jpeg',
78
+ 'jpeg': 'image/jpeg',
79
+ 'gif': 'image/gif',
80
+ 'webp': 'image/webp'
81
+ };
82
+ const mediaType = mediaTypeMap[ext] || 'image/png';
83
+ images.push({
84
+ id: `img_${index}_${Date.now()}`,
85
+ data: base64Data,
86
+ mediaType,
87
+ filename: path.basename(fullPath)
88
+ });
89
+ index++;
90
+ }
91
+ }
92
+ catch (error) {
93
+ console.warn(`[CursorCLI] Failed to load image from ${fullPath}:`, error);
94
+ }
95
+ }
96
+ return images;
97
+ }
98
+ /**
99
+ * Execute SQLite query using native sqlite3 CLI
100
+ * This properly handles WAL mode which sql.js doesn't support
101
+ */
102
+ function executeSqliteQuery(dbPath, query) {
103
+ try {
104
+ // Use -json for structured output, fall back to raw if not available
105
+ const result = (0, child_process_1.execSync)(`sqlite3 -json "${dbPath}" "${query}"`, {
106
+ encoding: 'utf-8',
107
+ maxBuffer: 50 * 1024 * 1024, // 50MB buffer for large results
108
+ });
109
+ return result;
110
+ }
111
+ catch (error) {
112
+ console.error('[CursorCLI] SQLite query failed:', error);
113
+ throw error;
114
+ }
115
+ }
116
+ /**
117
+ * Execute SQLite query and return raw blob data as hex
118
+ */
119
+ function executeSqliteBlobQuery(dbPath, query) {
120
+ try {
121
+ // Use hex() to convert blob to hex string for safe transport
122
+ const result = (0, child_process_1.execSync)(`sqlite3 "${dbPath}" "${query}"`, {
123
+ encoding: 'utf-8',
124
+ maxBuffer: 50 * 1024 * 1024,
125
+ });
126
+ // Parse pipe-separated output: id|hex_data
127
+ const lines = result.trim().split('\n').filter(line => line.length > 0);
128
+ return lines.map(line => {
129
+ const pipeIndex = line.indexOf('|');
130
+ if (pipeIndex === -1)
131
+ return { id: line, data: '' };
132
+ return {
133
+ id: line.substring(0, pipeIndex),
134
+ data: line.substring(pipeIndex + 1),
135
+ };
136
+ });
137
+ }
138
+ catch (error) {
139
+ console.error('[CursorCLI] SQLite blob query failed:', error);
140
+ return [];
141
+ }
142
+ }
143
+ /**
144
+ * Generate workspace hash from project path (MD5)
145
+ */
146
+ function getWorkspaceHash(projectPath) {
147
+ // Resolve symlinks first
148
+ let resolvedPath = projectPath;
149
+ try {
150
+ resolvedPath = fs.realpathSync(projectPath);
151
+ }
152
+ catch {
153
+ // If path doesn't exist, use original
154
+ }
155
+ return crypto.createHash('md5').update(resolvedPath).digest('hex');
156
+ }
157
+ /**
158
+ * Get the Cursor chats directory
159
+ */
160
+ function getCursorChatsDir() {
161
+ return path.join(os.homedir(), '.cursor', 'chats');
162
+ }
163
+ /**
164
+ * Extract text content from message content array or string
165
+ */
166
+ function extractTextContent(content) {
167
+ if (typeof content === 'string') {
168
+ return content;
169
+ }
170
+ if (Array.isArray(content)) {
171
+ return content
172
+ .filter((c) => c.type === 'text' && 'text' in c && typeof c.text === 'string')
173
+ .map(c => c.text)
174
+ .join('\n');
175
+ }
176
+ return '';
177
+ }
178
+ /**
179
+ * Clean up user query by removing XML tags and extracting the actual query
180
+ */
181
+ function cleanUserQuery(text) {
182
+ // Extract content from <user_query> tags if present
183
+ const userQueryMatch = text.match(/<user_query>\s*([\s\S]*?)\s*<\/user_query>/);
184
+ if (userQueryMatch) {
185
+ return userQueryMatch[1].trim();
186
+ }
187
+ // If text starts with system info tags, skip it
188
+ if (text.startsWith('<user_info>') || text.startsWith('<rules>')) {
189
+ return '';
190
+ }
191
+ return text;
192
+ }
193
+ /**
194
+ * Parse text content and extract thinking blocks
195
+ * Returns { thinking: string | null, text: string }
196
+ */
197
+ function parseThinkingContent(text) {
198
+ // Match <think>...</think> or <thinking>...</thinking> blocks
199
+ const thinkingMatch = text.match(/<think(?:ing)?>\s*([\s\S]*?)\s*<\/think(?:ing)?>/);
200
+ if (thinkingMatch) {
201
+ const thinking = thinkingMatch[1].trim();
202
+ // Remove thinking block from text
203
+ const remainingText = text
204
+ .replace(/<think(?:ing)?>\s*[\s\S]*?\s*<\/think(?:ing)?>/g, '')
205
+ .trim();
206
+ return { thinking, text: remainingText };
207
+ }
208
+ return { thinking: null, text };
209
+ }
210
+ /**
211
+ * Extract a clean title from user message, skipping system info
212
+ */
213
+ function extractSessionTitle(messages, sessionId, metaName) {
214
+ // Find the first user message with actual content
215
+ for (const msg of messages) {
216
+ if (msg.role === 'user' && msg.content) {
217
+ // Skip if it's system info
218
+ if (msg.content.startsWith('<user_info>') ||
219
+ msg.content.startsWith('<rules>') ||
220
+ msg.content.includes('<user_info>')) {
221
+ continue;
222
+ }
223
+ // Use the first 50 characters as title
224
+ let title = msg.content.substring(0, 50);
225
+ if (msg.content.length > 50) {
226
+ title += '...';
227
+ }
228
+ return title;
229
+ }
230
+ }
231
+ // Fallback to meta name or session ID
232
+ return metaName || `Session ${sessionId.substring(0, 8)}`;
233
+ }
234
+ /**
235
+ * Parse blob data to extract JSON messages
236
+ */
237
+ function parseBlobData(data) {
238
+ try {
239
+ // Convert buffer to string
240
+ const dataStr = data.toString('utf-8');
241
+ // Try parsing as JSON first
242
+ try {
243
+ const parsed = JSON.parse(dataStr);
244
+ if (parsed.role) {
245
+ return parsed;
246
+ }
247
+ }
248
+ catch {
249
+ // Not valid JSON, continue
250
+ }
251
+ return null;
252
+ }
253
+ catch {
254
+ return null;
255
+ }
256
+ }
257
+ /**
258
+ * Tool name mapping from Cursor SDK names to frontend expected names
259
+ * This ensures tool names match what CursorToolRenderer.tsx expects
260
+ */
261
+ const CURSOR_TOOL_NAME_MAP = {
262
+ // Standard tools
263
+ 'LS': 'lsToolCall',
264
+ 'Ls': 'lsToolCall',
265
+ 'Read': 'readToolCall',
266
+ 'Write': 'writeToolCall',
267
+ 'Edit': 'editToolCall',
268
+ 'Delete': 'deleteToolCall',
269
+ 'Glob': 'globToolCall',
270
+ 'Grep': 'grepToolCall',
271
+ 'Shell': 'shellToolCall',
272
+ 'WebFetch': 'webFetchToolCall',
273
+ 'SemSearch': 'semSearchToolCall',
274
+ 'ListMcpResources': 'listMcpResourcesToolCall',
275
+ // Special mappings - Cursor SDK uses different names than frontend expects
276
+ 'TodoWrite': 'updateTodosToolCall',
277
+ 'StrReplace': 'strReplaceToolCall',
278
+ // MCP tool
279
+ 'Mcp': 'mcpToolCall',
280
+ };
281
+ /**
282
+ * Convert tool name to Cursor format (e.g., "Glob" -> "globToolCall")
283
+ * Uses mapping table for known tools, falls back to camelCase conversion for unknown tools
284
+ */
285
+ function toCursorToolName(toolName) {
286
+ // Check mapping table first
287
+ if (CURSOR_TOOL_NAME_MAP[toolName]) {
288
+ return CURSOR_TOOL_NAME_MAP[toolName];
289
+ }
290
+ // Fallback: convert to camelCase and add ToolCall suffix
291
+ // Handle all-uppercase names like "LS" -> "ls"
292
+ const baseName = toolName.length <= 2
293
+ ? toolName.toLowerCase()
294
+ : toolName.charAt(0).toLowerCase() + toolName.slice(1);
295
+ return baseName + 'ToolCall';
296
+ }
297
+ /**
298
+ * Convert snake_case keys to camelCase
299
+ */
300
+ function snakeToCamel(str) {
301
+ return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
302
+ }
303
+ /**
304
+ * Convert all keys in an object from snake_case to camelCase
305
+ * Also handles arrays containing objects
306
+ */
307
+ function convertKeysToCamelCase(obj) {
308
+ const result = {};
309
+ for (const key of Object.keys(obj)) {
310
+ const camelKey = snakeToCamel(key);
311
+ const value = obj[key];
312
+ if (Array.isArray(value)) {
313
+ // Handle arrays - convert objects within arrays
314
+ result[camelKey] = value.map(item => {
315
+ if (item && typeof item === 'object' && !Array.isArray(item)) {
316
+ return convertKeysToCamelCase(item);
317
+ }
318
+ return item;
319
+ });
320
+ }
321
+ else if (value && typeof value === 'object') {
322
+ // Recursively convert nested objects
323
+ result[camelKey] = convertKeysToCamelCase(value);
324
+ }
325
+ else {
326
+ result[camelKey] = value;
327
+ }
328
+ }
329
+ return result;
330
+ }
331
+ /**
332
+ * Extract tool calls from message content
333
+ * @param content - Array of message content items
334
+ * @param isUserMessage - Whether this is a user message (to clean <user_query> tags)
335
+ */
336
+ function extractToolCalls(content, isUserMessage = false) {
337
+ const parts = [];
338
+ let order = 0;
339
+ for (const item of content) {
340
+ if (item.type === 'text' && 'text' in item && item.text) {
341
+ // Clean user query tags if this is a user message
342
+ let textContent = isUserMessage ? cleanUserQuery(item.text) : item.text;
343
+ // Skip empty text after cleaning
344
+ if (!textContent.trim())
345
+ continue;
346
+ // For assistant messages, check for thinking blocks
347
+ if (!isUserMessage) {
348
+ const { thinking, text } = parseThinkingContent(textContent);
349
+ // Add thinking part if present
350
+ if (thinking) {
351
+ parts.push({
352
+ id: `part_thinking_${order}`,
353
+ type: 'thinking',
354
+ content: thinking,
355
+ order: order++
356
+ });
357
+ }
358
+ // Update textContent to the remaining text
359
+ textContent = text;
360
+ // Skip if no remaining text
361
+ if (!textContent.trim())
362
+ continue;
363
+ }
364
+ parts.push({
365
+ id: `part_text_${order}`,
366
+ type: 'text',
367
+ content: textContent,
368
+ order: order++
369
+ });
370
+ }
371
+ else if (item.type === 'tool-call' && 'toolCallId' in item) {
372
+ parts.push({
373
+ id: item.toolCallId,
374
+ type: 'tool',
375
+ order: order++,
376
+ toolData: {
377
+ id: item.toolCallId,
378
+ toolName: toCursorToolName(item.toolName), // Convert to Cursor tool name format (e.g., "globToolCall")
379
+ toolInput: convertKeysToCamelCase(item.args || {}), // Convert snake_case to camelCase
380
+ }
381
+ });
382
+ }
383
+ }
384
+ return parts;
385
+ }
386
+ /**
387
+ * Parse a single CLI session from SQLite database
388
+ *
389
+ * @param sessionDir - Path to the session directory containing store.db
390
+ * @param sessionId - Session ID
391
+ * @param projectPath - Optional project path for loading image references
392
+ */
393
+ async function parseCliSession(sessionDir, sessionId, projectPath) {
394
+ const dbPath = path.join(sessionDir, 'store.db');
395
+ if (!fs.existsSync(dbPath)) {
396
+ return null;
397
+ }
398
+ try {
399
+ // Use native sqlite3 CLI to properly handle WAL mode
400
+ // sql.js doesn't support WAL and would miss recent changes
401
+ // Get meta information
402
+ // The value in meta table is stored as a hex-encoded JSON string
403
+ const metaValue = (0, child_process_1.execSync)(`sqlite3 "${dbPath}" "SELECT value FROM meta WHERE key = 0"`, {
404
+ encoding: 'utf-8',
405
+ maxBuffer: 10 * 1024 * 1024,
406
+ }).trim();
407
+ if (!metaValue) {
408
+ return null;
409
+ }
410
+ // Decode hex-encoded meta value (stored as hex string in the database)
411
+ const metaJson = Buffer.from(metaValue, 'hex').toString('utf-8');
412
+ const meta = JSON.parse(metaJson);
413
+ // Get all blobs with hex-encoded data
414
+ const blobRows = executeSqliteBlobQuery(dbPath, 'SELECT id, hex(data) FROM blobs');
415
+ // Convert hex strings to Buffer
416
+ const blobs = blobRows.map(row => ({
417
+ id: row.id,
418
+ data: Buffer.from(row.data, 'hex'),
419
+ }));
420
+ // Parse messages from blobs - use Map to deduplicate by message id
421
+ const messageMap = new Map();
422
+ const toolResults = new Map();
423
+ let messageIndex = 0;
424
+ // Track seen content to deduplicate messages with same content
425
+ const seenContent = new Set();
426
+ // First pass: collect all messages and tool results
427
+ for (const blob of blobs) {
428
+ const parsed = parseBlobData(blob.data);
429
+ if (!parsed)
430
+ continue;
431
+ // Handle tool results
432
+ if (parsed.role === 'tool' && 'id' in parsed) {
433
+ const toolMsg = parsed;
434
+ if (Array.isArray(toolMsg.content)) {
435
+ for (const item of toolMsg.content) {
436
+ if (item.type === 'tool-result') {
437
+ toolResults.set(toolMsg.id, {
438
+ toolName: item.toolName,
439
+ result: item.result,
440
+ isError: item.isError
441
+ });
442
+ }
443
+ }
444
+ }
445
+ continue;
446
+ }
447
+ // Skip system messages
448
+ if (parsed.role === 'system')
449
+ continue;
450
+ // Handle user and assistant messages
451
+ if (parsed.role === 'user' || parsed.role === 'assistant') {
452
+ // Generate a unique message ID using blob.id (from database)
453
+ // This ensures each blob is processed independently
454
+ const msgId = `${parsed.role}_${blob.id}`;
455
+ // Skip if we already have this exact message (by message ID)
456
+ if (messageMap.has(msgId))
457
+ continue;
458
+ let textContent = '';
459
+ let messageParts = [];
460
+ const isUserMessage = parsed.role === 'user';
461
+ if (Array.isArray(parsed.content)) {
462
+ // Extract text content and tool calls from content array
463
+ // Pass isUserMessage to clean <user_query> tags
464
+ messageParts = extractToolCalls(parsed.content, isUserMessage);
465
+ textContent = messageParts
466
+ .filter(p => p.type === 'text' && p.content)
467
+ .map(p => p.content)
468
+ .join('\n');
469
+ }
470
+ else if (typeof parsed.content === 'string') {
471
+ // For string content, clean user query tags if needed
472
+ let rawContent = isUserMessage ? cleanUserQuery(parsed.content) : parsed.content;
473
+ if (rawContent) {
474
+ // For assistant messages, parse thinking blocks
475
+ if (!isUserMessage) {
476
+ const { thinking, text } = parseThinkingContent(rawContent);
477
+ if (thinking) {
478
+ messageParts.push({
479
+ id: `part_thinking_${messageIndex}`,
480
+ type: 'thinking',
481
+ content: thinking,
482
+ order: messageParts.length
483
+ });
484
+ }
485
+ textContent = text;
486
+ }
487
+ else {
488
+ textContent = rawContent;
489
+ }
490
+ if (textContent) {
491
+ messageParts.push({
492
+ id: `part_${messageIndex}_0`,
493
+ type: 'text',
494
+ content: textContent,
495
+ order: messageParts.length
496
+ });
497
+ }
498
+ }
499
+ }
500
+ // textContent is already cleaned, use it directly
501
+ const cleanedContent = textContent;
502
+ // Skip if no meaningful content (no text, no thinking, no tool calls)
503
+ const hasToolCalls = messageParts.some(p => p.type === 'tool');
504
+ const hasThinking = messageParts.some(p => p.type === 'thinking');
505
+ if (!cleanedContent && !hasToolCalls && !hasThinking) {
506
+ continue;
507
+ }
508
+ // Skip system info in user messages
509
+ if (parsed.role === 'user' &&
510
+ (cleanedContent.startsWith('<user_info>') ||
511
+ cleanedContent.startsWith('<rules>') ||
512
+ cleanedContent.includes('<user_info>'))) {
513
+ continue;
514
+ }
515
+ // Create content hash for deduplication (based on role + text content + tool calls)
516
+ const toolCallIds = messageParts
517
+ .filter(p => p.type === 'tool' && p.toolData)
518
+ .map(p => p.toolData.id)
519
+ .sort()
520
+ .join(',');
521
+ const contentHash = `${parsed.role}:${cleanedContent.substring(0, 200)}:${toolCallIds}`;
522
+ // Skip if we've already seen this exact content
523
+ if (seenContent.has(contentHash)) {
524
+ continue;
525
+ }
526
+ seenContent.add(contentHash);
527
+ // For user messages, try to extract and load image references
528
+ let images;
529
+ if (parsed.role === 'user' && projectPath && cleanedContent.includes('@.agentstudio-images/')) {
530
+ images = extractAndLoadImages(cleanedContent, projectPath);
531
+ if (images.length > 0) {
532
+ console.log(`📷 [CursorCLI] Loaded ${images.length} image(s) for user message`);
533
+ }
534
+ }
535
+ messageMap.set(msgId, {
536
+ id: msgId,
537
+ role: parsed.role,
538
+ content: cleanedContent,
539
+ timestamp: meta.createdAt + (messageIndex * 1000),
540
+ messageParts: messageParts.length > 0 ? messageParts : [{
541
+ id: `part_${messageIndex}_0`,
542
+ type: 'text',
543
+ content: cleanedContent,
544
+ order: 0
545
+ }],
546
+ images // Include loaded images if any
547
+ });
548
+ messageIndex++;
549
+ }
550
+ }
551
+ // Second pass: attach tool results to tool calls
552
+ for (const message of messageMap.values()) {
553
+ for (const part of message.messageParts) {
554
+ if (part.type === 'tool' && part.toolData) {
555
+ const result = toolResults.get(part.toolData.id);
556
+ if (result) {
557
+ part.toolData.toolResult = typeof result.result === 'string'
558
+ ? result.result
559
+ : JSON.stringify(result.result);
560
+ // Also set toolUseResult as object with camelCase keys for frontend components
561
+ if (result.result && typeof result.result === 'object') {
562
+ part.toolData.toolUseResult = convertKeysToCamelCase(result.result);
563
+ }
564
+ else if (typeof result.result === 'string') {
565
+ // Try to parse string as JSON
566
+ try {
567
+ const parsed = JSON.parse(result.result);
568
+ if (typeof parsed === 'object' && parsed !== null) {
569
+ part.toolData.toolUseResult = convertKeysToCamelCase(parsed);
570
+ }
571
+ }
572
+ catch {
573
+ // Not JSON, leave toolUseResult undefined
574
+ }
575
+ }
576
+ part.toolData.isError = result.isError;
577
+ }
578
+ }
579
+ }
580
+ }
581
+ // Convert map to array and sort by timestamp
582
+ const messages = Array.from(messageMap.values())
583
+ .sort((a, b) => a.timestamp - b.timestamp);
584
+ if (messages.length === 0) {
585
+ return null;
586
+ }
587
+ // Generate title from first meaningful user message (skip system info)
588
+ const title = extractSessionTitle(messages, sessionId, meta.name);
589
+ // Get directory stats for timestamps
590
+ const stats = fs.statSync(sessionDir);
591
+ return {
592
+ id: sessionId,
593
+ title,
594
+ createdAt: new Date(meta.createdAt).toISOString(),
595
+ lastUpdated: stats.mtime.toISOString(),
596
+ messages,
597
+ mode: meta.mode
598
+ };
599
+ }
600
+ catch (error) {
601
+ console.error(`Failed to parse CLI session ${sessionId}:`, error);
602
+ return null;
603
+ }
604
+ }
605
+ /**
606
+ * Read all Cursor CLI sessions for a project
607
+ */
608
+ async function readCursorCliSessions(projectPath) {
609
+ try {
610
+ const workspaceHash = getWorkspaceHash(projectPath);
611
+ const chatsDir = path.join(getCursorChatsDir(), workspaceHash);
612
+ console.log(`📂 [CURSOR CLI] Reading sessions from: ${chatsDir}`);
613
+ console.log(`📂 [CURSOR CLI] Workspace hash: ${workspaceHash} (from ${projectPath})`);
614
+ if (!fs.existsSync(chatsDir)) {
615
+ console.log(`❌ [CURSOR CLI] Chats directory not found: ${chatsDir}`);
616
+ return [];
617
+ }
618
+ const sessionDirs = fs.readdirSync(chatsDir)
619
+ .filter(name => {
620
+ const fullPath = path.join(chatsDir, name);
621
+ return fs.statSync(fullPath).isDirectory() && !name.startsWith('.');
622
+ });
623
+ console.log(`📋 [CURSOR CLI] Found ${sessionDirs.length} session directories`);
624
+ const sessions = [];
625
+ for (const sessionId of sessionDirs) {
626
+ const sessionDir = path.join(chatsDir, sessionId);
627
+ const session = await parseCliSession(sessionDir, sessionId);
628
+ if (session) {
629
+ sessions.push(session);
630
+ }
631
+ }
632
+ // Sort by lastUpdated descending
633
+ sessions.sort((a, b) => new Date(b.lastUpdated).getTime() - new Date(a.lastUpdated).getTime());
634
+ console.log(`✅ [CURSOR CLI] Parsed ${sessions.length} sessions successfully`);
635
+ return sessions;
636
+ }
637
+ catch (error) {
638
+ console.error('Failed to read Cursor CLI sessions:', error);
639
+ return [];
640
+ }
641
+ }
642
+ /**
643
+ * Read a single Cursor CLI session by ID
644
+ */
645
+ async function readCursorCliSession(projectPath, sessionId) {
646
+ try {
647
+ const workspaceHash = getWorkspaceHash(projectPath);
648
+ // Strip 'cursor-' prefix if present (added by AgentStudio for internal tracking)
649
+ const actualSessionId = sessionId.startsWith('cursor-') ? sessionId.slice(7) : sessionId;
650
+ const sessionDir = path.join(getCursorChatsDir(), workspaceHash, actualSessionId);
651
+ if (!fs.existsSync(sessionDir)) {
652
+ console.log(`❌ [CURSOR CLI] Session directory not found: ${sessionDir}`);
653
+ return null;
654
+ }
655
+ // Pass projectPath for loading image references
656
+ // Use original sessionId (with prefix) to maintain consistency
657
+ return await parseCliSession(sessionDir, sessionId, projectPath);
658
+ }
659
+ catch (error) {
660
+ console.error(`Failed to read Cursor CLI session ${sessionId}:`, error);
661
+ return null;
662
+ }
663
+ }
664
+ //# sourceMappingURL=cursorCliHistoryParser.js.map