claude-code-workflow 7.2.18 → 7.2.20

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 (200) hide show
  1. package/.claude/commands/workflow/analyze-with-file.md +33 -8
  2. package/.codex/skills/analyze-with-file/SKILL.md +55 -8
  3. package/ccw/dist/core/routes/agent-definitions-routes.d.ts.map +1 -1
  4. package/ccw/dist/core/routes/agent-definitions-routes.js +152 -6
  5. package/ccw/dist/core/routes/agent-definitions-routes.js.map +1 -1
  6. package/ccw/frontend/dist/assets/{AlertDialog-5DA_OF9w.js → AlertDialog-Cukb0xv2.js} +2 -2
  7. package/ccw/frontend/dist/assets/{AlertDialog-5DA_OF9w.js.map → AlertDialog-Cukb0xv2.js.map} +1 -1
  8. package/ccw/frontend/dist/assets/{AnalysisPage-MoK5luZM.js → AnalysisPage-Ddmv0J4x.js} +2 -2
  9. package/ccw/frontend/dist/assets/{AnalysisPage-MoK5luZM.js.map → AnalysisPage-Ddmv0J4x.js.map} +1 -1
  10. package/ccw/frontend/dist/assets/{ApiSettingsPage-OreSF7CY.js → ApiSettingsPage-DMkrTZDX.js} +2 -2
  11. package/ccw/frontend/dist/assets/{ApiSettingsPage-OreSF7CY.js.map → ApiSettingsPage-DMkrTZDX.js.map} +1 -1
  12. package/ccw/frontend/dist/assets/{CliModeToggle-B_Vu8NDb.js → CliModeToggle-DXenjpbe.js} +2 -2
  13. package/ccw/frontend/dist/assets/{CliModeToggle-B_Vu8NDb.js.map → CliModeToggle-DXenjpbe.js.map} +1 -1
  14. package/ccw/frontend/dist/assets/{CliSessionSharePage-Bb3DrLGF.js → CliSessionSharePage-B-ZIMqmX.js} +2 -2
  15. package/ccw/frontend/dist/assets/{CliSessionSharePage-Bb3DrLGF.js.map → CliSessionSharePage-B-ZIMqmX.js.map} +1 -1
  16. package/ccw/frontend/dist/assets/{CliViewerPage-BS4zrFVp.js → CliViewerPage-9YxGyLxh.js} +2 -2
  17. package/ccw/frontend/dist/assets/{CliViewerPage-BS4zrFVp.js.map → CliViewerPage-9YxGyLxh.js.map} +1 -1
  18. package/ccw/frontend/dist/assets/{CodexLensPage-BWSIk06e.js → CodexLensPage-B_uv5wdn.js} +2 -2
  19. package/ccw/frontend/dist/assets/{CodexLensPage-BWSIk06e.js.map → CodexLensPage-B_uv5wdn.js.map} +1 -1
  20. package/ccw/frontend/dist/assets/{Collapsible-Cw1zJkjU.js → Collapsible-C2qk3yV0.js} +2 -2
  21. package/ccw/frontend/dist/assets/{Collapsible-Cw1zJkjU.js.map → Collapsible-C2qk3yV0.js.map} +1 -1
  22. package/ccw/frontend/dist/assets/{CommandsManagerPage-a240GHzx.js → CommandsManagerPage-DBtaWxLB.js} +2 -2
  23. package/ccw/frontend/dist/assets/{CommandsManagerPage-a240GHzx.js.map → CommandsManagerPage-DBtaWxLB.js.map} +1 -1
  24. package/ccw/frontend/dist/assets/{DeepWikiPage-CZ4pN-5G.js → DeepWikiPage-d9K4_TgG.js} +2 -2
  25. package/ccw/frontend/dist/assets/{DeepWikiPage-CZ4pN-5G.js.map → DeepWikiPage-d9K4_TgG.js.map} +1 -1
  26. package/ccw/frontend/dist/assets/{EndpointsPage-Ct66AIze.js → EndpointsPage-DhW6hYrI.js} +2 -2
  27. package/ccw/frontend/dist/assets/{EndpointsPage-Ct66AIze.js.map → EndpointsPage-DhW6hYrI.js.map} +1 -1
  28. package/ccw/frontend/dist/assets/{ExplorerPage-DAZkXx2Q.js → ExplorerPage-DYYpCvtB.js} +2 -2
  29. package/ccw/frontend/dist/assets/{ExplorerPage-DAZkXx2Q.js.map → ExplorerPage-DYYpCvtB.js.map} +1 -1
  30. package/ccw/frontend/dist/assets/{FixSessionPage-cDE32BH8.js → FixSessionPage-CSmiT5SE.js} +2 -2
  31. package/ccw/frontend/dist/assets/{FixSessionPage-cDE32BH8.js.map → FixSessionPage-CSmiT5SE.js.map} +1 -1
  32. package/ccw/frontend/dist/assets/{FloatingFileBrowser-tgDOT5P0.js → FloatingFileBrowser-DvMsXLdP.js} +2 -2
  33. package/ccw/frontend/dist/assets/{FloatingFileBrowser-tgDOT5P0.js.map → FloatingFileBrowser-DvMsXLdP.js.map} +1 -1
  34. package/ccw/frontend/dist/assets/{FloatingPanel-Diyvdyo1.js → FloatingPanel-sqezhSI8.js} +2 -2
  35. package/ccw/frontend/dist/assets/{FloatingPanel-Diyvdyo1.js.map → FloatingPanel-sqezhSI8.js.map} +1 -1
  36. package/ccw/frontend/dist/assets/{GraphExplorerPage-CPwRsfd2.js → GraphExplorerPage-DS8ghMFM.js} +2 -2
  37. package/ccw/frontend/dist/assets/{GraphExplorerPage-CPwRsfd2.js.map → GraphExplorerPage-DS8ghMFM.js.map} +1 -1
  38. package/ccw/frontend/dist/assets/{HistoryPage-D2F7j-xY.js → HistoryPage-B-x1RyHu.js} +2 -2
  39. package/ccw/frontend/dist/assets/{HistoryPage-D2F7j-xY.js.map → HistoryPage-B-x1RyHu.js.map} +1 -1
  40. package/ccw/frontend/dist/assets/{HookManagerPage-Cq_CqegO.js → HookManagerPage-BbxpDb68.js} +2 -2
  41. package/ccw/frontend/dist/assets/{HookManagerPage-Cq_CqegO.js.map → HookManagerPage-BbxpDb68.js.map} +1 -1
  42. package/ccw/frontend/dist/assets/{InstallationsPage-DeBLZFZg.js → InstallationsPage-3bShz_Ai.js} +2 -2
  43. package/ccw/frontend/dist/assets/{InstallationsPage-DeBLZFZg.js.map → InstallationsPage-3bShz_Ai.js.map} +1 -1
  44. package/ccw/frontend/dist/assets/{IssueHubPage-DqytkqBW.js → IssueHubPage-BQY_Hh3e.js} +2 -2
  45. package/ccw/frontend/dist/assets/{IssueHubPage-DqytkqBW.js.map → IssueHubPage-BQY_Hh3e.js.map} +1 -1
  46. package/ccw/frontend/dist/assets/{LiteTasksPage-BOknokuo.js → LiteTasksPage-vD_8fQcR.js} +17 -22
  47. package/ccw/frontend/dist/assets/LiteTasksPage-vD_8fQcR.js.map +1 -0
  48. package/ccw/frontend/dist/assets/{McpManagerPage-DPF421ki.js → McpManagerPage-CI5ZzB8A.js} +2 -2
  49. package/ccw/frontend/dist/assets/{McpManagerPage-DPF421ki.js.map → McpManagerPage-CI5ZzB8A.js.map} +1 -1
  50. package/ccw/frontend/dist/assets/{MemoryPage-CK-QH9cl.js → MemoryPage-CNuj2eNg.js} +2 -2
  51. package/ccw/frontend/dist/assets/{MemoryPage-CK-QH9cl.js.map → MemoryPage-CNuj2eNg.js.map} +1 -1
  52. package/ccw/frontend/dist/assets/{NotFoundPage-Bk_u5rzz.js → NotFoundPage-BrnAXkb1.js} +2 -2
  53. package/ccw/frontend/dist/assets/{NotFoundPage-Bk_u5rzz.js.map → NotFoundPage-BrnAXkb1.js.map} +1 -1
  54. package/ccw/frontend/dist/assets/{OrchestratorPage-B9ND5ptW.js → OrchestratorPage-CH81PGt4.js} +2 -2
  55. package/ccw/frontend/dist/assets/{OrchestratorPage-B9ND5ptW.js.map → OrchestratorPage-CH81PGt4.js.map} +1 -1
  56. package/ccw/frontend/dist/assets/{ProjectOverviewPage-0DUpa-rl.js → ProjectOverviewPage-dwiEXl2O.js} +2 -2
  57. package/ccw/frontend/dist/assets/{ProjectOverviewPage-0DUpa-rl.js.map → ProjectOverviewPage-dwiEXl2O.js.map} +1 -1
  58. package/ccw/frontend/dist/assets/{PromptHistoryPage-B--0N_wr.js → PromptHistoryPage-CabgLjJU.js} +2 -2
  59. package/ccw/frontend/dist/assets/{PromptHistoryPage-B--0N_wr.js.map → PromptHistoryPage-CabgLjJU.js.map} +1 -1
  60. package/ccw/frontend/dist/assets/{ReviewSessionPage-DJtY0kQl.js → ReviewSessionPage-DAMrNFn8.js} +2 -2
  61. package/ccw/frontend/dist/assets/{ReviewSessionPage-DJtY0kQl.js.map → ReviewSessionPage-DAMrNFn8.js.map} +1 -1
  62. package/ccw/frontend/dist/assets/{RulesManagerPage-yW19Un_V.js → RulesManagerPage-4jzmxPn0.js} +2 -2
  63. package/ccw/frontend/dist/assets/{RulesManagerPage-yW19Un_V.js.map → RulesManagerPage-4jzmxPn0.js.map} +1 -1
  64. package/ccw/frontend/dist/assets/{SessionDetailPage-tr8g0Hc1.js → SessionDetailPage-C5Btktmp.js} +2 -2
  65. package/ccw/frontend/dist/assets/{SessionDetailPage-tr8g0Hc1.js.map → SessionDetailPage-C5Btktmp.js.map} +1 -1
  66. package/ccw/frontend/dist/assets/{SessionsPage-CxDytLfb.js → SessionsPage-CQIB4E8m.js} +2 -2
  67. package/ccw/frontend/dist/assets/{SessionsPage-CxDytLfb.js.map → SessionsPage-CQIB4E8m.js.map} +1 -1
  68. package/ccw/frontend/dist/assets/SettingsPage-Yi9UAfm7.js +150 -0
  69. package/ccw/frontend/dist/assets/SettingsPage-Yi9UAfm7.js.map +1 -0
  70. package/ccw/frontend/dist/assets/{SkillsManagerPage-C0MOJy-C.js → SkillsManagerPage-BqfvYSkT.js} +2 -2
  71. package/ccw/frontend/dist/assets/{SkillsManagerPage-C0MOJy-C.js.map → SkillsManagerPage-BqfvYSkT.js.map} +1 -1
  72. package/ccw/frontend/dist/assets/{SpecsSettingsPage-D9Y6-U-n.js → SpecsSettingsPage-BdVPM5R6.js} +4 -4
  73. package/ccw/frontend/dist/assets/{SpecsSettingsPage-D9Y6-U-n.js.map → SpecsSettingsPage-BdVPM5R6.js.map} +1 -1
  74. package/ccw/frontend/dist/assets/{Switch-BEfkMCxZ.js → Switch-BG929kV0.js} +2 -2
  75. package/ccw/frontend/dist/assets/{Switch-BEfkMCxZ.js.map → Switch-BG929kV0.js.map} +1 -1
  76. package/ccw/frontend/dist/assets/{TabsNavigation-Dit0DM3m.js → TabsNavigation-Bol1y09b.js} +2 -2
  77. package/ccw/frontend/dist/assets/{TabsNavigation-Dit0DM3m.js.map → TabsNavigation-Bol1y09b.js.map} +1 -1
  78. package/ccw/frontend/dist/assets/{TaskDrawer-XN-D_bDk.js → TaskDrawer-Dwutrn8_.js} +2 -2
  79. package/ccw/frontend/dist/assets/{TaskDrawer-XN-D_bDk.js.map → TaskDrawer-Dwutrn8_.js.map} +1 -1
  80. package/ccw/frontend/dist/assets/{TeamPage-BOwkjrDi.js → TeamPage-CpCSwpxD.js} +2 -2
  81. package/ccw/frontend/dist/assets/{TeamPage-BOwkjrDi.js.map → TeamPage-CpCSwpxD.js.map} +1 -1
  82. package/ccw/frontend/dist/assets/{TerminalDashboardPage-X8RymrSN.js → TerminalDashboardPage-DODKjOeK.js} +2 -2
  83. package/ccw/frontend/dist/assets/{TerminalDashboardPage-X8RymrSN.js.map → TerminalDashboardPage-DODKjOeK.js.map} +1 -1
  84. package/ccw/frontend/dist/assets/{archive-BMXBzq8R.js → archive-CQw634kD.js} +2 -2
  85. package/ccw/frontend/dist/assets/{archive-BMXBzq8R.js.map → archive-CQw634kD.js.map} +1 -1
  86. package/ccw/frontend/dist/assets/{archive-restore-DHvAhQBT.js → archive-restore-B-_EG6wE.js} +2 -2
  87. package/ccw/frontend/dist/assets/{archive-restore-DHvAhQBT.js.map → archive-restore-B-_EG6wE.js.map} +1 -1
  88. package/ccw/frontend/dist/assets/{arrow-right-CBObFEN0.js → arrow-right-CcQtxBrU.js} +2 -2
  89. package/ccw/frontend/dist/assets/{arrow-right-CBObFEN0.js.map → arrow-right-CcQtxBrU.js.map} +1 -1
  90. package/ccw/frontend/dist/assets/{bookmark-plus-D-2SQ5pV.js → bookmark-plus-Cl-BbcpR.js} +2 -2
  91. package/ccw/frontend/dist/assets/{bookmark-plus-D-2SQ5pV.js.map → bookmark-plus-Cl-BbcpR.js.map} +1 -1
  92. package/ccw/frontend/dist/assets/{bot-DS7saQkk.js → bot-CLSNSkW_.js} +2 -2
  93. package/ccw/frontend/dist/assets/{bot-DS7saQkk.js.map → bot-CLSNSkW_.js.map} +1 -1
  94. package/ccw/frontend/dist/assets/{braces-D0pAnktp.js → braces-DWwkaDS6.js} +2 -2
  95. package/ccw/frontend/dist/assets/{braces-D0pAnktp.js.map → braces-DWwkaDS6.js.map} +1 -1
  96. package/ccw/frontend/dist/assets/{circle-stop-FWSboNE6.js → circle-stop-DiS7e6ma.js} +2 -2
  97. package/ccw/frontend/dist/assets/{circle-stop-FWSboNE6.js.map → circle-stop-DiS7e6ma.js.map} +1 -1
  98. package/ccw/frontend/dist/assets/{cpu-BNM2uIpY.js → cpu-CuvHUVXO.js} +2 -2
  99. package/ccw/frontend/dist/assets/{cpu-BNM2uIpY.js.map → cpu-CuvHUVXO.js.map} +1 -1
  100. package/ccw/frontend/dist/assets/{ellipsis-vertical-GwdnnWQj.js → ellipsis-vertical-BoVlINSw.js} +2 -2
  101. package/ccw/frontend/dist/assets/{ellipsis-vertical-GwdnnWQj.js.map → ellipsis-vertical-BoVlINSw.js.map} +1 -1
  102. package/ccw/frontend/dist/assets/{eye-kV2pWXQ5.js → eye-BEMOdcAN.js} +2 -2
  103. package/ccw/frontend/dist/assets/{eye-kV2pWXQ5.js.map → eye-BEMOdcAN.js.map} +1 -1
  104. package/ccw/frontend/dist/assets/{eye-off-6o-KYsBM.js → eye-off-C5HS4Ytm.js} +2 -2
  105. package/ccw/frontend/dist/assets/{eye-off-6o-KYsBM.js.map → eye-off-C5HS4Ytm.js.map} +1 -1
  106. package/ccw/frontend/dist/assets/{file-json-Q4_Blhd8.js → file-json-DQ9XLq0B.js} +2 -2
  107. package/ccw/frontend/dist/assets/{file-json-Q4_Blhd8.js.map → file-json-DQ9XLq0B.js.map} +1 -1
  108. package/ccw/frontend/dist/assets/{file-text-DSroEAMu.js → file-text-TGs_qCbw.js} +2 -2
  109. package/ccw/frontend/dist/assets/{file-text-DSroEAMu.js.map → file-text-TGs_qCbw.js.map} +1 -1
  110. package/ccw/frontend/dist/assets/{filter-A5I9Xz7E.js → filter-CIuCqnDB.js} +2 -2
  111. package/ccw/frontend/dist/assets/{filter-A5I9Xz7E.js.map → filter-CIuCqnDB.js.map} +1 -1
  112. package/ccw/frontend/dist/assets/{folder-DNNgXVVH.js → folder-BkivHBwn.js} +2 -2
  113. package/ccw/frontend/dist/assets/{folder-DNNgXVVH.js.map → folder-BkivHBwn.js.map} +1 -1
  114. package/ccw/frontend/dist/assets/{gauge-PfGM68A8.js → gauge-CtM68fVY.js} +2 -2
  115. package/ccw/frontend/dist/assets/{gauge-PfGM68A8.js.map → gauge-CtM68fVY.js.map} +1 -1
  116. package/ccw/frontend/dist/assets/{globe-C3X8YQrU.js → globe-DpnrINqP.js} +2 -2
  117. package/ccw/frontend/dist/assets/{globe-C3X8YQrU.js.map → globe-DpnrINqP.js.map} +1 -1
  118. package/ccw/frontend/dist/assets/{grid-3x3-DpyJO-oF.js → grid-3x3-SjX0a5JH.js} +2 -2
  119. package/ccw/frontend/dist/assets/{grid-3x3-DpyJO-oF.js.map → grid-3x3-SjX0a5JH.js.map} +1 -1
  120. package/ccw/frontend/dist/assets/{hard-drive-C2PQHoNg.js → hard-drive-ByAmnoEg.js} +2 -2
  121. package/ccw/frontend/dist/assets/{hard-drive-C2PQHoNg.js.map → hard-drive-ByAmnoEg.js.map} +1 -1
  122. package/ccw/frontend/dist/assets/{hash-DX8VaW1j.js → hash-DbLc3VOZ.js} +2 -2
  123. package/ccw/frontend/dist/assets/{hash-DX8VaW1j.js.map → hash-DbLc3VOZ.js.map} +1 -1
  124. package/ccw/frontend/dist/assets/{history-BXaQEkhy.js → history-Botz5Z5d.js} +2 -2
  125. package/ccw/frontend/dist/assets/{history-BXaQEkhy.js.map → history-Botz5Z5d.js.map} +1 -1
  126. package/ccw/frontend/dist/assets/{index-BiN-BRcE.js → index-BGvyf4-9.js} +2 -2
  127. package/ccw/frontend/dist/assets/{index-BiN-BRcE.js.map → index-BGvyf4-9.js.map} +1 -1
  128. package/ccw/frontend/dist/assets/index-BoqylFO4.css +39 -0
  129. package/ccw/frontend/dist/assets/{index-B8K8MdMl.js → index-DP_mTJI8.js} +3 -3
  130. package/ccw/frontend/dist/assets/{index-B8K8MdMl.js.map → index-DP_mTJI8.js.map} +1 -1
  131. package/ccw/frontend/dist/assets/{index-Dpe_7YH0.js → index-MkgdhX7a.js} +2 -2
  132. package/ccw/frontend/dist/assets/{index-Dpe_7YH0.js.map → index-MkgdhX7a.js.map} +1 -1
  133. package/ccw/frontend/dist/assets/{index-4zmlzlPo.js → index-ni-tG9rm.js} +2 -2
  134. package/ccw/frontend/dist/assets/{index-4zmlzlPo.js.map → index-ni-tG9rm.js.map} +1 -1
  135. package/ccw/frontend/dist/assets/{layout-grid-CUqTukRt.js → layout-grid-11E4bGJz.js} +2 -2
  136. package/ccw/frontend/dist/assets/{layout-grid-CUqTukRt.js.map → layout-grid-11E4bGJz.js.map} +1 -1
  137. package/ccw/frontend/dist/assets/{lightbulb-h90ex0mh.js → lightbulb-8KrKY82b.js} +2 -2
  138. package/ccw/frontend/dist/assets/{lightbulb-h90ex0mh.js.map → lightbulb-8KrKY82b.js.map} +1 -1
  139. package/ccw/frontend/dist/assets/{link-2-1-DjXqTg.js → link-2-BUn6RILb.js} +2 -2
  140. package/ccw/frontend/dist/assets/{link-2-1-DjXqTg.js.map → link-2-BUn6RILb.js.map} +1 -1
  141. package/ccw/frontend/dist/assets/{link-DbyJpuls.js → link-CmP254Ai.js} +2 -2
  142. package/ccw/frontend/dist/assets/{link-DbyJpuls.js.map → link-CmP254Ai.js.map} +1 -1
  143. package/ccw/frontend/dist/assets/{list-CU0leArg.js → list-BAwzl4a2.js} +2 -2
  144. package/ccw/frontend/dist/assets/{list-CU0leArg.js.map → list-BAwzl4a2.js.map} +1 -1
  145. package/ccw/frontend/dist/assets/{map-pin-DheJ6EJB.js → map-pin-gi342rqk.js} +2 -2
  146. package/ccw/frontend/dist/assets/{map-pin-DheJ6EJB.js.map → map-pin-gi342rqk.js.map} +1 -1
  147. package/ccw/frontend/dist/assets/{messages-square-Bmo5DCr1.js → messages-square-C1Lh8q8b.js} +2 -2
  148. package/ccw/frontend/dist/assets/{messages-square-Bmo5DCr1.js.map → messages-square-C1Lh8q8b.js.map} +1 -1
  149. package/ccw/frontend/dist/assets/{minimize-2-h1gktUQ6.js → minimize-2-OgWNLKdq.js} +2 -2
  150. package/ccw/frontend/dist/assets/{minimize-2-h1gktUQ6.js.map → minimize-2-OgWNLKdq.js.map} +1 -1
  151. package/ccw/frontend/dist/assets/{package-CmuCX6Z_.js → package-Djsvs5qp.js} +2 -2
  152. package/ccw/frontend/dist/assets/{package-CmuCX6Z_.js.map → package-Djsvs5qp.js.map} +1 -1
  153. package/ccw/frontend/dist/assets/{plug-Jz5HaKIu.js → plug-DvSZP2cp.js} +2 -2
  154. package/ccw/frontend/dist/assets/{plug-Jz5HaKIu.js.map → plug-DvSZP2cp.js.map} +1 -1
  155. package/ccw/frontend/dist/assets/{power-CpN5I4BU.js → power-BY7vTLmU.js} +2 -2
  156. package/ccw/frontend/dist/assets/{power-CpN5I4BU.js.map → power-BY7vTLmU.js.map} +1 -1
  157. package/ccw/frontend/dist/assets/{save-B3iyK-h8.js → save-DXfqv84T.js} +2 -2
  158. package/ccw/frontend/dist/assets/{save-B3iyK-h8.js.map → save-DXfqv84T.js.map} +1 -1
  159. package/ccw/frontend/dist/assets/{send-CYO-YU9A.js → send-E2o2LZSX.js} +2 -2
  160. package/ccw/frontend/dist/assets/{send-CYO-YU9A.js.map → send-E2o2LZSX.js.map} +1 -1
  161. package/ccw/frontend/dist/assets/settings-2-ChD1LFHH.js +7 -0
  162. package/ccw/frontend/dist/assets/settings-2-ChD1LFHH.js.map +1 -0
  163. package/ccw/frontend/dist/assets/{square-check-big-1h37S4wz.js → square-check-big-CBymuqmD.js} +2 -2
  164. package/ccw/frontend/dist/assets/{square-check-big-1h37S4wz.js.map → square-check-big-CBymuqmD.js.map} +1 -1
  165. package/ccw/frontend/dist/assets/{square-pen-BS0-oO7y.js → square-pen-BfaiJgOX.js} +2 -2
  166. package/ccw/frontend/dist/assets/{square-pen-BS0-oO7y.js.map → square-pen-BfaiJgOX.js.map} +1 -1
  167. package/ccw/frontend/dist/assets/{star-Dal-o3Lo.js → star-DHMWqZ09.js} +2 -2
  168. package/ccw/frontend/dist/assets/{star-Dal-o3Lo.js.map → star-DHMWqZ09.js.map} +1 -1
  169. package/ccw/frontend/dist/assets/{style-wEWj0pe8.js → style-wvcOEAiM.js} +2 -2
  170. package/ccw/frontend/dist/assets/{style-wEWj0pe8.js.map → style-wvcOEAiM.js.map} +1 -1
  171. package/ccw/frontend/dist/assets/{target-BB9AJiC7.js → target-B8AMmf_N.js} +2 -2
  172. package/ccw/frontend/dist/assets/{target-BB9AJiC7.js.map → target-B8AMmf_N.js.map} +1 -1
  173. package/ccw/frontend/dist/assets/{test-tube-DDnQZrAm.js → test-tube-BpDeTJi1.js} +2 -2
  174. package/ccw/frontend/dist/assets/{test-tube-DDnQZrAm.js.map → test-tube-BpDeTJi1.js.map} +1 -1
  175. package/ccw/frontend/dist/assets/{upload-DshzYJC_.js → upload-pflkdIDG.js} +2 -2
  176. package/ccw/frontend/dist/assets/{upload-DshzYJC_.js.map → upload-pflkdIDG.js.map} +1 -1
  177. package/ccw/frontend/dist/assets/{useApiSettings-DkV-yWup.js → useApiSettings-BPx4DyKT.js} +2 -2
  178. package/ccw/frontend/dist/assets/{useApiSettings-DkV-yWup.js.map → useApiSettings-BPx4DyKT.js.map} +1 -1
  179. package/ccw/frontend/dist/assets/{useCli-CnwgIkqD.js → useCli-D1jfH3XA.js} +2 -2
  180. package/ccw/frontend/dist/assets/{useCli-CnwgIkqD.js.map → useCli-D1jfH3XA.js.map} +1 -1
  181. package/ccw/frontend/dist/assets/{useCommands-S0sc5bfK.js → useCommands-DhR71vpa.js} +2 -2
  182. package/ccw/frontend/dist/assets/{useCommands-S0sc5bfK.js.map → useCommands-DhR71vpa.js.map} +1 -1
  183. package/ccw/frontend/dist/assets/{useDebounce-HxG5rpQo.js → useDebounce-a6Yyer3m.js} +2 -2
  184. package/ccw/frontend/dist/assets/{useDebounce-HxG5rpQo.js.map → useDebounce-a6Yyer3m.js.map} +1 -1
  185. package/ccw/frontend/dist/assets/{useFileExplorer-CTg0zndf.js → useFileExplorer-B8W2JTj2.js} +2 -2
  186. package/ccw/frontend/dist/assets/{useFileExplorer-CTg0zndf.js.map → useFileExplorer-B8W2JTj2.js.map} +1 -1
  187. package/ccw/frontend/dist/assets/{useLocale-C2BlVToA.js → useLocale-aMHdQIL_.js} +2 -2
  188. package/ccw/frontend/dist/assets/{useLocale-C2BlVToA.js.map → useLocale-aMHdQIL_.js.map} +1 -1
  189. package/ccw/frontend/dist/assets/{useSkills-8IWJgwQU.js → useSkills-BHpc2LtN.js} +3 -3
  190. package/ccw/frontend/dist/assets/{useSkills-8IWJgwQU.js.map → useSkills-BHpc2LtN.js.map} +1 -1
  191. package/ccw/frontend/dist/assets/{useSystemSettings-BAtCCf8T.js → useSystemSettings-BFD0SvEF.js} +2 -2
  192. package/ccw/frontend/dist/assets/{useSystemSettings-BAtCCf8T.js.map → useSystemSettings-BFD0SvEF.js.map} +1 -1
  193. package/ccw/frontend/dist/assets/{wand-sparkles-CI1Tfudg.js → wand-sparkles-dYtI2IKM.js} +2 -2
  194. package/ccw/frontend/dist/assets/{wand-sparkles-CI1Tfudg.js.map → wand-sparkles-dYtI2IKM.js.map} +1 -1
  195. package/ccw/frontend/dist/index.html +2 -2
  196. package/package.json +1 -1
  197. package/ccw/frontend/dist/assets/LiteTasksPage-BOknokuo.js.map +0 -1
  198. package/ccw/frontend/dist/assets/SettingsPage-DJltvfrs.js +0 -144
  199. package/ccw/frontend/dist/assets/SettingsPage-DJltvfrs.js.map +0 -1
  200. package/ccw/frontend/dist/assets/index-D6YeIKg_.css +0 -39
@@ -1 +1 @@
1
- {"version":3,"file":"PromptHistoryPage-B--0N_wr.js","sources":["../../../../node_modules/lucide-react/dist/esm/icons/file-type.js","../../../../node_modules/lucide-react/dist/esm/icons/minus.js","../../../../node_modules/lucide-react/dist/esm/icons/trending-down.js","../../../../node_modules/lucide-react/dist/esm/icons/trending-up.js","../../src/components/shared/StatCard.tsx","../../src/components/shared/QualityBadge.tsx","../../src/components/shared/PromptCard.tsx","../../src/components/shared/InsightsPanel.tsx","../../src/components/shared/PromptStats.tsx","../../src/hooks/usePromptHistory.ts","../../src/components/shared/BatchOperationToolbar.tsx","../../src/components/shared/InsightsHistoryList.tsx","../../src/components/shared/InsightDetailPanel.tsx","../../src/pages/PromptHistoryPage.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileType = createLucideIcon(\"FileType\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"path\", { d: \"M9 13v-1h6v1\", key: \"1bb014\" }],\n [\"path\", { d: \"M12 12v6\", key: \"3ahymv\" }],\n [\"path\", { d: \"M11 18h2\", key: \"12mj7e\" }]\n]);\n\nexport { FileType as default };\n//# sourceMappingURL=file-type.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Minus = createLucideIcon(\"Minus\", [[\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }]]);\n\nexport { Minus as default };\n//# sourceMappingURL=minus.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst TrendingDown = createLucideIcon(\"TrendingDown\", [\n [\"polyline\", { points: \"22 17 13.5 8.5 8.5 13.5 2 7\", key: \"1r2t7k\" }],\n [\"polyline\", { points: \"16 17 22 17 22 11\", key: \"11uiuu\" }]\n]);\n\nexport { TrendingDown as default };\n//# sourceMappingURL=trending-down.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst TrendingUp = createLucideIcon(\"TrendingUp\", [\n [\"polyline\", { points: \"22 7 13.5 15.5 8.5 10.5 2 17\", key: \"126l90\" }],\n [\"polyline\", { points: \"16 7 22 7 22 13\", key: \"kwv8wd\" }]\n]);\n\nexport { TrendingUp as default };\n//# sourceMappingURL=trending-up.js.map\n","// ========================================\r\n// StatCard Component\r\n// ========================================\r\n// Reusable stat card for dashboard metrics\r\n\r\nimport * as React from 'react';\r\nimport { cva, type VariantProps } from 'class-variance-authority';\r\nimport { cn } from '@/lib/utils';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { TrendingUp, TrendingDown, Minus, type LucideIcon } from 'lucide-react';\r\nimport { Sparkline } from '@/components/charts/Sparkline';\r\n\r\nconst statCardVariants = cva(\r\n 'transition-all duration-200 hover:shadow-md hover-glow',\r\n {\r\n variants: {\r\n variant: {\r\n default: 'border-border',\r\n primary: 'border-primary/30 bg-primary/5',\r\n success: 'border-success/30 bg-success/5',\r\n warning: 'border-warning/30 bg-warning/5',\r\n danger: 'border-destructive/30 bg-destructive/5',\r\n info: 'border-info/30 bg-info/5',\r\n },\r\n },\r\n defaultVariants: {\r\n variant: 'default',\r\n },\r\n }\r\n);\r\n\r\nconst iconContainerVariants = cva(\r\n 'flex h-10 w-10 items-center justify-center rounded-lg',\r\n {\r\n variants: {\r\n variant: {\r\n default: 'bg-muted text-muted-foreground',\r\n primary: 'bg-primary/10 text-primary',\r\n success: 'bg-success/10 text-success',\r\n warning: 'bg-warning/10 text-warning',\r\n danger: 'bg-destructive/10 text-destructive',\r\n info: 'bg-info/10 text-info',\r\n },\r\n },\r\n defaultVariants: {\r\n variant: 'default',\r\n },\r\n }\r\n);\r\n\r\nexport interface StatCardProps\r\n extends React.HTMLAttributes<HTMLDivElement>,\r\n VariantProps<typeof statCardVariants> {\r\n /** Card title */\r\n title: string;\r\n /** Stat value to display */\r\n value: number | string;\r\n /** Optional icon component */\r\n icon?: LucideIcon;\r\n /** Optional trend direction */\r\n trend?: 'up' | 'down' | 'neutral';\r\n /** Optional trend value (e.g., \"+12%\") */\r\n trendValue?: string;\r\n /** Loading state */\r\n isLoading?: boolean;\r\n /** Optional description */\r\n description?: string;\r\n /** Optional sparkline data (e.g., last 7 days) */\r\n sparklineData?: number[];\r\n /** Whether to show sparkline */\r\n showSparkline?: boolean;\r\n}\r\n\r\n/**\r\n * StatCard component for displaying dashboard metrics\r\n *\r\n * @example\r\n * ```tsx\r\n * <StatCard\r\n * title=\"Total Sessions\"\r\n * value={42}\r\n * icon={FolderIcon}\r\n * variant=\"primary\"\r\n * trend=\"up\"\r\n * trendValue=\"+5\"\r\n * />\r\n * ```\r\n */\r\nexport function StatCard({\r\n className,\r\n variant,\r\n title,\r\n value,\r\n icon: Icon,\r\n trend,\r\n trendValue,\r\n isLoading = false,\r\n description,\r\n sparklineData,\r\n showSparkline = false,\r\n ...props\r\n}: StatCardProps) {\r\n const TrendIcon = trend === 'up' ? TrendingUp : trend === 'down' ? TrendingDown : Minus;\r\n const trendColor =\r\n trend === 'up'\r\n ? 'text-success'\r\n : trend === 'down'\r\n ? 'text-destructive'\r\n : 'text-muted-foreground';\r\n\r\n return (\r\n <Card className={cn(statCardVariants({ variant }), className)} {...props}>\r\n <CardContent className=\"p-4\">\r\n <div className=\"flex items-start justify-between\">\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"text-sm font-medium text-muted-foreground truncate\">\r\n {title}\r\n </p>\r\n <div className=\"mt-2 flex items-baseline gap-2\">\r\n {isLoading ? (\r\n <div className=\"h-8 w-16 animate-pulse rounded bg-muted\" />\r\n ) : (\r\n <p className=\"text-2xl font-semibold text-card-foreground\">\r\n {typeof value === 'number' ? value.toLocaleString() : value}\r\n </p>\r\n )}\r\n {trend && trendValue && !isLoading && (\r\n <span className={cn('flex items-center text-xs font-medium', trendColor)}>\r\n <TrendIcon className=\"mr-0.5 h-3 w-3\" />\r\n {trendValue}\r\n </span>\r\n )}\r\n </div>\r\n {description && (\r\n <p className=\"mt-1 text-xs text-muted-foreground truncate\">\r\n {description}\r\n </p>\r\n )}\r\n {showSparkline && sparklineData && sparklineData.length > 0 && (\r\n <div className=\"mt-3 -mx-2\">\r\n <Sparkline\r\n data={sparklineData}\r\n height={40}\r\n strokeWidth={2}\r\n />\r\n </div>\r\n )}\r\n </div>\r\n {Icon && (\r\n <div className={cn(iconContainerVariants({ variant }))}>\r\n <Icon className=\"h-5 w-5\" />\r\n </div>\r\n )}\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n\r\n/**\r\n * Skeleton loader for StatCard\r\n */\r\nexport function StatCardSkeleton({ className }: { className?: string }) {\r\n return (\r\n <Card className={cn('animate-pulse', className)}>\r\n <CardContent className=\"p-4\">\r\n <div className=\"flex items-start justify-between\">\r\n <div className=\"flex-1\">\r\n <div className=\"h-4 w-20 rounded bg-muted\" />\r\n <div className=\"mt-3 h-8 w-16 rounded bg-muted\" />\r\n </div>\r\n <div className=\"h-10 w-10 rounded-lg bg-muted\" />\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n","// ========================================\n// QualityBadge Component\n// ========================================\n// Badge component for displaying prompt quality score\n\nimport { useIntl } from 'react-intl';\nimport { Badge } from '@/components/ui/Badge';\nimport type { Prompt } from '@/types/store';\n\nexport interface QualityBadgeProps {\n /** Quality score (0-100) */\n qualityScore?: number;\n /** Optional className */\n className?: string;\n}\n\n/**\n * Get quality level from score\n */\nfunction getQualityLevel(score?: number): 'high' | 'medium' | 'low' | 'none' {\n if (score === undefined || score === null) return 'none';\n if (score >= 80) return 'high';\n if (score >= 60) return 'medium';\n return 'low';\n}\n\n/**\n * Get badge variant for quality level\n */\nfunction getBadgeVariant(level: 'high' | 'medium' | 'low' | 'none'): 'success' | 'warning' | 'secondary' | 'outline' {\n switch (level) {\n case 'high':\n return 'success';\n case 'medium':\n return 'warning';\n case 'low':\n return 'secondary';\n default:\n return 'outline';\n }\n}\n\n/**\n * QualityBadge component - displays prompt quality score with color coding\n *\n * Quality levels:\n * - High (>=80): Green badge\n * - Medium (>=60): Yellow badge\n * - Low (<60): Gray badge\n * - No score: Outline badge\n */\nexport function QualityBadge({ qualityScore, className }: QualityBadgeProps) {\n const { formatMessage } = useIntl();\n const level = getQualityLevel(qualityScore);\n const variant = getBadgeVariant(level);\n\n const labelKey = `prompts.quality.${level}`;\n const label = formatMessage({ id: labelKey });\n\n if (level === 'none') {\n return null;\n }\n\n return (\n <Badge variant={variant} className={className}>\n {qualityScore !== undefined && `${qualityScore} `}\n {label}\n </Badge>\n );\n}\n\n/**\n * Hook to get quality badge data for a prompt\n */\nexport function useQualityBadge(prompt: Prompt) {\n const qualityScore = prompt.quality_score;\n const level = getQualityLevel(qualityScore);\n const variant = getBadgeVariant(level);\n\n return {\n qualityScore,\n level,\n variant,\n hasQuality: qualityScore !== undefined && qualityScore !== null,\n };\n}\n\nexport default QualityBadge;\n","// ========================================\n// PromptCard Component\n// ========================================\n// Card component for displaying prompt history items\n\nimport * as React from 'react';\nimport { useIntl } from 'react-intl';\nimport { cn } from '@/lib/utils';\nimport { Card, CardContent, CardHeader } from '@/components/ui/Card';\nimport { Badge } from '@/components/ui/Badge';\nimport { Button } from '@/components/ui/Button';\nimport { Checkbox } from '@/components/ui/Checkbox';\nimport { QualityBadge } from '@/components/shared/QualityBadge';\nimport {\n Copy,\n Trash2,\n ChevronDown,\n ChevronUp,\n Clock,\n Tag,\n Calendar,\n} from 'lucide-react';\nimport type { Prompt } from '@/types/store';\n\nexport interface PromptCardProps {\n /** Prompt data */\n prompt: Prompt;\n /** Called when delete action is triggered */\n onDelete?: (id: string) => void;\n /** Optional className */\n className?: string;\n /** Disabled state for actions */\n actionsDisabled?: boolean;\n /** Default expanded state */\n defaultExpanded?: boolean;\n /** Selection state for batch operations */\n selected?: boolean;\n /** Called when selection state changes */\n onSelectChange?: (id: string, selected: boolean) => void;\n /** Whether selection mode is active */\n selectionMode?: boolean;\n}\n\n/**\n * Format date to readable string\n */\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString);\n return date.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\n/**\n * Format content length\n */\nfunction formatContentLength(length: number): string {\n if (length >= 1000) {\n return `${(length / 1000).toFixed(1)}k chars`;\n }\n return `${length} chars`;\n}\n\n/**\n * PromptCard component for displaying prompt history items\n */\nexport function PromptCard({\n prompt,\n onDelete,\n className,\n actionsDisabled = false,\n defaultExpanded = false,\n selected = false,\n onSelectChange,\n selectionMode = false,\n}: PromptCardProps) {\n const { formatMessage } = useIntl();\n const [expanded, setExpanded] = React.useState(defaultExpanded);\n const [copied, setCopied] = React.useState(false);\n\n const handleCopy = async (e: React.MouseEvent) => {\n e.stopPropagation();\n try {\n await navigator.clipboard.writeText(prompt.content);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch {\n console.error('Failed to copy prompt');\n }\n };\n\n const handleDelete = (e: React.MouseEvent) => {\n e.stopPropagation();\n onDelete?.(prompt.id);\n };\n\n const toggleExpanded = () => {\n setExpanded((prev) => !prev);\n };\n\n const handleSelectionChange = (checked: boolean) => {\n onSelectChange?.(prompt.id, checked);\n };\n\n const handleCardClick = (e: React.MouseEvent) => {\n if (selectionMode && (e.target as HTMLElement).closest('.prompt-card-checkbox')) {\n return;\n }\n if (selectionMode) {\n handleSelectionChange(!selected);\n }\n };\n\n return (\n <Card\n className={cn(\n 'transition-all duration-200',\n selected && 'ring-2 ring-primary',\n selectionMode && 'cursor-pointer',\n className\n )}\n onClick={handleCardClick}\n >\n <CardHeader className=\"p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n {/* Checkbox for selection mode */}\n {selectionMode && (\n <div className=\"prompt-card-checkbox\">\n <Checkbox\n checked={selected}\n onCheckedChange={handleSelectionChange}\n className=\"mt-1\"\n />\n </div>\n )}\n\n {/* Title and metadata */}\n <div className={cn('flex-1 min-w-0', !selectionMode && 'ml-0')}>\n <div className=\"flex items-center gap-2 mb-2\">\n <h3 className=\"text-sm font-medium text-foreground truncate\">\n {prompt.title || formatMessage({ id: 'prompts.card.untitled' })}\n </h3>\n {prompt.category && (\n <Badge variant=\"secondary\" className=\"text-xs\">\n {prompt.category}\n </Badge>\n )}\n <QualityBadge qualityScore={prompt.quality_score} className=\"text-xs\" />\n </div>\n\n {/* Metadata */}\n <div className=\"flex flex-wrap items-center gap-3 text-xs text-muted-foreground\">\n <span className=\"flex items-center gap-1\">\n <Calendar className=\"h-3 w-3\" />\n {formatDate(prompt.createdAt)}\n </span>\n <span className=\"flex items-center gap-1\">\n <Tag className=\"h-3 w-3\" />\n {formatContentLength(prompt.content.length)}\n </span>\n {prompt.useCount !== undefined && prompt.useCount > 0 && (\n <span className=\"flex items-center gap-1\">\n <Clock className=\"h-3 w-3\" />\n {formatMessage({ id: 'prompts.card.used' }, { count: prompt.useCount })}\n </span>\n )}\n </div>\n\n {/* Tags */}\n {prompt.tags && prompt.tags.length > 0 && (\n <div className=\"flex flex-wrap gap-1 mt-2\">\n {prompt.tags.slice(0, 3).map((tag) => (\n <Badge key={tag} variant=\"outline\" className=\"text-xs\">\n {tag}\n </Badge>\n ))}\n {prompt.tags.length > 3 && (\n <Badge variant=\"outline\" className=\"text-xs\">\n +{prompt.tags.length - 3}\n </Badge>\n )}\n </div>\n )}\n </div>\n\n {/* Actions */}\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={handleCopy}\n disabled={actionsDisabled}\n title={formatMessage({ id: 'prompts.actions.copy' })}\n >\n <Copy className=\"h-4 w-4\" />\n <span className=\"sr-only\">{formatMessage({ id: 'prompts.actions.copy' })}</span>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-destructive hover:text-destructive\"\n onClick={handleDelete}\n disabled={actionsDisabled}\n title={formatMessage({ id: 'prompts.actions.delete' })}\n >\n <Trash2 className=\"h-4 w-4\" />\n <span className=\"sr-only\">{formatMessage({ id: 'prompts.actions.delete' })}</span>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={toggleExpanded}\n title={expanded ? formatMessage({ id: 'prompts.actions.collapse' }) : formatMessage({ id: 'prompts.actions.expand' })}\n >\n {expanded ? <ChevronUp className=\"h-4 w-4\" /> : <ChevronDown className=\"h-4 w-4\" />}\n <span className=\"sr-only\">{expanded ? 'Collapse' : 'Expand'}</span>\n </Button>\n </div>\n </div>\n\n {copied && (\n <p className=\"text-xs text-success mt-2\">\n {formatMessage({ id: 'prompts.actions.copied' })}\n </p>\n )}\n </CardHeader>\n\n {/* Expanded content */}\n {expanded && (\n <CardContent className=\"px-4 pb-4 pt-0\">\n <div className=\"rounded-lg bg-muted/50 p-3\">\n <pre className=\"text-sm whitespace-pre-wrap break-words text-foreground\">\n {prompt.content}\n </pre>\n </div>\n </CardContent>\n )}\n </Card>\n );\n}\n\nexport default PromptCard;\n","// ========================================\n// InsightsPanel Component\n// ========================================\n// AI insights panel for prompt history analysis\n\nimport { useIntl } from 'react-intl';\nimport { cn } from '@/lib/utils';\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card';\nimport { Badge } from '@/components/ui/Badge';\nimport { Button } from '@/components/ui/Button';\nimport {\n Sparkles,\n AlertTriangle,\n Lightbulb,\n Wand2,\n Loader2,\n RefreshCw,\n} from 'lucide-react';\nimport type { PromptInsight, Pattern, Suggestion } from '@/types/store';\n\nexport interface InsightsPanelProps {\n /** Available insights */\n insights?: PromptInsight[];\n /** Detected patterns */\n patterns?: Pattern[];\n /** AI suggestions */\n suggestions?: Suggestion[];\n /** Currently selected tool */\n selectedTool: 'gemini' | 'qwen' | 'codex';\n /** Called when tool selection changes */\n onToolChange: (tool: 'gemini' | 'qwen' | 'codex') => void;\n /** Called when analyze is triggered */\n onAnalyze: () => void;\n /** Loading state */\n isAnalyzing?: boolean;\n /** Optional className */\n className?: string;\n}\n\nconst toolConfig = {\n gemini: {\n label: 'Gemini',\n color: 'text-blue-500',\n bgColor: 'bg-blue-500/10',\n },\n qwen: {\n label: 'Qwen',\n color: 'text-purple-500',\n bgColor: 'bg-purple-500/10',\n },\n codex: {\n label: 'Codex',\n color: 'text-green-500',\n bgColor: 'bg-green-500/10',\n },\n};\n\n/**\n * InsightCard component for displaying a single insight\n */\nfunction InsightCard({ insight }: { insight: PromptInsight }) {\n const { formatMessage } = useIntl();\n\n const typeConfig = {\n suggestion: {\n icon: Lightbulb,\n variant: 'info' as const,\n color: 'text-blue-500',\n },\n optimization: {\n icon: Sparkles,\n variant: 'success' as const,\n color: 'text-green-500',\n },\n warning: {\n icon: AlertTriangle,\n variant: 'warning' as const,\n color: 'text-orange-500',\n },\n };\n\n const config = typeConfig[insight.type];\n const Icon = config.icon;\n\n return (\n <div className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50\">\n <div className={cn('flex-shrink-0', config.color)}>\n <Icon className=\"h-4 w-4\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm text-foreground\">{insight.content}</p>\n <div className=\"flex items-center gap-2 mt-1\">\n <Badge variant=\"outline\" className=\"text-xs\">\n {Math.round(insight.confidence * 100)}% {formatMessage({ id: 'prompts.insights.confidence' })}\n </Badge>\n </div>\n </div>\n </div>\n );\n}\n\n/**\n * PatternCard component for displaying a detected pattern\n */\nfunction PatternCard({ pattern }: { pattern: Pattern }) {\n return (\n <div className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50\">\n <div className=\"flex-shrink-0 text-purple-500\">\n <Wand2 className=\"h-4 w-4\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-foreground\">{pattern.name}</p>\n <p className=\"text-xs text-muted-foreground mt-1\">{pattern.description}</p>\n {pattern.example && (\n <code className=\"block mt-2 text-xs bg-background rounded p-2 overflow-x-auto\">\n {pattern.example}\n </code>\n )}\n {pattern.severity && (\n <Badge variant={pattern.severity === 'error' ? 'destructive' : pattern.severity === 'warning' ? 'warning' : 'secondary'} className=\"mt-2 text-xs\">\n {pattern.severity}\n </Badge>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * SuggestionCard component for displaying a suggestion\n */\nfunction SuggestionCard({ suggestion }: { suggestion: Suggestion }) {\n const { formatMessage } = useIntl();\n\n const typeConfig = {\n refactor: { color: 'text-blue-500', label: formatMessage({ id: 'prompts.suggestions.types.refactor' }) },\n optimize: { color: 'text-green-500', label: formatMessage({ id: 'prompts.suggestions.types.optimize' }) },\n fix: { color: 'text-orange-500', label: formatMessage({ id: 'prompts.suggestions.types.fix' }) },\n document: { color: 'text-purple-500', label: formatMessage({ id: 'prompts.suggestions.types.document' }) },\n };\n\n const config = typeConfig[suggestion.type];\n\n return (\n <div className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50\">\n <div className={cn('flex-shrink-0', config.color)}>\n <Lightbulb className=\"h-4 w-4\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <p className=\"text-sm font-medium text-foreground\">{suggestion.title}</p>\n <Badge variant=\"outline\" className=\"text-xs\">\n {config.label}\n </Badge>\n </div>\n <p className=\"text-xs text-muted-foreground mt-1\">{suggestion.description}</p>\n {suggestion.code && (\n <code className=\"block mt-2 text-xs bg-background rounded p-2 overflow-x-auto\">\n {suggestion.code}\n </code>\n )}\n {suggestion.effort && (\n <Badge variant=\"secondary\" className=\"mt-2 text-xs\">\n {formatMessage({ id: 'prompts.suggestions.effort' })}: {suggestion.effort}\n </Badge>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * InsightsPanel component - AI analysis panel for prompt history\n */\nexport function InsightsPanel({\n insights = [],\n patterns = [],\n suggestions = [],\n selectedTool,\n onToolChange,\n onAnalyze,\n isAnalyzing = false,\n className,\n}: InsightsPanelProps) {\n const { formatMessage } = useIntl();\n\n const hasContent = insights.length > 0 || patterns.length > 0 || suggestions.length > 0;\n\n return (\n <Card className={cn('flex flex-col h-full', className)}>\n <CardHeader className=\"pb-3\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-lg flex items-center gap-2\">\n <Sparkles className=\"h-5 w-5 text-primary\" />\n {formatMessage({ id: 'prompts.insights.title' })}\n </CardTitle>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => onAnalyze()}\n disabled={isAnalyzing}\n className=\"gap-2\"\n >\n {isAnalyzing ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <RefreshCw className=\"h-4 w-4\" />\n )}\n {formatMessage({ id: 'prompts.insights.analyze' })}\n </Button>\n </div>\n\n {/* Tool selector */}\n <div className=\"flex items-center gap-2 mt-3\">\n <span className=\"text-sm text-muted-foreground\">\n {formatMessage({ id: 'prompts.insights.selectTool' })}:\n </span>\n <div className=\"flex gap-1\">\n {(Object.keys(toolConfig) as Array<keyof typeof toolConfig>).map((tool) => (\n <button\n key={tool}\n onClick={() => onToolChange(tool)}\n className={cn(\n 'px-3 py-1.5 rounded-md text-sm font-medium transition-colors',\n selectedTool === tool\n ? cn(toolConfig[tool].bgColor, toolConfig[tool].color)\n : 'bg-muted text-muted-foreground hover:bg-muted/80'\n )}\n >\n {toolConfig[tool].label}\n </button>\n ))}\n </div>\n </div>\n </CardHeader>\n\n <CardContent className=\"flex-1 overflow-y-auto\">\n {!hasContent && !isAnalyzing ? (\n <div className=\"flex flex-col items-center justify-center py-12 px-4 text-center\">\n <Sparkles className=\"h-12 w-12 text-muted-foreground/50 mb-4\" />\n <h3 className=\"text-sm font-medium text-foreground mb-1\">\n {formatMessage({ id: 'prompts.insights.empty.title' })}\n </h3>\n <p className=\"text-xs text-muted-foreground max-w-sm\">\n {formatMessage({ id: 'prompts.insights.empty.message' })}\n </p>\n </div>\n ) : (\n <div className=\"space-y-4\">\n {/* Insights section */}\n {insights.length > 0 && (\n <div>\n <h4 className=\"text-sm font-medium text-foreground mb-2 flex items-center gap-2\">\n <Lightbulb className=\"h-4 w-4\" />\n {formatMessage({ id: 'prompts.insights.sections.insights' })}\n </h4>\n <div className=\"space-y-2\">\n {insights.map((insight) => (\n <InsightCard key={insight.id} insight={insight} />\n ))}\n </div>\n </div>\n )}\n\n {/* Patterns section */}\n {patterns.length > 0 && (\n <div>\n <h4 className=\"text-sm font-medium text-foreground mb-2 flex items-center gap-2\">\n <Wand2 className=\"h-4 w-4\" />\n {formatMessage({ id: 'prompts.insights.sections.patterns' })}\n </h4>\n <div className=\"space-y-2\">\n {patterns.map((pattern) => (\n <PatternCard key={pattern.id} pattern={pattern} />\n ))}\n </div>\n </div>\n )}\n\n {/* Suggestions section */}\n {suggestions.length > 0 && (\n <div>\n <h4 className=\"text-sm font-medium text-foreground mb-2 flex items-center gap-2\">\n <Sparkles className=\"h-4 w-4\" />\n {formatMessage({ id: 'prompts.insights.sections.suggestions' })}\n </h4>\n <div className=\"space-y-2\">\n {suggestions.map((suggestion) => (\n <SuggestionCard key={suggestion.id} suggestion={suggestion} />\n ))}\n </div>\n </div>\n )}\n\n {isAnalyzing && (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"h-6 w-6 animate-spin text-muted-foreground\" />\n <span className=\"ml-2 text-sm text-muted-foreground\">\n {formatMessage({ id: 'prompts.insights.analyzing' })}\n </span>\n </div>\n )}\n </div>\n )}\n </CardContent>\n </Card>\n );\n}\n\nexport default InsightsPanel;\n","// ========================================\n// PromptStats Component\n// ========================================\n// Statistics display for prompt history\n\nimport { useIntl } from 'react-intl';\nimport { StatCard, StatCardSkeleton } from '@/components/shared/StatCard';\nimport { MessageSquare, FileType, Hash, Star } from 'lucide-react';\n\nexport interface QualityDistribution {\n high: number;\n medium: number;\n low: number;\n}\n\nexport interface PromptStatsProps {\n /** Total number of prompts */\n totalCount: number;\n /** Average prompt length in characters */\n avgLength: number;\n /** Most common intent/category */\n topIntent: string | null;\n /** Average quality score (0-100) */\n avgQualityScore?: number;\n /** Quality distribution */\n qualityDistribution?: QualityDistribution;\n /** Loading state */\n isLoading?: boolean;\n}\n\n/**\n * PromptStats component - displays prompt history statistics\n *\n * Shows four key metrics:\n * - Total prompts: overall count of stored prompts\n * - Average length: mean character count across all prompts\n * - Top intent: most frequently used category\n * - Quality: average quality score with distribution\n */\nexport function PromptStats({\n totalCount,\n avgLength,\n topIntent,\n avgQualityScore,\n qualityDistribution,\n isLoading = false,\n}: PromptStatsProps) {\n const { formatMessage } = useIntl();\n\n // Format average length for display\n const formatLength = (length: number): string => {\n if (length >= 1000) {\n return `${(length / 1000).toFixed(1)}k`;\n }\n return length.toString();\n };\n\n return (\n <div className=\"grid gap-4 grid-cols-1 md:grid-cols-4\">\n <StatCard\n title={formatMessage({ id: 'prompts.stats.totalCount' })}\n value={totalCount}\n icon={MessageSquare}\n variant=\"primary\"\n isLoading={isLoading}\n description={formatMessage({ id: 'prompts.stats.totalCountDesc' })}\n />\n <StatCard\n title={formatMessage({ id: 'prompts.stats.avgLength' })}\n value={formatLength(avgLength)}\n icon={FileType}\n variant=\"info\"\n isLoading={isLoading}\n description={formatMessage({ id: 'prompts.stats.avgLengthDesc' })}\n />\n <StatCard\n title={formatMessage({ id: 'prompts.stats.topIntent' })}\n value={topIntent || formatMessage({ id: 'prompts.stats.noIntent' })}\n icon={Hash}\n variant=\"success\"\n isLoading={isLoading}\n description={formatMessage({ id: 'prompts.stats.topIntentDesc' })}\n />\n <StatCard\n title={formatMessage({ id: 'prompts.stats.avgQuality' })}\n value={avgQualityScore !== undefined ? Math.round(avgQualityScore) : 'N/A'}\n icon={Star}\n variant=\"warning\"\n isLoading={isLoading}\n description={qualityDistribution\n ? `${formatMessage({ id: 'prompts.quality.high' })}: ${qualityDistribution.high} | ${formatMessage({ id: 'prompts.quality.medium' })}: ${qualityDistribution.medium} | ${formatMessage({ id: 'prompts.quality.low' })}: ${qualityDistribution.low}`\n : formatMessage({ id: 'prompts.stats.avgQualityDesc' })\n }\n />\n </div>\n );\n}\n\n/**\n * Skeleton loader for PromptStats\n */\nexport function PromptStatsSkeleton() {\n return (\n <div className=\"grid gap-4 grid-cols-1 md:grid-cols-4\">\n <StatCardSkeleton />\n <StatCardSkeleton />\n <StatCardSkeleton />\n <StatCardSkeleton />\n </div>\n );\n}\n\nexport default PromptStats;\n","// ========================================\r\n// usePromptHistory Hook\r\n// ========================================\r\n// TanStack Query hooks for prompt history with real-time updates\r\n\r\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport {\r\n fetchPrompts,\r\n fetchPromptInsights,\r\n fetchInsightsHistory,\r\n analyzePrompts,\r\n deletePrompt,\r\n batchDeletePrompts,\r\n deleteInsight,\r\n type Prompt,\r\n type PromptsResponse,\r\n type PromptInsightsResponse,\r\n type InsightsHistoryResponse,\r\n} from '../lib/api';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\nimport { workspaceQueryKeys } from '@/lib/queryKeys';\r\n\r\n// Default stale time: 30 seconds (prompts update less frequently)\r\nconst STALE_TIME = 30 * 1000;\r\n\r\nexport interface PromptHistoryFilter {\r\n search?: string;\r\n intent?: string;\r\n project?: string;\r\n dateRange?: { start: Date | null; end: Date | null };\r\n}\r\n\r\nexport interface UsePromptHistoryOptions {\r\n filter?: PromptHistoryFilter;\r\n staleTime?: number;\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface UsePromptHistoryReturn {\r\n prompts: Prompt[];\r\n allPrompts: Prompt[];\r\n totalPrompts: number;\r\n promptsBySession: Record<string, Prompt[]>;\r\n stats: {\r\n totalCount: number;\r\n avgLength: number;\r\n topIntent: string | null;\r\n avgQualityScore?: number;\r\n qualityDistribution?: {\r\n high: number;\r\n medium: number;\r\n low: number;\r\n };\r\n };\r\n isLoading: boolean;\r\n isFetching: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n invalidate: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching and filtering prompt history\r\n */\r\nexport function usePromptHistory(options: UsePromptHistoryOptions = {}): UsePromptHistoryReturn {\r\n const { filter, staleTime = STALE_TIME, enabled = true } = options;\r\n const queryClient = useQueryClient();\r\n\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n const queryEnabled = enabled && !!projectPath;\r\n\r\n const query = useQuery({\r\n queryKey: workspaceQueryKeys.promptsList(projectPath),\r\n queryFn: () => fetchPrompts(projectPath),\r\n staleTime,\r\n enabled: queryEnabled,\r\n retry: 2,\r\n });\r\n\r\n const allPrompts = query.data?.prompts ?? [];\r\n const totalCount = query.data?.total ?? 0;\r\n\r\n // Apply filters\r\n const filteredPrompts = (() => {\r\n let prompts = allPrompts;\r\n\r\n if (filter?.search) {\r\n const searchLower = filter.search.toLowerCase();\r\n prompts = prompts.filter(\r\n (p) =>\r\n p.title?.toLowerCase().includes(searchLower) ||\r\n p.content.toLowerCase().includes(searchLower) ||\r\n p.tags?.some((t) => t.toLowerCase().includes(searchLower))\r\n );\r\n }\r\n\r\n if (filter?.intent) {\r\n prompts = prompts.filter((p) => p.category === filter.intent);\r\n }\r\n\r\n if (filter?.project) {\r\n prompts = prompts.filter((p) => p.project === filter.project);\r\n }\r\n\r\n if (filter?.dateRange?.start || filter?.dateRange?.end) {\r\n prompts = prompts.filter((p) => {\r\n const date = new Date(p.createdAt);\r\n const start = filter.dateRange?.start;\r\n const end = filter.dateRange?.end;\r\n if (start && date < start) return false;\r\n if (end && date > end) return false;\r\n return true;\r\n });\r\n }\r\n\r\n return prompts;\r\n })();\r\n\r\n // Group by session for timeline view\r\n const promptsBySession: Record<string, Prompt[]> = {};\r\n for (const prompt of allPrompts) {\r\n const sessionKey = prompt.tags?.find((t) => t.startsWith('session:'))?.replace('session:', '') || 'ungrouped';\r\n if (!promptsBySession[sessionKey]) {\r\n promptsBySession[sessionKey] = [];\r\n }\r\n promptsBySession[sessionKey].push(prompt);\r\n }\r\n\r\n // Calculate stats\r\n const avgLength = allPrompts.length > 0\r\n ? Math.round(allPrompts.reduce((sum, p) => sum + p.content.length, 0) / allPrompts.length)\r\n : 0;\r\n\r\n const intentCounts: Record<string, number> = {};\r\n for (const prompt of allPrompts) {\r\n const category = prompt.category || 'uncategorized';\r\n intentCounts[category] = (intentCounts[category] || 0) + 1;\r\n }\r\n const topIntent = Object.entries(intentCounts).sort((a, b) => b[1] - a[1])[0]?.[0] || null;\r\n\r\n // Calculate quality distribution\r\n const qualityDistribution = {\r\n high: 0,\r\n medium: 0,\r\n low: 0,\r\n };\r\n let totalQualityScore = 0;\r\n let qualityScoreCount = 0;\r\n\r\n for (const prompt of allPrompts) {\r\n if (prompt.quality_score !== undefined && prompt.quality_score !== null) {\r\n totalQualityScore += prompt.quality_score;\r\n qualityScoreCount++;\r\n\r\n if (prompt.quality_score >= 80) {\r\n qualityDistribution.high++;\r\n } else if (prompt.quality_score >= 60) {\r\n qualityDistribution.medium++;\r\n } else {\r\n qualityDistribution.low++;\r\n }\r\n }\r\n }\r\n\r\n const avgQualityScore = qualityScoreCount > 0\r\n ? totalQualityScore / qualityScoreCount\r\n : undefined;\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n const invalidate = async () => {\r\n await queryClient.invalidateQueries({ queryKey: workspaceQueryKeys.prompts(projectPath) });\r\n };\r\n\r\n return {\r\n prompts: filteredPrompts,\r\n allPrompts,\r\n totalPrompts: totalCount,\r\n promptsBySession,\r\n stats: {\r\n totalCount: allPrompts.length,\r\n avgLength,\r\n topIntent,\r\n avgQualityScore,\r\n qualityDistribution,\r\n },\r\n isLoading: query.isLoading,\r\n isFetching: query.isFetching,\r\n error: query.error,\r\n refetch,\r\n invalidate,\r\n };\r\n}\r\n\r\n\r\n\r\n/**\r\n * Hook for fetching prompt insights\r\n */\r\nexport function usePromptInsights(options: { enabled?: boolean; staleTime?: number } = {}) {\r\n const { enabled = true, staleTime = STALE_TIME } = options;\r\n\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n const queryEnabled = enabled && !!projectPath;\r\n\r\n return useQuery({\r\n queryKey: workspaceQueryKeys.promptsInsights(projectPath),\r\n queryFn: () => fetchPromptInsights(projectPath),\r\n staleTime,\r\n enabled: queryEnabled,\r\n retry: 2,\r\n });\r\n}\r\n\r\n/**\r\n * Hook for fetching insights history (past CLI analyses)\r\n */\r\nexport function useInsightsHistory(options: {\r\n limit?: number;\r\n enabled?: boolean;\r\n staleTime?: number;\r\n} = {}) {\r\n const { limit = 20, enabled = true, staleTime = STALE_TIME } = options;\r\n\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n const queryEnabled = enabled && !!projectPath;\r\n\r\n return useQuery({\r\n queryKey: workspaceQueryKeys.promptsInsightsHistory(projectPath),\r\n queryFn: () => fetchInsightsHistory(projectPath, limit),\r\n staleTime,\r\n enabled: queryEnabled,\r\n retry: 2,\r\n });\r\n}\r\n\r\n// ========== Mutations ==========\r\n\r\nexport interface UseAnalyzePromptsReturn {\r\n analyzePrompts: (request?: { tool?: 'gemini' | 'qwen' | 'codex'; limit?: number }) => Promise<PromptInsightsResponse>;\r\n isAnalyzing: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useAnalyzePrompts(): UseAnalyzePromptsReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: analyzePrompts,\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: workspaceQueryKeys.promptsInsights(projectPath) });\r\n },\r\n });\r\n\r\n return {\r\n analyzePrompts: mutation.mutateAsync,\r\n isAnalyzing: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseDeletePromptReturn {\r\n deletePrompt: (promptId: string) => Promise<void>;\r\n isDeleting: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useDeletePrompt(): UseDeletePromptReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: deletePrompt,\r\n onMutate: async (promptId) => {\r\n await queryClient.cancelQueries({ queryKey: workspaceQueryKeys.prompts(projectPath) });\r\n const previousPrompts = queryClient.getQueryData<PromptsResponse>(workspaceQueryKeys.promptsList(projectPath));\r\n\r\n queryClient.setQueryData<PromptsResponse>(workspaceQueryKeys.promptsList(projectPath), (old) => {\r\n if (!old) return old;\r\n return {\r\n ...old,\r\n prompts: old.prompts.filter((p) => p.id !== promptId),\r\n total: old.total - 1,\r\n };\r\n });\r\n\r\n return { previousPrompts };\r\n },\r\n onError: (_error, _promptId, context) => {\r\n if (context?.previousPrompts) {\r\n queryClient.setQueryData(workspaceQueryKeys.promptsList(projectPath), context.previousPrompts);\r\n }\r\n },\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: workspaceQueryKeys.prompts(projectPath) });\r\n },\r\n });\r\n\r\n return {\r\n deletePrompt: mutation.mutateAsync,\r\n isDeleting: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseBatchDeletePromptsReturn {\r\n batchDeletePrompts: (promptIds: string[]) => Promise<{ deleted: number }>;\r\n isBatchDeleting: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useBatchDeletePrompts(): UseBatchDeletePromptsReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: batchDeletePrompts,\r\n onMutate: async (promptIds) => {\r\n await queryClient.cancelQueries({ queryKey: workspaceQueryKeys.prompts(projectPath) });\r\n const previousPrompts = queryClient.getQueryData<PromptsResponse>(workspaceQueryKeys.promptsList(projectPath));\r\n\r\n queryClient.setQueryData<PromptsResponse>(workspaceQueryKeys.promptsList(projectPath), (old) => {\r\n if (!old) return old;\r\n return {\r\n ...old,\r\n prompts: old.prompts.filter((p) => !promptIds.includes(p.id)),\r\n total: old.total - promptIds.length,\r\n };\r\n });\r\n\r\n return { previousPrompts };\r\n },\r\n onError: (_error, _promptIds, context) => {\r\n if (context?.previousPrompts) {\r\n queryClient.setQueryData(workspaceQueryKeys.promptsList(projectPath), context.previousPrompts);\r\n }\r\n },\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: workspaceQueryKeys.prompts(projectPath) });\r\n },\r\n });\r\n\r\n return {\r\n batchDeletePrompts: mutation.mutateAsync,\r\n isBatchDeleting: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseDeleteInsightReturn {\r\n deleteInsight: (insightId: string) => Promise<{ success: boolean }>;\r\n isDeleting: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useDeleteInsight(): UseDeleteInsightReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: (insightId: string) => deleteInsight(insightId, projectPath),\r\n onMutate: async (insightId) => {\r\n await queryClient.cancelQueries({ queryKey: workspaceQueryKeys.promptsInsightsHistory(projectPath) });\r\n const previousInsights = queryClient.getQueryData<InsightsHistoryResponse>(workspaceQueryKeys.promptsInsightsHistory(projectPath));\r\n\r\n queryClient.setQueryData<InsightsHistoryResponse>(workspaceQueryKeys.promptsInsightsHistory(projectPath), (old) => {\r\n if (!old) return old;\r\n return {\r\n ...old,\r\n insights: old.insights.filter((i) => i.id !== insightId),\r\n };\r\n });\r\n\r\n return { previousInsights };\r\n },\r\n onError: (_error, _insightId, context) => {\r\n if (context?.previousInsights) {\r\n queryClient.setQueryData(workspaceQueryKeys.promptsInsightsHistory(projectPath), context.previousInsights);\r\n }\r\n },\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: workspaceQueryKeys.promptsInsightsHistory(projectPath) });\r\n },\r\n });\r\n\r\n return {\r\n deleteInsight: mutation.mutateAsync,\r\n isDeleting: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\n/**\r\n * Combined hook for all prompt history mutations\r\n */\r\nexport function usePromptHistoryMutations() {\r\n const analyze = useAnalyzePrompts();\r\n const remove = useDeletePrompt();\r\n const batchRemove = useBatchDeletePrompts();\r\n\r\n return {\r\n analyzePrompts: analyze.analyzePrompts,\r\n deletePrompt: remove.deletePrompt,\r\n batchDeletePrompts: batchRemove.batchDeletePrompts,\r\n isAnalyzing: analyze.isAnalyzing,\r\n isDeleting: remove.isDeleting,\r\n isBatchDeleting: batchRemove.isBatchDeleting,\r\n isMutating: analyze.isAnalyzing || remove.isDeleting || batchRemove.isBatchDeleting,\r\n };\r\n}\r\n\r\n/**\r\n * Extract unique projects from prompts list\r\n */\r\nexport function extractUniqueProjects(prompts: Prompt[]): string[] {\r\n const projectsSet = new Set<string>();\r\n for (const prompt of prompts) {\r\n if (prompt.project) {\r\n projectsSet.add(prompt.project);\r\n }\r\n }\r\n return Array.from(projectsSet).sort();\r\n}\r\n","// ========================================\n// BatchOperationToolbar Component\n// ========================================\n// Toolbar for batch operations on prompts\n\nimport { useIntl } from 'react-intl';\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/Button';\nimport { Checkbox } from '@/components/ui/Checkbox';\nimport { Trash2, X } from 'lucide-react';\n\nexport interface BatchOperationToolbarProps {\n /** Number of selected items */\n selectedCount: number;\n /** Whether all items are selected */\n allSelected: boolean;\n /** Called when select all is toggled */\n onSelectAll: (selected: boolean) => void;\n /** Called when clear selection is triggered */\n onClearSelection: () => void;\n /** Called when batch delete is triggered */\n onDelete: () => void;\n /** Whether delete operation is in progress */\n isDeleting?: boolean;\n /** Optional className */\n className?: string;\n}\n\n/**\n * BatchOperationToolbar component for bulk actions\n */\nexport function BatchOperationToolbar({\n selectedCount,\n allSelected,\n onSelectAll,\n onClearSelection,\n onDelete,\n isDeleting = false,\n className,\n}: BatchOperationToolbarProps) {\n const { formatMessage } = useIntl();\n\n if (selectedCount === 0) {\n return null;\n }\n\n return (\n <div\n className={cn(\n 'flex items-center justify-between gap-4 p-3 bg-primary/10 rounded-lg border border-primary/20',\n className\n )}\n >\n {/* Selection info and select all */}\n <div className=\"flex items-center gap-3\">\n <Checkbox\n checked={allSelected}\n onCheckedChange={(checked) => onSelectAll(checked === true)}\n aria-label={formatMessage({ id: 'prompts.batch.selectAll' })}\n />\n <span className=\"text-sm font-medium text-foreground\">\n {formatMessage({ id: 'prompts.batch.selected' }, { count: selectedCount })}\n </span>\n </div>\n\n {/* Action buttons */}\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onClearSelection}\n disabled={isDeleting}\n >\n <X className=\"h-4 w-4 mr-1\" />\n {formatMessage({ id: 'prompts.batch.clearSelection' })}\n </Button>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={onDelete}\n disabled={isDeleting}\n >\n <Trash2 className=\"h-4 w-4 mr-1\" />\n {formatMessage({ id: 'prompts.batch.deleteSelected' })}\n </Button>\n </div>\n </div>\n );\n}\n\nexport default BatchOperationToolbar;\n","// ========================================\r\n// InsightsHistoryList Component\r\n// ========================================\r\n// Display past insight analysis results with tool icon, timestamp, pattern count, and suggestion count\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { cn } from '@/lib/utils';\r\nimport {\r\n Sparkles,\r\n Bot,\r\n Code2,\r\n Cpu,\r\n Brain,\r\n Loader2,\r\n} from 'lucide-react';\r\nimport type { InsightHistory } from '@/lib/api';\r\n\r\nexport interface InsightsHistoryListProps {\r\n /** Array of historical insights */\r\n insights?: InsightHistory[];\r\n /** Loading state */\r\n isLoading?: boolean;\r\n /** Called when an insight card is clicked */\r\n onInsightSelect?: (insightId: string) => void;\r\n /** Optional className */\r\n className?: string;\r\n}\r\n\r\n// Tool icon mapping\r\nconst toolConfig = {\r\n gemini: {\r\n icon: Sparkles,\r\n color: 'text-blue-500',\r\n bgColor: 'bg-blue-500/10',\r\n label: 'Gemini',\r\n },\r\n qwen: {\r\n icon: Bot,\r\n color: 'text-purple-500',\r\n bgColor: 'bg-purple-500/10',\r\n label: 'Qwen',\r\n },\r\n codex: {\r\n icon: Code2,\r\n color: 'text-green-500',\r\n bgColor: 'bg-green-500/10',\r\n label: 'Codex',\r\n },\r\n default: {\r\n icon: Cpu,\r\n color: 'text-gray-500',\r\n bgColor: 'bg-gray-500/10',\r\n label: 'CLI',\r\n },\r\n};\r\n\r\n/**\r\n * Format timestamp to relative time (e.g., \"2h ago\")\r\n */\r\nfunction formatTimeAgo(timestamp: string, locale: string): string {\r\n const date = new Date(timestamp);\r\n const now = new Date();\r\n const diff = now.getTime() - date.getTime();\r\n const minutes = Math.floor(diff / 60000);\r\n const hours = Math.floor(diff / 3600000);\r\n const days = Math.floor(diff / 86400000);\r\n\r\n const isZh = locale === 'zh';\r\n\r\n if (minutes < 1) return isZh ? '刚刚' : 'Just now';\r\n if (minutes < 60) return isZh ? `${minutes} 分钟前` : `${minutes}m ago`;\r\n if (hours < 24) return isZh ? `${hours} 小时前` : `${hours}h ago`;\r\n if (days < 7) return isZh ? `${days} 天前` : `${days}d ago`;\r\n return date.toLocaleDateString();\r\n}\r\n\r\n/**\r\n * Get severity level from patterns\r\n * Pattern severity: 'error' | 'warning' | 'info'\r\n */\r\nfunction getSeverityLevel(patterns: InsightHistory['patterns']): 'low' | 'medium' | 'high' {\r\n if (!patterns || patterns.length === 0) return 'low';\r\n const hasHigh = patterns.some(p => p.severity === 'error');\r\n const hasMedium = patterns.some(p => p.severity === 'warning');\r\n return hasHigh ? 'high' : hasMedium ? 'medium' : 'low';\r\n}\r\n\r\n/**\r\n * Severity color mapping\r\n */\r\nconst severityConfig = {\r\n low: {\r\n border: 'border-l-4 border-l-green-500',\r\n },\r\n medium: {\r\n border: 'border-l-4 border-l-yellow-500',\r\n },\r\n high: {\r\n border: 'border-l-4 border-l-red-500',\r\n },\r\n};\r\n\r\n/**\r\n * InsightHistoryCard component for displaying a single insight history entry\r\n */\r\nfunction InsightHistoryCard({\r\n insight,\r\n locale,\r\n onClick,\r\n}: {\r\n insight: InsightHistory;\r\n locale: string;\r\n onClick: () => void;\r\n}) {\r\n const { formatMessage } = useIntl();\r\n const severity = getSeverityLevel(insight.patterns);\r\n const config = toolConfig[insight.tool as keyof typeof toolConfig] ?? toolConfig.default;\r\n const ToolIcon = config.icon;\r\n const timeAgo = formatTimeAgo(insight.created_at, locale);\r\n const patternCount = insight.patterns?.length ?? 0;\r\n const suggestionCount = insight.suggestions?.length ?? 0;\r\n\r\n return (\r\n <div\r\n onClick={onClick}\r\n className={cn(\r\n 'p-3 rounded-lg border border-border bg-card hover:bg-muted/50 cursor-pointer transition-colors',\r\n 'border-l-4',\r\n severityConfig[severity].border\r\n )}\r\n >\r\n {/* Header: Tool and timestamp */}\r\n <div className=\"flex items-center justify-between mb-2\">\r\n <div className={cn('flex items-center gap-1.5', config.color)}>\r\n <ToolIcon className=\"h-3.5 w-3.5\" />\r\n <span className=\"text-xs font-medium\">{config.label}</span>\r\n </div>\r\n <div className=\"text-xs text-muted-foreground\">{timeAgo}</div>\r\n </div>\r\n\r\n {/* Stats: Patterns, Suggestions, Prompts */}\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"flex items-baseline gap-1\">\r\n <span className=\"text-sm font-semibold text-foreground\">{patternCount}</span>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'prompts.insightsHistory.patterns' })}\r\n </span>\r\n </div>\r\n <div className=\"flex items-baseline gap-1\">\r\n <span className=\"text-sm font-semibold text-foreground\">{suggestionCount}</span>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'prompts.insightsHistory.suggestions' })}\r\n </span>\r\n </div>\r\n <div className=\"flex items-baseline gap-1\">\r\n <span className=\"text-sm font-semibold text-foreground\">{insight.prompt_count}</span>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'prompts.insightsHistory.prompts' })}\r\n </span>\r\n </div>\r\n </div>\r\n\r\n {/* Pattern preview (if available) */}\r\n {insight.patterns && insight.patterns.length > 0 && (\r\n <div className=\"mt-2 pt-2 border-t border-border/50\">\r\n <div\r\n className={cn(\r\n 'flex items-start gap-1.5 text-xs',\r\n insight.patterns[0].severity === 'error'\r\n ? 'text-red-500'\r\n : insight.patterns[0].severity === 'warning'\r\n ? 'text-yellow-600'\r\n : 'text-blue-500'\r\n )}\r\n >\r\n <span className=\"font-medium uppercase\">\r\n {insight.patterns[0].name?.split(' ')[0] || 'Pattern'}\r\n </span>\r\n <span className=\"text-muted-foreground truncate flex-1\">\r\n {insight.patterns[0].description?.slice(0, 50)}\r\n {insight.patterns[0].description && insight.patterns[0].description.length > 50 ? '...' : ''}\r\n </span>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * InsightsHistoryList component - Display past insight analysis results\r\n */\r\nexport function InsightsHistoryList({\r\n insights = [],\r\n isLoading = false,\r\n onInsightSelect,\r\n className,\r\n}: InsightsHistoryListProps) {\r\n const { formatMessage } = useIntl();\r\n const locale = useIntl().locale;\r\n\r\n // Loading state\r\n if (isLoading) {\r\n return (\r\n <div className={cn('rounded-lg border border-border bg-card p-4', className)}>\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"h-5 w-5 animate-spin text-muted-foreground mr-2\" />\r\n <span className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'prompts.insightsHistory.loading' })}\r\n </span>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // Empty state\r\n if (insights.length === 0) {\r\n return (\r\n <div className={cn('rounded-lg border border-border bg-card p-4', className)}>\r\n <div className=\"flex flex-col items-center justify-center py-8 px-4 text-center\">\r\n <Brain className=\"h-10 w-10 text-muted-foreground/50 mb-3\" />\r\n <h3 className=\"text-sm font-medium text-foreground mb-1\">\r\n {formatMessage({ id: 'prompts.insightsHistory.empty.title' })}\r\n </h3>\r\n <p className=\"text-xs text-muted-foreground max-w-xs\">\r\n {formatMessage({ id: 'prompts.insightsHistory.empty.message' })}\r\n </p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // List of insights\r\n return (\r\n <div className={cn('space-y-2', className)}>\r\n {insights.map((insight) => (\r\n <InsightHistoryCard\r\n key={insight.id}\r\n insight={insight}\r\n locale={locale}\r\n onClick={() => onInsightSelect?.(insight.id)}\r\n />\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\nexport default InsightsHistoryList;\r\n","// ========================================\r\n// InsightDetailPanel Component\r\n// ========================================\r\n// Display detailed view of a single insight with patterns, suggestions, and metadata\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { cn } from '@/lib/utils';\r\nimport {\r\n X,\r\n Sparkles,\r\n Bot,\r\n Code2,\r\n Cpu,\r\n Trash2,\r\n AlertTriangle,\r\n Lightbulb,\r\n Clock,\r\n FileText,\r\n} from 'lucide-react';\r\nimport type { InsightHistory, Pattern, Suggestion } from '@/lib/api';\r\nimport { Button } from '@/components/ui/Button';\r\n\r\nexport interface InsightDetailPanelProps {\r\n /** Insight to display (null = panel hidden) */\r\n insight: InsightHistory | null;\r\n /** Called when close button clicked */\r\n onClose: () => void;\r\n /** Called when delete button clicked */\r\n onDelete?: (insightId: string) => void;\r\n /** Is delete operation in progress */\r\n isDeleting?: boolean;\r\n /** Optional className */\r\n className?: string;\r\n}\r\n\r\n// Tool icon mapping\r\nconst toolConfig = {\r\n gemini: {\r\n icon: Sparkles,\r\n color: 'text-blue-500',\r\n bgColor: 'bg-blue-500/10',\r\n label: 'Gemini',\r\n },\r\n qwen: {\r\n icon: Bot,\r\n color: 'text-purple-500',\r\n bgColor: 'bg-purple-500/10',\r\n label: 'Qwen',\r\n },\r\n codex: {\r\n icon: Code2,\r\n color: 'text-green-500',\r\n bgColor: 'bg-green-500/10',\r\n label: 'Codex',\r\n },\r\n default: {\r\n icon: Cpu,\r\n color: 'text-gray-500',\r\n bgColor: 'bg-gray-500/10',\r\n label: 'CLI',\r\n },\r\n};\r\n\r\n// Severity configuration\r\nconst severityConfig = {\r\n error: {\r\n badge: 'bg-red-500/10 text-red-500 border-red-500/20',\r\n border: 'border-l-red-500',\r\n dot: 'bg-red-500',\r\n },\r\n warning: {\r\n badge: 'bg-yellow-500/10 text-yellow-600 border-yellow-500/20',\r\n border: 'border-l-yellow-500',\r\n dot: 'bg-yellow-500',\r\n },\r\n info: {\r\n badge: 'bg-blue-500/10 text-blue-500 border-blue-500/20',\r\n border: 'border-l-blue-500',\r\n dot: 'bg-blue-500',\r\n },\r\n default: {\r\n badge: 'bg-gray-500/10 text-gray-500 border-gray-500/20',\r\n border: 'border-l-gray-500',\r\n dot: 'bg-gray-500',\r\n },\r\n};\r\n\r\n// Suggestion type configuration\r\nconst suggestionTypeConfig = {\r\n refactor: {\r\n badge: 'bg-purple-500/10 text-purple-500 border-purple-500/20',\r\n icon: 'refactor',\r\n },\r\n optimize: {\r\n badge: 'bg-green-500/10 text-green-500 border-green-500/20',\r\n icon: 'optimize',\r\n },\r\n fix: {\r\n badge: 'bg-red-500/10 text-red-500 border-red-500/20',\r\n icon: 'fix',\r\n },\r\n document: {\r\n badge: 'bg-blue-500/10 text-blue-500 border-blue-500/20',\r\n icon: 'document',\r\n },\r\n};\r\n\r\n/**\r\n * Format timestamp to relative time\r\n */\r\nfunction formatRelativeTime(timestamp: string, locale: string): string {\r\n const date = new Date(timestamp);\r\n const now = new Date();\r\n const diffMs = now.getTime() - date.getTime();\r\n const diffMins = Math.floor(diffMs / 60000);\r\n const diffHours = Math.floor(diffMs / 3600000);\r\n const diffDays = Math.floor(diffMs / 86400000);\r\n\r\n if (locale === 'zh') {\r\n if (diffMins < 1) return '刚刚';\r\n if (diffMins < 60) return `${diffMins}分钟前`;\r\n if (diffHours < 24) return `${diffHours}小时前`;\r\n return `${diffDays}天前`;\r\n }\r\n\r\n if (diffMins < 1) return 'just now';\r\n if (diffMins < 60) return `${diffMins}m ago`;\r\n if (diffHours < 24) return `${diffHours}h ago`;\r\n return `${diffDays}d ago`;\r\n}\r\n\r\n/**\r\n * PatternItem component for displaying a single pattern\r\n */\r\nfunction PatternItem({ pattern }: { pattern: Pattern; locale: string }) {\r\n const severity = pattern.severity ?? 'info';\r\n const config = severityConfig[severity] ?? severityConfig.default;\r\n\r\n return (\r\n <div\r\n className={cn(\r\n 'p-3 rounded-md border bg-card',\r\n 'border-l-4',\r\n config.border\r\n )}\r\n >\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <span\r\n className={cn(\r\n 'px-2 py-0.5 text-xs font-medium rounded border',\r\n config.badge\r\n )}\r\n >\r\n {pattern.name?.split(' ')[0] || 'Pattern'}\r\n </span>\r\n <span\r\n className={cn(\r\n 'px-2 py-0.5 text-xs font-medium rounded border uppercase',\r\n config.badge\r\n )}\r\n >\r\n {severity}\r\n </span>\r\n </div>\r\n <p className=\"text-sm text-foreground mb-2\">{pattern.description}</p>\r\n {pattern.example && (\r\n <div className=\"mt-2 p-2 bg-muted rounded text-xs font-mono overflow-x-auto\">\r\n <code className=\"text-muted-foreground\">{pattern.example}</code>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * SuggestionItem component for displaying a single suggestion\r\n */\r\nfunction SuggestionItem({ suggestion }: { suggestion: Suggestion; locale: string }) {\r\n const { formatMessage } = useIntl();\r\n const config = suggestionTypeConfig[suggestion.type] ?? suggestionTypeConfig.refactor;\r\n const typeLabel = formatMessage({ id: `prompts.suggestions.types.${suggestion.type}` });\r\n\r\n return (\r\n <div className=\"p-3 rounded-md border border-border bg-card\">\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <span\r\n className={cn(\r\n 'px-2 py-0.5 text-xs font-medium rounded border',\r\n config.badge\r\n )}\r\n >\r\n {typeLabel}\r\n </span>\r\n {suggestion.effort && (\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'prompts.suggestions.effort' })}: {suggestion.effort}\r\n </span>\r\n )}\r\n </div>\r\n <h4 className=\"text-sm font-medium text-foreground mb-1\">{suggestion.title}</h4>\r\n <p className=\"text-sm text-muted-foreground mb-2\">{suggestion.description}</p>\r\n {suggestion.code && (\r\n <div className=\"mt-2 p-2 bg-muted rounded text-xs font-mono overflow-x-auto\">\r\n <code className=\"text-muted-foreground\">{suggestion.code}</code>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * InsightDetailPanel component - Display full insight details\r\n */\r\nexport function InsightDetailPanel({\r\n insight,\r\n onClose,\r\n onDelete,\r\n isDeleting = false,\r\n className,\r\n}: InsightDetailPanelProps) {\r\n const { formatMessage } = useIntl();\r\n const locale = useIntl().locale;\r\n\r\n // Don't render if no insight\r\n if (!insight) {\r\n return null;\r\n }\r\n\r\n const config = toolConfig[insight.tool as keyof typeof toolConfig] ?? toolConfig.default;\r\n const ToolIcon = config.icon;\r\n const timeAgo = formatRelativeTime(insight.created_at, locale);\r\n const patternCount = insight.patterns?.length ?? 0;\r\n const suggestionCount = insight.suggestions?.length ?? 0;\r\n\r\n return (\r\n <div\r\n className={cn(\r\n 'fixed inset-y-0 right-0 w-full max-w-md bg-background border-l border-border shadow-lg',\r\n 'flex flex-col',\r\n 'animate-in slide-in-from-right',\r\n className\r\n )}\r\n >\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between p-4 border-b border-border\">\r\n <div className=\"flex items-center gap-2\">\r\n <ToolIcon className={cn('h-5 w-5', config.color)} />\r\n <h2 className=\"text-lg font-semibold text-card-foreground\">\r\n {formatMessage({ id: 'prompts.insightDetail.title' })}\r\n </h2>\r\n </div>\r\n <button\r\n onClick={onClose}\r\n className=\"p-1 rounded-md hover:bg-accent transition-colors\"\r\n aria-label={formatMessage({ id: 'common.actions.close' })}\r\n >\r\n <X className=\"h-5 w-5 text-muted-foreground\" />\r\n </button>\r\n </div>\r\n\r\n {/* Scrollable content */}\r\n <div className=\"flex-1 overflow-y-auto p-4 space-y-6\">\r\n {/* Metadata */}\r\n <div className=\"flex flex-wrap items-center gap-4 text-sm text-muted-foreground\">\r\n <div className={cn('flex items-center gap-1.5', config.color)}>\r\n <ToolIcon className=\"h-3.5 w-3.5\" />\r\n <span className=\"font-medium\">{config.label}</span>\r\n </div>\r\n <div className=\"flex items-center gap-1.5\">\r\n <Clock className=\"h-3.5 w-3.5\" />\r\n <span>{timeAgo}</span>\r\n </div>\r\n <div className=\"flex items-center gap-1.5\">\r\n <FileText className=\"h-3.5 w-3.5\" />\r\n <span>\r\n {insight.prompt_count} {formatMessage({ id: 'prompts.insightDetail.promptsAnalyzed' })}\r\n </span>\r\n </div>\r\n </div>\r\n\r\n {/* Patterns */}\r\n {insight.patterns && insight.patterns.length > 0 && (\r\n <div className=\"space-y-3\">\r\n <div className=\"flex items-center gap-2\">\r\n <AlertTriangle className=\"h-4 w-4 text-muted-foreground\" />\r\n <h3 className=\"text-sm font-semibold text-card-foreground\">\r\n {formatMessage({ id: 'prompts.insightDetail.patterns' })} ({patternCount})\r\n </h3>\r\n </div>\r\n <div className=\"space-y-2\">\r\n {insight.patterns.map((pattern) => (\r\n <PatternItem key={pattern.id} pattern={pattern} locale={locale} />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Suggestions */}\r\n {insight.suggestions && insight.suggestions.length > 0 && (\r\n <div className=\"space-y-3\">\r\n <div className=\"flex items-center gap-2\">\r\n <Lightbulb className=\"h-4 w-4 text-muted-foreground\" />\r\n <h3 className=\"text-sm font-semibold text-card-foreground\">\r\n {formatMessage({ id: 'prompts.insightDetail.suggestions' })} ({suggestionCount})\r\n </h3>\r\n </div>\r\n <div className=\"space-y-2\">\r\n {insight.suggestions.map((suggestion) => (\r\n <SuggestionItem key={suggestion.id} suggestion={suggestion} locale={locale} />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Empty state */}\r\n {(!insight.patterns || insight.patterns.length === 0) &&\r\n (!insight.suggestions || insight.suggestions.length === 0) && (\r\n <div className=\"text-center py-8 text-muted-foreground text-sm\">\r\n {formatMessage({ id: 'prompts.insightDetail.noContent' })}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Footer actions */}\r\n {onDelete && (\r\n <div className=\"p-4 border-t border-border\">\r\n <Button\r\n variant=\"destructive\"\r\n size=\"sm\"\r\n onClick={() => onDelete(insight.id)}\r\n disabled={isDeleting}\r\n className=\"w-full\"\r\n >\r\n <Trash2 className=\"h-4 w-4 mr-2\" />\r\n {isDeleting\r\n ? formatMessage({ id: 'prompts.insightDetail.deleting' })\r\n : formatMessage({ id: 'common.actions.delete' })\r\n }\r\n </Button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * InsightDetailPanelOverlay - Full screen overlay with panel\r\n */\r\nexport interface InsightDetailPanelOverlayProps extends InsightDetailPanelProps {\r\n /** Show overlay backdrop */\r\n showOverlay?: boolean;\r\n}\r\n\r\nexport function InsightDetailPanelOverlay({\r\n insight,\r\n onClose,\r\n onDelete,\r\n isDeleting = false,\r\n showOverlay = true,\r\n className,\r\n}: InsightDetailPanelOverlayProps) {\r\n if (!insight) {\r\n return null;\r\n }\r\n\r\n return (\r\n <>\r\n {showOverlay && (\r\n <div\r\n className=\"fixed inset-0 bg-black/60 z-40 animate-in fade-in\"\r\n onClick={onClose}\r\n />\r\n )}\r\n <InsightDetailPanel\r\n insight={insight}\r\n onClose={onClose}\r\n onDelete={onDelete}\r\n isDeleting={isDeleting}\r\n className={cn('z-50', className)}\r\n />\r\n </>\r\n );\r\n}\r\n\r\nexport default InsightDetailPanel;\r\n","// ========================================\n// PromptHistoryPage Component\n// ========================================\n// Prompt history page with timeline, stats, and AI insights\n\nimport * as React from 'react';\nimport { useIntl } from 'react-intl';\nimport {\n RefreshCw,\n Search,\n Filter,\n AlertCircle,\n History,\n X,\n FolderOpen,\n} from 'lucide-react';\nimport {\n usePromptHistory,\n usePromptInsights,\n useInsightsHistory,\n usePromptHistoryMutations,\n useDeleteInsight,\n extractUniqueProjects,\n type PromptHistoryFilter,\n} from '@/hooks/usePromptHistory';\nimport { PromptStats, PromptStatsSkeleton } from '@/components/shared/PromptStats';\nimport { PromptCard } from '@/components/shared/PromptCard';\nimport { BatchOperationToolbar } from '@/components/shared/BatchOperationToolbar';\nimport { InsightsPanel } from '@/components/shared/InsightsPanel';\nimport { InsightsHistoryList } from '@/components/shared/InsightsHistoryList';\nimport { InsightDetailPanelOverlay } from '@/components/shared/InsightDetailPanel';\nimport { fetchInsightDetail } from '@/lib/api';\nimport type { InsightHistory } from '@/lib/api';\nimport { Button } from '@/components/ui/Button';\nimport { Input } from '@/components/ui/Input';\nimport { Badge } from '@/components/ui/Badge';\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from '@/components/ui/Dialog';\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuLabel,\n} from '@/components/ui/Dropdown';\nimport { cn } from '@/lib/utils';\n\ntype IntentFilter = 'all' | string;\n\n/**\n * PromptHistoryPage component - Main page for prompt history management\n */\nexport function PromptHistoryPage() {\n const { formatMessage } = useIntl();\n\n // Filter state\n const [searchQuery, setSearchQuery] = React.useState('');\n const [intentFilter, setIntentFilter] = React.useState<IntentFilter>('all');\n const [projectFilter, setProjectFilter] = React.useState<string>('all');\n const [selectedTool, setSelectedTool] = React.useState<'gemini' | 'qwen' | 'codex'>('gemini');\n\n // Dialog state\n const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false);\n const [promptToDelete, setPromptToDelete] = React.useState<string | null>(null);\n\n // Insight detail state\n const [selectedInsight, setSelectedInsight] = React.useState<InsightHistory | null>(null);\n const [, setInsightDetailOpen] = React.useState(false);\n\n // Batch operations state\n const [selectedPromptIds, setSelectedPromptIds] = React.useState<Set<string>>(new Set());\n const [batchDeleteDialogOpen, setBatchDeleteDialogOpen] = React.useState(false);\n\n // Build filter object\n const filter: PromptHistoryFilter = React.useMemo(\n () => ({\n search: searchQuery,\n intent: intentFilter === 'all' ? undefined : intentFilter,\n project: projectFilter === 'all' ? undefined : projectFilter,\n }),\n [searchQuery, intentFilter, projectFilter]\n );\n\n // Fetch prompts and insights\n const {\n prompts,\n allPrompts,\n promptsBySession,\n stats,\n isLoading,\n isFetching,\n error,\n refetch,\n } = usePromptHistory({ filter });\n\n const { data: insightsData, isLoading: insightsLoading } = usePromptInsights();\n const { data: insightsHistoryData, isLoading: insightsHistoryLoading } = useInsightsHistory({ limit: 20 });\n\n const { analyzePrompts, deletePrompt, batchDeletePrompts, isAnalyzing, isBatchDeleting } = usePromptHistoryMutations();\n const { deleteInsight: deleteInsightMutation, isDeleting: isDeletingInsight } = useDeleteInsight();\n\n const isMutating = isAnalyzing || isBatchDeleting;\n\n // Extract unique projects from all prompts\n const uniqueProjects = React.useMemo(\n () => extractUniqueProjects(allPrompts),\n [allPrompts]\n );\n\n // Handlers\n const handleAnalyze = async () => {\n try {\n await analyzePrompts({ tool: selectedTool });\n } catch (err) {\n console.error('Failed to analyze prompts:', err);\n }\n };\n\n const handleDeleteClick = (promptId: string) => {\n setPromptToDelete(promptId);\n setDeleteDialogOpen(true);\n };\n\n const handleConfirmDelete = async () => {\n if (!promptToDelete) return;\n\n try {\n await deletePrompt(promptToDelete);\n setDeleteDialogOpen(false);\n setPromptToDelete(null);\n } catch (err) {\n console.error('Failed to delete prompt:', err);\n }\n };\n\n const handleClearSearch = () => {\n setSearchQuery('');\n };\n\n const handleInsightSelect = async (insightId: string) => {\n try {\n const insight = await fetchInsightDetail(insightId);\n setSelectedInsight(insight);\n setInsightDetailOpen(true);\n } catch (err) {\n console.error('Failed to fetch insight detail:', err);\n }\n };\n\n const handleDeleteInsight = async (insightId: string) => {\n const locale = useIntl().locale;\n const confirmMessage = locale === 'zh'\n ? '确定要删除此分析吗?此操作无法撤销。'\n : 'Are you sure you want to delete this insight? This action cannot be undone.';\n\n if (!window.confirm(confirmMessage)) {\n return;\n }\n\n try {\n await deleteInsightMutation(insightId);\n setInsightDetailOpen(false);\n setSelectedInsight(null);\n // Show success toast\n const successMessage = locale === 'zh' ? '洞察已删除' : 'Insight deleted';\n if ((window as any).showToast) {\n (window as any).showToast(successMessage, 'success');\n }\n } catch (err) {\n console.error('Failed to delete insight:', err);\n // Show error toast\n const errorMessage = locale === 'zh' ? '删除洞察失败' : 'Failed to delete insight';\n if ((window as any).showToast) {\n (window as any).showToast(errorMessage, 'error');\n }\n }\n };\n\n const toggleIntentFilter = (intent: string) => {\n setIntentFilter((prev) => (prev === intent ? 'all' : intent));\n };\n\n const clearFilters = () => {\n setSearchQuery('');\n setIntentFilter('all');\n setProjectFilter('all');\n };\n\n // Batch operations handlers\n const handleSelectPrompt = (promptId: string, selected: boolean) => {\n setSelectedPromptIds((prev) => {\n const next = new Set(prev);\n if (selected) {\n next.add(promptId);\n } else {\n next.delete(promptId);\n }\n return next;\n });\n };\n\n const handleSelectAll = (selected: boolean) => {\n if (selected) {\n setSelectedPromptIds(new Set(prompts.map((p) => p.id)));\n } else {\n setSelectedPromptIds(new Set());\n }\n };\n\n const handleClearSelection = () => {\n setSelectedPromptIds(new Set());\n };\n\n const handleBatchDeleteClick = () => {\n if (selectedPromptIds.size > 0) {\n setBatchDeleteDialogOpen(true);\n }\n };\n\n const handleConfirmBatchDelete = async () => {\n if (selectedPromptIds.size === 0) return;\n\n try {\n await batchDeletePrompts(Array.from(selectedPromptIds));\n setBatchDeleteDialogOpen(false);\n setSelectedPromptIds(new Set());\n } catch (err) {\n console.error('Failed to batch delete prompts:', err);\n }\n };\n\n const hasActiveFilters = searchQuery.length > 0 || intentFilter !== 'all' || projectFilter !== 'all';\n\n // Group prompts for timeline view\n const timelineGroups = React.useMemo(() => {\n const groups: Array<{ key: string; label: string; prompts: typeof prompts }> = [];\n\n // Group by session if available, otherwise by date\n const sessionKeys = Object.keys(promptsBySession);\n if (sessionKeys.length > 0 && sessionKeys.some((k) => k !== 'ungrouped')) {\n // Session-based grouping\n for (const [sessionKey, sessionPrompts] of Object.entries(promptsBySession)) {\n const filtered = sessionPrompts.filter((p) =>\n prompts.some((fp) => fp.id === p.id)\n );\n if (filtered.length > 0) {\n groups.push({\n key: sessionKey,\n label: sessionKey === 'ungrouped'\n ? formatMessage({ id: 'prompts.timeline.ungrouped' })\n : formatMessage({ id: 'prompts.timeline.session' }, { session: sessionKey }),\n prompts: filtered,\n });\n }\n }\n } else {\n // Date-based grouping\n const dateGroups: Record<string, typeof prompts> = {};\n for (const prompt of prompts) {\n const date = new Date(prompt.createdAt).toLocaleDateString();\n if (!dateGroups[date]) {\n dateGroups[date] = [];\n }\n dateGroups[date].push(prompt);\n }\n for (const [date, datePrompts] of Object.entries(dateGroups)) {\n groups.push({ key: date, label: date, prompts: datePrompts });\n }\n }\n\n return groups.sort((a, b) => {\n const aDate = a.prompts[0]?.createdAt ? new Date(a.prompts[0].createdAt).getTime() : 0;\n const bDate = b.prompts[0]?.createdAt ? new Date(b.prompts[0].createdAt).getTime() : 0;\n return bDate - aDate;\n });\n }, [prompts, promptsBySession, formatMessage]);\n\n return (\n <div className=\"space-y-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold text-foreground flex items-center gap-2\">\n <History className=\"h-6 w-6\" />\n {formatMessage({ id: 'prompts.title' })}\n </h1>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {formatMessage({ id: 'prompts.description' })}\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => refetch()}\n disabled={isFetching}\n >\n <RefreshCw className={cn('h-4 w-4 mr-2', isFetching && 'animate-spin')} />\n {formatMessage({ id: 'common.actions.refresh' })}\n </Button>\n </div>\n </div>\n\n {/* Error alert */}\n {error && (\n <div className=\"flex items-center gap-2 p-4 rounded-lg bg-destructive/10 border border-destructive/30 text-destructive\">\n <AlertCircle className=\"h-5 w-5 flex-shrink-0\" />\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium\">{formatMessage({ id: 'common.errors.loadFailed' })}</p>\n <p className=\"text-xs mt-0.5\">{error.message}</p>\n </div>\n <Button variant=\"outline\" size=\"sm\" onClick={() => refetch()}>\n {formatMessage({ id: 'home.errors.retry' })}\n </Button>\n </div>\n )}\n\n {/* Stats */}\n {isLoading ? <PromptStatsSkeleton /> : <PromptStats {...stats} />}\n\n {/* Main content area with timeline and insights */}\n <div className=\"grid gap-6 grid-cols-1 lg:grid-cols-3\">\n {/* Timeline section */}\n <div className=\"lg:col-span-2 space-y-4\">\n {/* Filters */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center\">\n {/* Search input */}\n <div className=\"flex-1 max-w-sm relative\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground\" />\n <Input\n placeholder={formatMessage({ id: 'prompts.searchPlaceholder' })}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-9 pr-9\"\n />\n {searchQuery && (\n <button\n onClick={handleClearSearch}\n className=\"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n )}\n </div>\n\n {/* Intent filter dropdown */}\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"sm\" className=\"gap-2\">\n <Filter className=\"h-4 w-4\" />\n {formatMessage({ id: 'common.actions.filter' })}\n {(intentFilter !== 'all' || projectFilter !== 'all') && (\n <Badge variant=\"secondary\" className=\"ml-1 h-5 min-w-5 px-1\">\n {(intentFilter !== 'all' ? 1 : 0) + (projectFilter !== 'all' ? 1 : 0)}\n </Badge>\n )}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-48\">\n <DropdownMenuLabel>{formatMessage({ id: 'prompts.filterByIntent' })}</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n onClick={() => setIntentFilter('all')}\n className=\"justify-between\"\n >\n <span>{formatMessage({ id: 'prompts.intents.all' })}</span>\n {intentFilter === 'all' && <span className=\"text-primary\">&#10003;</span>}\n </DropdownMenuItem>\n {['bug-fix', 'feature', 'refactor', 'document', 'analyze'].map((intent) => (\n <DropdownMenuItem\n key={intent}\n onClick={() => toggleIntentFilter(intent)}\n className=\"justify-between\"\n >\n <span>{formatMessage({ id: `prompts.intents.${intent}` })}</span>\n {intentFilter === intent && <span className=\"text-primary\">&#10003;</span>}\n </DropdownMenuItem>\n ))}\n <DropdownMenuSeparator />\n <DropdownMenuLabel>{formatMessage({ id: 'prompts.filterByProject' })}</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n onClick={() => setProjectFilter('all')}\n className=\"justify-between\"\n >\n <span>{formatMessage({ id: 'prompts.projects.all' })}</span>\n {projectFilter === 'all' && <span className=\"text-primary\">&#10003;</span>}\n </DropdownMenuItem>\n {uniqueProjects.map((project) => (\n <DropdownMenuItem\n key={project}\n onClick={() => setProjectFilter(project)}\n className=\"justify-between\"\n >\n <span className=\"truncate max-w-32\" title={project}>{project}</span>\n {projectFilter === project && <span className=\"text-primary\">&#10003;</span>}\n </DropdownMenuItem>\n ))}\n {hasActiveFilters && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={clearFilters} className=\"text-destructive\">\n {formatMessage({ id: 'common.actions.clearFilters' })}\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n\n {/* Active filters display */}\n {hasActiveFilters && (\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm text-muted-foreground\">{formatMessage({ id: 'common.actions.filters' })}:</span>\n {intentFilter !== 'all' && (\n <Badge\n variant=\"secondary\"\n className=\"cursor-pointer\"\n onClick={() => setIntentFilter('all')}\n >\n {formatMessage({ id: 'prompts.intents.intent' })}: {intentFilter}\n <X className=\"ml-1 h-3 w-3\" />\n </Badge>\n )}\n {projectFilter !== 'all' && (\n <Badge\n variant=\"secondary\"\n className=\"cursor-pointer\"\n onClick={() => setProjectFilter('all')}\n >\n {formatMessage({ id: 'prompts.projects.project' })}: {projectFilter}\n <X className=\"ml-1 h-3 w-3\" />\n </Badge>\n )}\n {searchQuery && (\n <Badge\n variant=\"secondary\"\n className=\"cursor-pointer\"\n onClick={handleClearSearch}\n >\n {formatMessage({ id: 'common.actions.search' })}: {searchQuery}\n <X className=\"ml-1 h-3 w-3\" />\n </Badge>\n )}\n <Button variant=\"ghost\" size=\"sm\" onClick={clearFilters} className=\"h-6 text-xs\">\n {formatMessage({ id: 'common.actions.clearAll' })}\n </Button>\n </div>\n )}\n\n {/* Batch operations toolbar */}\n <BatchOperationToolbar\n selectedCount={selectedPromptIds.size}\n allSelected={prompts.length > 0 && selectedPromptIds.size === prompts.length}\n onSelectAll={handleSelectAll}\n onClearSelection={handleClearSelection}\n onDelete={handleBatchDeleteClick}\n isDeleting={isBatchDeleting}\n />\n\n {/* Timeline */}\n {isLoading ? (\n <div className=\"space-y-4\">\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"p-4 rounded-lg border border-border animate-pulse\">\n <div className=\"h-4 w-32 bg-muted rounded mb-2\" />\n <div className=\"h-20 bg-muted rounded\" />\n </div>\n ))}\n </div>\n ) : timelineGroups.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-16 px-4 border border-dashed border-border rounded-lg\">\n <FolderOpen className=\"h-12 w-12 text-muted-foreground mb-4\" />\n <h3 className=\"text-lg font-medium text-foreground mb-1\">\n {hasActiveFilters\n ? formatMessage({ id: 'prompts.emptyState.title' })\n : formatMessage({ id: 'prompts.emptyState.noPrompts' })}\n </h3>\n <p className=\"text-sm text-muted-foreground text-center max-w-sm mb-4\">\n {hasActiveFilters\n ? formatMessage({ id: 'prompts.emptyState.message' })\n : formatMessage({ id: 'prompts.emptyState.createFirst' })}\n </p>\n {hasActiveFilters && (\n <Button variant=\"outline\" onClick={clearFilters}>\n {formatMessage({ id: 'common.actions.clearFilters' })}\n </Button>\n )}\n </div>\n ) : (\n <div className=\"space-y-6\">\n {timelineGroups.map((group) => (\n <div key={group.key} className=\"space-y-3\">\n {/* Group header */}\n <div className=\"flex items-center gap-2\">\n <div className=\"h-px bg-border flex-1\" />\n <h3 className=\"text-sm font-medium text-muted-foreground px-2\">\n {group.label}\n </h3>\n <div className=\"h-px bg-border flex-1\" />\n </div>\n\n {/* Prompt cards in group */}\n <div className=\"space-y-2\">\n {group.prompts.map((prompt) => (\n <PromptCard\n key={prompt.id}\n prompt={prompt}\n onDelete={handleDeleteClick}\n actionsDisabled={isMutating}\n selected={selectedPromptIds.has(prompt.id)}\n onSelectChange={handleSelectPrompt}\n selectionMode={selectedPromptIds.size > 0 || prompts.some(p => selectedPromptIds.has(p.id))}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Insights panel */}\n <div className=\"lg:col-span-1 space-y-4\">\n <InsightsPanel\n insights={insightsData?.insights}\n patterns={insightsData?.patterns}\n suggestions={insightsData?.suggestions}\n selectedTool={selectedTool}\n onToolChange={setSelectedTool}\n onAnalyze={handleAnalyze}\n isAnalyzing={isAnalyzing || insightsLoading}\n className=\"sticky top-4\"\n />\n <InsightsHistoryList\n insights={insightsHistoryData?.insights}\n isLoading={insightsHistoryLoading}\n onInsightSelect={handleInsightSelect}\n />\n </div>\n </div>\n\n {/* Delete Confirmation Dialog */}\n <Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>{formatMessage({ id: 'prompts.dialog.deleteTitle' })}</DialogTitle>\n <DialogDescription>\n {formatMessage({ id: 'prompts.dialog.deleteConfirm' })}\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => {\n setDeleteDialogOpen(false);\n setPromptToDelete(null);\n }}\n >\n {formatMessage({ id: 'common.actions.cancel' })}\n </Button>\n <Button\n variant=\"destructive\"\n onClick={handleConfirmDelete}\n disabled={isAnalyzing}\n >\n {formatMessage({ id: 'common.actions.delete' })}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {/* Batch Delete Confirmation Dialog */}\n <Dialog open={batchDeleteDialogOpen} onOpenChange={setBatchDeleteDialogOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>{formatMessage({ id: 'prompts.dialog.batchDeleteTitle' })}</DialogTitle>\n <DialogDescription>\n {formatMessage({ id: 'prompts.dialog.batchDeleteConfirm' }, { count: selectedPromptIds.size })}\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => {\n setBatchDeleteDialogOpen(false);\n }}\n disabled={isBatchDeleting}\n >\n {formatMessage({ id: 'common.actions.cancel' })}\n </Button>\n <Button\n variant=\"destructive\"\n onClick={handleConfirmBatchDelete}\n disabled={isBatchDeleting}\n >\n {isBatchDeleting ? formatMessage({ id: 'common.actions.deleting' }, { defaultValue: 'Deleting...' }) : formatMessage({ id: 'common.actions.delete' })}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {/* Insight Detail Panel Overlay */}\n <InsightDetailPanelOverlay\n insight={selectedInsight}\n onClose={() => {\n setInsightDetailOpen(false);\n setSelectedInsight(null);\n }}\n onDelete={handleDeleteInsight}\n isDeleting={isDeletingInsight}\n showOverlay={true}\n />\n </div>\n );\n}\n\nexport default PromptHistoryPage;\n"],"names":["FileType","createLucideIcon","Minus","TrendingDown","TrendingUp","statCardVariants","cva","iconContainerVariants","StatCard","className","variant","title","value","Icon","trend","trendValue","isLoading","description","sparklineData","showSparkline","props","TrendIcon","trendColor","jsx","Card","cn","CardContent","jsxs","Sparkline","StatCardSkeleton","getQualityLevel","score","getBadgeVariant","level","QualityBadge","qualityScore","formatMessage","useIntl","labelKey","label","Badge","formatDate","dateString","formatContentLength","length","PromptCard","prompt","onDelete","actionsDisabled","defaultExpanded","selected","onSelectChange","selectionMode","expanded","setExpanded","React.useState","copied","setCopied","handleCopy","e","handleDelete","toggleExpanded","prev","handleSelectionChange","checked","handleCardClick","CardHeader","Checkbox","Calendar","Tag","Clock","tag","Button","Copy","Trash2","ChevronUp","ChevronDown","toolConfig","InsightCard","insight","config","Lightbulb","Sparkles","AlertTriangle","PatternCard","pattern","Wand2","SuggestionCard","suggestion","InsightsPanel","insights","patterns","suggestions","selectedTool","onToolChange","onAnalyze","isAnalyzing","hasContent","CardTitle","Loader2","RefreshCw","tool","PromptStats","totalCount","avgLength","topIntent","avgQualityScore","qualityDistribution","formatLength","MessageSquare","Hash","Star","PromptStatsSkeleton","STALE_TIME","usePromptHistory","options","filter","staleTime","enabled","queryClient","useQueryClient","projectPath","useWorkflowStore","selectProjectPath","queryEnabled","query","useQuery","workspaceQueryKeys","fetchPrompts","allPrompts","_a","_b","filteredPrompts","prompts","searchLower","p","t","date","start","end","promptsBySession","sessionKey","_d","_c","sum","intentCounts","category","_e","a","b","totalQualityScore","qualityScoreCount","refetch","invalidate","usePromptInsights","fetchPromptInsights","useInsightsHistory","limit","fetchInsightsHistory","useAnalyzePrompts","mutation","useMutation","analyzePrompts","useDeletePrompt","deletePrompt","promptId","previousPrompts","old","_error","_promptId","context","useBatchDeletePrompts","batchDeletePrompts","promptIds","_promptIds","useDeleteInsight","insightId","deleteInsight","previousInsights","i","_insightId","usePromptHistoryMutations","analyze","remove","batchRemove","extractUniqueProjects","projectsSet","BatchOperationToolbar","selectedCount","allSelected","onSelectAll","onClearSelection","isDeleting","X","Bot","Code2","Cpu","formatTimeAgo","timestamp","locale","diff","minutes","hours","days","isZh","getSeverityLevel","hasHigh","hasMedium","severityConfig","InsightHistoryCard","onClick","severity","ToolIcon","timeAgo","patternCount","suggestionCount","InsightsHistoryList","onInsightSelect","Brain","suggestionTypeConfig","formatRelativeTime","diffMs","diffMins","diffHours","diffDays","PatternItem","SuggestionItem","typeLabel","InsightDetailPanel","onClose","FileText","InsightDetailPanelOverlay","showOverlay","Fragment","PromptHistoryPage","searchQuery","setSearchQuery","intentFilter","setIntentFilter","projectFilter","setProjectFilter","setSelectedTool","deleteDialogOpen","setDeleteDialogOpen","promptToDelete","setPromptToDelete","selectedInsight","setSelectedInsight","setInsightDetailOpen","selectedPromptIds","setSelectedPromptIds","batchDeleteDialogOpen","setBatchDeleteDialogOpen","React.useMemo","stats","isFetching","error","insightsData","insightsLoading","insightsHistoryData","insightsHistoryLoading","isBatchDeleting","deleteInsightMutation","isDeletingInsight","isMutating","uniqueProjects","handleAnalyze","err","handleDeleteClick","handleConfirmDelete","handleClearSearch","handleInsightSelect","fetchInsightDetail","handleDeleteInsight","confirmMessage","successMessage","errorMessage","toggleIntentFilter","intent","clearFilters","handleSelectPrompt","next","handleSelectAll","handleClearSelection","handleBatchDeleteClick","handleConfirmBatchDelete","hasActiveFilters","timelineGroups","groups","sessionKeys","k","sessionPrompts","filtered","fp","dateGroups","datePrompts","aDate","History","AlertCircle","Search","Input","DropdownMenu","DropdownMenuTrigger","Filter","DropdownMenuContent","DropdownMenuLabel","DropdownMenuSeparator","DropdownMenuItem","project","FolderOpen","group","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","DialogFooter"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
1
+ {"version":3,"file":"PromptHistoryPage-CabgLjJU.js","sources":["../../../../node_modules/lucide-react/dist/esm/icons/file-type.js","../../../../node_modules/lucide-react/dist/esm/icons/minus.js","../../../../node_modules/lucide-react/dist/esm/icons/trending-down.js","../../../../node_modules/lucide-react/dist/esm/icons/trending-up.js","../../src/components/shared/StatCard.tsx","../../src/components/shared/QualityBadge.tsx","../../src/components/shared/PromptCard.tsx","../../src/components/shared/InsightsPanel.tsx","../../src/components/shared/PromptStats.tsx","../../src/hooks/usePromptHistory.ts","../../src/components/shared/BatchOperationToolbar.tsx","../../src/components/shared/InsightsHistoryList.tsx","../../src/components/shared/InsightDetailPanel.tsx","../../src/pages/PromptHistoryPage.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileType = createLucideIcon(\"FileType\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"path\", { d: \"M9 13v-1h6v1\", key: \"1bb014\" }],\n [\"path\", { d: \"M12 12v6\", key: \"3ahymv\" }],\n [\"path\", { d: \"M11 18h2\", key: \"12mj7e\" }]\n]);\n\nexport { FileType as default };\n//# sourceMappingURL=file-type.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Minus = createLucideIcon(\"Minus\", [[\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }]]);\n\nexport { Minus as default };\n//# sourceMappingURL=minus.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst TrendingDown = createLucideIcon(\"TrendingDown\", [\n [\"polyline\", { points: \"22 17 13.5 8.5 8.5 13.5 2 7\", key: \"1r2t7k\" }],\n [\"polyline\", { points: \"16 17 22 17 22 11\", key: \"11uiuu\" }]\n]);\n\nexport { TrendingDown as default };\n//# sourceMappingURL=trending-down.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst TrendingUp = createLucideIcon(\"TrendingUp\", [\n [\"polyline\", { points: \"22 7 13.5 15.5 8.5 10.5 2 17\", key: \"126l90\" }],\n [\"polyline\", { points: \"16 7 22 7 22 13\", key: \"kwv8wd\" }]\n]);\n\nexport { TrendingUp as default };\n//# sourceMappingURL=trending-up.js.map\n","// ========================================\r\n// StatCard Component\r\n// ========================================\r\n// Reusable stat card for dashboard metrics\r\n\r\nimport * as React from 'react';\r\nimport { cva, type VariantProps } from 'class-variance-authority';\r\nimport { cn } from '@/lib/utils';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { TrendingUp, TrendingDown, Minus, type LucideIcon } from 'lucide-react';\r\nimport { Sparkline } from '@/components/charts/Sparkline';\r\n\r\nconst statCardVariants = cva(\r\n 'transition-all duration-200 hover:shadow-md hover-glow',\r\n {\r\n variants: {\r\n variant: {\r\n default: 'border-border',\r\n primary: 'border-primary/30 bg-primary/5',\r\n success: 'border-success/30 bg-success/5',\r\n warning: 'border-warning/30 bg-warning/5',\r\n danger: 'border-destructive/30 bg-destructive/5',\r\n info: 'border-info/30 bg-info/5',\r\n },\r\n },\r\n defaultVariants: {\r\n variant: 'default',\r\n },\r\n }\r\n);\r\n\r\nconst iconContainerVariants = cva(\r\n 'flex h-10 w-10 items-center justify-center rounded-lg',\r\n {\r\n variants: {\r\n variant: {\r\n default: 'bg-muted text-muted-foreground',\r\n primary: 'bg-primary/10 text-primary',\r\n success: 'bg-success/10 text-success',\r\n warning: 'bg-warning/10 text-warning',\r\n danger: 'bg-destructive/10 text-destructive',\r\n info: 'bg-info/10 text-info',\r\n },\r\n },\r\n defaultVariants: {\r\n variant: 'default',\r\n },\r\n }\r\n);\r\n\r\nexport interface StatCardProps\r\n extends React.HTMLAttributes<HTMLDivElement>,\r\n VariantProps<typeof statCardVariants> {\r\n /** Card title */\r\n title: string;\r\n /** Stat value to display */\r\n value: number | string;\r\n /** Optional icon component */\r\n icon?: LucideIcon;\r\n /** Optional trend direction */\r\n trend?: 'up' | 'down' | 'neutral';\r\n /** Optional trend value (e.g., \"+12%\") */\r\n trendValue?: string;\r\n /** Loading state */\r\n isLoading?: boolean;\r\n /** Optional description */\r\n description?: string;\r\n /** Optional sparkline data (e.g., last 7 days) */\r\n sparklineData?: number[];\r\n /** Whether to show sparkline */\r\n showSparkline?: boolean;\r\n}\r\n\r\n/**\r\n * StatCard component for displaying dashboard metrics\r\n *\r\n * @example\r\n * ```tsx\r\n * <StatCard\r\n * title=\"Total Sessions\"\r\n * value={42}\r\n * icon={FolderIcon}\r\n * variant=\"primary\"\r\n * trend=\"up\"\r\n * trendValue=\"+5\"\r\n * />\r\n * ```\r\n */\r\nexport function StatCard({\r\n className,\r\n variant,\r\n title,\r\n value,\r\n icon: Icon,\r\n trend,\r\n trendValue,\r\n isLoading = false,\r\n description,\r\n sparklineData,\r\n showSparkline = false,\r\n ...props\r\n}: StatCardProps) {\r\n const TrendIcon = trend === 'up' ? TrendingUp : trend === 'down' ? TrendingDown : Minus;\r\n const trendColor =\r\n trend === 'up'\r\n ? 'text-success'\r\n : trend === 'down'\r\n ? 'text-destructive'\r\n : 'text-muted-foreground';\r\n\r\n return (\r\n <Card className={cn(statCardVariants({ variant }), className)} {...props}>\r\n <CardContent className=\"p-4\">\r\n <div className=\"flex items-start justify-between\">\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"text-sm font-medium text-muted-foreground truncate\">\r\n {title}\r\n </p>\r\n <div className=\"mt-2 flex items-baseline gap-2\">\r\n {isLoading ? (\r\n <div className=\"h-8 w-16 animate-pulse rounded bg-muted\" />\r\n ) : (\r\n <p className=\"text-2xl font-semibold text-card-foreground\">\r\n {typeof value === 'number' ? value.toLocaleString() : value}\r\n </p>\r\n )}\r\n {trend && trendValue && !isLoading && (\r\n <span className={cn('flex items-center text-xs font-medium', trendColor)}>\r\n <TrendIcon className=\"mr-0.5 h-3 w-3\" />\r\n {trendValue}\r\n </span>\r\n )}\r\n </div>\r\n {description && (\r\n <p className=\"mt-1 text-xs text-muted-foreground truncate\">\r\n {description}\r\n </p>\r\n )}\r\n {showSparkline && sparklineData && sparklineData.length > 0 && (\r\n <div className=\"mt-3 -mx-2\">\r\n <Sparkline\r\n data={sparklineData}\r\n height={40}\r\n strokeWidth={2}\r\n />\r\n </div>\r\n )}\r\n </div>\r\n {Icon && (\r\n <div className={cn(iconContainerVariants({ variant }))}>\r\n <Icon className=\"h-5 w-5\" />\r\n </div>\r\n )}\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n\r\n/**\r\n * Skeleton loader for StatCard\r\n */\r\nexport function StatCardSkeleton({ className }: { className?: string }) {\r\n return (\r\n <Card className={cn('animate-pulse', className)}>\r\n <CardContent className=\"p-4\">\r\n <div className=\"flex items-start justify-between\">\r\n <div className=\"flex-1\">\r\n <div className=\"h-4 w-20 rounded bg-muted\" />\r\n <div className=\"mt-3 h-8 w-16 rounded bg-muted\" />\r\n </div>\r\n <div className=\"h-10 w-10 rounded-lg bg-muted\" />\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n","// ========================================\n// QualityBadge Component\n// ========================================\n// Badge component for displaying prompt quality score\n\nimport { useIntl } from 'react-intl';\nimport { Badge } from '@/components/ui/Badge';\nimport type { Prompt } from '@/types/store';\n\nexport interface QualityBadgeProps {\n /** Quality score (0-100) */\n qualityScore?: number;\n /** Optional className */\n className?: string;\n}\n\n/**\n * Get quality level from score\n */\nfunction getQualityLevel(score?: number): 'high' | 'medium' | 'low' | 'none' {\n if (score === undefined || score === null) return 'none';\n if (score >= 80) return 'high';\n if (score >= 60) return 'medium';\n return 'low';\n}\n\n/**\n * Get badge variant for quality level\n */\nfunction getBadgeVariant(level: 'high' | 'medium' | 'low' | 'none'): 'success' | 'warning' | 'secondary' | 'outline' {\n switch (level) {\n case 'high':\n return 'success';\n case 'medium':\n return 'warning';\n case 'low':\n return 'secondary';\n default:\n return 'outline';\n }\n}\n\n/**\n * QualityBadge component - displays prompt quality score with color coding\n *\n * Quality levels:\n * - High (>=80): Green badge\n * - Medium (>=60): Yellow badge\n * - Low (<60): Gray badge\n * - No score: Outline badge\n */\nexport function QualityBadge({ qualityScore, className }: QualityBadgeProps) {\n const { formatMessage } = useIntl();\n const level = getQualityLevel(qualityScore);\n const variant = getBadgeVariant(level);\n\n const labelKey = `prompts.quality.${level}`;\n const label = formatMessage({ id: labelKey });\n\n if (level === 'none') {\n return null;\n }\n\n return (\n <Badge variant={variant} className={className}>\n {qualityScore !== undefined && `${qualityScore} `}\n {label}\n </Badge>\n );\n}\n\n/**\n * Hook to get quality badge data for a prompt\n */\nexport function useQualityBadge(prompt: Prompt) {\n const qualityScore = prompt.quality_score;\n const level = getQualityLevel(qualityScore);\n const variant = getBadgeVariant(level);\n\n return {\n qualityScore,\n level,\n variant,\n hasQuality: qualityScore !== undefined && qualityScore !== null,\n };\n}\n\nexport default QualityBadge;\n","// ========================================\n// PromptCard Component\n// ========================================\n// Card component for displaying prompt history items\n\nimport * as React from 'react';\nimport { useIntl } from 'react-intl';\nimport { cn } from '@/lib/utils';\nimport { Card, CardContent, CardHeader } from '@/components/ui/Card';\nimport { Badge } from '@/components/ui/Badge';\nimport { Button } from '@/components/ui/Button';\nimport { Checkbox } from '@/components/ui/Checkbox';\nimport { QualityBadge } from '@/components/shared/QualityBadge';\nimport {\n Copy,\n Trash2,\n ChevronDown,\n ChevronUp,\n Clock,\n Tag,\n Calendar,\n} from 'lucide-react';\nimport type { Prompt } from '@/types/store';\n\nexport interface PromptCardProps {\n /** Prompt data */\n prompt: Prompt;\n /** Called when delete action is triggered */\n onDelete?: (id: string) => void;\n /** Optional className */\n className?: string;\n /** Disabled state for actions */\n actionsDisabled?: boolean;\n /** Default expanded state */\n defaultExpanded?: boolean;\n /** Selection state for batch operations */\n selected?: boolean;\n /** Called when selection state changes */\n onSelectChange?: (id: string, selected: boolean) => void;\n /** Whether selection mode is active */\n selectionMode?: boolean;\n}\n\n/**\n * Format date to readable string\n */\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString);\n return date.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\n/**\n * Format content length\n */\nfunction formatContentLength(length: number): string {\n if (length >= 1000) {\n return `${(length / 1000).toFixed(1)}k chars`;\n }\n return `${length} chars`;\n}\n\n/**\n * PromptCard component for displaying prompt history items\n */\nexport function PromptCard({\n prompt,\n onDelete,\n className,\n actionsDisabled = false,\n defaultExpanded = false,\n selected = false,\n onSelectChange,\n selectionMode = false,\n}: PromptCardProps) {\n const { formatMessage } = useIntl();\n const [expanded, setExpanded] = React.useState(defaultExpanded);\n const [copied, setCopied] = React.useState(false);\n\n const handleCopy = async (e: React.MouseEvent) => {\n e.stopPropagation();\n try {\n await navigator.clipboard.writeText(prompt.content);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch {\n console.error('Failed to copy prompt');\n }\n };\n\n const handleDelete = (e: React.MouseEvent) => {\n e.stopPropagation();\n onDelete?.(prompt.id);\n };\n\n const toggleExpanded = () => {\n setExpanded((prev) => !prev);\n };\n\n const handleSelectionChange = (checked: boolean) => {\n onSelectChange?.(prompt.id, checked);\n };\n\n const handleCardClick = (e: React.MouseEvent) => {\n if (selectionMode && (e.target as HTMLElement).closest('.prompt-card-checkbox')) {\n return;\n }\n if (selectionMode) {\n handleSelectionChange(!selected);\n }\n };\n\n return (\n <Card\n className={cn(\n 'transition-all duration-200',\n selected && 'ring-2 ring-primary',\n selectionMode && 'cursor-pointer',\n className\n )}\n onClick={handleCardClick}\n >\n <CardHeader className=\"p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n {/* Checkbox for selection mode */}\n {selectionMode && (\n <div className=\"prompt-card-checkbox\">\n <Checkbox\n checked={selected}\n onCheckedChange={handleSelectionChange}\n className=\"mt-1\"\n />\n </div>\n )}\n\n {/* Title and metadata */}\n <div className={cn('flex-1 min-w-0', !selectionMode && 'ml-0')}>\n <div className=\"flex items-center gap-2 mb-2\">\n <h3 className=\"text-sm font-medium text-foreground truncate\">\n {prompt.title || formatMessage({ id: 'prompts.card.untitled' })}\n </h3>\n {prompt.category && (\n <Badge variant=\"secondary\" className=\"text-xs\">\n {prompt.category}\n </Badge>\n )}\n <QualityBadge qualityScore={prompt.quality_score} className=\"text-xs\" />\n </div>\n\n {/* Metadata */}\n <div className=\"flex flex-wrap items-center gap-3 text-xs text-muted-foreground\">\n <span className=\"flex items-center gap-1\">\n <Calendar className=\"h-3 w-3\" />\n {formatDate(prompt.createdAt)}\n </span>\n <span className=\"flex items-center gap-1\">\n <Tag className=\"h-3 w-3\" />\n {formatContentLength(prompt.content.length)}\n </span>\n {prompt.useCount !== undefined && prompt.useCount > 0 && (\n <span className=\"flex items-center gap-1\">\n <Clock className=\"h-3 w-3\" />\n {formatMessage({ id: 'prompts.card.used' }, { count: prompt.useCount })}\n </span>\n )}\n </div>\n\n {/* Tags */}\n {prompt.tags && prompt.tags.length > 0 && (\n <div className=\"flex flex-wrap gap-1 mt-2\">\n {prompt.tags.slice(0, 3).map((tag) => (\n <Badge key={tag} variant=\"outline\" className=\"text-xs\">\n {tag}\n </Badge>\n ))}\n {prompt.tags.length > 3 && (\n <Badge variant=\"outline\" className=\"text-xs\">\n +{prompt.tags.length - 3}\n </Badge>\n )}\n </div>\n )}\n </div>\n\n {/* Actions */}\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={handleCopy}\n disabled={actionsDisabled}\n title={formatMessage({ id: 'prompts.actions.copy' })}\n >\n <Copy className=\"h-4 w-4\" />\n <span className=\"sr-only\">{formatMessage({ id: 'prompts.actions.copy' })}</span>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-destructive hover:text-destructive\"\n onClick={handleDelete}\n disabled={actionsDisabled}\n title={formatMessage({ id: 'prompts.actions.delete' })}\n >\n <Trash2 className=\"h-4 w-4\" />\n <span className=\"sr-only\">{formatMessage({ id: 'prompts.actions.delete' })}</span>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={toggleExpanded}\n title={expanded ? formatMessage({ id: 'prompts.actions.collapse' }) : formatMessage({ id: 'prompts.actions.expand' })}\n >\n {expanded ? <ChevronUp className=\"h-4 w-4\" /> : <ChevronDown className=\"h-4 w-4\" />}\n <span className=\"sr-only\">{expanded ? 'Collapse' : 'Expand'}</span>\n </Button>\n </div>\n </div>\n\n {copied && (\n <p className=\"text-xs text-success mt-2\">\n {formatMessage({ id: 'prompts.actions.copied' })}\n </p>\n )}\n </CardHeader>\n\n {/* Expanded content */}\n {expanded && (\n <CardContent className=\"px-4 pb-4 pt-0\">\n <div className=\"rounded-lg bg-muted/50 p-3\">\n <pre className=\"text-sm whitespace-pre-wrap break-words text-foreground\">\n {prompt.content}\n </pre>\n </div>\n </CardContent>\n )}\n </Card>\n );\n}\n\nexport default PromptCard;\n","// ========================================\n// InsightsPanel Component\n// ========================================\n// AI insights panel for prompt history analysis\n\nimport { useIntl } from 'react-intl';\nimport { cn } from '@/lib/utils';\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card';\nimport { Badge } from '@/components/ui/Badge';\nimport { Button } from '@/components/ui/Button';\nimport {\n Sparkles,\n AlertTriangle,\n Lightbulb,\n Wand2,\n Loader2,\n RefreshCw,\n} from 'lucide-react';\nimport type { PromptInsight, Pattern, Suggestion } from '@/types/store';\n\nexport interface InsightsPanelProps {\n /** Available insights */\n insights?: PromptInsight[];\n /** Detected patterns */\n patterns?: Pattern[];\n /** AI suggestions */\n suggestions?: Suggestion[];\n /** Currently selected tool */\n selectedTool: 'gemini' | 'qwen' | 'codex';\n /** Called when tool selection changes */\n onToolChange: (tool: 'gemini' | 'qwen' | 'codex') => void;\n /** Called when analyze is triggered */\n onAnalyze: () => void;\n /** Loading state */\n isAnalyzing?: boolean;\n /** Optional className */\n className?: string;\n}\n\nconst toolConfig = {\n gemini: {\n label: 'Gemini',\n color: 'text-blue-500',\n bgColor: 'bg-blue-500/10',\n },\n qwen: {\n label: 'Qwen',\n color: 'text-purple-500',\n bgColor: 'bg-purple-500/10',\n },\n codex: {\n label: 'Codex',\n color: 'text-green-500',\n bgColor: 'bg-green-500/10',\n },\n};\n\n/**\n * InsightCard component for displaying a single insight\n */\nfunction InsightCard({ insight }: { insight: PromptInsight }) {\n const { formatMessage } = useIntl();\n\n const typeConfig = {\n suggestion: {\n icon: Lightbulb,\n variant: 'info' as const,\n color: 'text-blue-500',\n },\n optimization: {\n icon: Sparkles,\n variant: 'success' as const,\n color: 'text-green-500',\n },\n warning: {\n icon: AlertTriangle,\n variant: 'warning' as const,\n color: 'text-orange-500',\n },\n };\n\n const config = typeConfig[insight.type];\n const Icon = config.icon;\n\n return (\n <div className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50\">\n <div className={cn('flex-shrink-0', config.color)}>\n <Icon className=\"h-4 w-4\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm text-foreground\">{insight.content}</p>\n <div className=\"flex items-center gap-2 mt-1\">\n <Badge variant=\"outline\" className=\"text-xs\">\n {Math.round(insight.confidence * 100)}% {formatMessage({ id: 'prompts.insights.confidence' })}\n </Badge>\n </div>\n </div>\n </div>\n );\n}\n\n/**\n * PatternCard component for displaying a detected pattern\n */\nfunction PatternCard({ pattern }: { pattern: Pattern }) {\n return (\n <div className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50\">\n <div className=\"flex-shrink-0 text-purple-500\">\n <Wand2 className=\"h-4 w-4\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-foreground\">{pattern.name}</p>\n <p className=\"text-xs text-muted-foreground mt-1\">{pattern.description}</p>\n {pattern.example && (\n <code className=\"block mt-2 text-xs bg-background rounded p-2 overflow-x-auto\">\n {pattern.example}\n </code>\n )}\n {pattern.severity && (\n <Badge variant={pattern.severity === 'error' ? 'destructive' : pattern.severity === 'warning' ? 'warning' : 'secondary'} className=\"mt-2 text-xs\">\n {pattern.severity}\n </Badge>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * SuggestionCard component for displaying a suggestion\n */\nfunction SuggestionCard({ suggestion }: { suggestion: Suggestion }) {\n const { formatMessage } = useIntl();\n\n const typeConfig = {\n refactor: { color: 'text-blue-500', label: formatMessage({ id: 'prompts.suggestions.types.refactor' }) },\n optimize: { color: 'text-green-500', label: formatMessage({ id: 'prompts.suggestions.types.optimize' }) },\n fix: { color: 'text-orange-500', label: formatMessage({ id: 'prompts.suggestions.types.fix' }) },\n document: { color: 'text-purple-500', label: formatMessage({ id: 'prompts.suggestions.types.document' }) },\n };\n\n const config = typeConfig[suggestion.type];\n\n return (\n <div className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50\">\n <div className={cn('flex-shrink-0', config.color)}>\n <Lightbulb className=\"h-4 w-4\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <p className=\"text-sm font-medium text-foreground\">{suggestion.title}</p>\n <Badge variant=\"outline\" className=\"text-xs\">\n {config.label}\n </Badge>\n </div>\n <p className=\"text-xs text-muted-foreground mt-1\">{suggestion.description}</p>\n {suggestion.code && (\n <code className=\"block mt-2 text-xs bg-background rounded p-2 overflow-x-auto\">\n {suggestion.code}\n </code>\n )}\n {suggestion.effort && (\n <Badge variant=\"secondary\" className=\"mt-2 text-xs\">\n {formatMessage({ id: 'prompts.suggestions.effort' })}: {suggestion.effort}\n </Badge>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * InsightsPanel component - AI analysis panel for prompt history\n */\nexport function InsightsPanel({\n insights = [],\n patterns = [],\n suggestions = [],\n selectedTool,\n onToolChange,\n onAnalyze,\n isAnalyzing = false,\n className,\n}: InsightsPanelProps) {\n const { formatMessage } = useIntl();\n\n const hasContent = insights.length > 0 || patterns.length > 0 || suggestions.length > 0;\n\n return (\n <Card className={cn('flex flex-col h-full', className)}>\n <CardHeader className=\"pb-3\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-lg flex items-center gap-2\">\n <Sparkles className=\"h-5 w-5 text-primary\" />\n {formatMessage({ id: 'prompts.insights.title' })}\n </CardTitle>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => onAnalyze()}\n disabled={isAnalyzing}\n className=\"gap-2\"\n >\n {isAnalyzing ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <RefreshCw className=\"h-4 w-4\" />\n )}\n {formatMessage({ id: 'prompts.insights.analyze' })}\n </Button>\n </div>\n\n {/* Tool selector */}\n <div className=\"flex items-center gap-2 mt-3\">\n <span className=\"text-sm text-muted-foreground\">\n {formatMessage({ id: 'prompts.insights.selectTool' })}:\n </span>\n <div className=\"flex gap-1\">\n {(Object.keys(toolConfig) as Array<keyof typeof toolConfig>).map((tool) => (\n <button\n key={tool}\n onClick={() => onToolChange(tool)}\n className={cn(\n 'px-3 py-1.5 rounded-md text-sm font-medium transition-colors',\n selectedTool === tool\n ? cn(toolConfig[tool].bgColor, toolConfig[tool].color)\n : 'bg-muted text-muted-foreground hover:bg-muted/80'\n )}\n >\n {toolConfig[tool].label}\n </button>\n ))}\n </div>\n </div>\n </CardHeader>\n\n <CardContent className=\"flex-1 overflow-y-auto\">\n {!hasContent && !isAnalyzing ? (\n <div className=\"flex flex-col items-center justify-center py-12 px-4 text-center\">\n <Sparkles className=\"h-12 w-12 text-muted-foreground/50 mb-4\" />\n <h3 className=\"text-sm font-medium text-foreground mb-1\">\n {formatMessage({ id: 'prompts.insights.empty.title' })}\n </h3>\n <p className=\"text-xs text-muted-foreground max-w-sm\">\n {formatMessage({ id: 'prompts.insights.empty.message' })}\n </p>\n </div>\n ) : (\n <div className=\"space-y-4\">\n {/* Insights section */}\n {insights.length > 0 && (\n <div>\n <h4 className=\"text-sm font-medium text-foreground mb-2 flex items-center gap-2\">\n <Lightbulb className=\"h-4 w-4\" />\n {formatMessage({ id: 'prompts.insights.sections.insights' })}\n </h4>\n <div className=\"space-y-2\">\n {insights.map((insight) => (\n <InsightCard key={insight.id} insight={insight} />\n ))}\n </div>\n </div>\n )}\n\n {/* Patterns section */}\n {patterns.length > 0 && (\n <div>\n <h4 className=\"text-sm font-medium text-foreground mb-2 flex items-center gap-2\">\n <Wand2 className=\"h-4 w-4\" />\n {formatMessage({ id: 'prompts.insights.sections.patterns' })}\n </h4>\n <div className=\"space-y-2\">\n {patterns.map((pattern) => (\n <PatternCard key={pattern.id} pattern={pattern} />\n ))}\n </div>\n </div>\n )}\n\n {/* Suggestions section */}\n {suggestions.length > 0 && (\n <div>\n <h4 className=\"text-sm font-medium text-foreground mb-2 flex items-center gap-2\">\n <Sparkles className=\"h-4 w-4\" />\n {formatMessage({ id: 'prompts.insights.sections.suggestions' })}\n </h4>\n <div className=\"space-y-2\">\n {suggestions.map((suggestion) => (\n <SuggestionCard key={suggestion.id} suggestion={suggestion} />\n ))}\n </div>\n </div>\n )}\n\n {isAnalyzing && (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"h-6 w-6 animate-spin text-muted-foreground\" />\n <span className=\"ml-2 text-sm text-muted-foreground\">\n {formatMessage({ id: 'prompts.insights.analyzing' })}\n </span>\n </div>\n )}\n </div>\n )}\n </CardContent>\n </Card>\n );\n}\n\nexport default InsightsPanel;\n","// ========================================\n// PromptStats Component\n// ========================================\n// Statistics display for prompt history\n\nimport { useIntl } from 'react-intl';\nimport { StatCard, StatCardSkeleton } from '@/components/shared/StatCard';\nimport { MessageSquare, FileType, Hash, Star } from 'lucide-react';\n\nexport interface QualityDistribution {\n high: number;\n medium: number;\n low: number;\n}\n\nexport interface PromptStatsProps {\n /** Total number of prompts */\n totalCount: number;\n /** Average prompt length in characters */\n avgLength: number;\n /** Most common intent/category */\n topIntent: string | null;\n /** Average quality score (0-100) */\n avgQualityScore?: number;\n /** Quality distribution */\n qualityDistribution?: QualityDistribution;\n /** Loading state */\n isLoading?: boolean;\n}\n\n/**\n * PromptStats component - displays prompt history statistics\n *\n * Shows four key metrics:\n * - Total prompts: overall count of stored prompts\n * - Average length: mean character count across all prompts\n * - Top intent: most frequently used category\n * - Quality: average quality score with distribution\n */\nexport function PromptStats({\n totalCount,\n avgLength,\n topIntent,\n avgQualityScore,\n qualityDistribution,\n isLoading = false,\n}: PromptStatsProps) {\n const { formatMessage } = useIntl();\n\n // Format average length for display\n const formatLength = (length: number): string => {\n if (length >= 1000) {\n return `${(length / 1000).toFixed(1)}k`;\n }\n return length.toString();\n };\n\n return (\n <div className=\"grid gap-4 grid-cols-1 md:grid-cols-4\">\n <StatCard\n title={formatMessage({ id: 'prompts.stats.totalCount' })}\n value={totalCount}\n icon={MessageSquare}\n variant=\"primary\"\n isLoading={isLoading}\n description={formatMessage({ id: 'prompts.stats.totalCountDesc' })}\n />\n <StatCard\n title={formatMessage({ id: 'prompts.stats.avgLength' })}\n value={formatLength(avgLength)}\n icon={FileType}\n variant=\"info\"\n isLoading={isLoading}\n description={formatMessage({ id: 'prompts.stats.avgLengthDesc' })}\n />\n <StatCard\n title={formatMessage({ id: 'prompts.stats.topIntent' })}\n value={topIntent || formatMessage({ id: 'prompts.stats.noIntent' })}\n icon={Hash}\n variant=\"success\"\n isLoading={isLoading}\n description={formatMessage({ id: 'prompts.stats.topIntentDesc' })}\n />\n <StatCard\n title={formatMessage({ id: 'prompts.stats.avgQuality' })}\n value={avgQualityScore !== undefined ? Math.round(avgQualityScore) : 'N/A'}\n icon={Star}\n variant=\"warning\"\n isLoading={isLoading}\n description={qualityDistribution\n ? `${formatMessage({ id: 'prompts.quality.high' })}: ${qualityDistribution.high} | ${formatMessage({ id: 'prompts.quality.medium' })}: ${qualityDistribution.medium} | ${formatMessage({ id: 'prompts.quality.low' })}: ${qualityDistribution.low}`\n : formatMessage({ id: 'prompts.stats.avgQualityDesc' })\n }\n />\n </div>\n );\n}\n\n/**\n * Skeleton loader for PromptStats\n */\nexport function PromptStatsSkeleton() {\n return (\n <div className=\"grid gap-4 grid-cols-1 md:grid-cols-4\">\n <StatCardSkeleton />\n <StatCardSkeleton />\n <StatCardSkeleton />\n <StatCardSkeleton />\n </div>\n );\n}\n\nexport default PromptStats;\n","// ========================================\r\n// usePromptHistory Hook\r\n// ========================================\r\n// TanStack Query hooks for prompt history with real-time updates\r\n\r\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport {\r\n fetchPrompts,\r\n fetchPromptInsights,\r\n fetchInsightsHistory,\r\n analyzePrompts,\r\n deletePrompt,\r\n batchDeletePrompts,\r\n deleteInsight,\r\n type Prompt,\r\n type PromptsResponse,\r\n type PromptInsightsResponse,\r\n type InsightsHistoryResponse,\r\n} from '../lib/api';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\nimport { workspaceQueryKeys } from '@/lib/queryKeys';\r\n\r\n// Default stale time: 30 seconds (prompts update less frequently)\r\nconst STALE_TIME = 30 * 1000;\r\n\r\nexport interface PromptHistoryFilter {\r\n search?: string;\r\n intent?: string;\r\n project?: string;\r\n dateRange?: { start: Date | null; end: Date | null };\r\n}\r\n\r\nexport interface UsePromptHistoryOptions {\r\n filter?: PromptHistoryFilter;\r\n staleTime?: number;\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface UsePromptHistoryReturn {\r\n prompts: Prompt[];\r\n allPrompts: Prompt[];\r\n totalPrompts: number;\r\n promptsBySession: Record<string, Prompt[]>;\r\n stats: {\r\n totalCount: number;\r\n avgLength: number;\r\n topIntent: string | null;\r\n avgQualityScore?: number;\r\n qualityDistribution?: {\r\n high: number;\r\n medium: number;\r\n low: number;\r\n };\r\n };\r\n isLoading: boolean;\r\n isFetching: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n invalidate: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching and filtering prompt history\r\n */\r\nexport function usePromptHistory(options: UsePromptHistoryOptions = {}): UsePromptHistoryReturn {\r\n const { filter, staleTime = STALE_TIME, enabled = true } = options;\r\n const queryClient = useQueryClient();\r\n\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n const queryEnabled = enabled && !!projectPath;\r\n\r\n const query = useQuery({\r\n queryKey: workspaceQueryKeys.promptsList(projectPath),\r\n queryFn: () => fetchPrompts(projectPath),\r\n staleTime,\r\n enabled: queryEnabled,\r\n retry: 2,\r\n });\r\n\r\n const allPrompts = query.data?.prompts ?? [];\r\n const totalCount = query.data?.total ?? 0;\r\n\r\n // Apply filters\r\n const filteredPrompts = (() => {\r\n let prompts = allPrompts;\r\n\r\n if (filter?.search) {\r\n const searchLower = filter.search.toLowerCase();\r\n prompts = prompts.filter(\r\n (p) =>\r\n p.title?.toLowerCase().includes(searchLower) ||\r\n p.content.toLowerCase().includes(searchLower) ||\r\n p.tags?.some((t) => t.toLowerCase().includes(searchLower))\r\n );\r\n }\r\n\r\n if (filter?.intent) {\r\n prompts = prompts.filter((p) => p.category === filter.intent);\r\n }\r\n\r\n if (filter?.project) {\r\n prompts = prompts.filter((p) => p.project === filter.project);\r\n }\r\n\r\n if (filter?.dateRange?.start || filter?.dateRange?.end) {\r\n prompts = prompts.filter((p) => {\r\n const date = new Date(p.createdAt);\r\n const start = filter.dateRange?.start;\r\n const end = filter.dateRange?.end;\r\n if (start && date < start) return false;\r\n if (end && date > end) return false;\r\n return true;\r\n });\r\n }\r\n\r\n return prompts;\r\n })();\r\n\r\n // Group by session for timeline view\r\n const promptsBySession: Record<string, Prompt[]> = {};\r\n for (const prompt of allPrompts) {\r\n const sessionKey = prompt.tags?.find((t) => t.startsWith('session:'))?.replace('session:', '') || 'ungrouped';\r\n if (!promptsBySession[sessionKey]) {\r\n promptsBySession[sessionKey] = [];\r\n }\r\n promptsBySession[sessionKey].push(prompt);\r\n }\r\n\r\n // Calculate stats\r\n const avgLength = allPrompts.length > 0\r\n ? Math.round(allPrompts.reduce((sum, p) => sum + p.content.length, 0) / allPrompts.length)\r\n : 0;\r\n\r\n const intentCounts: Record<string, number> = {};\r\n for (const prompt of allPrompts) {\r\n const category = prompt.category || 'uncategorized';\r\n intentCounts[category] = (intentCounts[category] || 0) + 1;\r\n }\r\n const topIntent = Object.entries(intentCounts).sort((a, b) => b[1] - a[1])[0]?.[0] || null;\r\n\r\n // Calculate quality distribution\r\n const qualityDistribution = {\r\n high: 0,\r\n medium: 0,\r\n low: 0,\r\n };\r\n let totalQualityScore = 0;\r\n let qualityScoreCount = 0;\r\n\r\n for (const prompt of allPrompts) {\r\n if (prompt.quality_score !== undefined && prompt.quality_score !== null) {\r\n totalQualityScore += prompt.quality_score;\r\n qualityScoreCount++;\r\n\r\n if (prompt.quality_score >= 80) {\r\n qualityDistribution.high++;\r\n } else if (prompt.quality_score >= 60) {\r\n qualityDistribution.medium++;\r\n } else {\r\n qualityDistribution.low++;\r\n }\r\n }\r\n }\r\n\r\n const avgQualityScore = qualityScoreCount > 0\r\n ? totalQualityScore / qualityScoreCount\r\n : undefined;\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n const invalidate = async () => {\r\n await queryClient.invalidateQueries({ queryKey: workspaceQueryKeys.prompts(projectPath) });\r\n };\r\n\r\n return {\r\n prompts: filteredPrompts,\r\n allPrompts,\r\n totalPrompts: totalCount,\r\n promptsBySession,\r\n stats: {\r\n totalCount: allPrompts.length,\r\n avgLength,\r\n topIntent,\r\n avgQualityScore,\r\n qualityDistribution,\r\n },\r\n isLoading: query.isLoading,\r\n isFetching: query.isFetching,\r\n error: query.error,\r\n refetch,\r\n invalidate,\r\n };\r\n}\r\n\r\n\r\n\r\n/**\r\n * Hook for fetching prompt insights\r\n */\r\nexport function usePromptInsights(options: { enabled?: boolean; staleTime?: number } = {}) {\r\n const { enabled = true, staleTime = STALE_TIME } = options;\r\n\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n const queryEnabled = enabled && !!projectPath;\r\n\r\n return useQuery({\r\n queryKey: workspaceQueryKeys.promptsInsights(projectPath),\r\n queryFn: () => fetchPromptInsights(projectPath),\r\n staleTime,\r\n enabled: queryEnabled,\r\n retry: 2,\r\n });\r\n}\r\n\r\n/**\r\n * Hook for fetching insights history (past CLI analyses)\r\n */\r\nexport function useInsightsHistory(options: {\r\n limit?: number;\r\n enabled?: boolean;\r\n staleTime?: number;\r\n} = {}) {\r\n const { limit = 20, enabled = true, staleTime = STALE_TIME } = options;\r\n\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n const queryEnabled = enabled && !!projectPath;\r\n\r\n return useQuery({\r\n queryKey: workspaceQueryKeys.promptsInsightsHistory(projectPath),\r\n queryFn: () => fetchInsightsHistory(projectPath, limit),\r\n staleTime,\r\n enabled: queryEnabled,\r\n retry: 2,\r\n });\r\n}\r\n\r\n// ========== Mutations ==========\r\n\r\nexport interface UseAnalyzePromptsReturn {\r\n analyzePrompts: (request?: { tool?: 'gemini' | 'qwen' | 'codex'; limit?: number }) => Promise<PromptInsightsResponse>;\r\n isAnalyzing: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useAnalyzePrompts(): UseAnalyzePromptsReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: analyzePrompts,\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: workspaceQueryKeys.promptsInsights(projectPath) });\r\n },\r\n });\r\n\r\n return {\r\n analyzePrompts: mutation.mutateAsync,\r\n isAnalyzing: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseDeletePromptReturn {\r\n deletePrompt: (promptId: string) => Promise<void>;\r\n isDeleting: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useDeletePrompt(): UseDeletePromptReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: deletePrompt,\r\n onMutate: async (promptId) => {\r\n await queryClient.cancelQueries({ queryKey: workspaceQueryKeys.prompts(projectPath) });\r\n const previousPrompts = queryClient.getQueryData<PromptsResponse>(workspaceQueryKeys.promptsList(projectPath));\r\n\r\n queryClient.setQueryData<PromptsResponse>(workspaceQueryKeys.promptsList(projectPath), (old) => {\r\n if (!old) return old;\r\n return {\r\n ...old,\r\n prompts: old.prompts.filter((p) => p.id !== promptId),\r\n total: old.total - 1,\r\n };\r\n });\r\n\r\n return { previousPrompts };\r\n },\r\n onError: (_error, _promptId, context) => {\r\n if (context?.previousPrompts) {\r\n queryClient.setQueryData(workspaceQueryKeys.promptsList(projectPath), context.previousPrompts);\r\n }\r\n },\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: workspaceQueryKeys.prompts(projectPath) });\r\n },\r\n });\r\n\r\n return {\r\n deletePrompt: mutation.mutateAsync,\r\n isDeleting: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseBatchDeletePromptsReturn {\r\n batchDeletePrompts: (promptIds: string[]) => Promise<{ deleted: number }>;\r\n isBatchDeleting: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useBatchDeletePrompts(): UseBatchDeletePromptsReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: batchDeletePrompts,\r\n onMutate: async (promptIds) => {\r\n await queryClient.cancelQueries({ queryKey: workspaceQueryKeys.prompts(projectPath) });\r\n const previousPrompts = queryClient.getQueryData<PromptsResponse>(workspaceQueryKeys.promptsList(projectPath));\r\n\r\n queryClient.setQueryData<PromptsResponse>(workspaceQueryKeys.promptsList(projectPath), (old) => {\r\n if (!old) return old;\r\n return {\r\n ...old,\r\n prompts: old.prompts.filter((p) => !promptIds.includes(p.id)),\r\n total: old.total - promptIds.length,\r\n };\r\n });\r\n\r\n return { previousPrompts };\r\n },\r\n onError: (_error, _promptIds, context) => {\r\n if (context?.previousPrompts) {\r\n queryClient.setQueryData(workspaceQueryKeys.promptsList(projectPath), context.previousPrompts);\r\n }\r\n },\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: workspaceQueryKeys.prompts(projectPath) });\r\n },\r\n });\r\n\r\n return {\r\n batchDeletePrompts: mutation.mutateAsync,\r\n isBatchDeleting: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseDeleteInsightReturn {\r\n deleteInsight: (insightId: string) => Promise<{ success: boolean }>;\r\n isDeleting: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useDeleteInsight(): UseDeleteInsightReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: (insightId: string) => deleteInsight(insightId, projectPath),\r\n onMutate: async (insightId) => {\r\n await queryClient.cancelQueries({ queryKey: workspaceQueryKeys.promptsInsightsHistory(projectPath) });\r\n const previousInsights = queryClient.getQueryData<InsightsHistoryResponse>(workspaceQueryKeys.promptsInsightsHistory(projectPath));\r\n\r\n queryClient.setQueryData<InsightsHistoryResponse>(workspaceQueryKeys.promptsInsightsHistory(projectPath), (old) => {\r\n if (!old) return old;\r\n return {\r\n ...old,\r\n insights: old.insights.filter((i) => i.id !== insightId),\r\n };\r\n });\r\n\r\n return { previousInsights };\r\n },\r\n onError: (_error, _insightId, context) => {\r\n if (context?.previousInsights) {\r\n queryClient.setQueryData(workspaceQueryKeys.promptsInsightsHistory(projectPath), context.previousInsights);\r\n }\r\n },\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: workspaceQueryKeys.promptsInsightsHistory(projectPath) });\r\n },\r\n });\r\n\r\n return {\r\n deleteInsight: mutation.mutateAsync,\r\n isDeleting: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\n/**\r\n * Combined hook for all prompt history mutations\r\n */\r\nexport function usePromptHistoryMutations() {\r\n const analyze = useAnalyzePrompts();\r\n const remove = useDeletePrompt();\r\n const batchRemove = useBatchDeletePrompts();\r\n\r\n return {\r\n analyzePrompts: analyze.analyzePrompts,\r\n deletePrompt: remove.deletePrompt,\r\n batchDeletePrompts: batchRemove.batchDeletePrompts,\r\n isAnalyzing: analyze.isAnalyzing,\r\n isDeleting: remove.isDeleting,\r\n isBatchDeleting: batchRemove.isBatchDeleting,\r\n isMutating: analyze.isAnalyzing || remove.isDeleting || batchRemove.isBatchDeleting,\r\n };\r\n}\r\n\r\n/**\r\n * Extract unique projects from prompts list\r\n */\r\nexport function extractUniqueProjects(prompts: Prompt[]): string[] {\r\n const projectsSet = new Set<string>();\r\n for (const prompt of prompts) {\r\n if (prompt.project) {\r\n projectsSet.add(prompt.project);\r\n }\r\n }\r\n return Array.from(projectsSet).sort();\r\n}\r\n","// ========================================\n// BatchOperationToolbar Component\n// ========================================\n// Toolbar for batch operations on prompts\n\nimport { useIntl } from 'react-intl';\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/Button';\nimport { Checkbox } from '@/components/ui/Checkbox';\nimport { Trash2, X } from 'lucide-react';\n\nexport interface BatchOperationToolbarProps {\n /** Number of selected items */\n selectedCount: number;\n /** Whether all items are selected */\n allSelected: boolean;\n /** Called when select all is toggled */\n onSelectAll: (selected: boolean) => void;\n /** Called when clear selection is triggered */\n onClearSelection: () => void;\n /** Called when batch delete is triggered */\n onDelete: () => void;\n /** Whether delete operation is in progress */\n isDeleting?: boolean;\n /** Optional className */\n className?: string;\n}\n\n/**\n * BatchOperationToolbar component for bulk actions\n */\nexport function BatchOperationToolbar({\n selectedCount,\n allSelected,\n onSelectAll,\n onClearSelection,\n onDelete,\n isDeleting = false,\n className,\n}: BatchOperationToolbarProps) {\n const { formatMessage } = useIntl();\n\n if (selectedCount === 0) {\n return null;\n }\n\n return (\n <div\n className={cn(\n 'flex items-center justify-between gap-4 p-3 bg-primary/10 rounded-lg border border-primary/20',\n className\n )}\n >\n {/* Selection info and select all */}\n <div className=\"flex items-center gap-3\">\n <Checkbox\n checked={allSelected}\n onCheckedChange={(checked) => onSelectAll(checked === true)}\n aria-label={formatMessage({ id: 'prompts.batch.selectAll' })}\n />\n <span className=\"text-sm font-medium text-foreground\">\n {formatMessage({ id: 'prompts.batch.selected' }, { count: selectedCount })}\n </span>\n </div>\n\n {/* Action buttons */}\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onClearSelection}\n disabled={isDeleting}\n >\n <X className=\"h-4 w-4 mr-1\" />\n {formatMessage({ id: 'prompts.batch.clearSelection' })}\n </Button>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={onDelete}\n disabled={isDeleting}\n >\n <Trash2 className=\"h-4 w-4 mr-1\" />\n {formatMessage({ id: 'prompts.batch.deleteSelected' })}\n </Button>\n </div>\n </div>\n );\n}\n\nexport default BatchOperationToolbar;\n","// ========================================\r\n// InsightsHistoryList Component\r\n// ========================================\r\n// Display past insight analysis results with tool icon, timestamp, pattern count, and suggestion count\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { cn } from '@/lib/utils';\r\nimport {\r\n Sparkles,\r\n Bot,\r\n Code2,\r\n Cpu,\r\n Brain,\r\n Loader2,\r\n} from 'lucide-react';\r\nimport type { InsightHistory } from '@/lib/api';\r\n\r\nexport interface InsightsHistoryListProps {\r\n /** Array of historical insights */\r\n insights?: InsightHistory[];\r\n /** Loading state */\r\n isLoading?: boolean;\r\n /** Called when an insight card is clicked */\r\n onInsightSelect?: (insightId: string) => void;\r\n /** Optional className */\r\n className?: string;\r\n}\r\n\r\n// Tool icon mapping\r\nconst toolConfig = {\r\n gemini: {\r\n icon: Sparkles,\r\n color: 'text-blue-500',\r\n bgColor: 'bg-blue-500/10',\r\n label: 'Gemini',\r\n },\r\n qwen: {\r\n icon: Bot,\r\n color: 'text-purple-500',\r\n bgColor: 'bg-purple-500/10',\r\n label: 'Qwen',\r\n },\r\n codex: {\r\n icon: Code2,\r\n color: 'text-green-500',\r\n bgColor: 'bg-green-500/10',\r\n label: 'Codex',\r\n },\r\n default: {\r\n icon: Cpu,\r\n color: 'text-gray-500',\r\n bgColor: 'bg-gray-500/10',\r\n label: 'CLI',\r\n },\r\n};\r\n\r\n/**\r\n * Format timestamp to relative time (e.g., \"2h ago\")\r\n */\r\nfunction formatTimeAgo(timestamp: string, locale: string): string {\r\n const date = new Date(timestamp);\r\n const now = new Date();\r\n const diff = now.getTime() - date.getTime();\r\n const minutes = Math.floor(diff / 60000);\r\n const hours = Math.floor(diff / 3600000);\r\n const days = Math.floor(diff / 86400000);\r\n\r\n const isZh = locale === 'zh';\r\n\r\n if (minutes < 1) return isZh ? '刚刚' : 'Just now';\r\n if (minutes < 60) return isZh ? `${minutes} 分钟前` : `${minutes}m ago`;\r\n if (hours < 24) return isZh ? `${hours} 小时前` : `${hours}h ago`;\r\n if (days < 7) return isZh ? `${days} 天前` : `${days}d ago`;\r\n return date.toLocaleDateString();\r\n}\r\n\r\n/**\r\n * Get severity level from patterns\r\n * Pattern severity: 'error' | 'warning' | 'info'\r\n */\r\nfunction getSeverityLevel(patterns: InsightHistory['patterns']): 'low' | 'medium' | 'high' {\r\n if (!patterns || patterns.length === 0) return 'low';\r\n const hasHigh = patterns.some(p => p.severity === 'error');\r\n const hasMedium = patterns.some(p => p.severity === 'warning');\r\n return hasHigh ? 'high' : hasMedium ? 'medium' : 'low';\r\n}\r\n\r\n/**\r\n * Severity color mapping\r\n */\r\nconst severityConfig = {\r\n low: {\r\n border: 'border-l-4 border-l-green-500',\r\n },\r\n medium: {\r\n border: 'border-l-4 border-l-yellow-500',\r\n },\r\n high: {\r\n border: 'border-l-4 border-l-red-500',\r\n },\r\n};\r\n\r\n/**\r\n * InsightHistoryCard component for displaying a single insight history entry\r\n */\r\nfunction InsightHistoryCard({\r\n insight,\r\n locale,\r\n onClick,\r\n}: {\r\n insight: InsightHistory;\r\n locale: string;\r\n onClick: () => void;\r\n}) {\r\n const { formatMessage } = useIntl();\r\n const severity = getSeverityLevel(insight.patterns);\r\n const config = toolConfig[insight.tool as keyof typeof toolConfig] ?? toolConfig.default;\r\n const ToolIcon = config.icon;\r\n const timeAgo = formatTimeAgo(insight.created_at, locale);\r\n const patternCount = insight.patterns?.length ?? 0;\r\n const suggestionCount = insight.suggestions?.length ?? 0;\r\n\r\n return (\r\n <div\r\n onClick={onClick}\r\n className={cn(\r\n 'p-3 rounded-lg border border-border bg-card hover:bg-muted/50 cursor-pointer transition-colors',\r\n 'border-l-4',\r\n severityConfig[severity].border\r\n )}\r\n >\r\n {/* Header: Tool and timestamp */}\r\n <div className=\"flex items-center justify-between mb-2\">\r\n <div className={cn('flex items-center gap-1.5', config.color)}>\r\n <ToolIcon className=\"h-3.5 w-3.5\" />\r\n <span className=\"text-xs font-medium\">{config.label}</span>\r\n </div>\r\n <div className=\"text-xs text-muted-foreground\">{timeAgo}</div>\r\n </div>\r\n\r\n {/* Stats: Patterns, Suggestions, Prompts */}\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"flex items-baseline gap-1\">\r\n <span className=\"text-sm font-semibold text-foreground\">{patternCount}</span>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'prompts.insightsHistory.patterns' })}\r\n </span>\r\n </div>\r\n <div className=\"flex items-baseline gap-1\">\r\n <span className=\"text-sm font-semibold text-foreground\">{suggestionCount}</span>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'prompts.insightsHistory.suggestions' })}\r\n </span>\r\n </div>\r\n <div className=\"flex items-baseline gap-1\">\r\n <span className=\"text-sm font-semibold text-foreground\">{insight.prompt_count}</span>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'prompts.insightsHistory.prompts' })}\r\n </span>\r\n </div>\r\n </div>\r\n\r\n {/* Pattern preview (if available) */}\r\n {insight.patterns && insight.patterns.length > 0 && (\r\n <div className=\"mt-2 pt-2 border-t border-border/50\">\r\n <div\r\n className={cn(\r\n 'flex items-start gap-1.5 text-xs',\r\n insight.patterns[0].severity === 'error'\r\n ? 'text-red-500'\r\n : insight.patterns[0].severity === 'warning'\r\n ? 'text-yellow-600'\r\n : 'text-blue-500'\r\n )}\r\n >\r\n <span className=\"font-medium uppercase\">\r\n {insight.patterns[0].name?.split(' ')[0] || 'Pattern'}\r\n </span>\r\n <span className=\"text-muted-foreground truncate flex-1\">\r\n {insight.patterns[0].description?.slice(0, 50)}\r\n {insight.patterns[0].description && insight.patterns[0].description.length > 50 ? '...' : ''}\r\n </span>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * InsightsHistoryList component - Display past insight analysis results\r\n */\r\nexport function InsightsHistoryList({\r\n insights = [],\r\n isLoading = false,\r\n onInsightSelect,\r\n className,\r\n}: InsightsHistoryListProps) {\r\n const { formatMessage } = useIntl();\r\n const locale = useIntl().locale;\r\n\r\n // Loading state\r\n if (isLoading) {\r\n return (\r\n <div className={cn('rounded-lg border border-border bg-card p-4', className)}>\r\n <div className=\"flex items-center justify-center py-8\">\r\n <Loader2 className=\"h-5 w-5 animate-spin text-muted-foreground mr-2\" />\r\n <span className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'prompts.insightsHistory.loading' })}\r\n </span>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // Empty state\r\n if (insights.length === 0) {\r\n return (\r\n <div className={cn('rounded-lg border border-border bg-card p-4', className)}>\r\n <div className=\"flex flex-col items-center justify-center py-8 px-4 text-center\">\r\n <Brain className=\"h-10 w-10 text-muted-foreground/50 mb-3\" />\r\n <h3 className=\"text-sm font-medium text-foreground mb-1\">\r\n {formatMessage({ id: 'prompts.insightsHistory.empty.title' })}\r\n </h3>\r\n <p className=\"text-xs text-muted-foreground max-w-xs\">\r\n {formatMessage({ id: 'prompts.insightsHistory.empty.message' })}\r\n </p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // List of insights\r\n return (\r\n <div className={cn('space-y-2', className)}>\r\n {insights.map((insight) => (\r\n <InsightHistoryCard\r\n key={insight.id}\r\n insight={insight}\r\n locale={locale}\r\n onClick={() => onInsightSelect?.(insight.id)}\r\n />\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\nexport default InsightsHistoryList;\r\n","// ========================================\r\n// InsightDetailPanel Component\r\n// ========================================\r\n// Display detailed view of a single insight with patterns, suggestions, and metadata\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { cn } from '@/lib/utils';\r\nimport {\r\n X,\r\n Sparkles,\r\n Bot,\r\n Code2,\r\n Cpu,\r\n Trash2,\r\n AlertTriangle,\r\n Lightbulb,\r\n Clock,\r\n FileText,\r\n} from 'lucide-react';\r\nimport type { InsightHistory, Pattern, Suggestion } from '@/lib/api';\r\nimport { Button } from '@/components/ui/Button';\r\n\r\nexport interface InsightDetailPanelProps {\r\n /** Insight to display (null = panel hidden) */\r\n insight: InsightHistory | null;\r\n /** Called when close button clicked */\r\n onClose: () => void;\r\n /** Called when delete button clicked */\r\n onDelete?: (insightId: string) => void;\r\n /** Is delete operation in progress */\r\n isDeleting?: boolean;\r\n /** Optional className */\r\n className?: string;\r\n}\r\n\r\n// Tool icon mapping\r\nconst toolConfig = {\r\n gemini: {\r\n icon: Sparkles,\r\n color: 'text-blue-500',\r\n bgColor: 'bg-blue-500/10',\r\n label: 'Gemini',\r\n },\r\n qwen: {\r\n icon: Bot,\r\n color: 'text-purple-500',\r\n bgColor: 'bg-purple-500/10',\r\n label: 'Qwen',\r\n },\r\n codex: {\r\n icon: Code2,\r\n color: 'text-green-500',\r\n bgColor: 'bg-green-500/10',\r\n label: 'Codex',\r\n },\r\n default: {\r\n icon: Cpu,\r\n color: 'text-gray-500',\r\n bgColor: 'bg-gray-500/10',\r\n label: 'CLI',\r\n },\r\n};\r\n\r\n// Severity configuration\r\nconst severityConfig = {\r\n error: {\r\n badge: 'bg-red-500/10 text-red-500 border-red-500/20',\r\n border: 'border-l-red-500',\r\n dot: 'bg-red-500',\r\n },\r\n warning: {\r\n badge: 'bg-yellow-500/10 text-yellow-600 border-yellow-500/20',\r\n border: 'border-l-yellow-500',\r\n dot: 'bg-yellow-500',\r\n },\r\n info: {\r\n badge: 'bg-blue-500/10 text-blue-500 border-blue-500/20',\r\n border: 'border-l-blue-500',\r\n dot: 'bg-blue-500',\r\n },\r\n default: {\r\n badge: 'bg-gray-500/10 text-gray-500 border-gray-500/20',\r\n border: 'border-l-gray-500',\r\n dot: 'bg-gray-500',\r\n },\r\n};\r\n\r\n// Suggestion type configuration\r\nconst suggestionTypeConfig = {\r\n refactor: {\r\n badge: 'bg-purple-500/10 text-purple-500 border-purple-500/20',\r\n icon: 'refactor',\r\n },\r\n optimize: {\r\n badge: 'bg-green-500/10 text-green-500 border-green-500/20',\r\n icon: 'optimize',\r\n },\r\n fix: {\r\n badge: 'bg-red-500/10 text-red-500 border-red-500/20',\r\n icon: 'fix',\r\n },\r\n document: {\r\n badge: 'bg-blue-500/10 text-blue-500 border-blue-500/20',\r\n icon: 'document',\r\n },\r\n};\r\n\r\n/**\r\n * Format timestamp to relative time\r\n */\r\nfunction formatRelativeTime(timestamp: string, locale: string): string {\r\n const date = new Date(timestamp);\r\n const now = new Date();\r\n const diffMs = now.getTime() - date.getTime();\r\n const diffMins = Math.floor(diffMs / 60000);\r\n const diffHours = Math.floor(diffMs / 3600000);\r\n const diffDays = Math.floor(diffMs / 86400000);\r\n\r\n if (locale === 'zh') {\r\n if (diffMins < 1) return '刚刚';\r\n if (diffMins < 60) return `${diffMins}分钟前`;\r\n if (diffHours < 24) return `${diffHours}小时前`;\r\n return `${diffDays}天前`;\r\n }\r\n\r\n if (diffMins < 1) return 'just now';\r\n if (diffMins < 60) return `${diffMins}m ago`;\r\n if (diffHours < 24) return `${diffHours}h ago`;\r\n return `${diffDays}d ago`;\r\n}\r\n\r\n/**\r\n * PatternItem component for displaying a single pattern\r\n */\r\nfunction PatternItem({ pattern }: { pattern: Pattern; locale: string }) {\r\n const severity = pattern.severity ?? 'info';\r\n const config = severityConfig[severity] ?? severityConfig.default;\r\n\r\n return (\r\n <div\r\n className={cn(\r\n 'p-3 rounded-md border bg-card',\r\n 'border-l-4',\r\n config.border\r\n )}\r\n >\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <span\r\n className={cn(\r\n 'px-2 py-0.5 text-xs font-medium rounded border',\r\n config.badge\r\n )}\r\n >\r\n {pattern.name?.split(' ')[0] || 'Pattern'}\r\n </span>\r\n <span\r\n className={cn(\r\n 'px-2 py-0.5 text-xs font-medium rounded border uppercase',\r\n config.badge\r\n )}\r\n >\r\n {severity}\r\n </span>\r\n </div>\r\n <p className=\"text-sm text-foreground mb-2\">{pattern.description}</p>\r\n {pattern.example && (\r\n <div className=\"mt-2 p-2 bg-muted rounded text-xs font-mono overflow-x-auto\">\r\n <code className=\"text-muted-foreground\">{pattern.example}</code>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * SuggestionItem component for displaying a single suggestion\r\n */\r\nfunction SuggestionItem({ suggestion }: { suggestion: Suggestion; locale: string }) {\r\n const { formatMessage } = useIntl();\r\n const config = suggestionTypeConfig[suggestion.type] ?? suggestionTypeConfig.refactor;\r\n const typeLabel = formatMessage({ id: `prompts.suggestions.types.${suggestion.type}` });\r\n\r\n return (\r\n <div className=\"p-3 rounded-md border border-border bg-card\">\r\n <div className=\"flex items-center gap-2 mb-2\">\r\n <span\r\n className={cn(\r\n 'px-2 py-0.5 text-xs font-medium rounded border',\r\n config.badge\r\n )}\r\n >\r\n {typeLabel}\r\n </span>\r\n {suggestion.effort && (\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'prompts.suggestions.effort' })}: {suggestion.effort}\r\n </span>\r\n )}\r\n </div>\r\n <h4 className=\"text-sm font-medium text-foreground mb-1\">{suggestion.title}</h4>\r\n <p className=\"text-sm text-muted-foreground mb-2\">{suggestion.description}</p>\r\n {suggestion.code && (\r\n <div className=\"mt-2 p-2 bg-muted rounded text-xs font-mono overflow-x-auto\">\r\n <code className=\"text-muted-foreground\">{suggestion.code}</code>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * InsightDetailPanel component - Display full insight details\r\n */\r\nexport function InsightDetailPanel({\r\n insight,\r\n onClose,\r\n onDelete,\r\n isDeleting = false,\r\n className,\r\n}: InsightDetailPanelProps) {\r\n const { formatMessage } = useIntl();\r\n const locale = useIntl().locale;\r\n\r\n // Don't render if no insight\r\n if (!insight) {\r\n return null;\r\n }\r\n\r\n const config = toolConfig[insight.tool as keyof typeof toolConfig] ?? toolConfig.default;\r\n const ToolIcon = config.icon;\r\n const timeAgo = formatRelativeTime(insight.created_at, locale);\r\n const patternCount = insight.patterns?.length ?? 0;\r\n const suggestionCount = insight.suggestions?.length ?? 0;\r\n\r\n return (\r\n <div\r\n className={cn(\r\n 'fixed inset-y-0 right-0 w-full max-w-md bg-background border-l border-border shadow-lg',\r\n 'flex flex-col',\r\n 'animate-in slide-in-from-right',\r\n className\r\n )}\r\n >\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between p-4 border-b border-border\">\r\n <div className=\"flex items-center gap-2\">\r\n <ToolIcon className={cn('h-5 w-5', config.color)} />\r\n <h2 className=\"text-lg font-semibold text-card-foreground\">\r\n {formatMessage({ id: 'prompts.insightDetail.title' })}\r\n </h2>\r\n </div>\r\n <button\r\n onClick={onClose}\r\n className=\"p-1 rounded-md hover:bg-accent transition-colors\"\r\n aria-label={formatMessage({ id: 'common.actions.close' })}\r\n >\r\n <X className=\"h-5 w-5 text-muted-foreground\" />\r\n </button>\r\n </div>\r\n\r\n {/* Scrollable content */}\r\n <div className=\"flex-1 overflow-y-auto p-4 space-y-6\">\r\n {/* Metadata */}\r\n <div className=\"flex flex-wrap items-center gap-4 text-sm text-muted-foreground\">\r\n <div className={cn('flex items-center gap-1.5', config.color)}>\r\n <ToolIcon className=\"h-3.5 w-3.5\" />\r\n <span className=\"font-medium\">{config.label}</span>\r\n </div>\r\n <div className=\"flex items-center gap-1.5\">\r\n <Clock className=\"h-3.5 w-3.5\" />\r\n <span>{timeAgo}</span>\r\n </div>\r\n <div className=\"flex items-center gap-1.5\">\r\n <FileText className=\"h-3.5 w-3.5\" />\r\n <span>\r\n {insight.prompt_count} {formatMessage({ id: 'prompts.insightDetail.promptsAnalyzed' })}\r\n </span>\r\n </div>\r\n </div>\r\n\r\n {/* Patterns */}\r\n {insight.patterns && insight.patterns.length > 0 && (\r\n <div className=\"space-y-3\">\r\n <div className=\"flex items-center gap-2\">\r\n <AlertTriangle className=\"h-4 w-4 text-muted-foreground\" />\r\n <h3 className=\"text-sm font-semibold text-card-foreground\">\r\n {formatMessage({ id: 'prompts.insightDetail.patterns' })} ({patternCount})\r\n </h3>\r\n </div>\r\n <div className=\"space-y-2\">\r\n {insight.patterns.map((pattern) => (\r\n <PatternItem key={pattern.id} pattern={pattern} locale={locale} />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Suggestions */}\r\n {insight.suggestions && insight.suggestions.length > 0 && (\r\n <div className=\"space-y-3\">\r\n <div className=\"flex items-center gap-2\">\r\n <Lightbulb className=\"h-4 w-4 text-muted-foreground\" />\r\n <h3 className=\"text-sm font-semibold text-card-foreground\">\r\n {formatMessage({ id: 'prompts.insightDetail.suggestions' })} ({suggestionCount})\r\n </h3>\r\n </div>\r\n <div className=\"space-y-2\">\r\n {insight.suggestions.map((suggestion) => (\r\n <SuggestionItem key={suggestion.id} suggestion={suggestion} locale={locale} />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Empty state */}\r\n {(!insight.patterns || insight.patterns.length === 0) &&\r\n (!insight.suggestions || insight.suggestions.length === 0) && (\r\n <div className=\"text-center py-8 text-muted-foreground text-sm\">\r\n {formatMessage({ id: 'prompts.insightDetail.noContent' })}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Footer actions */}\r\n {onDelete && (\r\n <div className=\"p-4 border-t border-border\">\r\n <Button\r\n variant=\"destructive\"\r\n size=\"sm\"\r\n onClick={() => onDelete(insight.id)}\r\n disabled={isDeleting}\r\n className=\"w-full\"\r\n >\r\n <Trash2 className=\"h-4 w-4 mr-2\" />\r\n {isDeleting\r\n ? formatMessage({ id: 'prompts.insightDetail.deleting' })\r\n : formatMessage({ id: 'common.actions.delete' })\r\n }\r\n </Button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * InsightDetailPanelOverlay - Full screen overlay with panel\r\n */\r\nexport interface InsightDetailPanelOverlayProps extends InsightDetailPanelProps {\r\n /** Show overlay backdrop */\r\n showOverlay?: boolean;\r\n}\r\n\r\nexport function InsightDetailPanelOverlay({\r\n insight,\r\n onClose,\r\n onDelete,\r\n isDeleting = false,\r\n showOverlay = true,\r\n className,\r\n}: InsightDetailPanelOverlayProps) {\r\n if (!insight) {\r\n return null;\r\n }\r\n\r\n return (\r\n <>\r\n {showOverlay && (\r\n <div\r\n className=\"fixed inset-0 bg-black/60 z-40 animate-in fade-in\"\r\n onClick={onClose}\r\n />\r\n )}\r\n <InsightDetailPanel\r\n insight={insight}\r\n onClose={onClose}\r\n onDelete={onDelete}\r\n isDeleting={isDeleting}\r\n className={cn('z-50', className)}\r\n />\r\n </>\r\n );\r\n}\r\n\r\nexport default InsightDetailPanel;\r\n","// ========================================\n// PromptHistoryPage Component\n// ========================================\n// Prompt history page with timeline, stats, and AI insights\n\nimport * as React from 'react';\nimport { useIntl } from 'react-intl';\nimport {\n RefreshCw,\n Search,\n Filter,\n AlertCircle,\n History,\n X,\n FolderOpen,\n} from 'lucide-react';\nimport {\n usePromptHistory,\n usePromptInsights,\n useInsightsHistory,\n usePromptHistoryMutations,\n useDeleteInsight,\n extractUniqueProjects,\n type PromptHistoryFilter,\n} from '@/hooks/usePromptHistory';\nimport { PromptStats, PromptStatsSkeleton } from '@/components/shared/PromptStats';\nimport { PromptCard } from '@/components/shared/PromptCard';\nimport { BatchOperationToolbar } from '@/components/shared/BatchOperationToolbar';\nimport { InsightsPanel } from '@/components/shared/InsightsPanel';\nimport { InsightsHistoryList } from '@/components/shared/InsightsHistoryList';\nimport { InsightDetailPanelOverlay } from '@/components/shared/InsightDetailPanel';\nimport { fetchInsightDetail } from '@/lib/api';\nimport type { InsightHistory } from '@/lib/api';\nimport { Button } from '@/components/ui/Button';\nimport { Input } from '@/components/ui/Input';\nimport { Badge } from '@/components/ui/Badge';\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from '@/components/ui/Dialog';\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuLabel,\n} from '@/components/ui/Dropdown';\nimport { cn } from '@/lib/utils';\n\ntype IntentFilter = 'all' | string;\n\n/**\n * PromptHistoryPage component - Main page for prompt history management\n */\nexport function PromptHistoryPage() {\n const { formatMessage } = useIntl();\n\n // Filter state\n const [searchQuery, setSearchQuery] = React.useState('');\n const [intentFilter, setIntentFilter] = React.useState<IntentFilter>('all');\n const [projectFilter, setProjectFilter] = React.useState<string>('all');\n const [selectedTool, setSelectedTool] = React.useState<'gemini' | 'qwen' | 'codex'>('gemini');\n\n // Dialog state\n const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false);\n const [promptToDelete, setPromptToDelete] = React.useState<string | null>(null);\n\n // Insight detail state\n const [selectedInsight, setSelectedInsight] = React.useState<InsightHistory | null>(null);\n const [, setInsightDetailOpen] = React.useState(false);\n\n // Batch operations state\n const [selectedPromptIds, setSelectedPromptIds] = React.useState<Set<string>>(new Set());\n const [batchDeleteDialogOpen, setBatchDeleteDialogOpen] = React.useState(false);\n\n // Build filter object\n const filter: PromptHistoryFilter = React.useMemo(\n () => ({\n search: searchQuery,\n intent: intentFilter === 'all' ? undefined : intentFilter,\n project: projectFilter === 'all' ? undefined : projectFilter,\n }),\n [searchQuery, intentFilter, projectFilter]\n );\n\n // Fetch prompts and insights\n const {\n prompts,\n allPrompts,\n promptsBySession,\n stats,\n isLoading,\n isFetching,\n error,\n refetch,\n } = usePromptHistory({ filter });\n\n const { data: insightsData, isLoading: insightsLoading } = usePromptInsights();\n const { data: insightsHistoryData, isLoading: insightsHistoryLoading } = useInsightsHistory({ limit: 20 });\n\n const { analyzePrompts, deletePrompt, batchDeletePrompts, isAnalyzing, isBatchDeleting } = usePromptHistoryMutations();\n const { deleteInsight: deleteInsightMutation, isDeleting: isDeletingInsight } = useDeleteInsight();\n\n const isMutating = isAnalyzing || isBatchDeleting;\n\n // Extract unique projects from all prompts\n const uniqueProjects = React.useMemo(\n () => extractUniqueProjects(allPrompts),\n [allPrompts]\n );\n\n // Handlers\n const handleAnalyze = async () => {\n try {\n await analyzePrompts({ tool: selectedTool });\n } catch (err) {\n console.error('Failed to analyze prompts:', err);\n }\n };\n\n const handleDeleteClick = (promptId: string) => {\n setPromptToDelete(promptId);\n setDeleteDialogOpen(true);\n };\n\n const handleConfirmDelete = async () => {\n if (!promptToDelete) return;\n\n try {\n await deletePrompt(promptToDelete);\n setDeleteDialogOpen(false);\n setPromptToDelete(null);\n } catch (err) {\n console.error('Failed to delete prompt:', err);\n }\n };\n\n const handleClearSearch = () => {\n setSearchQuery('');\n };\n\n const handleInsightSelect = async (insightId: string) => {\n try {\n const insight = await fetchInsightDetail(insightId);\n setSelectedInsight(insight);\n setInsightDetailOpen(true);\n } catch (err) {\n console.error('Failed to fetch insight detail:', err);\n }\n };\n\n const handleDeleteInsight = async (insightId: string) => {\n const locale = useIntl().locale;\n const confirmMessage = locale === 'zh'\n ? '确定要删除此分析吗?此操作无法撤销。'\n : 'Are you sure you want to delete this insight? This action cannot be undone.';\n\n if (!window.confirm(confirmMessage)) {\n return;\n }\n\n try {\n await deleteInsightMutation(insightId);\n setInsightDetailOpen(false);\n setSelectedInsight(null);\n // Show success toast\n const successMessage = locale === 'zh' ? '洞察已删除' : 'Insight deleted';\n if ((window as any).showToast) {\n (window as any).showToast(successMessage, 'success');\n }\n } catch (err) {\n console.error('Failed to delete insight:', err);\n // Show error toast\n const errorMessage = locale === 'zh' ? '删除洞察失败' : 'Failed to delete insight';\n if ((window as any).showToast) {\n (window as any).showToast(errorMessage, 'error');\n }\n }\n };\n\n const toggleIntentFilter = (intent: string) => {\n setIntentFilter((prev) => (prev === intent ? 'all' : intent));\n };\n\n const clearFilters = () => {\n setSearchQuery('');\n setIntentFilter('all');\n setProjectFilter('all');\n };\n\n // Batch operations handlers\n const handleSelectPrompt = (promptId: string, selected: boolean) => {\n setSelectedPromptIds((prev) => {\n const next = new Set(prev);\n if (selected) {\n next.add(promptId);\n } else {\n next.delete(promptId);\n }\n return next;\n });\n };\n\n const handleSelectAll = (selected: boolean) => {\n if (selected) {\n setSelectedPromptIds(new Set(prompts.map((p) => p.id)));\n } else {\n setSelectedPromptIds(new Set());\n }\n };\n\n const handleClearSelection = () => {\n setSelectedPromptIds(new Set());\n };\n\n const handleBatchDeleteClick = () => {\n if (selectedPromptIds.size > 0) {\n setBatchDeleteDialogOpen(true);\n }\n };\n\n const handleConfirmBatchDelete = async () => {\n if (selectedPromptIds.size === 0) return;\n\n try {\n await batchDeletePrompts(Array.from(selectedPromptIds));\n setBatchDeleteDialogOpen(false);\n setSelectedPromptIds(new Set());\n } catch (err) {\n console.error('Failed to batch delete prompts:', err);\n }\n };\n\n const hasActiveFilters = searchQuery.length > 0 || intentFilter !== 'all' || projectFilter !== 'all';\n\n // Group prompts for timeline view\n const timelineGroups = React.useMemo(() => {\n const groups: Array<{ key: string; label: string; prompts: typeof prompts }> = [];\n\n // Group by session if available, otherwise by date\n const sessionKeys = Object.keys(promptsBySession);\n if (sessionKeys.length > 0 && sessionKeys.some((k) => k !== 'ungrouped')) {\n // Session-based grouping\n for (const [sessionKey, sessionPrompts] of Object.entries(promptsBySession)) {\n const filtered = sessionPrompts.filter((p) =>\n prompts.some((fp) => fp.id === p.id)\n );\n if (filtered.length > 0) {\n groups.push({\n key: sessionKey,\n label: sessionKey === 'ungrouped'\n ? formatMessage({ id: 'prompts.timeline.ungrouped' })\n : formatMessage({ id: 'prompts.timeline.session' }, { session: sessionKey }),\n prompts: filtered,\n });\n }\n }\n } else {\n // Date-based grouping\n const dateGroups: Record<string, typeof prompts> = {};\n for (const prompt of prompts) {\n const date = new Date(prompt.createdAt).toLocaleDateString();\n if (!dateGroups[date]) {\n dateGroups[date] = [];\n }\n dateGroups[date].push(prompt);\n }\n for (const [date, datePrompts] of Object.entries(dateGroups)) {\n groups.push({ key: date, label: date, prompts: datePrompts });\n }\n }\n\n return groups.sort((a, b) => {\n const aDate = a.prompts[0]?.createdAt ? new Date(a.prompts[0].createdAt).getTime() : 0;\n const bDate = b.prompts[0]?.createdAt ? new Date(b.prompts[0].createdAt).getTime() : 0;\n return bDate - aDate;\n });\n }, [prompts, promptsBySession, formatMessage]);\n\n return (\n <div className=\"space-y-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold text-foreground flex items-center gap-2\">\n <History className=\"h-6 w-6\" />\n {formatMessage({ id: 'prompts.title' })}\n </h1>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {formatMessage({ id: 'prompts.description' })}\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => refetch()}\n disabled={isFetching}\n >\n <RefreshCw className={cn('h-4 w-4 mr-2', isFetching && 'animate-spin')} />\n {formatMessage({ id: 'common.actions.refresh' })}\n </Button>\n </div>\n </div>\n\n {/* Error alert */}\n {error && (\n <div className=\"flex items-center gap-2 p-4 rounded-lg bg-destructive/10 border border-destructive/30 text-destructive\">\n <AlertCircle className=\"h-5 w-5 flex-shrink-0\" />\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium\">{formatMessage({ id: 'common.errors.loadFailed' })}</p>\n <p className=\"text-xs mt-0.5\">{error.message}</p>\n </div>\n <Button variant=\"outline\" size=\"sm\" onClick={() => refetch()}>\n {formatMessage({ id: 'home.errors.retry' })}\n </Button>\n </div>\n )}\n\n {/* Stats */}\n {isLoading ? <PromptStatsSkeleton /> : <PromptStats {...stats} />}\n\n {/* Main content area with timeline and insights */}\n <div className=\"grid gap-6 grid-cols-1 lg:grid-cols-3\">\n {/* Timeline section */}\n <div className=\"lg:col-span-2 space-y-4\">\n {/* Filters */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center\">\n {/* Search input */}\n <div className=\"flex-1 max-w-sm relative\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground\" />\n <Input\n placeholder={formatMessage({ id: 'prompts.searchPlaceholder' })}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-9 pr-9\"\n />\n {searchQuery && (\n <button\n onClick={handleClearSearch}\n className=\"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n )}\n </div>\n\n {/* Intent filter dropdown */}\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"sm\" className=\"gap-2\">\n <Filter className=\"h-4 w-4\" />\n {formatMessage({ id: 'common.actions.filter' })}\n {(intentFilter !== 'all' || projectFilter !== 'all') && (\n <Badge variant=\"secondary\" className=\"ml-1 h-5 min-w-5 px-1\">\n {(intentFilter !== 'all' ? 1 : 0) + (projectFilter !== 'all' ? 1 : 0)}\n </Badge>\n )}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-48\">\n <DropdownMenuLabel>{formatMessage({ id: 'prompts.filterByIntent' })}</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n onClick={() => setIntentFilter('all')}\n className=\"justify-between\"\n >\n <span>{formatMessage({ id: 'prompts.intents.all' })}</span>\n {intentFilter === 'all' && <span className=\"text-primary\">&#10003;</span>}\n </DropdownMenuItem>\n {['bug-fix', 'feature', 'refactor', 'document', 'analyze'].map((intent) => (\n <DropdownMenuItem\n key={intent}\n onClick={() => toggleIntentFilter(intent)}\n className=\"justify-between\"\n >\n <span>{formatMessage({ id: `prompts.intents.${intent}` })}</span>\n {intentFilter === intent && <span className=\"text-primary\">&#10003;</span>}\n </DropdownMenuItem>\n ))}\n <DropdownMenuSeparator />\n <DropdownMenuLabel>{formatMessage({ id: 'prompts.filterByProject' })}</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n onClick={() => setProjectFilter('all')}\n className=\"justify-between\"\n >\n <span>{formatMessage({ id: 'prompts.projects.all' })}</span>\n {projectFilter === 'all' && <span className=\"text-primary\">&#10003;</span>}\n </DropdownMenuItem>\n {uniqueProjects.map((project) => (\n <DropdownMenuItem\n key={project}\n onClick={() => setProjectFilter(project)}\n className=\"justify-between\"\n >\n <span className=\"truncate max-w-32\" title={project}>{project}</span>\n {projectFilter === project && <span className=\"text-primary\">&#10003;</span>}\n </DropdownMenuItem>\n ))}\n {hasActiveFilters && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={clearFilters} className=\"text-destructive\">\n {formatMessage({ id: 'common.actions.clearFilters' })}\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n\n {/* Active filters display */}\n {hasActiveFilters && (\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm text-muted-foreground\">{formatMessage({ id: 'common.actions.filters' })}:</span>\n {intentFilter !== 'all' && (\n <Badge\n variant=\"secondary\"\n className=\"cursor-pointer\"\n onClick={() => setIntentFilter('all')}\n >\n {formatMessage({ id: 'prompts.intents.intent' })}: {intentFilter}\n <X className=\"ml-1 h-3 w-3\" />\n </Badge>\n )}\n {projectFilter !== 'all' && (\n <Badge\n variant=\"secondary\"\n className=\"cursor-pointer\"\n onClick={() => setProjectFilter('all')}\n >\n {formatMessage({ id: 'prompts.projects.project' })}: {projectFilter}\n <X className=\"ml-1 h-3 w-3\" />\n </Badge>\n )}\n {searchQuery && (\n <Badge\n variant=\"secondary\"\n className=\"cursor-pointer\"\n onClick={handleClearSearch}\n >\n {formatMessage({ id: 'common.actions.search' })}: {searchQuery}\n <X className=\"ml-1 h-3 w-3\" />\n </Badge>\n )}\n <Button variant=\"ghost\" size=\"sm\" onClick={clearFilters} className=\"h-6 text-xs\">\n {formatMessage({ id: 'common.actions.clearAll' })}\n </Button>\n </div>\n )}\n\n {/* Batch operations toolbar */}\n <BatchOperationToolbar\n selectedCount={selectedPromptIds.size}\n allSelected={prompts.length > 0 && selectedPromptIds.size === prompts.length}\n onSelectAll={handleSelectAll}\n onClearSelection={handleClearSelection}\n onDelete={handleBatchDeleteClick}\n isDeleting={isBatchDeleting}\n />\n\n {/* Timeline */}\n {isLoading ? (\n <div className=\"space-y-4\">\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"p-4 rounded-lg border border-border animate-pulse\">\n <div className=\"h-4 w-32 bg-muted rounded mb-2\" />\n <div className=\"h-20 bg-muted rounded\" />\n </div>\n ))}\n </div>\n ) : timelineGroups.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-16 px-4 border border-dashed border-border rounded-lg\">\n <FolderOpen className=\"h-12 w-12 text-muted-foreground mb-4\" />\n <h3 className=\"text-lg font-medium text-foreground mb-1\">\n {hasActiveFilters\n ? formatMessage({ id: 'prompts.emptyState.title' })\n : formatMessage({ id: 'prompts.emptyState.noPrompts' })}\n </h3>\n <p className=\"text-sm text-muted-foreground text-center max-w-sm mb-4\">\n {hasActiveFilters\n ? formatMessage({ id: 'prompts.emptyState.message' })\n : formatMessage({ id: 'prompts.emptyState.createFirst' })}\n </p>\n {hasActiveFilters && (\n <Button variant=\"outline\" onClick={clearFilters}>\n {formatMessage({ id: 'common.actions.clearFilters' })}\n </Button>\n )}\n </div>\n ) : (\n <div className=\"space-y-6\">\n {timelineGroups.map((group) => (\n <div key={group.key} className=\"space-y-3\">\n {/* Group header */}\n <div className=\"flex items-center gap-2\">\n <div className=\"h-px bg-border flex-1\" />\n <h3 className=\"text-sm font-medium text-muted-foreground px-2\">\n {group.label}\n </h3>\n <div className=\"h-px bg-border flex-1\" />\n </div>\n\n {/* Prompt cards in group */}\n <div className=\"space-y-2\">\n {group.prompts.map((prompt) => (\n <PromptCard\n key={prompt.id}\n prompt={prompt}\n onDelete={handleDeleteClick}\n actionsDisabled={isMutating}\n selected={selectedPromptIds.has(prompt.id)}\n onSelectChange={handleSelectPrompt}\n selectionMode={selectedPromptIds.size > 0 || prompts.some(p => selectedPromptIds.has(p.id))}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Insights panel */}\n <div className=\"lg:col-span-1 space-y-4\">\n <InsightsPanel\n insights={insightsData?.insights}\n patterns={insightsData?.patterns}\n suggestions={insightsData?.suggestions}\n selectedTool={selectedTool}\n onToolChange={setSelectedTool}\n onAnalyze={handleAnalyze}\n isAnalyzing={isAnalyzing || insightsLoading}\n className=\"sticky top-4\"\n />\n <InsightsHistoryList\n insights={insightsHistoryData?.insights}\n isLoading={insightsHistoryLoading}\n onInsightSelect={handleInsightSelect}\n />\n </div>\n </div>\n\n {/* Delete Confirmation Dialog */}\n <Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>{formatMessage({ id: 'prompts.dialog.deleteTitle' })}</DialogTitle>\n <DialogDescription>\n {formatMessage({ id: 'prompts.dialog.deleteConfirm' })}\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => {\n setDeleteDialogOpen(false);\n setPromptToDelete(null);\n }}\n >\n {formatMessage({ id: 'common.actions.cancel' })}\n </Button>\n <Button\n variant=\"destructive\"\n onClick={handleConfirmDelete}\n disabled={isAnalyzing}\n >\n {formatMessage({ id: 'common.actions.delete' })}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {/* Batch Delete Confirmation Dialog */}\n <Dialog open={batchDeleteDialogOpen} onOpenChange={setBatchDeleteDialogOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>{formatMessage({ id: 'prompts.dialog.batchDeleteTitle' })}</DialogTitle>\n <DialogDescription>\n {formatMessage({ id: 'prompts.dialog.batchDeleteConfirm' }, { count: selectedPromptIds.size })}\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => {\n setBatchDeleteDialogOpen(false);\n }}\n disabled={isBatchDeleting}\n >\n {formatMessage({ id: 'common.actions.cancel' })}\n </Button>\n <Button\n variant=\"destructive\"\n onClick={handleConfirmBatchDelete}\n disabled={isBatchDeleting}\n >\n {isBatchDeleting ? formatMessage({ id: 'common.actions.deleting' }, { defaultValue: 'Deleting...' }) : formatMessage({ id: 'common.actions.delete' })}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {/* Insight Detail Panel Overlay */}\n <InsightDetailPanelOverlay\n insight={selectedInsight}\n onClose={() => {\n setInsightDetailOpen(false);\n setSelectedInsight(null);\n }}\n onDelete={handleDeleteInsight}\n isDeleting={isDeletingInsight}\n showOverlay={true}\n />\n </div>\n );\n}\n\nexport default PromptHistoryPage;\n"],"names":["FileType","createLucideIcon","Minus","TrendingDown","TrendingUp","statCardVariants","cva","iconContainerVariants","StatCard","className","variant","title","value","Icon","trend","trendValue","isLoading","description","sparklineData","showSparkline","props","TrendIcon","trendColor","jsx","Card","cn","CardContent","jsxs","Sparkline","StatCardSkeleton","getQualityLevel","score","getBadgeVariant","level","QualityBadge","qualityScore","formatMessage","useIntl","labelKey","label","Badge","formatDate","dateString","formatContentLength","length","PromptCard","prompt","onDelete","actionsDisabled","defaultExpanded","selected","onSelectChange","selectionMode","expanded","setExpanded","React.useState","copied","setCopied","handleCopy","e","handleDelete","toggleExpanded","prev","handleSelectionChange","checked","handleCardClick","CardHeader","Checkbox","Calendar","Tag","Clock","tag","Button","Copy","Trash2","ChevronUp","ChevronDown","toolConfig","InsightCard","insight","config","Lightbulb","Sparkles","AlertTriangle","PatternCard","pattern","Wand2","SuggestionCard","suggestion","InsightsPanel","insights","patterns","suggestions","selectedTool","onToolChange","onAnalyze","isAnalyzing","hasContent","CardTitle","Loader2","RefreshCw","tool","PromptStats","totalCount","avgLength","topIntent","avgQualityScore","qualityDistribution","formatLength","MessageSquare","Hash","Star","PromptStatsSkeleton","STALE_TIME","usePromptHistory","options","filter","staleTime","enabled","queryClient","useQueryClient","projectPath","useWorkflowStore","selectProjectPath","queryEnabled","query","useQuery","workspaceQueryKeys","fetchPrompts","allPrompts","_a","_b","filteredPrompts","prompts","searchLower","p","t","date","start","end","promptsBySession","sessionKey","_d","_c","sum","intentCounts","category","_e","a","b","totalQualityScore","qualityScoreCount","refetch","invalidate","usePromptInsights","fetchPromptInsights","useInsightsHistory","limit","fetchInsightsHistory","useAnalyzePrompts","mutation","useMutation","analyzePrompts","useDeletePrompt","deletePrompt","promptId","previousPrompts","old","_error","_promptId","context","useBatchDeletePrompts","batchDeletePrompts","promptIds","_promptIds","useDeleteInsight","insightId","deleteInsight","previousInsights","i","_insightId","usePromptHistoryMutations","analyze","remove","batchRemove","extractUniqueProjects","projectsSet","BatchOperationToolbar","selectedCount","allSelected","onSelectAll","onClearSelection","isDeleting","X","Bot","Code2","Cpu","formatTimeAgo","timestamp","locale","diff","minutes","hours","days","isZh","getSeverityLevel","hasHigh","hasMedium","severityConfig","InsightHistoryCard","onClick","severity","ToolIcon","timeAgo","patternCount","suggestionCount","InsightsHistoryList","onInsightSelect","Brain","suggestionTypeConfig","formatRelativeTime","diffMs","diffMins","diffHours","diffDays","PatternItem","SuggestionItem","typeLabel","InsightDetailPanel","onClose","FileText","InsightDetailPanelOverlay","showOverlay","Fragment","PromptHistoryPage","searchQuery","setSearchQuery","intentFilter","setIntentFilter","projectFilter","setProjectFilter","setSelectedTool","deleteDialogOpen","setDeleteDialogOpen","promptToDelete","setPromptToDelete","selectedInsight","setSelectedInsight","setInsightDetailOpen","selectedPromptIds","setSelectedPromptIds","batchDeleteDialogOpen","setBatchDeleteDialogOpen","React.useMemo","stats","isFetching","error","insightsData","insightsLoading","insightsHistoryData","insightsHistoryLoading","isBatchDeleting","deleteInsightMutation","isDeletingInsight","isMutating","uniqueProjects","handleAnalyze","err","handleDeleteClick","handleConfirmDelete","handleClearSearch","handleInsightSelect","fetchInsightDetail","handleDeleteInsight","confirmMessage","successMessage","errorMessage","toggleIntentFilter","intent","clearFilters","handleSelectPrompt","next","handleSelectAll","handleClearSelection","handleBatchDeleteClick","handleConfirmBatchDelete","hasActiveFilters","timelineGroups","groups","sessionKeys","k","sessionPrompts","filtered","fp","dateGroups","datePrompts","aDate","History","AlertCircle","Search","Input","DropdownMenu","DropdownMenuTrigger","Filter","DropdownMenuContent","DropdownMenuLabel","DropdownMenuSeparator","DropdownMenuItem","project","FolderOpen","group","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","DialogFooter"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}