claude-code-workflow 7.2.19 → 7.2.21

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 (232) hide show
  1. package/.claude/commands/workflow/analyze-with-file.md +58 -20
  2. package/.codex/skills/analyze-with-file/SKILL.md +55 -8
  3. package/.codex/skills/team-arch-opt/SKILL.md +24 -0
  4. package/.codex/skills/team-arch-opt/roles/coordinator/role.md +22 -0
  5. package/.codex/skills/team-brainstorm/SKILL.md +24 -0
  6. package/.codex/skills/team-brainstorm/roles/coordinator/role.md +20 -0
  7. package/.codex/skills/team-coordinate/SKILL.md +24 -0
  8. package/.codex/skills/team-coordinate/roles/coordinator/role.md +40 -12
  9. package/.codex/skills/team-frontend/SKILL.md +24 -0
  10. package/.codex/skills/team-frontend/roles/coordinator/role.md +20 -0
  11. package/.codex/skills/team-frontend-debug/SKILL.md +24 -0
  12. package/.codex/skills/team-frontend-debug/roles/coordinator/role.md +21 -0
  13. package/.codex/skills/team-issue/SKILL.md +24 -0
  14. package/.codex/skills/team-issue/roles/coordinator/role.md +19 -0
  15. package/.codex/skills/team-iterdev/SKILL.md +24 -0
  16. package/.codex/skills/team-iterdev/roles/coordinator/role.md +20 -0
  17. package/.codex/skills/team-lifecycle-v4/SKILL.md +24 -0
  18. package/.codex/skills/team-lifecycle-v4/roles/coordinator/role.md +28 -2
  19. package/.codex/skills/team-perf-opt/SKILL.md +24 -0
  20. package/.codex/skills/team-perf-opt/roles/coordinator/role.md +20 -0
  21. package/.codex/skills/team-planex/SKILL.md +24 -0
  22. package/.codex/skills/team-planex/roles/coordinator/role.md +19 -0
  23. package/.codex/skills/team-quality-assurance/SKILL.md +24 -0
  24. package/.codex/skills/team-quality-assurance/roles/coordinator/role.md +21 -0
  25. package/.codex/skills/team-review/SKILL.md +24 -0
  26. package/.codex/skills/team-review/roles/coordinator/role.md +21 -0
  27. package/.codex/skills/team-roadmap-dev/SKILL.md +24 -0
  28. package/.codex/skills/team-roadmap-dev/roles/coordinator/role.md +19 -0
  29. package/.codex/skills/team-tech-debt/SKILL.md +24 -0
  30. package/.codex/skills/team-tech-debt/roles/coordinator/role.md +19 -0
  31. package/.codex/skills/team-testing/SKILL.md +24 -0
  32. package/.codex/skills/team-testing/roles/coordinator/role.md +21 -0
  33. package/.codex/skills/team-uidesign/SKILL.md +24 -0
  34. package/.codex/skills/team-uidesign/roles/coordinator/role.md +20 -0
  35. package/.codex/skills/team-ultra-analyze/SKILL.md +24 -0
  36. package/.codex/skills/team-ultra-analyze/roles/coordinator/role.md +20 -0
  37. package/.codex/skills/team-ux-improve/SKILL.md +24 -0
  38. package/.codex/skills/team-ux-improve/roles/coordinator/role.md +20 -0
  39. package/ccw/frontend/dist/assets/{AlertDialog-zDuLRyN3.js → AlertDialog-Cukb0xv2.js} +2 -2
  40. package/ccw/frontend/dist/assets/{AlertDialog-zDuLRyN3.js.map → AlertDialog-Cukb0xv2.js.map} +1 -1
  41. package/ccw/frontend/dist/assets/{AnalysisPage-DGCGwIZY.js → AnalysisPage-Ddmv0J4x.js} +2 -2
  42. package/ccw/frontend/dist/assets/{AnalysisPage-DGCGwIZY.js.map → AnalysisPage-Ddmv0J4x.js.map} +1 -1
  43. package/ccw/frontend/dist/assets/{ApiSettingsPage-CgclCqmv.js → ApiSettingsPage-DMkrTZDX.js} +2 -2
  44. package/ccw/frontend/dist/assets/{ApiSettingsPage-CgclCqmv.js.map → ApiSettingsPage-DMkrTZDX.js.map} +1 -1
  45. package/ccw/frontend/dist/assets/{CliModeToggle-CbGH7qO4.js → CliModeToggle-DXenjpbe.js} +2 -2
  46. package/ccw/frontend/dist/assets/{CliModeToggle-CbGH7qO4.js.map → CliModeToggle-DXenjpbe.js.map} +1 -1
  47. package/ccw/frontend/dist/assets/{CliSessionSharePage-CJGlwyDw.js → CliSessionSharePage-B-ZIMqmX.js} +2 -2
  48. package/ccw/frontend/dist/assets/{CliSessionSharePage-CJGlwyDw.js.map → CliSessionSharePage-B-ZIMqmX.js.map} +1 -1
  49. package/ccw/frontend/dist/assets/{CliViewerPage-D-MHYyDt.js → CliViewerPage-9YxGyLxh.js} +2 -2
  50. package/ccw/frontend/dist/assets/{CliViewerPage-D-MHYyDt.js.map → CliViewerPage-9YxGyLxh.js.map} +1 -1
  51. package/ccw/frontend/dist/assets/{CodexLensPage-z6miX68P.js → CodexLensPage-B_uv5wdn.js} +2 -2
  52. package/ccw/frontend/dist/assets/{CodexLensPage-z6miX68P.js.map → CodexLensPage-B_uv5wdn.js.map} +1 -1
  53. package/ccw/frontend/dist/assets/{Collapsible-D5zS2wef.js → Collapsible-C2qk3yV0.js} +2 -2
  54. package/ccw/frontend/dist/assets/{Collapsible-D5zS2wef.js.map → Collapsible-C2qk3yV0.js.map} +1 -1
  55. package/ccw/frontend/dist/assets/{CommandsManagerPage-ChcTwmAn.js → CommandsManagerPage-DBtaWxLB.js} +2 -2
  56. package/ccw/frontend/dist/assets/{CommandsManagerPage-ChcTwmAn.js.map → CommandsManagerPage-DBtaWxLB.js.map} +1 -1
  57. package/ccw/frontend/dist/assets/{DeepWikiPage-Cv5LifSi.js → DeepWikiPage-d9K4_TgG.js} +2 -2
  58. package/ccw/frontend/dist/assets/{DeepWikiPage-Cv5LifSi.js.map → DeepWikiPage-d9K4_TgG.js.map} +1 -1
  59. package/ccw/frontend/dist/assets/{EndpointsPage-BcyNmqIa.js → EndpointsPage-DhW6hYrI.js} +2 -2
  60. package/ccw/frontend/dist/assets/{EndpointsPage-BcyNmqIa.js.map → EndpointsPage-DhW6hYrI.js.map} +1 -1
  61. package/ccw/frontend/dist/assets/{ExplorerPage-DfHtqeQM.js → ExplorerPage-DYYpCvtB.js} +2 -2
  62. package/ccw/frontend/dist/assets/{ExplorerPage-DfHtqeQM.js.map → ExplorerPage-DYYpCvtB.js.map} +1 -1
  63. package/ccw/frontend/dist/assets/{FixSessionPage-CbvZApeF.js → FixSessionPage-CSmiT5SE.js} +2 -2
  64. package/ccw/frontend/dist/assets/{FixSessionPage-CbvZApeF.js.map → FixSessionPage-CSmiT5SE.js.map} +1 -1
  65. package/ccw/frontend/dist/assets/{FloatingFileBrowser-DLz85cw9.js → FloatingFileBrowser-DvMsXLdP.js} +2 -2
  66. package/ccw/frontend/dist/assets/{FloatingFileBrowser-DLz85cw9.js.map → FloatingFileBrowser-DvMsXLdP.js.map} +1 -1
  67. package/ccw/frontend/dist/assets/{FloatingPanel-DrUTmgtV.js → FloatingPanel-sqezhSI8.js} +2 -2
  68. package/ccw/frontend/dist/assets/{FloatingPanel-DrUTmgtV.js.map → FloatingPanel-sqezhSI8.js.map} +1 -1
  69. package/ccw/frontend/dist/assets/{GraphExplorerPage-C439yLvH.js → GraphExplorerPage-DS8ghMFM.js} +2 -2
  70. package/ccw/frontend/dist/assets/{GraphExplorerPage-C439yLvH.js.map → GraphExplorerPage-DS8ghMFM.js.map} +1 -1
  71. package/ccw/frontend/dist/assets/{HistoryPage-BClJJMEy.js → HistoryPage-B-x1RyHu.js} +2 -2
  72. package/ccw/frontend/dist/assets/{HistoryPage-BClJJMEy.js.map → HistoryPage-B-x1RyHu.js.map} +1 -1
  73. package/ccw/frontend/dist/assets/{HookManagerPage-DI-2QDLJ.js → HookManagerPage-BbxpDb68.js} +2 -2
  74. package/ccw/frontend/dist/assets/{HookManagerPage-DI-2QDLJ.js.map → HookManagerPage-BbxpDb68.js.map} +1 -1
  75. package/ccw/frontend/dist/assets/{InstallationsPage-DKlz1ypL.js → InstallationsPage-3bShz_Ai.js} +2 -2
  76. package/ccw/frontend/dist/assets/{InstallationsPage-DKlz1ypL.js.map → InstallationsPage-3bShz_Ai.js.map} +1 -1
  77. package/ccw/frontend/dist/assets/{IssueHubPage--6DduN4j.js → IssueHubPage-BQY_Hh3e.js} +2 -2
  78. package/ccw/frontend/dist/assets/{IssueHubPage--6DduN4j.js.map → IssueHubPage-BQY_Hh3e.js.map} +1 -1
  79. package/ccw/frontend/dist/assets/{LiteTasksPage-39j6xEeL.js → LiteTasksPage-vD_8fQcR.js} +2 -2
  80. package/ccw/frontend/dist/assets/{LiteTasksPage-39j6xEeL.js.map → LiteTasksPage-vD_8fQcR.js.map} +1 -1
  81. package/ccw/frontend/dist/assets/{McpManagerPage-D00C9RVN.js → McpManagerPage-CI5ZzB8A.js} +2 -2
  82. package/ccw/frontend/dist/assets/{McpManagerPage-D00C9RVN.js.map → McpManagerPage-CI5ZzB8A.js.map} +1 -1
  83. package/ccw/frontend/dist/assets/{MemoryPage-BXWKdTyM.js → MemoryPage-CNuj2eNg.js} +2 -2
  84. package/ccw/frontend/dist/assets/{MemoryPage-BXWKdTyM.js.map → MemoryPage-CNuj2eNg.js.map} +1 -1
  85. package/ccw/frontend/dist/assets/{NotFoundPage-h5o3I7cF.js → NotFoundPage-BrnAXkb1.js} +2 -2
  86. package/ccw/frontend/dist/assets/{NotFoundPage-h5o3I7cF.js.map → NotFoundPage-BrnAXkb1.js.map} +1 -1
  87. package/ccw/frontend/dist/assets/{OrchestratorPage-jkyjmiI1.js → OrchestratorPage-CH81PGt4.js} +2 -2
  88. package/ccw/frontend/dist/assets/{OrchestratorPage-jkyjmiI1.js.map → OrchestratorPage-CH81PGt4.js.map} +1 -1
  89. package/ccw/frontend/dist/assets/{ProjectOverviewPage-C2bE5eb2.js → ProjectOverviewPage-dwiEXl2O.js} +2 -2
  90. package/ccw/frontend/dist/assets/{ProjectOverviewPage-C2bE5eb2.js.map → ProjectOverviewPage-dwiEXl2O.js.map} +1 -1
  91. package/ccw/frontend/dist/assets/{PromptHistoryPage-DzmPK4GZ.js → PromptHistoryPage-CabgLjJU.js} +2 -2
  92. package/ccw/frontend/dist/assets/{PromptHistoryPage-DzmPK4GZ.js.map → PromptHistoryPage-CabgLjJU.js.map} +1 -1
  93. package/ccw/frontend/dist/assets/{ReviewSessionPage-CVMH1K6G.js → ReviewSessionPage-DAMrNFn8.js} +2 -2
  94. package/ccw/frontend/dist/assets/{ReviewSessionPage-CVMH1K6G.js.map → ReviewSessionPage-DAMrNFn8.js.map} +1 -1
  95. package/ccw/frontend/dist/assets/{RulesManagerPage-BDZco-r2.js → RulesManagerPage-4jzmxPn0.js} +2 -2
  96. package/ccw/frontend/dist/assets/{RulesManagerPage-BDZco-r2.js.map → RulesManagerPage-4jzmxPn0.js.map} +1 -1
  97. package/ccw/frontend/dist/assets/{SessionDetailPage-D5cM-8Kk.js → SessionDetailPage-C5Btktmp.js} +2 -2
  98. package/ccw/frontend/dist/assets/{SessionDetailPage-D5cM-8Kk.js.map → SessionDetailPage-C5Btktmp.js.map} +1 -1
  99. package/ccw/frontend/dist/assets/{SessionsPage-BFy74ye3.js → SessionsPage-CQIB4E8m.js} +2 -2
  100. package/ccw/frontend/dist/assets/{SessionsPage-BFy74ye3.js.map → SessionsPage-CQIB4E8m.js.map} +1 -1
  101. package/ccw/frontend/dist/assets/SettingsPage-Yi9UAfm7.js +150 -0
  102. package/ccw/frontend/dist/assets/SettingsPage-Yi9UAfm7.js.map +1 -0
  103. package/ccw/frontend/dist/assets/{SkillsManagerPage-8Dsq4AUD.js → SkillsManagerPage-BqfvYSkT.js} +2 -2
  104. package/ccw/frontend/dist/assets/{SkillsManagerPage-8Dsq4AUD.js.map → SkillsManagerPage-BqfvYSkT.js.map} +1 -1
  105. package/ccw/frontend/dist/assets/{SpecsSettingsPage-CG77iAYQ.js → SpecsSettingsPage-BdVPM5R6.js} +2 -2
  106. package/ccw/frontend/dist/assets/{SpecsSettingsPage-CG77iAYQ.js.map → SpecsSettingsPage-BdVPM5R6.js.map} +1 -1
  107. package/ccw/frontend/dist/assets/{Switch-BbuvVsX-.js → Switch-BG929kV0.js} +2 -2
  108. package/ccw/frontend/dist/assets/{Switch-BbuvVsX-.js.map → Switch-BG929kV0.js.map} +1 -1
  109. package/ccw/frontend/dist/assets/{TabsNavigation-SGJhC8-P.js → TabsNavigation-Bol1y09b.js} +2 -2
  110. package/ccw/frontend/dist/assets/{TabsNavigation-SGJhC8-P.js.map → TabsNavigation-Bol1y09b.js.map} +1 -1
  111. package/ccw/frontend/dist/assets/{TaskDrawer-p51jeScU.js → TaskDrawer-Dwutrn8_.js} +2 -2
  112. package/ccw/frontend/dist/assets/{TaskDrawer-p51jeScU.js.map → TaskDrawer-Dwutrn8_.js.map} +1 -1
  113. package/ccw/frontend/dist/assets/{TeamPage-CvZBThbr.js → TeamPage-CpCSwpxD.js} +2 -2
  114. package/ccw/frontend/dist/assets/{TeamPage-CvZBThbr.js.map → TeamPage-CpCSwpxD.js.map} +1 -1
  115. package/ccw/frontend/dist/assets/{TerminalDashboardPage-uhM7kGKI.js → TerminalDashboardPage-DODKjOeK.js} +2 -2
  116. package/ccw/frontend/dist/assets/{TerminalDashboardPage-uhM7kGKI.js.map → TerminalDashboardPage-DODKjOeK.js.map} +1 -1
  117. package/ccw/frontend/dist/assets/{archive-D6ySrtHC.js → archive-CQw634kD.js} +2 -2
  118. package/ccw/frontend/dist/assets/{archive-D6ySrtHC.js.map → archive-CQw634kD.js.map} +1 -1
  119. package/ccw/frontend/dist/assets/{archive-restore-C1uI-5TY.js → archive-restore-B-_EG6wE.js} +2 -2
  120. package/ccw/frontend/dist/assets/{archive-restore-C1uI-5TY.js.map → archive-restore-B-_EG6wE.js.map} +1 -1
  121. package/ccw/frontend/dist/assets/{arrow-right-qE5-FMG8.js → arrow-right-CcQtxBrU.js} +2 -2
  122. package/ccw/frontend/dist/assets/{arrow-right-qE5-FMG8.js.map → arrow-right-CcQtxBrU.js.map} +1 -1
  123. package/ccw/frontend/dist/assets/{bookmark-plus-DL4iL38T.js → bookmark-plus-Cl-BbcpR.js} +2 -2
  124. package/ccw/frontend/dist/assets/{bookmark-plus-DL4iL38T.js.map → bookmark-plus-Cl-BbcpR.js.map} +1 -1
  125. package/ccw/frontend/dist/assets/{bot-CZzIeEkg.js → bot-CLSNSkW_.js} +2 -2
  126. package/ccw/frontend/dist/assets/{bot-CZzIeEkg.js.map → bot-CLSNSkW_.js.map} +1 -1
  127. package/ccw/frontend/dist/assets/{braces-MEPRT2LN.js → braces-DWwkaDS6.js} +2 -2
  128. package/ccw/frontend/dist/assets/{braces-MEPRT2LN.js.map → braces-DWwkaDS6.js.map} +1 -1
  129. package/ccw/frontend/dist/assets/{circle-stop-GQcecSUg.js → circle-stop-DiS7e6ma.js} +2 -2
  130. package/ccw/frontend/dist/assets/{circle-stop-GQcecSUg.js.map → circle-stop-DiS7e6ma.js.map} +1 -1
  131. package/ccw/frontend/dist/assets/{cpu-CzxYMs1Y.js → cpu-CuvHUVXO.js} +2 -2
  132. package/ccw/frontend/dist/assets/{cpu-CzxYMs1Y.js.map → cpu-CuvHUVXO.js.map} +1 -1
  133. package/ccw/frontend/dist/assets/{ellipsis-vertical-DZMfiFKo.js → ellipsis-vertical-BoVlINSw.js} +2 -2
  134. package/ccw/frontend/dist/assets/{ellipsis-vertical-DZMfiFKo.js.map → ellipsis-vertical-BoVlINSw.js.map} +1 -1
  135. package/ccw/frontend/dist/assets/{eye-BXfPoClW.js → eye-BEMOdcAN.js} +2 -2
  136. package/ccw/frontend/dist/assets/{eye-BXfPoClW.js.map → eye-BEMOdcAN.js.map} +1 -1
  137. package/ccw/frontend/dist/assets/{eye-off-CyaKXmAk.js → eye-off-C5HS4Ytm.js} +2 -2
  138. package/ccw/frontend/dist/assets/{eye-off-CyaKXmAk.js.map → eye-off-C5HS4Ytm.js.map} +1 -1
  139. package/ccw/frontend/dist/assets/{file-json-B4LbFfTU.js → file-json-DQ9XLq0B.js} +2 -2
  140. package/ccw/frontend/dist/assets/{file-json-B4LbFfTU.js.map → file-json-DQ9XLq0B.js.map} +1 -1
  141. package/ccw/frontend/dist/assets/{file-text-CIWG7Xgj.js → file-text-TGs_qCbw.js} +2 -2
  142. package/ccw/frontend/dist/assets/{file-text-CIWG7Xgj.js.map → file-text-TGs_qCbw.js.map} +1 -1
  143. package/ccw/frontend/dist/assets/{filter-CNBjjvBX.js → filter-CIuCqnDB.js} +2 -2
  144. package/ccw/frontend/dist/assets/{filter-CNBjjvBX.js.map → filter-CIuCqnDB.js.map} +1 -1
  145. package/ccw/frontend/dist/assets/{folder-DT_XOYw9.js → folder-BkivHBwn.js} +2 -2
  146. package/ccw/frontend/dist/assets/{folder-DT_XOYw9.js.map → folder-BkivHBwn.js.map} +1 -1
  147. package/ccw/frontend/dist/assets/{gauge-mvQWOG3S.js → gauge-CtM68fVY.js} +2 -2
  148. package/ccw/frontend/dist/assets/{gauge-mvQWOG3S.js.map → gauge-CtM68fVY.js.map} +1 -1
  149. package/ccw/frontend/dist/assets/{globe-B25jraBz.js → globe-DpnrINqP.js} +2 -2
  150. package/ccw/frontend/dist/assets/{globe-B25jraBz.js.map → globe-DpnrINqP.js.map} +1 -1
  151. package/ccw/frontend/dist/assets/{grid-3x3-CptugI_Z.js → grid-3x3-SjX0a5JH.js} +2 -2
  152. package/ccw/frontend/dist/assets/{grid-3x3-CptugI_Z.js.map → grid-3x3-SjX0a5JH.js.map} +1 -1
  153. package/ccw/frontend/dist/assets/{hard-drive-BUK9Wcoz.js → hard-drive-ByAmnoEg.js} +2 -2
  154. package/ccw/frontend/dist/assets/{hard-drive-BUK9Wcoz.js.map → hard-drive-ByAmnoEg.js.map} +1 -1
  155. package/ccw/frontend/dist/assets/{hash-dddMDYK7.js → hash-DbLc3VOZ.js} +2 -2
  156. package/ccw/frontend/dist/assets/{hash-dddMDYK7.js.map → hash-DbLc3VOZ.js.map} +1 -1
  157. package/ccw/frontend/dist/assets/{history-BdDj8MtC.js → history-Botz5Z5d.js} +2 -2
  158. package/ccw/frontend/dist/assets/{history-BdDj8MtC.js.map → history-Botz5Z5d.js.map} +1 -1
  159. package/ccw/frontend/dist/assets/{index-CcxBnbbQ.js → index-BGvyf4-9.js} +2 -2
  160. package/ccw/frontend/dist/assets/{index-CcxBnbbQ.js.map → index-BGvyf4-9.js.map} +1 -1
  161. package/ccw/frontend/dist/assets/index-BoqylFO4.css +39 -0
  162. package/ccw/frontend/dist/assets/{index-DZGHdspr.js → index-DP_mTJI8.js} +3 -3
  163. package/ccw/frontend/dist/assets/{index-DZGHdspr.js.map → index-DP_mTJI8.js.map} +1 -1
  164. package/ccw/frontend/dist/assets/{index-B6UfIzhR.js → index-MkgdhX7a.js} +2 -2
  165. package/ccw/frontend/dist/assets/{index-B6UfIzhR.js.map → index-MkgdhX7a.js.map} +1 -1
  166. package/ccw/frontend/dist/assets/{index-EFcT7h67.js → index-ni-tG9rm.js} +2 -2
  167. package/ccw/frontend/dist/assets/{index-EFcT7h67.js.map → index-ni-tG9rm.js.map} +1 -1
  168. package/ccw/frontend/dist/assets/{layout-grid-BVlT1oI7.js → layout-grid-11E4bGJz.js} +2 -2
  169. package/ccw/frontend/dist/assets/{layout-grid-BVlT1oI7.js.map → layout-grid-11E4bGJz.js.map} +1 -1
  170. package/ccw/frontend/dist/assets/{lightbulb-Mt3Tlwh4.js → lightbulb-8KrKY82b.js} +2 -2
  171. package/ccw/frontend/dist/assets/{lightbulb-Mt3Tlwh4.js.map → lightbulb-8KrKY82b.js.map} +1 -1
  172. package/ccw/frontend/dist/assets/{link-2-DXqT64qo.js → link-2-BUn6RILb.js} +2 -2
  173. package/ccw/frontend/dist/assets/{link-2-DXqT64qo.js.map → link-2-BUn6RILb.js.map} +1 -1
  174. package/ccw/frontend/dist/assets/{link-CBMtrpcI.js → link-CmP254Ai.js} +2 -2
  175. package/ccw/frontend/dist/assets/{link-CBMtrpcI.js.map → link-CmP254Ai.js.map} +1 -1
  176. package/ccw/frontend/dist/assets/{list-DDyEM4AO.js → list-BAwzl4a2.js} +2 -2
  177. package/ccw/frontend/dist/assets/{list-DDyEM4AO.js.map → list-BAwzl4a2.js.map} +1 -1
  178. package/ccw/frontend/dist/assets/{map-pin-B2FxBKfk.js → map-pin-gi342rqk.js} +2 -2
  179. package/ccw/frontend/dist/assets/{map-pin-B2FxBKfk.js.map → map-pin-gi342rqk.js.map} +1 -1
  180. package/ccw/frontend/dist/assets/{messages-square-zJfTY9pq.js → messages-square-C1Lh8q8b.js} +2 -2
  181. package/ccw/frontend/dist/assets/{messages-square-zJfTY9pq.js.map → messages-square-C1Lh8q8b.js.map} +1 -1
  182. package/ccw/frontend/dist/assets/{minimize-2-DnhGZj79.js → minimize-2-OgWNLKdq.js} +2 -2
  183. package/ccw/frontend/dist/assets/{minimize-2-DnhGZj79.js.map → minimize-2-OgWNLKdq.js.map} +1 -1
  184. package/ccw/frontend/dist/assets/{package-DYzAybhU.js → package-Djsvs5qp.js} +2 -2
  185. package/ccw/frontend/dist/assets/{package-DYzAybhU.js.map → package-Djsvs5qp.js.map} +1 -1
  186. package/ccw/frontend/dist/assets/{plug-B3kKHsu1.js → plug-DvSZP2cp.js} +2 -2
  187. package/ccw/frontend/dist/assets/{plug-B3kKHsu1.js.map → plug-DvSZP2cp.js.map} +1 -1
  188. package/ccw/frontend/dist/assets/{power-BPNNZgLy.js → power-BY7vTLmU.js} +2 -2
  189. package/ccw/frontend/dist/assets/{power-BPNNZgLy.js.map → power-BY7vTLmU.js.map} +1 -1
  190. package/ccw/frontend/dist/assets/{save-Cwry93p-.js → save-DXfqv84T.js} +2 -2
  191. package/ccw/frontend/dist/assets/{save-Cwry93p-.js.map → save-DXfqv84T.js.map} +1 -1
  192. package/ccw/frontend/dist/assets/{send-DuWWy2J8.js → send-E2o2LZSX.js} +2 -2
  193. package/ccw/frontend/dist/assets/{send-DuWWy2J8.js.map → send-E2o2LZSX.js.map} +1 -1
  194. package/ccw/frontend/dist/assets/{settings-2-C3U1eSK6.js → settings-2-ChD1LFHH.js} +2 -2
  195. package/ccw/frontend/dist/assets/{settings-2-C3U1eSK6.js.map → settings-2-ChD1LFHH.js.map} +1 -1
  196. package/ccw/frontend/dist/assets/{square-check-big-CrG1ejFB.js → square-check-big-CBymuqmD.js} +2 -2
  197. package/ccw/frontend/dist/assets/{square-check-big-CrG1ejFB.js.map → square-check-big-CBymuqmD.js.map} +1 -1
  198. package/ccw/frontend/dist/assets/{square-pen-eLWlCgZ5.js → square-pen-BfaiJgOX.js} +2 -2
  199. package/ccw/frontend/dist/assets/{square-pen-eLWlCgZ5.js.map → square-pen-BfaiJgOX.js.map} +1 -1
  200. package/ccw/frontend/dist/assets/{star-sveo4KRn.js → star-DHMWqZ09.js} +2 -2
  201. package/ccw/frontend/dist/assets/{star-sveo4KRn.js.map → star-DHMWqZ09.js.map} +1 -1
  202. package/ccw/frontend/dist/assets/{style-CRdAX7Cu.js → style-wvcOEAiM.js} +2 -2
  203. package/ccw/frontend/dist/assets/{style-CRdAX7Cu.js.map → style-wvcOEAiM.js.map} +1 -1
  204. package/ccw/frontend/dist/assets/{target-Oz1-z8Zu.js → target-B8AMmf_N.js} +2 -2
  205. package/ccw/frontend/dist/assets/{target-Oz1-z8Zu.js.map → target-B8AMmf_N.js.map} +1 -1
  206. package/ccw/frontend/dist/assets/{test-tube-BozkZKD6.js → test-tube-BpDeTJi1.js} +2 -2
  207. package/ccw/frontend/dist/assets/{test-tube-BozkZKD6.js.map → test-tube-BpDeTJi1.js.map} +1 -1
  208. package/ccw/frontend/dist/assets/{upload-CTlUsxyh.js → upload-pflkdIDG.js} +2 -2
  209. package/ccw/frontend/dist/assets/{upload-CTlUsxyh.js.map → upload-pflkdIDG.js.map} +1 -1
  210. package/ccw/frontend/dist/assets/{useApiSettings-D6WfgFYj.js → useApiSettings-BPx4DyKT.js} +2 -2
  211. package/ccw/frontend/dist/assets/{useApiSettings-D6WfgFYj.js.map → useApiSettings-BPx4DyKT.js.map} +1 -1
  212. package/ccw/frontend/dist/assets/{useCli-CgGVNN5I.js → useCli-D1jfH3XA.js} +2 -2
  213. package/ccw/frontend/dist/assets/{useCli-CgGVNN5I.js.map → useCli-D1jfH3XA.js.map} +1 -1
  214. package/ccw/frontend/dist/assets/{useCommands-o5CKv-10.js → useCommands-DhR71vpa.js} +2 -2
  215. package/ccw/frontend/dist/assets/{useCommands-o5CKv-10.js.map → useCommands-DhR71vpa.js.map} +1 -1
  216. package/ccw/frontend/dist/assets/{useDebounce-rKo_bCBK.js → useDebounce-a6Yyer3m.js} +2 -2
  217. package/ccw/frontend/dist/assets/{useDebounce-rKo_bCBK.js.map → useDebounce-a6Yyer3m.js.map} +1 -1
  218. package/ccw/frontend/dist/assets/{useFileExplorer-WeE4t9Hg.js → useFileExplorer-B8W2JTj2.js} +2 -2
  219. package/ccw/frontend/dist/assets/{useFileExplorer-WeE4t9Hg.js.map → useFileExplorer-B8W2JTj2.js.map} +1 -1
  220. package/ccw/frontend/dist/assets/{useLocale-BS0tTC-_.js → useLocale-aMHdQIL_.js} +2 -2
  221. package/ccw/frontend/dist/assets/{useLocale-BS0tTC-_.js.map → useLocale-aMHdQIL_.js.map} +1 -1
  222. package/ccw/frontend/dist/assets/{useSkills-BUgAhw6r.js → useSkills-BHpc2LtN.js} +3 -3
  223. package/ccw/frontend/dist/assets/{useSkills-BUgAhw6r.js.map → useSkills-BHpc2LtN.js.map} +1 -1
  224. package/ccw/frontend/dist/assets/{useSystemSettings-CLhmINg1.js → useSystemSettings-BFD0SvEF.js} +2 -2
  225. package/ccw/frontend/dist/assets/{useSystemSettings-CLhmINg1.js.map → useSystemSettings-BFD0SvEF.js.map} +1 -1
  226. package/ccw/frontend/dist/assets/{wand-sparkles-BUHKJH1X.js → wand-sparkles-dYtI2IKM.js} +2 -2
  227. package/ccw/frontend/dist/assets/{wand-sparkles-BUHKJH1X.js.map → wand-sparkles-dYtI2IKM.js.map} +1 -1
  228. package/ccw/frontend/dist/index.html +2 -2
  229. package/package.json +1 -1
  230. package/ccw/frontend/dist/assets/SettingsPage-Qj0fFDjX.js +0 -150
  231. package/ccw/frontend/dist/assets/SettingsPage-Qj0fFDjX.js.map +0 -1
  232. package/ccw/frontend/dist/assets/index-nU0QYi1y.css +0 -39
@@ -1 +1 @@
1
- {"version":3,"file":"TeamPage-CvZBThbr.js","sources":["../../src/stores/teamStore.ts","../../src/hooks/useTeamData.ts","../../src/components/team/TeamHeader.tsx","../../src/components/team/DynamicPipeline.tsx","../../src/components/team/TeamMembersPanel.tsx","../../src/components/team/TeamRolePanel.tsx","../../src/components/team/SessionCoordinates.tsx","../../src/components/team/TeamMessageFeed.tsx","../../src/components/team/TeamArtifacts.tsx","../../src/components/team/TeamCard.tsx","../../src/components/team/TeamListView.tsx","../../src/lib/pipeline-utils.ts","../../src/pages/TeamPage.tsx"],"sourcesContent":["// ========================================\r\n// Team Store\r\n// ========================================\r\n// UI state for team execution visualization\r\n\r\nimport { create } from 'zustand';\r\nimport { devtools, persist } from 'zustand/middleware';\r\nimport type { TeamMessageFilter } from '@/types/team';\r\n\r\nexport type TeamDetailTab = 'pipeline' | 'artifacts' | 'messages';\r\n\r\ninterface TeamStore {\r\n selectedTeam: string | null;\r\n autoRefresh: boolean;\r\n messageFilter: TeamMessageFilter;\r\n timelineExpanded: boolean;\r\n viewMode: 'list' | 'detail';\r\n locationFilter: 'active' | 'archived' | 'all';\r\n searchQuery: string;\r\n detailTab: TeamDetailTab;\r\n setSelectedTeam: (name: string | null) => void;\r\n toggleAutoRefresh: () => void;\r\n setMessageFilter: (filter: Partial<TeamMessageFilter>) => void;\r\n clearMessageFilter: () => void;\r\n setTimelineExpanded: (expanded: boolean) => void;\r\n setViewMode: (mode: 'list' | 'detail') => void;\r\n setLocationFilter: (filter: 'active' | 'archived' | 'all') => void;\r\n setSearchQuery: (query: string) => void;\r\n setDetailTab: (tab: TeamDetailTab) => void;\r\n selectTeamAndShowDetail: (name: string) => void;\r\n backToList: () => void;\r\n}\r\n\r\nexport const useTeamStore = create<TeamStore>()(\r\n devtools(\r\n persist(\r\n (set) => ({\r\n selectedTeam: null,\r\n autoRefresh: true,\r\n messageFilter: {},\r\n timelineExpanded: true,\r\n viewMode: 'list',\r\n locationFilter: 'active',\r\n searchQuery: '',\r\n detailTab: 'pipeline',\r\n setSelectedTeam: (name) => set({ selectedTeam: name }),\r\n toggleAutoRefresh: () => set((s) => ({ autoRefresh: !s.autoRefresh })),\r\n setMessageFilter: (filter) =>\r\n set((s) => ({ messageFilter: { ...s.messageFilter, ...filter } })),\r\n clearMessageFilter: () => set({ messageFilter: {} }),\r\n setTimelineExpanded: (expanded) => set({ timelineExpanded: expanded }),\r\n setViewMode: (mode) => set({ viewMode: mode }),\r\n setLocationFilter: (filter) => set({ locationFilter: filter }),\r\n setSearchQuery: (query) => set({ searchQuery: query }),\r\n setDetailTab: (tab) => set({ detailTab: tab }),\r\n selectTeamAndShowDetail: (name) => set({ selectedTeam: name, viewMode: 'detail', detailTab: 'pipeline' }),\r\n backToList: () => set({ viewMode: 'list', detailTab: 'pipeline' }),\r\n }),\r\n { name: 'ccw-team-store' }\r\n ),\r\n { name: 'TeamStore' }\r\n )\r\n);\r\n","// ========================================\r\n// useTeamData Hook\r\n// ========================================\r\n// TanStack Query hooks for team execution visualization\r\n\r\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport { fetchTeams, fetchTeamMessages, fetchTeamStatus, archiveTeam, unarchiveTeam, deleteTeam } from '@/lib/api';\r\nimport { useTeamStore } from '@/stores/teamStore';\r\nimport type {\r\n TeamSummaryExtended,\r\n TeamMessage,\r\n TeamMember,\r\n TeamMessageFilter,\r\n TeamMessagesResponse,\r\n TeamStatusResponse,\r\n TeamsListResponse,\r\n} from '@/types/team';\r\n\r\n// Query key factory\r\nexport const teamKeys = {\r\n all: ['teams'] as const,\r\n lists: () => [...teamKeys.all, 'list'] as const,\r\n listByLocation: (location: string) => [...teamKeys.lists(), location] as const,\r\n messages: (team: string, filter?: TeamMessageFilter) =>\r\n [...teamKeys.all, 'messages', team, filter] as const,\r\n status: (team: string) => [...teamKeys.all, 'status', team] as const,\r\n};\r\n\r\n/**\r\n * Hook: list all teams with location filter\r\n */\r\nexport function useTeams(location?: string) {\r\n const autoRefresh = useTeamStore((s) => s.autoRefresh);\r\n const effectiveLocation = location || 'active';\r\n\r\n const query = useQuery({\r\n queryKey: teamKeys.listByLocation(effectiveLocation),\r\n queryFn: async (): Promise<TeamsListResponse> => {\r\n const data = await fetchTeams(effectiveLocation);\r\n return { teams: (data.teams ?? []) as TeamSummaryExtended[] };\r\n },\r\n staleTime: 10_000,\r\n refetchInterval: autoRefresh ? 10_000 : false,\r\n });\r\n\r\n return {\r\n teams: (query.data?.teams ?? []) as TeamSummaryExtended[],\r\n isLoading: query.isLoading,\r\n isFetching: query.isFetching,\r\n error: query.error,\r\n refetch: query.refetch,\r\n };\r\n}\r\n\r\n/**\r\n * Hook: get messages for selected team\r\n */\r\nexport function useTeamMessages(\r\n teamName: string | null,\r\n filter?: TeamMessageFilter,\r\n options?: { last?: number; offset?: number }\r\n) {\r\n const autoRefresh = useTeamStore((s) => s.autoRefresh);\r\n\r\n const query = useQuery({\r\n queryKey: teamKeys.messages(teamName ?? '', filter),\r\n queryFn: async (): Promise<TeamMessagesResponse> => {\r\n if (!teamName) return { total: 0, showing: 0, messages: [] };\r\n const data = await fetchTeamMessages(teamName, {\r\n ...filter,\r\n last: options?.last ?? 50,\r\n offset: options?.offset,\r\n });\r\n return {\r\n total: data.total,\r\n showing: data.showing,\r\n messages: data.messages as unknown as TeamMessage[],\r\n };\r\n },\r\n enabled: !!teamName,\r\n staleTime: 5_000,\r\n refetchInterval: autoRefresh ? 5_000 : false,\r\n });\r\n\r\n return {\r\n messages: (query.data?.messages ?? []) as TeamMessage[],\r\n total: query.data?.total ?? 0,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch: query.refetch,\r\n };\r\n}\r\n\r\n/**\r\n * Hook: get member status for selected team\r\n */\r\nexport function useTeamStatus(teamName: string | null) {\r\n const autoRefresh = useTeamStore((s) => s.autoRefresh);\r\n\r\n const query = useQuery({\r\n queryKey: teamKeys.status(teamName ?? ''),\r\n queryFn: async (): Promise<TeamStatusResponse> => {\r\n if (!teamName) return { members: [], total_messages: 0 };\r\n const data = await fetchTeamStatus(teamName);\r\n return {\r\n members: data.members as TeamMember[],\r\n total_messages: data.total_messages,\r\n };\r\n },\r\n enabled: !!teamName,\r\n staleTime: 5_000,\r\n refetchInterval: autoRefresh ? 5_000 : false,\r\n });\r\n\r\n return {\r\n members: (query.data?.members ?? []) as TeamMember[],\r\n totalMessages: query.data?.total_messages ?? 0,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch: query.refetch,\r\n };\r\n}\r\n\r\n/**\r\n * Hook: invalidate all team queries\r\n */\r\nexport function useInvalidateTeamData() {\r\n const queryClient = useQueryClient();\r\n return () => queryClient.invalidateQueries({ queryKey: teamKeys.all });\r\n}\r\n\r\n// ========== Mutation Hooks ==========\r\n\r\n/**\r\n * Hook: archive a team\r\n */\r\nexport function useArchiveTeam() {\r\n const queryClient = useQueryClient();\r\n\r\n const mutation = useMutation({\r\n mutationFn: archiveTeam,\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: teamKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n archiveTeam: mutation.mutateAsync,\r\n isArchiving: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\n/**\r\n * Hook: unarchive a team\r\n */\r\nexport function useUnarchiveTeam() {\r\n const queryClient = useQueryClient();\r\n\r\n const mutation = useMutation({\r\n mutationFn: unarchiveTeam,\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: teamKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n unarchiveTeam: mutation.mutateAsync,\r\n isUnarchiving: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\n/**\r\n * Hook: delete a team\r\n */\r\nexport function useDeleteTeam() {\r\n const queryClient = useQueryClient();\r\n\r\n const mutation = useMutation({\r\n mutationFn: deleteTeam,\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: teamKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n deleteTeam: mutation.mutateAsync,\r\n isDeleting: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n","// ========================================\r\n// TeamHeader Component\r\n// ========================================\r\n// Detail view header with back button, stats, and controls\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { Users, MessageSquare, RefreshCw, ArrowLeft, GitBranch } from 'lucide-react';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Switch } from '@/components/ui/Switch';\r\nimport { Label } from '@/components/ui/Label';\r\nimport type { TeamMember } from '@/types/team';\r\n\r\ninterface TeamHeaderProps {\r\n selectedTeam: string | null;\r\n onBack: () => void;\r\n members: TeamMember[];\r\n totalMessages: number;\r\n autoRefresh: boolean;\r\n onToggleAutoRefresh: () => void;\r\n skillType?: string;\r\n pipelineMode?: string;\r\n}\r\n\r\nexport function TeamHeader({\r\n selectedTeam,\r\n onBack,\r\n members,\r\n totalMessages,\r\n autoRefresh,\r\n onToggleAutoRefresh,\r\n skillType,\r\n pipelineMode,\r\n}: TeamHeaderProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n return (\r\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\r\n <div className=\"flex items-center gap-3 flex-wrap\">\r\n {/* Back button */}\r\n <Button variant=\"ghost\" size=\"sm\" onClick={onBack} className=\"gap-1\">\r\n <ArrowLeft className=\"h-4 w-4\" />\r\n {formatMessage({ id: 'team.detail.backToList' })}\r\n </Button>\r\n\r\n {/* Team name */}\r\n {selectedTeam && (\r\n <>\r\n <h2 className=\"text-lg font-semibold\">{selectedTeam}</h2>\r\n\r\n {/* Stats chips */}\r\n <div className=\"flex items-center gap-2\">\r\n <Badge variant=\"secondary\" className=\"gap-1\">\r\n <Users className=\"w-3 h-3\" />\r\n {formatMessage({ id: 'team.members' })}: {members.length}\r\n </Badge>\r\n <Badge variant=\"secondary\" className=\"gap-1\">\r\n <MessageSquare className=\"w-3 h-3\" />\r\n {formatMessage({ id: 'team.messages' })}: {totalMessages}\r\n </Badge>\r\n </div>\r\n\r\n {/* Skill type and pipeline mode badges */}\r\n {(skillType || pipelineMode) && (\r\n <div className=\"flex items-center gap-2\">\r\n {skillType && (\r\n <Badge variant=\"outline\" className=\"gap-1\">\r\n {skillType}\r\n </Badge>\r\n )}\r\n {pipelineMode && (\r\n <Badge variant=\"default\" className=\"gap-1\">\r\n <GitBranch className=\"w-3 h-3\" />\r\n {pipelineMode}\r\n </Badge>\r\n )}\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n\r\n {/* Controls */}\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"flex items-center gap-2\">\r\n <Switch\r\n id=\"auto-refresh\"\r\n checked={autoRefresh}\r\n onCheckedChange={onToggleAutoRefresh}\r\n />\r\n <Label htmlFor=\"auto-refresh\" className=\"text-sm text-muted-foreground cursor-pointer\">\r\n {formatMessage({ id: 'team.autoRefresh' })}\r\n </Label>\r\n {autoRefresh && (\r\n <RefreshCw className=\"w-3.5 h-3.5 text-primary animate-spin\" style={{ animationDuration: '3s' }} />\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// DynamicPipeline Component\r\n// ========================================\r\n// Dynamic pipeline stage visualization with fallback to static TeamPipeline\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { CheckCircle2, Circle, Loader2, Ban, SkipForward } from 'lucide-react';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { cn } from '@/lib/utils';\r\nimport type { DynamicStage, DynamicStageStatus, PhaseInfo } from '@/types/team';\r\n\r\ninterface DynamicPipelineProps {\r\n stages: DynamicStage[];\r\n phaseInfo?: PhaseInfo | null;\r\n}\r\n\r\nconst statusConfig: Record<DynamicStageStatus, { icon: typeof CheckCircle2; color: string; bg: string; animate?: boolean }> = {\r\n completed: { icon: CheckCircle2, color: 'text-green-500', bg: 'bg-green-500/10 border-green-500/30' },\r\n in_progress: { icon: Loader2, color: 'text-blue-500', bg: 'bg-blue-500/10 border-blue-500/30', animate: true },\r\n pending: { icon: Circle, color: 'text-muted-foreground', bg: 'bg-muted border-border' },\r\n blocked: { icon: Ban, color: 'text-red-500', bg: 'bg-red-500/10 border-red-500/30' },\r\n skipped: { icon: SkipForward, color: 'text-yellow-500', bg: 'bg-yellow-500/10 border-yellow-500/30' },\r\n};\r\n\r\nconst LEGEND_STATUSES: DynamicStageStatus[] = ['completed', 'in_progress', 'pending', 'blocked', 'skipped'];\r\n\r\nfunction StageNode({ stage }: { stage: DynamicStage }) {\r\n const { formatMessage } = useIntl();\r\n const config = statusConfig[stage.status];\r\n const Icon = config.icon;\r\n\r\n const statusKey = stage.status === 'in_progress' ? 'inProgress' : stage.status;\r\n\r\n return (\r\n <div\r\n className={cn(\r\n 'flex flex-col items-center gap-1.5 px-4 py-3 rounded-lg border-2 min-w-[90px] transition-all',\r\n config.bg\r\n )}\r\n >\r\n <Icon\r\n className={cn('w-5 h-5', config.color, config.animate && 'animate-spin')}\r\n style={config.animate ? { animationDuration: '2s' } : undefined}\r\n />\r\n <span className=\"text-xs font-medium\">\r\n {stage.label}\r\n </span>\r\n <span className={cn('text-[10px]', config.color)}>\r\n {formatMessage({ id: `team.pipeline.${statusKey}` })}\r\n </span>\r\n {stage.role && (\r\n <span className=\"text-[10px] text-muted-foreground truncate max-w-[80px]\">\r\n {stage.role}\r\n </span>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction Arrow() {\r\n return (\r\n <div className=\"flex items-center px-1\">\r\n <div className=\"w-6 h-0.5 bg-border\" />\r\n <div className=\"w-0 h-0 border-t-[4px] border-t-transparent border-b-[4px] border-b-transparent border-l-[6px] border-l-border\" />\r\n </div>\r\n );\r\n}\r\n\r\nexport function DynamicPipeline({ stages, phaseInfo }: DynamicPipelineProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n // Fallback: empty state when no dynamic stages are available\r\n if (stages.length === 0) {\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n <h3 className=\"text-sm font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'team.pipeline.title' })}\r\n </h3>\r\n <p className=\"text-xs text-muted-foreground text-center py-8\">\r\n {formatMessage({ id: 'team.pipeline.noStages' })}\r\n </p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n <div className=\"space-y-3 flex-1\">\r\n <h3 className=\"text-sm font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'team.pipeline.title' })}\r\n </h3>\r\n\r\n {/* Phase header */}\r\n {phaseInfo && (\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <Badge variant=\"secondary\">\r\n {formatMessage({ id: 'team.coordinates.phase' })}: {phaseInfo.currentPhase}\r\n {phaseInfo.totalPhases != null && `/${phaseInfo.totalPhases}`}\r\n </Badge>\r\n {phaseInfo.currentStep && (\r\n <Badge variant=\"secondary\">\r\n {formatMessage({ id: 'team.coordinates.step' })}: {phaseInfo.currentStep}\r\n </Badge>\r\n )}\r\n {phaseInfo.gapIteration > 0 && (\r\n <Badge variant=\"outline\">\r\n {formatMessage({ id: 'team.coordinates.gap' })}: {phaseInfo.gapIteration}\r\n </Badge>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Desktop: horizontal layout */}\r\n <div className=\"hidden sm:flex items-center gap-0\">\r\n {stages.map((stage, idx) => (\r\n <div key={stage.id} className=\"flex items-center\">\r\n {idx > 0 && <Arrow />}\r\n <StageNode stage={stage} />\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Mobile: vertical layout */}\r\n <div className=\"flex sm:hidden flex-col items-center gap-2\">\r\n {stages.map((stage) => (\r\n <StageNode key={stage.id} stage={stage} />\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Legend */}\r\n <div className=\"flex flex-wrap gap-3 text-[10px] text-muted-foreground mt-auto pt-3 border-t border-border\">\r\n {LEGEND_STATUSES.map((s) => {\r\n const cfg = statusConfig[s];\r\n const Icon = cfg.icon;\r\n const statusKey = s === 'in_progress' ? 'inProgress' : s;\r\n return (\r\n <span key={s} className=\"flex items-center gap-1\">\r\n <Icon className={cn('w-3 h-3', cfg.color)} />\r\n {formatMessage({ id: `team.pipeline.${statusKey}` })}\r\n </span>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// TeamMembersPanel Component\r\n// ========================================\r\n// Card-based member status display\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { cn } from '@/lib/utils';\r\nimport type { TeamMember } from '@/types/team';\r\n\r\ninterface TeamMembersPanelProps {\r\n members: TeamMember[];\r\n}\r\n\r\nfunction formatRelativeTime(isoString: string): string {\r\n if (!isoString) return '';\r\n const now = Date.now();\r\n const then = new Date(isoString).getTime();\r\n const diffMs = now - then;\r\n\r\n if (diffMs < 0) return 'now';\r\n const seconds = Math.floor(diffMs / 1000);\r\n if (seconds < 60) return `${seconds}s`;\r\n const minutes = Math.floor(seconds / 60);\r\n if (minutes < 60) return `${minutes}m`;\r\n const hours = Math.floor(minutes / 60);\r\n if (hours < 24) return `${hours}h`;\r\n const days = Math.floor(hours / 24);\r\n return `${days}d`;\r\n}\r\n\r\nfunction getMemberStatus(member: TeamMember): 'active' | 'idle' {\r\n if (!member.lastSeen) return 'idle';\r\n const diffMs = Date.now() - new Date(member.lastSeen).getTime();\r\n // Active if seen in last 2 minutes\r\n return diffMs < 2 * 60 * 1000 ? 'active' : 'idle';\r\n}\r\n\r\nexport function TeamMembersPanel({ members }: TeamMembersPanelProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n <h3 className=\"text-sm font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'team.membersPanel.title' })}\r\n </h3>\r\n <div className=\"space-y-2\">\r\n {members.map((m) => {\r\n const status = getMemberStatus(m);\r\n const isActive = status === 'active';\r\n\r\n return (\r\n <Card key={m.member} className=\"overflow-hidden\">\r\n <CardContent className=\"p-3\">\r\n <div className=\"flex items-start gap-3\">\r\n {/* Status indicator */}\r\n <div className=\"pt-0.5\">\r\n <div\r\n className={cn(\r\n 'w-2.5 h-2.5 rounded-full',\r\n isActive\r\n ? 'bg-green-500 shadow-[0_0_6px_rgba(34,197,94,0.5)]'\r\n : 'bg-muted-foreground/40'\r\n )}\r\n />\r\n </div>\r\n\r\n <div className=\"flex-1 min-w-0 space-y-1\">\r\n {/* Name + status badge */}\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium truncate\">{m.member}</span>\r\n <Badge\r\n variant={isActive ? 'success' : 'secondary'}\r\n className=\"text-[10px] px-1.5 py-0\"\r\n >\r\n {formatMessage({ id: `team.membersPanel.${status}` })}\r\n </Badge>\r\n </div>\r\n\r\n {/* Last action */}\r\n {m.lastAction && (\r\n <p className=\"text-xs text-muted-foreground truncate\">\r\n {m.lastAction}\r\n </p>\r\n )}\r\n\r\n {/* Stats row */}\r\n <div className=\"flex items-center gap-3 text-[10px] text-muted-foreground\">\r\n <span>\r\n {m.messageCount} {formatMessage({ id: 'team.messages' }).toLowerCase()}\r\n </span>\r\n {m.lastSeen && (\r\n <span>\r\n {formatRelativeTime(m.lastSeen)} {formatMessage({ id: 'team.membersPanel.ago' })}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n })}\r\n\r\n {members.length === 0 && (\r\n <p className=\"text-xs text-muted-foreground text-center py-4\">\r\n {formatMessage({ id: 'team.empty.noMessages' })}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// TeamRolePanel Component\r\n// ========================================\r\n// Member-to-pipeline-role mapping with fallback to TeamMembersPanel\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { cn } from '@/lib/utils';\r\nimport { TeamMembersPanel } from './TeamMembersPanel';\r\nimport type { TeamMember, DynamicStage } from '@/types/team';\r\n\r\ninterface TeamRolePanelProps {\r\n members: TeamMember[];\r\n stages: DynamicStage[];\r\n roleState?: Record<string, Record<string, unknown>>;\r\n}\r\n\r\nfunction formatRelativeTime(isoString: string): string {\r\n if (!isoString) return '';\r\n const now = Date.now();\r\n const then = new Date(isoString).getTime();\r\n const diffMs = now - then;\r\n if (diffMs < 0) return 'now';\r\n const seconds = Math.floor(diffMs / 1000);\r\n if (seconds < 60) return `${seconds}s`;\r\n const minutes = Math.floor(seconds / 60);\r\n if (minutes < 60) return `${minutes}m`;\r\n const hours = Math.floor(minutes / 60);\r\n if (hours < 24) return `${hours}h`;\r\n const days = Math.floor(hours / 24);\r\n return `${days}d`;\r\n}\r\n\r\nfunction getMemberStatus(member: TeamMember): 'active' | 'idle' {\r\n if (!member.lastSeen) return 'idle';\r\n const diffMs = Date.now() - new Date(member.lastSeen).getTime();\r\n // Active if seen in last 2 minutes\r\n return diffMs < 2 * 60 * 1000 ? 'active' : 'idle';\r\n}\r\n\r\n/** Find the matching dynamic stage for a member */\r\nfunction findMatchingStage(member: TeamMember, stages: DynamicStage[]): DynamicStage | undefined {\r\n const memberLower = member.member.toLowerCase();\r\n return stages.find(\r\n (stage) =>\r\n (stage.role && stage.role.toLowerCase() === memberLower) ||\r\n stage.id.toLowerCase() === memberLower\r\n );\r\n}\r\n\r\nconst stageBadgeVariant: Record<string, 'success' | 'info' | 'secondary' | 'destructive' | 'warning'> = {\r\n completed: 'success',\r\n in_progress: 'info',\r\n pending: 'secondary',\r\n blocked: 'destructive',\r\n skipped: 'warning',\r\n};\r\n\r\nexport function TeamRolePanel({ members, stages, roleState: _roleState }: TeamRolePanelProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n // Fallback to static members panel when no dynamic stages\r\n if (stages.length === 0) {\r\n return <TeamMembersPanel members={members} />;\r\n }\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n <h3 className=\"text-sm font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'team.membersPanel.title' })}\r\n </h3>\r\n <div className=\"space-y-2\">\r\n {members.map((m) => {\r\n const status = getMemberStatus(m);\r\n const isActive = status === 'active';\r\n const matchedStage = findMatchingStage(m, stages);\r\n\r\n return (\r\n <Card key={m.member} className=\"overflow-hidden\">\r\n <CardContent className=\"p-3\">\r\n <div className=\"flex items-start gap-3\">\r\n {/* Status indicator */}\r\n <div className=\"pt-0.5\">\r\n <div\r\n className={cn(\r\n 'w-2.5 h-2.5 rounded-full',\r\n isActive\r\n ? 'bg-green-500 shadow-[0_0_6px_rgba(34,197,94,0.5)]'\r\n : 'bg-muted-foreground/40'\r\n )}\r\n />\r\n </div>\r\n\r\n <div className=\"flex-1 min-w-0 space-y-1\">\r\n {/* Name + status badge + stage badge */}\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span className=\"text-sm font-medium truncate\">{m.member}</span>\r\n <Badge\r\n variant={isActive ? 'success' : 'secondary'}\r\n className=\"text-[10px] px-1.5 py-0\"\r\n >\r\n {formatMessage({ id: `team.membersPanel.${status}` })}\r\n </Badge>\r\n {matchedStage && (\r\n <Badge\r\n variant={stageBadgeVariant[matchedStage.status] ?? 'secondary'}\r\n className=\"text-[10px] px-1.5 py-0\"\r\n >\r\n {matchedStage.label}\r\n </Badge>\r\n )}\r\n </div>\r\n\r\n {/* Last action */}\r\n {m.lastAction && (\r\n <p className=\"text-xs text-muted-foreground truncate\">\r\n {m.lastAction}\r\n </p>\r\n )}\r\n\r\n {/* Stats row */}\r\n <div className=\"flex items-center gap-3 text-[10px] text-muted-foreground\">\r\n <span>\r\n {m.messageCount} {formatMessage({ id: 'team.messages' }).toLowerCase()}\r\n </span>\r\n {m.lastSeen && (\r\n <span>\r\n {formatRelativeTime(m.lastSeen)} {formatMessage({ id: 'team.membersPanel.ago' })}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n })}\r\n\r\n {members.length === 0 && (\r\n <p className=\"text-xs text-muted-foreground text-center py-4\">\r\n {formatMessage({ id: 'team.empty.noMessages' })}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// SessionCoordinates Component\r\n// ========================================\r\n// Compact inline display of phase/step/gap using Badge components\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport type { PhaseInfo } from '@/types/team';\r\n\r\ninterface SessionCoordinatesProps {\r\n phaseInfo: PhaseInfo;\r\n}\r\n\r\nexport function SessionCoordinates({ phaseInfo }: SessionCoordinatesProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n return (\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <Badge variant=\"secondary\">\r\n {formatMessage({ id: 'team.coordinates.phase' })}: {phaseInfo.currentPhase}\r\n {phaseInfo.totalPhases != null && `/${phaseInfo.totalPhases}`}\r\n </Badge>\r\n {phaseInfo.currentStep && (\r\n <Badge variant=\"secondary\">\r\n {formatMessage({ id: 'team.coordinates.step' })}: {phaseInfo.currentStep}\r\n </Badge>\r\n )}\r\n {phaseInfo.gapIteration > 0 && (\r\n <Badge variant=\"outline\">\r\n {formatMessage({ id: 'team.coordinates.gap' })}: {phaseInfo.gapIteration}\r\n </Badge>\r\n )}\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// TeamMessageFeed Component\r\n// ========================================\r\n// Message timeline with filtering and pagination\r\n\r\nimport { useState, useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { ChevronDown, ChevronUp, FileText, Filter, X } from 'lucide-react';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport {\r\n Select,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n} from '@/components/ui/Select';\r\nimport { cn } from '@/lib/utils';\r\nimport type { TeamMessage, TeamMessageFilter } from '@/types/team';\r\n\r\ninterface TeamMessageFeedProps {\r\n messages: TeamMessage[];\r\n total: number;\r\n filter: TeamMessageFilter;\r\n onFilterChange: (filter: Partial<TeamMessageFilter>) => void;\r\n onClearFilter: () => void;\r\n expanded: boolean;\r\n onExpandedChange: (expanded: boolean) => void;\r\n}\r\n\r\n// Message type → color mapping\r\nconst typeColorMap: Record<string, string> = {\r\n plan_ready: 'bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-500/30',\r\n plan_approved: 'bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-500/30',\r\n plan_revision: 'bg-amber-500/15 text-amber-600 dark:text-amber-400 border-amber-500/30',\r\n task_unblocked: 'bg-cyan-500/15 text-cyan-600 dark:text-cyan-400 border-cyan-500/30',\r\n impl_complete: 'bg-primary/15 text-primary border-primary/30',\r\n impl_progress: 'bg-primary/15 text-primary border-primary/30',\r\n test_result: 'bg-green-500/15 text-green-600 dark:text-green-400 border-green-500/30',\r\n review_result: 'bg-purple-500/15 text-purple-600 dark:text-purple-400 border-purple-500/30',\r\n fix_required: 'bg-red-500/15 text-red-600 dark:text-red-400 border-red-500/30',\r\n error: 'bg-red-500/15 text-red-600 dark:text-red-400 border-red-500/30',\r\n shutdown: 'bg-muted text-muted-foreground border-border',\r\n message: 'bg-muted text-muted-foreground border-border',\r\n};\r\n\r\nfunction MessageTypeBadge({ type }: { type: string }) {\r\n const { formatMessage } = useIntl();\r\n const color = typeColorMap[type] || typeColorMap.message;\r\n const labelKey = `team.messageType.${type}`;\r\n\r\n let label: string;\r\n try {\r\n label = formatMessage({ id: labelKey });\r\n } catch {\r\n label = type;\r\n }\r\n\r\n return (\r\n <span className={cn('text-[10px] px-1.5 py-0.5 rounded border font-medium', color)}>\r\n {label}\r\n </span>\r\n );\r\n}\r\n\r\nfunction MessageRow({ msg }: { msg: TeamMessage }) {\r\n const [dataExpanded, setDataExpanded] = useState(false);\r\n const time = msg.ts ? msg.ts.substring(11, 19) : '';\r\n\r\n return (\r\n <div className=\"flex gap-3 py-2.5 border-b border-border last:border-b-0 animate-in fade-in slide-in-from-top-1 duration-300\">\r\n {/* Timestamp */}\r\n <span className=\"text-[10px] font-mono text-muted-foreground w-16 shrink-0 pt-0.5\">\r\n {time}\r\n </span>\r\n\r\n {/* Content */}\r\n <div className=\"flex-1 min-w-0 space-y-1\">\r\n {/* Header: from → to + type */}\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span className=\"text-xs font-medium\">{msg.from}</span>\r\n <span className=\"text-[10px] text-muted-foreground\">&rarr;</span>\r\n <span className=\"text-xs font-medium\">{msg.to}</span>\r\n <MessageTypeBadge type={msg.type} />\r\n {msg.id && (\r\n <span className=\"text-[10px] text-muted-foreground\">{msg.id}</span>\r\n )}\r\n </div>\r\n\r\n {/* Summary */}\r\n <p className=\"text-xs text-foreground/80\">{msg.summary}</p>\r\n\r\n {/* Ref link (supports both legacy msg.ref and new data.ref) */}\r\n {(msg.ref || (msg.data?.ref as string)) && (\r\n <div className=\"flex items-center gap-1 text-[10px] text-muted-foreground\">\r\n <FileText className=\"w-3 h-3\" />\r\n <span className=\"font-mono truncate\">{msg.ref || (msg.data?.ref as string)}</span>\r\n </div>\r\n )}\r\n\r\n {/* Data toggle */}\r\n {msg.data && Object.keys(msg.data).length > 0 && (\r\n <div>\r\n <button\r\n onClick={() => setDataExpanded(!dataExpanded)}\r\n className=\"text-[10px] text-primary hover:underline flex items-center gap-0.5\"\r\n >\r\n {dataExpanded ? (\r\n <>\r\n <ChevronUp className=\"w-3 h-3\" /> collapse\r\n </>\r\n ) : (\r\n <>\r\n <ChevronDown className=\"w-3 h-3\" /> data\r\n </>\r\n )}\r\n </button>\r\n {dataExpanded && (\r\n <pre className=\"text-[10px] bg-muted p-2 rounded mt-1 overflow-x-auto max-h-40\">\r\n {JSON.stringify(msg.data, null, 2)}\r\n </pre>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport function TeamMessageFeed({\r\n messages,\r\n total,\r\n filter,\r\n onFilterChange,\r\n onClearFilter,\r\n expanded,\r\n onExpandedChange,\r\n}: TeamMessageFeedProps) {\r\n const { formatMessage } = useIntl();\r\n const hasFilter = !!(filter.from || filter.to || filter.type);\r\n\r\n // Extract unique senders/receivers for filter dropdowns\r\n const { senders, receivers, types } = useMemo(() => {\r\n const s = new Set<string>();\r\n const r = new Set<string>();\r\n const t = new Set<string>();\r\n for (const m of messages) {\r\n s.add(m.from);\r\n r.add(m.to);\r\n t.add(m.type);\r\n }\r\n return {\r\n senders: Array.from(s).sort(),\r\n receivers: Array.from(r).sort(),\r\n types: Array.from(t).sort(),\r\n };\r\n }, [messages]);\r\n\r\n // Reverse for newest-first display\r\n const displayMessages = [...messages].reverse();\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <button\r\n onClick={() => onExpandedChange(!expanded)}\r\n className=\"flex items-center gap-2 text-sm font-medium text-muted-foreground hover:text-foreground transition-colors\"\r\n >\r\n {expanded ? <ChevronUp className=\"w-4 h-4\" /> : <ChevronDown className=\"w-4 h-4\" />}\r\n {formatMessage({ id: 'team.timeline.title' })}\r\n <span className=\"text-xs font-normal\">\r\n ({formatMessage({ id: 'team.timeline.showing' }, { showing: messages.length, total })})\r\n </span>\r\n </button>\r\n\r\n {hasFilter && (\r\n <Button variant=\"ghost\" size=\"sm\" onClick={onClearFilter} className=\"h-6 text-xs gap-1\">\r\n <X className=\"w-3 h-3\" />\r\n {formatMessage({ id: 'team.timeline.clearFilters' })}\r\n </Button>\r\n )}\r\n </div>\r\n\r\n {expanded && (\r\n <>\r\n {/* Filters */}\r\n <div className=\"flex flex-wrap gap-2\">\r\n <Select\r\n value={filter.from ?? '__all__'}\r\n onValueChange={(v) => onFilterChange({ from: v === '__all__' ? undefined : v })}\r\n >\r\n <SelectTrigger className=\"w-[130px] h-7 text-xs\">\r\n <Filter className=\"w-3 h-3 mr-1\" />\r\n <SelectValue placeholder={formatMessage({ id: 'team.timeline.filterFrom' })} />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"__all__\">{formatMessage({ id: 'team.filterAll' })}</SelectItem>\r\n {senders.map((s) => (\r\n <SelectItem key={s} value={s}>{s}</SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n\r\n <Select\r\n value={filter.to ?? '__all__'}\r\n onValueChange={(v) => onFilterChange({ to: v === '__all__' ? undefined : v })}\r\n >\r\n <SelectTrigger className=\"w-[130px] h-7 text-xs\">\r\n <SelectValue placeholder={formatMessage({ id: 'team.timeline.filterTo' })} />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"__all__\">{formatMessage({ id: 'team.filterAll' })}</SelectItem>\r\n {receivers.map((r) => (\r\n <SelectItem key={r} value={r}>{r}</SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n\r\n <Select\r\n value={filter.type ?? '__all__'}\r\n onValueChange={(v) => onFilterChange({ type: v === '__all__' ? undefined : v })}\r\n >\r\n <SelectTrigger className=\"w-[150px] h-7 text-xs\">\r\n <SelectValue placeholder={formatMessage({ id: 'team.timeline.filterType' })} />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"__all__\">{formatMessage({ id: 'team.filterAll' })}</SelectItem>\r\n {types.map((t) => (\r\n <SelectItem key={t} value={t}>{t}</SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n\r\n {/* Messages list */}\r\n <Card>\r\n <CardContent className=\"p-3\">\r\n {displayMessages.length > 0 ? (\r\n <div className=\"divide-y-0\">\r\n {displayMessages.map((msg) => (\r\n <MessageRow key={msg.id} msg={msg} />\r\n ))}\r\n </div>\r\n ) : (\r\n <div className=\"text-center py-8\">\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'team.empty.noMessages' })}\r\n </p>\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'team.empty.noMessagesHint' })}\r\n </p>\r\n </div>\r\n )}\r\n </CardContent>\r\n </Card>\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// TeamArtifacts Component\r\n// ========================================\r\n// Displays team artifacts with hybrid layout: tree navigation + file preview\r\n\r\nimport * as React from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n ChevronDown,\r\n ChevronRight,\r\n Folder,\r\n FileText,\r\n FileJson,\r\n Package,\r\n Loader2,\r\n} from 'lucide-react';\r\nimport { fetchTeamArtifacts, fetchArtifactContent } from '@/lib/api';\r\nimport { cn } from '@/lib/utils';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport type { ArtifactNode, ContentType } from '@/types/team';\r\n\r\n// ========================================\r\n// Types\r\n// ========================================\r\n\r\ninterface TeamArtifactsProps {\r\n teamName: string;\r\n}\r\n\r\n// ========================================\r\n// Helpers\r\n// ========================================\r\n\r\nfunction getContentTypeFromPath(path: string): ContentType {\r\n if (path.endsWith('.json')) return 'json';\r\n if (path.endsWith('.md')) return 'markdown';\r\n if (path.endsWith('.txt') || path.endsWith('.log') || path.endsWith('.tsv') || path.endsWith('.csv')) return 'text';\r\n return 'unknown';\r\n}\r\n\r\nfunction formatSize(bytes?: number): string {\r\n if (!bytes) return '';\r\n if (bytes < 1024) return `${bytes} B`;\r\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\r\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\r\n}\r\n\r\nfunction formatDate(ts?: string): string {\r\n if (!ts) return '';\r\n try {\r\n const date = new Date(ts);\r\n return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });\r\n } catch {\r\n return '';\r\n }\r\n}\r\n\r\n// ========================================\r\n// Sub-components\r\n// ========================================\r\n\r\nfunction FileIcon({ contentType }: { contentType?: ContentType }) {\r\n if (contentType === 'json') {\r\n return <FileJson className=\"w-4 h-4 text-blue-500\" />;\r\n }\r\n return <FileText className=\"w-4 h-4 text-gray-500\" />;\r\n}\r\n\r\ninterface TreeNodeProps {\r\n node: ArtifactNode;\r\n depth: number;\r\n expanded: Set<string>;\r\n selectedPath?: string;\r\n onToggle: (path: string) => void;\r\n onSelect: (node: ArtifactNode) => void;\r\n}\r\n\r\nfunction TreeNode({\r\n node,\r\n depth,\r\n expanded,\r\n selectedPath,\r\n onToggle,\r\n onSelect,\r\n}: TreeNodeProps) {\r\n if (node.type === 'directory') {\r\n const isExpanded = expanded.has(node.path);\r\n return (\r\n <div key={node.path}>\r\n <div\r\n className=\"flex items-center gap-1 py-1.5 px-2 cursor-pointer hover:bg-accent/50 rounded transition-colors\"\r\n style={{ paddingLeft: depth * 16 + 8 }}\r\n onClick={() => onToggle(node.path)}\r\n >\r\n {isExpanded ? (\r\n <ChevronDown className=\"w-4 h-4 text-muted-foreground\" />\r\n ) : (\r\n <ChevronRight className=\"w-4 h-4 text-muted-foreground\" />\r\n )}\r\n <Folder\r\n className={cn(\r\n 'w-4 h-4',\r\n isExpanded ? 'text-amber-500' : 'text-amber-400'\r\n )}\r\n />\r\n <span className=\"text-sm truncate\">{node.name}</span>\r\n </div>\r\n {isExpanded && node.children && (\r\n <div>\r\n {node.children.map((child) => (\r\n <TreeNode\r\n key={child.path}\r\n node={child}\r\n depth={depth + 1}\r\n expanded={expanded}\r\n selectedPath={selectedPath}\r\n onToggle={onToggle}\r\n onSelect={onSelect}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n }\r\n\r\n // File node\r\n const isSelected = selectedPath === node.path;\r\n const contentType = node.contentType || getContentTypeFromPath(node.path);\r\n\r\n return (\r\n <div\r\n key={node.path}\r\n className={cn(\r\n 'flex items-center gap-1 py-1.5 px-2 cursor-pointer hover:bg-accent/50 rounded transition-colors',\r\n isSelected && 'bg-accent'\r\n )}\r\n style={{ paddingLeft: depth * 16 + 28 }}\r\n onClick={() => onSelect(node)}\r\n >\r\n <FileIcon contentType={contentType} />\r\n <span className=\"text-sm truncate flex-1\">{node.name}</span>\r\n {node.size !== undefined && (\r\n <span className=\"text-xs text-muted-foreground ml-2\">\r\n {formatSize(node.size)}\r\n </span>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n// ========================================\r\n// Main Component\r\n// ========================================\r\n\r\nexport function TeamArtifacts({ teamName }: TeamArtifactsProps) {\r\n const { formatMessage } = useIntl();\r\n const [tree, setTree] = React.useState<ArtifactNode[]>([]);\r\n const [expanded, setExpanded] = React.useState<Set<string>>(new Set());\r\n const [selectedFile, setSelectedFile] = React.useState<ArtifactNode | null>(null);\r\n const [content, setContent] = React.useState<string>('');\r\n const [loading, setLoading] = React.useState(false);\r\n const [treeLoading, setTreeLoading] = React.useState(true);\r\n const [error, setError] = React.useState<string | null>(null);\r\n\r\n // Load artifacts tree\r\n React.useEffect(() => {\r\n if (!teamName) return;\r\n\r\n setTreeLoading(true);\r\n setError(null);\r\n\r\n fetchTeamArtifacts(teamName)\r\n .then((data) => {\r\n setTree(data.tree || []);\r\n // Auto-expand first level directories\r\n const firstLevelDirs = (data.tree || [])\r\n .filter((n) => n.type === 'directory')\r\n .map((n) => n.path);\r\n setExpanded(new Set(firstLevelDirs));\r\n })\r\n .catch((err) => {\r\n console.error('Failed to load artifacts:', err);\r\n setError(formatMessage({ id: 'team.artifacts.loadError', defaultMessage: 'Failed to load artifacts' }));\r\n })\r\n .finally(() => {\r\n setTreeLoading(false);\r\n });\r\n }, [teamName, formatMessage]);\r\n\r\n const handleToggle = React.useCallback((path: string) => {\r\n setExpanded((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(path)) {\r\n next.delete(path);\r\n } else {\r\n next.add(path);\r\n }\r\n return next;\r\n });\r\n }, []);\r\n\r\n const handleSelect = React.useCallback(\r\n async (node: ArtifactNode) => {\r\n if (node.type === 'directory') return;\r\n\r\n setSelectedFile(node);\r\n setLoading(true);\r\n setContent('');\r\n\r\n try {\r\n const result = await fetchArtifactContent(teamName, node.path);\r\n setContent(result.content);\r\n } catch (err) {\r\n console.error('Failed to load file content:', err);\r\n setContent(formatMessage({ id: 'team.artifacts.contentError', defaultMessage: 'Failed to load file content' }));\r\n } finally {\r\n setLoading(false);\r\n }\r\n },\r\n [teamName, formatMessage]\r\n );\r\n\r\n // Get content type for preview\r\n const previewContentType = selectedFile\r\n ? selectedFile.contentType || getContentTypeFromPath(selectedFile.path)\r\n : 'text';\r\n\r\n // Map to MarkdownModal content type\r\n const modalContentType: 'markdown' | 'json' | 'text' =\r\n previewContentType === 'json' ? 'json' : previewContentType === 'markdown' ? 'markdown' : 'text';\r\n\r\n // Loading state\r\n if (treeLoading) {\r\n return (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\r\n <span className=\"ml-3 text-muted-foreground\">\r\n {formatMessage({ id: 'team.artifacts.loading', defaultMessage: 'Loading artifacts...' })}\r\n </span>\r\n </div>\r\n );\r\n }\r\n\r\n // Error state\r\n if (error) {\r\n return (\r\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\r\n <Package className=\"h-12 w-12 text-destructive mb-4\" />\r\n <p className=\"text-muted-foreground\">{error}</p>\r\n </div>\r\n );\r\n }\r\n\r\n // Empty state\r\n if (tree.length === 0) {\r\n return (\r\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\r\n <Package className=\"h-12 w-12 text-muted-foreground mb-4\" />\r\n <h3 className=\"text-lg font-medium text-foreground mb-2\">\r\n {formatMessage({ id: 'team.artifacts.noArtifacts', defaultMessage: 'No artifacts yet' })}\r\n </h3>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'team.artifacts.emptyHint', defaultMessage: 'Artifacts will appear here when the team generates them' })}\r\n </p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"flex h-[600px] border rounded-lg overflow-hidden\">\r\n {/* Left: Tree Navigation */}\r\n <div className=\"w-72 shrink-0 border-r bg-muted/30 flex flex-col\">\r\n <div className=\"p-3 border-b bg-background shrink-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <Package className=\"w-4 h-4 text-muted-foreground\" />\r\n <span className=\"text-sm font-medium\">\r\n {formatMessage({ id: 'team.artifacts.title', defaultMessage: 'Artifacts' })}\r\n </span>\r\n </div>\r\n </div>\r\n <div className=\"flex-1 overflow-y-auto py-2\">\r\n {tree.map((node) => (\r\n <TreeNode\r\n key={node.path}\r\n node={node}\r\n depth={0}\r\n expanded={expanded}\r\n selectedPath={selectedFile?.path}\r\n onToggle={handleToggle}\r\n onSelect={handleSelect}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Right: File Preview */}\r\n <div className=\"flex-1 flex flex-col min-w-0\">\r\n {selectedFile ? (\r\n <>\r\n <div className=\"p-3 border-b bg-muted/30 shrink-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <FileIcon contentType={previewContentType} />\r\n <span className=\"text-sm font-medium truncate\">\r\n {selectedFile.name}\r\n </span>\r\n {selectedFile.size !== undefined && (\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatSize(selectedFile.size)}\r\n </span>\r\n )}\r\n {selectedFile.modifiedAt && (\r\n <span className=\"text-xs text-muted-foreground ml-auto\">\r\n {formatDate(selectedFile.modifiedAt)}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"flex-1 overflow-y-auto p-4\">\r\n {loading ? (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"h-6 w-6 animate-spin text-muted-foreground\" />\r\n </div>\r\n ) : (\r\n <PreviewContent\r\n content={content}\r\n contentType={modalContentType}\r\n />\r\n )}\r\n </div>\r\n </>\r\n ) : (\r\n <div className=\"flex-1 flex items-center justify-center text-center p-8\">\r\n <div>\r\n <FileText className=\"h-12 w-12 text-muted-foreground mx-auto mb-4\" />\r\n <p className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'team.artifacts.selectFile', defaultMessage: 'Select a file to preview' })}\r\n </p>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ========================================\r\n// JSON Card Viewer\r\n// ========================================\r\n\r\nfunction JsonCardViewer({ data, depth = 0 }: { data: unknown; depth?: number }) {\r\n // Primitive values\r\n if (data === null) {\r\n return <span className=\"text-red-500 font-mono text-sm\">null</span>;\r\n }\r\n if (data === undefined) {\r\n return <span className=\"text-muted-foreground font-mono text-sm\">undefined</span>;\r\n }\r\n if (typeof data === 'boolean') {\r\n return (\r\n <span className={cn('font-mono text-sm', data ? 'text-orange-500' : 'text-red-500')}>\r\n {data ? 'true' : 'false'}\r\n </span>\r\n );\r\n }\r\n if (typeof data === 'number') {\r\n return <span className=\"text-blue-500 font-mono text-sm\">{data}</span>;\r\n }\r\n if (typeof data === 'string') {\r\n // Check if it's a long string that should be truncated\r\n if (data.length > 200) {\r\n return (\r\n <span className=\"text-green-600 dark:text-green-400 font-mono text-sm break-all\">\r\n \"{data.slice(0, 200)}...\"\r\n </span>\r\n );\r\n }\r\n return <span className=\"text-green-600 dark:text-green-400 font-mono text-sm\">\"{data}\"</span>;\r\n }\r\n\r\n // Array\r\n if (Array.isArray(data)) {\r\n if (data.length === 0) {\r\n return <span className=\"text-muted-foreground text-sm\">[]</span>;\r\n }\r\n return (\r\n <div className=\"space-y-2\">\r\n {data.map((item, index) => (\r\n <div key={index} className=\"flex items-start gap-2\">\r\n <Badge variant=\"outline\" className=\"text-xs shrink-0 mt-0.5\">\r\n {index}\r\n </Badge>\r\n <div className=\"flex-1 min-w-0\">\r\n {typeof item === 'object' && item !== null ? (\r\n <div className=\"bg-muted/30 rounded-lg p-2 border\">\r\n <JsonCardViewer data={item} depth={depth + 1} />\r\n </div>\r\n ) : (\r\n <JsonCardViewer data={item} depth={depth + 1} />\r\n )}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n }\r\n\r\n // Object\r\n if (typeof data === 'object') {\r\n const entries = Object.entries(data);\r\n if (entries.length === 0) {\r\n return <span className=\"text-muted-foreground text-sm\">{'{}'}</span>;\r\n }\r\n\r\n return (\r\n <div className={cn('space-y-2', depth > 0 && 'pl-2 border-l-2 border-border')}>\r\n {entries.map(([key, value]) => {\r\n const isExpandable = typeof value === 'object' && value !== null;\r\n const isArray = Array.isArray(value);\r\n const itemCount = isArray ? value.length : isExpandable ? Object.keys(value).length : 0;\r\n\r\n return (\r\n <div key={key} className=\"group\">\r\n <div className=\"flex items-center gap-2 py-1\">\r\n <span className=\"text-purple-600 dark:text-purple-400 font-medium text-sm shrink-0\">\r\n {key}\r\n </span>\r\n {isExpandable && (\r\n <Badge variant=\"secondary\" className=\"text-[10px] h-4 px-1\">\r\n {isArray ? `${itemCount} items` : `${itemCount} fields`}\r\n </Badge>\r\n )}\r\n </div>\r\n <div className=\"ml-3\">\r\n {isExpandable ? (\r\n <div className=\"bg-muted/20 rounded-md p-2 border\">\r\n <JsonCardViewer data={value} depth={depth + 1} />\r\n </div>\r\n ) : (\r\n <JsonCardViewer data={value} depth={depth + 1} />\r\n )}\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n }\r\n\r\n return <span className=\"text-sm\">{String(data)}</span>;\r\n}\r\n\r\n// ========================================\r\n// JSON Summary Card\r\n// ========================================\r\n\r\nfunction JsonSummaryCard({ data }: { data: unknown }) {\r\n const stats = React.useMemo(() => {\r\n const result = {\r\n type: '',\r\n fields: 0,\r\n items: 0,\r\n depth: 0,\r\n };\r\n\r\n const analyze = (obj: unknown, currentDepth: number): void => {\r\n result.depth = Math.max(result.depth, currentDepth);\r\n\r\n if (Array.isArray(obj)) {\r\n result.type = 'Array';\r\n result.items = obj.length;\r\n obj.forEach(item => analyze(item, currentDepth + 1));\r\n } else if (typeof obj === 'object' && obj !== null) {\r\n result.type = 'Object';\r\n result.fields = Object.keys(obj).length;\r\n Object.values(obj).forEach(val => analyze(val, currentDepth + 1));\r\n }\r\n };\r\n\r\n analyze(data, 0);\r\n return result;\r\n }, [data]);\r\n\r\n return (\r\n <div className=\"flex items-center gap-4 p-3 bg-muted/50 rounded-lg mb-4 text-sm\">\r\n <div className=\"flex items-center gap-2\">\r\n <Badge variant=\"outline\">{stats.type}</Badge>\r\n </div>\r\n {stats.type === 'Object' && (\r\n <div className=\"text-muted-foreground\">\r\n <span className=\"font-medium text-foreground\">{stats.fields}</span> fields\r\n </div>\r\n )}\r\n {stats.type === 'Array' && (\r\n <div className=\"text-muted-foreground\">\r\n <span className=\"font-medium text-foreground\">{stats.items}</span> items\r\n </div>\r\n )}\r\n <div className=\"text-muted-foreground\">\r\n <span className=\"font-medium text-foreground\">{stats.depth}</span> levels deep\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ========================================\r\n// Preview Content Component\r\n// ========================================\r\n\r\nfunction PreviewContent({\r\n content,\r\n contentType,\r\n}: {\r\n content: string;\r\n contentType: 'markdown' | 'json' | 'text';\r\n}) {\r\n if (!content) {\r\n return (\r\n <div className=\"text-muted-foreground text-sm\">\r\n No content\r\n </div>\r\n );\r\n }\r\n\r\n if (contentType === 'json') {\r\n try {\r\n const parsed = JSON.parse(content);\r\n return (\r\n <div className=\"space-y-2\">\r\n <JsonSummaryCard data={parsed} />\r\n <div className=\"bg-card rounded-lg\">\r\n <JsonCardViewer data={parsed} />\r\n </div>\r\n </div>\r\n );\r\n } catch {\r\n return (\r\n <pre className=\"text-xs bg-muted/50 p-4 rounded-lg overflow-auto font-mono whitespace-pre-wrap break-words border\">\r\n {content}\r\n </pre>\r\n );\r\n }\r\n }\r\n\r\n if (contentType === 'markdown') {\r\n return (\r\n <div className=\"prose prose-sm dark:prose-invert max-w-none\">\r\n <pre className=\"whitespace-pre-wrap break-words font-sans text-sm leading-relaxed bg-transparent p-0\">\r\n {content}\r\n </pre>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <pre className=\"text-xs bg-muted/50 p-4 rounded-lg overflow-auto font-mono whitespace-pre-wrap break-words border\">\r\n {content}\r\n </pre>\r\n );\r\n}\r\n\r\nexport default TeamArtifacts;\r\n","// ========================================\r\n// TeamCard Component\r\n// ========================================\r\n// Team card with status badge and action menu\r\n\r\nimport * as React from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { cn } from '@/lib/utils';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { Button } from '@/components/ui/Button';\r\nimport {\r\n DropdownMenu,\r\n DropdownMenuTrigger,\r\n DropdownMenuContent,\r\n DropdownMenuItem,\r\n DropdownMenuSeparator,\r\n} from '@/components/ui/Dropdown';\r\nimport {\r\n Users,\r\n MessageSquare,\r\n MoreVertical,\r\n Eye,\r\n Archive,\r\n ArchiveRestore,\r\n Trash2,\r\n Clock,\r\n GitBranch,\r\n} from 'lucide-react';\r\nimport type { TeamSummaryExtended, TeamStatus } from '@/types/team';\r\n\r\nexport interface TeamCardProps {\r\n team: TeamSummaryExtended;\r\n onClick?: (name: string) => void;\r\n onArchive?: (name: string) => void;\r\n onUnarchive?: (name: string) => void;\r\n onDelete?: (name: string) => void;\r\n showActions?: boolean;\r\n actionsDisabled?: boolean;\r\n className?: string;\r\n}\r\n\r\nconst statusVariantConfig: Record<\r\n TeamStatus,\r\n { variant: 'default' | 'secondary' | 'success' | 'info' }\r\n> = {\r\n active: { variant: 'info' },\r\n completed: { variant: 'success' },\r\n archived: { variant: 'secondary' },\r\n};\r\n\r\nconst statusLabelKeys: Record<TeamStatus, string> = {\r\n active: 'team.status.active',\r\n completed: 'team.status.completed',\r\n archived: 'team.status.archived',\r\n};\r\n\r\nfunction formatDate(dateString: string | undefined): string {\r\n if (!dateString) return '';\r\n try {\r\n const date = new Date(dateString);\r\n return date.toLocaleDateString(undefined, {\r\n year: 'numeric',\r\n month: 'short',\r\n day: 'numeric',\r\n });\r\n } catch {\r\n return '';\r\n }\r\n}\r\n\r\nexport function TeamCard({\r\n team,\r\n onClick,\r\n onArchive,\r\n onUnarchive,\r\n onDelete,\r\n showActions = true,\r\n actionsDisabled = false,\r\n className,\r\n}: TeamCardProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n const { variant: statusVariant } = statusVariantConfig[team.status] || { variant: 'default' as const };\r\n const statusLabel = statusLabelKeys[team.status]\r\n ? formatMessage({ id: statusLabelKeys[team.status] })\r\n : team.status;\r\n\r\n const isArchived = team.status === 'archived';\r\n\r\n const handleCardClick = (e: React.MouseEvent) => {\r\n if ((e.target as HTMLElement).closest('[data-radix-popper-content-wrapper]')) return;\r\n onClick?.(team.name);\r\n };\r\n\r\n const handleAction = (e: React.MouseEvent, action: 'view' | 'archive' | 'unarchive' | 'delete') => {\r\n e.stopPropagation();\r\n switch (action) {\r\n case 'view':\r\n onClick?.(team.name);\r\n break;\r\n case 'archive':\r\n onArchive?.(team.name);\r\n break;\r\n case 'unarchive':\r\n onUnarchive?.(team.name);\r\n break;\r\n case 'delete':\r\n onDelete?.(team.name);\r\n break;\r\n }\r\n };\r\n\r\n return (\r\n <Card\r\n className={cn(\r\n 'group cursor-pointer transition-all duration-200 hover:shadow-md hover:border-primary/30',\r\n className\r\n )}\r\n onClick={handleCardClick}\r\n >\r\n <CardContent className=\"p-4\">\r\n {/* Header: team name + status + actions */}\r\n <div className=\"flex items-start justify-between gap-2 mb-2\">\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2 mb-1\">\r\n <h3 className=\"font-bold text-card-foreground text-sm tracking-wide truncate\">\r\n {team.name}\r\n </h3>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2 flex-shrink-0\">\r\n <Badge variant={statusVariant}>{statusLabel}</Badge>\r\n {team.pipeline_mode && (\r\n <Badge variant=\"default\" className=\"gap-1\">\r\n <GitBranch className=\"h-3 w-3\" />\r\n {team.pipeline_mode}\r\n </Badge>\r\n )}\r\n {showActions && (\r\n <DropdownMenu>\r\n <DropdownMenuTrigger asChild>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"h-8 w-8 opacity-0 group-hover:opacity-100 transition-opacity\"\r\n onClick={(e) => e.stopPropagation()}\r\n disabled={actionsDisabled}\r\n >\r\n <MoreVertical className=\"h-4 w-4\" />\r\n </Button>\r\n </DropdownMenuTrigger>\r\n <DropdownMenuContent align=\"end\">\r\n <DropdownMenuItem onClick={(e) => handleAction(e, 'view')}>\r\n <Eye className=\"mr-2 h-4 w-4\" />\r\n {formatMessage({ id: 'team.actions.viewDetails' })}\r\n </DropdownMenuItem>\r\n <DropdownMenuSeparator />\r\n {isArchived ? (\r\n <DropdownMenuItem onClick={(e) => handleAction(e, 'unarchive')}>\r\n <ArchiveRestore className=\"mr-2 h-4 w-4\" />\r\n {formatMessage({ id: 'team.actions.unarchive' })}\r\n </DropdownMenuItem>\r\n ) : (\r\n <DropdownMenuItem onClick={(e) => handleAction(e, 'archive')}>\r\n <Archive className=\"mr-2 h-4 w-4\" />\r\n {formatMessage({ id: 'team.actions.archive' })}\r\n </DropdownMenuItem>\r\n )}\r\n <DropdownMenuSeparator />\r\n <DropdownMenuItem\r\n onClick={(e) => handleAction(e, 'delete')}\r\n className=\"text-destructive focus:text-destructive\"\r\n >\r\n <Trash2 className=\"mr-2 h-4 w-4\" />\r\n {formatMessage({ id: 'team.actions.delete' })}\r\n </DropdownMenuItem>\r\n </DropdownMenuContent>\r\n </DropdownMenu>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Meta info row */}\r\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-muted-foreground\">\r\n <span className=\"flex items-center gap-1\">\r\n <MessageSquare className=\"h-3.5 w-3.5\" />\r\n {team.messageCount} {formatMessage({ id: 'team.card.messages' })}\r\n </span>\r\n {team.lastActivity && (\r\n <span className=\"flex items-center gap-1\">\r\n <Clock className=\"h-3.5 w-3.5\" />\r\n {formatDate(team.lastActivity)}\r\n </span>\r\n )}\r\n </div>\r\n\r\n {/* Members row */}\r\n {team.members && team.members.length > 0 && (\r\n <div className=\"flex items-center gap-1.5 mt-2 flex-wrap\">\r\n <Users className=\"h-3.5 w-3.5 text-muted-foreground shrink-0\" />\r\n {team.members.map((name) => (\r\n <Badge key={name} variant=\"outline\" className=\"text-[10px] px-1.5 py-0 font-normal\">\r\n {name}\r\n </Badge>\r\n ))}\r\n </div>\r\n )}\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n\r\n/**\r\n * Skeleton loader for TeamCard\r\n */\r\nexport function TeamCardSkeleton({ 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-5 w-32 rounded bg-muted\" />\r\n </div>\r\n <div className=\"h-5 w-16 rounded-full bg-muted\" />\r\n </div>\r\n <div className=\"mt-3 flex gap-4\">\r\n <div className=\"h-4 w-24 rounded bg-muted\" />\r\n <div className=\"h-4 w-20 rounded bg-muted\" />\r\n <div className=\"h-4 w-20 rounded bg-muted\" />\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n","// ========================================\r\n// TeamListView Component\r\n// ========================================\r\n// Team card grid with tabs, search, and actions\r\n\r\nimport * as React from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n RefreshCw,\r\n Search,\r\n Users,\r\n X,\r\n} from 'lucide-react';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { TabsNavigation } from '@/components/ui/TabsNavigation';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogDescription,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport { cn } from '@/lib/utils';\r\nimport { TeamCard, TeamCardSkeleton } from './TeamCard';\r\nimport { useTeamStore } from '@/stores/teamStore';\r\nimport { useTeams, useArchiveTeam, useUnarchiveTeam, useDeleteTeam } from '@/hooks/useTeamData';\r\n\r\nexport function TeamListView() {\r\n const { formatMessage } = useIntl();\r\n const {\r\n locationFilter,\r\n setLocationFilter,\r\n searchQuery,\r\n setSearchQuery,\r\n selectTeamAndShowDetail,\r\n } = useTeamStore();\r\n\r\n // Dialog state\r\n const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false);\r\n const [teamToDelete, setTeamToDelete] = React.useState<string | null>(null);\r\n\r\n // Data\r\n const { teams, isLoading, isFetching, refetch } = useTeams(locationFilter);\r\n const { archiveTeam, isArchiving } = useArchiveTeam();\r\n const { unarchiveTeam, isUnarchiving } = useUnarchiveTeam();\r\n const { deleteTeam, isDeleting } = useDeleteTeam();\r\n\r\n const isMutating = isArchiving || isUnarchiving || isDeleting;\r\n\r\n // Client-side search filter\r\n const filteredTeams = React.useMemo(() => {\r\n if (!searchQuery) return teams;\r\n const q = searchQuery.toLowerCase();\r\n return teams.filter((t) => t.name.toLowerCase().includes(q));\r\n }, [teams, searchQuery]);\r\n\r\n // Handlers\r\n const handleArchive = async (name: string) => {\r\n try {\r\n await archiveTeam(name);\r\n } catch (err) {\r\n console.error('Failed to archive team:', err);\r\n }\r\n };\r\n\r\n const handleUnarchive = async (name: string) => {\r\n try {\r\n await unarchiveTeam(name);\r\n } catch (err) {\r\n console.error('Failed to unarchive team:', err);\r\n }\r\n };\r\n\r\n const handleDeleteClick = (name: string) => {\r\n setTeamToDelete(name);\r\n setDeleteDialogOpen(true);\r\n };\r\n\r\n const handleConfirmDelete = async () => {\r\n if (!teamToDelete) return;\r\n try {\r\n await deleteTeam(teamToDelete);\r\n setDeleteDialogOpen(false);\r\n setTeamToDelete(null);\r\n } catch (err) {\r\n console.error('Failed to delete team:', err);\r\n }\r\n };\r\n\r\n const handleClearSearch = () => setSearchQuery('');\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Header */}\r\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\r\n <div>\r\n <div className=\"flex items-center gap-2\">\r\n <Users className=\"w-5 h-5\" />\r\n <h1 className=\"text-2xl font-semibold text-foreground\">\r\n {formatMessage({ id: 'team.title' })}\r\n </h1>\r\n </div>\r\n <p className=\"text-sm text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'team.description' })}\r\n </p>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => refetch()}\r\n disabled={isFetching}\r\n >\r\n <RefreshCw className={cn('h-4 w-4 mr-2', isFetching && 'animate-spin')} />\r\n {formatMessage({ id: 'common.actions.refresh' })}\r\n </Button>\r\n </div>\r\n </div>\r\n\r\n {/* Filters */}\r\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center\">\r\n {/* Location tabs */}\r\n <TabsNavigation\r\n value={locationFilter}\r\n onValueChange={(v) => setLocationFilter(v as 'active' | 'archived' | 'all')}\r\n tabs={[\r\n { value: 'active', label: formatMessage({ id: 'team.filters.active' }) },\r\n { value: 'archived', label: formatMessage({ id: 'team.filters.archived' }) },\r\n { value: 'all', label: formatMessage({ id: 'team.filters.all' }) },\r\n ]}\r\n />\r\n\r\n {/* Search input */}\r\n <div className=\"flex-1 max-w-sm relative\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground\" />\r\n <Input\r\n placeholder={formatMessage({ id: 'team.searchPlaceholder' })}\r\n value={searchQuery}\r\n onChange={(e) => setSearchQuery(e.target.value)}\r\n className=\"pl-9 pr-9\"\r\n />\r\n {searchQuery && (\r\n <button\r\n onClick={handleClearSearch}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground\"\r\n >\r\n <X className=\"h-4 w-4\" />\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Team grid */}\r\n {isLoading ? (\r\n <div className=\"grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3\">\r\n {Array.from({ length: 6 }).map((_, i) => (\r\n <TeamCardSkeleton key={i} />\r\n ))}\r\n </div>\r\n ) : filteredTeams.length === 0 ? (\r\n <div className=\"flex flex-col items-center justify-center py-16 px-4 border border-dashed border-border rounded-lg\">\r\n <Users className=\"h-12 w-12 text-muted-foreground mb-4\" />\r\n <h3 className=\"text-lg font-medium text-foreground mb-1\">\r\n {searchQuery\r\n ? formatMessage({ id: 'team.emptyState.noMatching' })\r\n : formatMessage({ id: 'team.emptyState.noTeams' })}\r\n </h3>\r\n <p className=\"text-sm text-muted-foreground text-center max-w-sm mb-4\">\r\n {searchQuery\r\n ? formatMessage({ id: 'team.emptyState.noMatchingDescription' })\r\n : formatMessage({ id: 'team.emptyState.noTeamsDescription' })}\r\n </p>\r\n {searchQuery && (\r\n <Button variant=\"outline\" onClick={handleClearSearch}>\r\n {formatMessage({ id: 'common.actions.clearFilters' })}\r\n </Button>\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3\">\r\n {filteredTeams.map((team) => (\r\n <TeamCard\r\n key={team.name}\r\n team={team}\r\n onClick={selectTeamAndShowDetail}\r\n onArchive={handleArchive}\r\n onUnarchive={handleUnarchive}\r\n onDelete={handleDeleteClick}\r\n actionsDisabled={isMutating}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Delete Confirmation Dialog */}\r\n <Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>\r\n <DialogContent>\r\n <DialogHeader>\r\n <DialogTitle>{formatMessage({ id: 'team.dialog.deleteTeam' })}</DialogTitle>\r\n <DialogDescription>\r\n {formatMessage({ id: 'team.dialog.deleteConfirm' })}\r\n </DialogDescription>\r\n </DialogHeader>\r\n <DialogFooter>\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => {\r\n setDeleteDialogOpen(false);\r\n setTeamToDelete(null);\r\n }}\r\n >\r\n {formatMessage({ id: 'team.dialog.cancel' })}\r\n </Button>\r\n <Button\r\n variant=\"destructive\"\r\n onClick={handleConfirmDelete}\r\n disabled={isDeleting}\r\n >\r\n {isDeleting\r\n ? formatMessage({ id: 'team.dialog.deleting' })\r\n : formatMessage({ id: 'team.actions.delete' })}\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n </div>\r\n );\r\n}\r\n","import type { TeamMessage, DynamicStage, DynamicStageStatus, PhaseInfo } from '@/types/team';\r\n\r\nconst LEGACY_STAGES = ['plan', 'impl', 'test', 'review'] as const;\r\n\r\n/**\r\n * Capitalize first letter, lowercase rest.\r\n * \"SCAN\" -> \"Scan\", \"review\" -> \"Review\"\r\n */\r\nexport function formatStageLabel(stageId: string): string {\r\n if (!stageId) return '';\r\n return stageId.charAt(0).toUpperCase() + stageId.slice(1).toLowerCase();\r\n}\r\n\r\n/**\r\n * Derive the status of a pipeline stage from the message history.\r\n *\r\n * Matches messages whose `from` field equals or starts with `roleOrStage`\r\n * (case-insensitive). The status is determined by the LAST matching message's type.\r\n */\r\nexport function deriveStageStatus(\r\n roleOrStage: string,\r\n messages: TeamMessage[],\r\n): DynamicStageStatus {\r\n const needle = roleOrStage.toLowerCase();\r\n const matching = messages.filter((m) => {\r\n const from = m.from.toLowerCase();\r\n return from === needle || from.startsWith(needle);\r\n });\r\n\r\n if (matching.length === 0) return 'pending';\r\n\r\n const last = matching[matching.length - 1];\r\n const completionTypes: string[] = ['shutdown', 'impl_complete', 'review_result', 'test_result'];\r\n\r\n if (completionTypes.includes(last.type)) return 'completed';\r\n if (last.type === 'error') return 'blocked';\r\n return 'in_progress';\r\n}\r\n\r\n/**\r\n * Four-tier pipeline stage detection.\r\n *\r\n * Tier 1 - explicit `pipeline_stages` from meta\r\n * Tier 2 - explicit `roles` list from meta (excluding coordinator)\r\n * Tier 3 - inferred from message senders (excluding \"coordinator\")\r\n * Tier 4 - legacy 4-stage fallback\r\n */\r\nexport function derivePipelineStages(\r\n meta: {\r\n pipeline_stages?: string[];\r\n role_state?: Record<string, Record<string, unknown>>;\r\n roles?: string[];\r\n },\r\n messages: TeamMessage[],\r\n): DynamicStage[] {\r\n // Tier 1: explicit pipeline_stages\r\n if (meta.pipeline_stages && meta.pipeline_stages.length > 0) {\r\n return meta.pipeline_stages.map((stage) => {\r\n const id = stage.toUpperCase();\r\n const lowerStage = stage.toLowerCase();\r\n const role = meta.roles?.find((r) => r.toLowerCase().startsWith(lowerStage));\r\n return {\r\n id,\r\n label: formatStageLabel(stage),\r\n role,\r\n status: deriveStageStatus(stage, messages),\r\n };\r\n });\r\n }\r\n\r\n // Tier 2: explicit roles list from meta (authoritative source from coordinator)\r\n if (meta.roles && meta.roles.length > 0) {\r\n const workerRoles = meta.roles.filter((r) => r.toLowerCase() !== 'coordinator');\r\n if (workerRoles.length > 0) {\r\n return workerRoles.map((role) => ({\r\n id: role.toUpperCase(),\r\n label: formatStageLabel(role),\r\n role,\r\n status: deriveStageStatus(role, messages),\r\n }));\r\n }\r\n }\r\n\r\n // Tier 3: extract from message senders\r\n if (messages.length > 0) {\r\n const seen = new Map<string, string>(); // lowercase sender -> original sender\r\n for (const msg of messages) {\r\n const sender = msg.from;\r\n if (sender.toLowerCase() === 'coordinator') continue;\r\n const key = sender.toLowerCase();\r\n if (!seen.has(key)) {\r\n seen.set(key, sender);\r\n }\r\n }\r\n\r\n if (seen.size > 0) {\r\n return Array.from(seen.entries()).map(([, sender]) => ({\r\n id: sender.toUpperCase(),\r\n label: formatStageLabel(sender),\r\n role: sender,\r\n status: deriveStageStatus(sender, messages),\r\n }));\r\n }\r\n }\r\n\r\n // Tier 4: legacy fallback\r\n return LEGACY_STAGES.map((stage) => ({\r\n id: stage.toUpperCase(),\r\n label: formatStageLabel(stage),\r\n role: undefined,\r\n status: deriveStageStatus(stage, messages),\r\n }));\r\n}\r\n\r\n/**\r\n * Detect multi-phase execution from coordinator role state.\r\n * Returns PhaseInfo when the coordinator reports `current_phase`, otherwise null.\r\n */\r\nexport function detectMultiPhase(\r\n roleState?: Record<string, Record<string, unknown>>,\r\n): PhaseInfo | null {\r\n if (!roleState || Object.keys(roleState).length === 0) return null;\r\n\r\n const coordinator = roleState['coordinator'];\r\n if (!coordinator || typeof coordinator.current_phase !== 'number') return null;\r\n\r\n return {\r\n currentPhase: coordinator.current_phase as number,\r\n totalPhases: typeof coordinator.total_phases === 'number' ? coordinator.total_phases : null,\r\n currentStep: typeof coordinator.current_step === 'string' ? coordinator.current_step : null,\r\n gapIteration: typeof coordinator.gap_iteration === 'number' ? coordinator.gap_iteration : 0,\r\n };\r\n}\r\n","// ========================================\r\n// TeamPage\r\n// ========================================\r\n// Main page for team execution - list/detail dual view with tabbed detail\r\n\r\nimport { useMemo, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { Package, MessageSquare, Maximize2, Minimize2, GitBranch, AlertTriangle } from 'lucide-react';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { cn } from '@/lib/utils';\r\nimport { useAppStore, selectIsImmersiveMode } from '@/stores/appStore';\r\nimport { TabsNavigation, type TabItem } from '@/components/ui/TabsNavigation';\r\nimport { useTeamStore } from '@/stores/teamStore';\r\nimport type { TeamDetailTab } from '@/stores/teamStore';\r\nimport { useTeams, useTeamMessages, useTeamStatus } from '@/hooks/useTeamData';\r\nimport { TeamHeader } from '@/components/team/TeamHeader';\r\nimport { DynamicPipeline } from '@/components/team/DynamicPipeline';\r\nimport { TeamRolePanel } from '@/components/team/TeamRolePanel';\r\nimport { SessionCoordinates } from '@/components/team/SessionCoordinates';\r\nimport { TeamMessageFeed } from '@/components/team/TeamMessageFeed';\r\nimport { TeamArtifacts } from '@/components/team/TeamArtifacts';\r\nimport { TeamListView } from '@/components/team/TeamListView';\r\nimport { derivePipelineStages, detectMultiPhase } from '@/lib/pipeline-utils';\r\n\r\nexport function TeamPage() {\r\n const { formatMessage } = useIntl();\r\n const {\r\n selectedTeam,\r\n viewMode,\r\n autoRefresh,\r\n toggleAutoRefresh,\r\n messageFilter,\r\n setMessageFilter,\r\n clearMessageFilter,\r\n timelineExpanded,\r\n setTimelineExpanded,\r\n detailTab,\r\n setDetailTab,\r\n backToList,\r\n locationFilter,\r\n } = useTeamStore();\r\n const isImmersiveMode = useAppStore(selectIsImmersiveMode);\r\n const toggleImmersiveMode = useAppStore((s) => s.toggleImmersiveMode);\r\n\r\n // Data hooks\r\n const { teams, error: teamsError, isLoading: teamsLoading } = useTeams(locationFilter);\r\n const { messages, total: messageTotal } = useTeamMessages(\r\n viewMode === 'detail' ? selectedTeam : null,\r\n messageFilter\r\n );\r\n const { members, totalMessages } = useTeamStatus(\r\n viewMode === 'detail' ? selectedTeam : null\r\n );\r\n\r\n // Find enriched team data from list response\r\n const teamData = useMemo(\r\n () => teams.find((t) => t.name === selectedTeam),\r\n [teams, selectedTeam]\r\n );\r\n\r\n // Auto-reset to list view when in detail mode but team data is missing after loading\r\n useEffect(() => {\r\n if (viewMode === 'detail' && selectedTeam && !teamsLoading && teams.length > 0 && !teamData) {\r\n // Team no longer exists or is filtered out, return to list\r\n backToList();\r\n }\r\n }, [viewMode, selectedTeam, teamsLoading, teams.length, teamData, backToList]);\r\n\r\n // Derive dynamic pipeline stages and multi-phase info\r\n const stages = useMemo(\r\n () =>\r\n derivePipelineStages(\r\n {\r\n pipeline_stages: teamData?.pipeline_stages,\r\n role_state: teamData?.role_state,\r\n roles: teamData?.roles,\r\n },\r\n messages\r\n ),\r\n [teamData?.pipeline_stages, teamData?.role_state, teamData?.roles, messages]\r\n );\r\n\r\n const phaseInfo = useMemo(\r\n () => detectMultiPhase(teamData?.role_state),\r\n [teamData?.role_state]\r\n );\r\n\r\n // Error state - show error page with back button when API fails\r\n if (teamsError && viewMode === 'detail') {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px] p-8\">\r\n <div className=\"text-center max-w-md\">\r\n <div className=\"mb-4\">\r\n <AlertTriangle className=\"w-16 h-16 mx-auto text-destructive\" />\r\n </div>\r\n <h2 className=\"text-xl font-semibold mb-2\">\r\n {formatMessage({ id: 'team.error.loadFailed' })}\r\n </h2>\r\n <p className=\"text-muted-foreground mb-6\">\r\n {teamsError instanceof Error ? teamsError.message : String(teamsError)}\r\n </p>\r\n <div className=\"flex gap-3 justify-center\">\r\n <Button onClick={backToList} variant=\"default\">\r\n {formatMessage({ id: 'team.detail.backToList' })}\r\n </Button>\r\n <Button\r\n onClick={() => window.location.reload()}\r\n variant=\"outline\"\r\n >\r\n {formatMessage({ id: 'common.actions.retry' })}\r\n </Button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // List view (also fallback when selected team data is not available)\r\n if (viewMode === 'list' || !selectedTeam || (viewMode === 'detail' && teams.length > 0 && !teamData)) {\r\n return (\r\n <div className=\"space-y-6\">\r\n <TeamListView />\r\n </div>\r\n );\r\n }\r\n\r\n const tabs: TabItem[] = [\r\n {\r\n value: 'pipeline',\r\n label: formatMessage({ id: 'team.tabs.pipeline' }),\r\n icon: <GitBranch className=\"h-4 w-4\" />,\r\n },\r\n {\r\n value: 'artifacts',\r\n label: formatMessage({ id: 'team.tabs.artifacts' }),\r\n icon: <Package className=\"h-4 w-4\" />,\r\n },\r\n {\r\n value: 'messages',\r\n label: formatMessage({ id: 'team.tabs.messages' }),\r\n icon: <MessageSquare className=\"h-4 w-4\" />,\r\n },\r\n ];\r\n\r\n // Detail view\r\n return (\r\n <div className={cn(\"space-y-6\", isImmersiveMode && \"h-screen overflow-hidden\")}>\r\n {/* Detail Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <TeamHeader\r\n selectedTeam={selectedTeam}\r\n onBack={backToList}\r\n members={members}\r\n totalMessages={totalMessages}\r\n autoRefresh={autoRefresh}\r\n onToggleAutoRefresh={toggleAutoRefresh}\r\n skillType={teamData?.team_name ? `team-${teamData.team_name}` : undefined}\r\n pipelineMode={teamData?.pipeline_mode}\r\n />\r\n <button\r\n onClick={toggleImmersiveMode}\r\n className={cn(\r\n 'p-2 rounded-md transition-colors',\r\n isImmersiveMode\r\n ? 'bg-primary/10 text-primary'\r\n : 'text-muted-foreground hover:text-foreground hover:bg-muted'\r\n )}\r\n title={isImmersiveMode ? 'Exit Fullscreen' : 'Fullscreen'}\r\n >\r\n {isImmersiveMode ? <Minimize2 className=\"w-4 h-4\" /> : <Maximize2 className=\"w-4 h-4\" />}\r\n </button>\r\n </div>\r\n\r\n {/* Overview: DynamicPipeline + TeamRolePanel */}\r\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\r\n <Card className=\"lg:col-span-2 flex flex-col\">\r\n <CardContent className=\"p-4 flex-1\">\r\n <DynamicPipeline stages={stages} phaseInfo={phaseInfo} />\r\n </CardContent>\r\n </Card>\r\n <Card>\r\n <CardContent className=\"p-4\">\r\n <TeamRolePanel\r\n members={members}\r\n stages={stages}\r\n roleState={teamData?.role_state}\r\n />\r\n </CardContent>\r\n </Card>\r\n </div>\r\n\r\n {/* Session Coordinates (only for multi-phase sessions) */}\r\n {phaseInfo && (\r\n <SessionCoordinates phaseInfo={phaseInfo} />\r\n )}\r\n\r\n {/* Tab Navigation */}\r\n <TabsNavigation\r\n value={detailTab}\r\n onValueChange={(v) => setDetailTab(v as TeamDetailTab)}\r\n tabs={tabs}\r\n />\r\n\r\n {/* Pipeline Tab - shows role details */}\r\n {detailTab === 'pipeline' && (\r\n <Card>\r\n <CardContent className=\"p-6\">\r\n <TeamRolePanel\r\n members={members}\r\n stages={stages}\r\n roleState={teamData?.role_state}\r\n />\r\n </CardContent>\r\n </Card>\r\n )}\r\n\r\n {/* Artifacts Tab */}\r\n {detailTab === 'artifacts' && (\r\n <TeamArtifacts teamName={selectedTeam} />\r\n )}\r\n\r\n {/* Messages Tab */}\r\n {detailTab === 'messages' && (\r\n <TeamMessageFeed\r\n messages={messages}\r\n total={messageTotal}\r\n filter={messageFilter}\r\n onFilterChange={setMessageFilter}\r\n onClearFilter={clearMessageFilter}\r\n expanded={timelineExpanded}\r\n onExpandedChange={setTimelineExpanded}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default TeamPage;\r\n"],"names":["useTeamStore","create","devtools","persist","set","name","s","filter","expanded","mode","query","tab","teamKeys","location","team","useTeams","autoRefresh","effectiveLocation","useQuery","fetchTeams","_a","useTeamMessages","teamName","options","data","fetchTeamMessages","_b","useTeamStatus","fetchTeamStatus","useArchiveTeam","queryClient","useQueryClient","mutation","useMutation","archiveTeam","useUnarchiveTeam","unarchiveTeam","useDeleteTeam","deleteTeam","TeamHeader","selectedTeam","onBack","members","totalMessages","onToggleAutoRefresh","skillType","pipelineMode","formatMessage","useIntl","jsxs","Button","jsx","ArrowLeft","Fragment","Badge","Users","MessageSquare","GitBranch","Switch","Label","RefreshCw","statusConfig","CheckCircle2","Loader2","Circle","Ban","SkipForward","LEGEND_STATUSES","StageNode","stage","config","Icon","statusKey","cn","Arrow","DynamicPipeline","stages","phaseInfo","idx","cfg","formatRelativeTime","isoString","now","then","diffMs","seconds","minutes","hours","getMemberStatus","member","TeamMembersPanel","m","status","isActive","Card","CardContent","findMatchingStage","memberLower","stageBadgeVariant","TeamRolePanel","_roleState","matchedStage","SessionCoordinates","typeColorMap","MessageTypeBadge","type","color","labelKey","label","MessageRow","msg","dataExpanded","setDataExpanded","useState","time","FileText","ChevronUp","ChevronDown","TeamMessageFeed","messages","total","onFilterChange","onClearFilter","onExpandedChange","hasFilter","senders","receivers","types","useMemo","r","t","displayMessages","X","Select","v","SelectTrigger","Filter","SelectValue","SelectContent","SelectItem","getContentTypeFromPath","path","formatSize","bytes","formatDate","ts","FileIcon","contentType","FileJson","TreeNode","node","depth","selectedPath","onToggle","onSelect","isExpanded","ChevronRight","Folder","child","isSelected","TeamArtifacts","tree","setTree","React.useState","setExpanded","selectedFile","setSelectedFile","content","setContent","loading","setLoading","treeLoading","setTreeLoading","error","setError","React.useEffect","fetchTeamArtifacts","firstLevelDirs","n","err","handleToggle","React.useCallback","prev","next","handleSelect","result","fetchArtifactContent","previewContentType","modalContentType","Package","PreviewContent","JsonCardViewer","item","index","entries","key","value","isExpandable","isArray","itemCount","JsonSummaryCard","stats","React.useMemo","analyze","obj","currentDepth","val","parsed","statusVariantConfig","statusLabelKeys","dateString","TeamCard","onClick","onArchive","onUnarchive","onDelete","showActions","actionsDisabled","className","statusVariant","statusLabel","isArchived","handleCardClick","e","handleAction","action","DropdownMenu","DropdownMenuTrigger","MoreVertical","DropdownMenuContent","DropdownMenuItem","Eye","DropdownMenuSeparator","ArchiveRestore","Archive","Trash2","Clock","TeamCardSkeleton","TeamListView","locationFilter","setLocationFilter","searchQuery","setSearchQuery","selectTeamAndShowDetail","deleteDialogOpen","setDeleteDialogOpen","teamToDelete","setTeamToDelete","teams","isLoading","isFetching","refetch","isArchiving","isUnarchiving","isDeleting","isMutating","filteredTeams","q","handleArchive","handleUnarchive","handleDeleteClick","handleConfirmDelete","handleClearSearch","TabsNavigation","Search","Input","_","i","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","DialogFooter","LEGACY_STAGES","formatStageLabel","stageId","deriveStageStatus","roleOrStage","needle","matching","from","last","derivePipelineStages","meta","id","lowerStage","role","workerRoles","seen","sender","detectMultiPhase","roleState","coordinator","TeamPage","viewMode","toggleAutoRefresh","messageFilter","setMessageFilter","clearMessageFilter","timelineExpanded","setTimelineExpanded","detailTab","setDetailTab","backToList","isImmersiveMode","useAppStore","selectIsImmersiveMode","toggleImmersiveMode","teamsError","teamsLoading","messageTotal","teamData","useEffect","AlertTriangle","tabs","Minimize2","Maximize2"],"mappings":"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"}
1
+ {"version":3,"file":"TeamPage-CpCSwpxD.js","sources":["../../src/stores/teamStore.ts","../../src/hooks/useTeamData.ts","../../src/components/team/TeamHeader.tsx","../../src/components/team/DynamicPipeline.tsx","../../src/components/team/TeamMembersPanel.tsx","../../src/components/team/TeamRolePanel.tsx","../../src/components/team/SessionCoordinates.tsx","../../src/components/team/TeamMessageFeed.tsx","../../src/components/team/TeamArtifacts.tsx","../../src/components/team/TeamCard.tsx","../../src/components/team/TeamListView.tsx","../../src/lib/pipeline-utils.ts","../../src/pages/TeamPage.tsx"],"sourcesContent":["// ========================================\r\n// Team Store\r\n// ========================================\r\n// UI state for team execution visualization\r\n\r\nimport { create } from 'zustand';\r\nimport { devtools, persist } from 'zustand/middleware';\r\nimport type { TeamMessageFilter } from '@/types/team';\r\n\r\nexport type TeamDetailTab = 'pipeline' | 'artifacts' | 'messages';\r\n\r\ninterface TeamStore {\r\n selectedTeam: string | null;\r\n autoRefresh: boolean;\r\n messageFilter: TeamMessageFilter;\r\n timelineExpanded: boolean;\r\n viewMode: 'list' | 'detail';\r\n locationFilter: 'active' | 'archived' | 'all';\r\n searchQuery: string;\r\n detailTab: TeamDetailTab;\r\n setSelectedTeam: (name: string | null) => void;\r\n toggleAutoRefresh: () => void;\r\n setMessageFilter: (filter: Partial<TeamMessageFilter>) => void;\r\n clearMessageFilter: () => void;\r\n setTimelineExpanded: (expanded: boolean) => void;\r\n setViewMode: (mode: 'list' | 'detail') => void;\r\n setLocationFilter: (filter: 'active' | 'archived' | 'all') => void;\r\n setSearchQuery: (query: string) => void;\r\n setDetailTab: (tab: TeamDetailTab) => void;\r\n selectTeamAndShowDetail: (name: string) => void;\r\n backToList: () => void;\r\n}\r\n\r\nexport const useTeamStore = create<TeamStore>()(\r\n devtools(\r\n persist(\r\n (set) => ({\r\n selectedTeam: null,\r\n autoRefresh: true,\r\n messageFilter: {},\r\n timelineExpanded: true,\r\n viewMode: 'list',\r\n locationFilter: 'active',\r\n searchQuery: '',\r\n detailTab: 'pipeline',\r\n setSelectedTeam: (name) => set({ selectedTeam: name }),\r\n toggleAutoRefresh: () => set((s) => ({ autoRefresh: !s.autoRefresh })),\r\n setMessageFilter: (filter) =>\r\n set((s) => ({ messageFilter: { ...s.messageFilter, ...filter } })),\r\n clearMessageFilter: () => set({ messageFilter: {} }),\r\n setTimelineExpanded: (expanded) => set({ timelineExpanded: expanded }),\r\n setViewMode: (mode) => set({ viewMode: mode }),\r\n setLocationFilter: (filter) => set({ locationFilter: filter }),\r\n setSearchQuery: (query) => set({ searchQuery: query }),\r\n setDetailTab: (tab) => set({ detailTab: tab }),\r\n selectTeamAndShowDetail: (name) => set({ selectedTeam: name, viewMode: 'detail', detailTab: 'pipeline' }),\r\n backToList: () => set({ viewMode: 'list', detailTab: 'pipeline' }),\r\n }),\r\n { name: 'ccw-team-store' }\r\n ),\r\n { name: 'TeamStore' }\r\n )\r\n);\r\n","// ========================================\r\n// useTeamData Hook\r\n// ========================================\r\n// TanStack Query hooks for team execution visualization\r\n\r\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport { fetchTeams, fetchTeamMessages, fetchTeamStatus, archiveTeam, unarchiveTeam, deleteTeam } from '@/lib/api';\r\nimport { useTeamStore } from '@/stores/teamStore';\r\nimport type {\r\n TeamSummaryExtended,\r\n TeamMessage,\r\n TeamMember,\r\n TeamMessageFilter,\r\n TeamMessagesResponse,\r\n TeamStatusResponse,\r\n TeamsListResponse,\r\n} from '@/types/team';\r\n\r\n// Query key factory\r\nexport const teamKeys = {\r\n all: ['teams'] as const,\r\n lists: () => [...teamKeys.all, 'list'] as const,\r\n listByLocation: (location: string) => [...teamKeys.lists(), location] as const,\r\n messages: (team: string, filter?: TeamMessageFilter) =>\r\n [...teamKeys.all, 'messages', team, filter] as const,\r\n status: (team: string) => [...teamKeys.all, 'status', team] as const,\r\n};\r\n\r\n/**\r\n * Hook: list all teams with location filter\r\n */\r\nexport function useTeams(location?: string) {\r\n const autoRefresh = useTeamStore((s) => s.autoRefresh);\r\n const effectiveLocation = location || 'active';\r\n\r\n const query = useQuery({\r\n queryKey: teamKeys.listByLocation(effectiveLocation),\r\n queryFn: async (): Promise<TeamsListResponse> => {\r\n const data = await fetchTeams(effectiveLocation);\r\n return { teams: (data.teams ?? []) as TeamSummaryExtended[] };\r\n },\r\n staleTime: 10_000,\r\n refetchInterval: autoRefresh ? 10_000 : false,\r\n });\r\n\r\n return {\r\n teams: (query.data?.teams ?? []) as TeamSummaryExtended[],\r\n isLoading: query.isLoading,\r\n isFetching: query.isFetching,\r\n error: query.error,\r\n refetch: query.refetch,\r\n };\r\n}\r\n\r\n/**\r\n * Hook: get messages for selected team\r\n */\r\nexport function useTeamMessages(\r\n teamName: string | null,\r\n filter?: TeamMessageFilter,\r\n options?: { last?: number; offset?: number }\r\n) {\r\n const autoRefresh = useTeamStore((s) => s.autoRefresh);\r\n\r\n const query = useQuery({\r\n queryKey: teamKeys.messages(teamName ?? '', filter),\r\n queryFn: async (): Promise<TeamMessagesResponse> => {\r\n if (!teamName) return { total: 0, showing: 0, messages: [] };\r\n const data = await fetchTeamMessages(teamName, {\r\n ...filter,\r\n last: options?.last ?? 50,\r\n offset: options?.offset,\r\n });\r\n return {\r\n total: data.total,\r\n showing: data.showing,\r\n messages: data.messages as unknown as TeamMessage[],\r\n };\r\n },\r\n enabled: !!teamName,\r\n staleTime: 5_000,\r\n refetchInterval: autoRefresh ? 5_000 : false,\r\n });\r\n\r\n return {\r\n messages: (query.data?.messages ?? []) as TeamMessage[],\r\n total: query.data?.total ?? 0,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch: query.refetch,\r\n };\r\n}\r\n\r\n/**\r\n * Hook: get member status for selected team\r\n */\r\nexport function useTeamStatus(teamName: string | null) {\r\n const autoRefresh = useTeamStore((s) => s.autoRefresh);\r\n\r\n const query = useQuery({\r\n queryKey: teamKeys.status(teamName ?? ''),\r\n queryFn: async (): Promise<TeamStatusResponse> => {\r\n if (!teamName) return { members: [], total_messages: 0 };\r\n const data = await fetchTeamStatus(teamName);\r\n return {\r\n members: data.members as TeamMember[],\r\n total_messages: data.total_messages,\r\n };\r\n },\r\n enabled: !!teamName,\r\n staleTime: 5_000,\r\n refetchInterval: autoRefresh ? 5_000 : false,\r\n });\r\n\r\n return {\r\n members: (query.data?.members ?? []) as TeamMember[],\r\n totalMessages: query.data?.total_messages ?? 0,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch: query.refetch,\r\n };\r\n}\r\n\r\n/**\r\n * Hook: invalidate all team queries\r\n */\r\nexport function useInvalidateTeamData() {\r\n const queryClient = useQueryClient();\r\n return () => queryClient.invalidateQueries({ queryKey: teamKeys.all });\r\n}\r\n\r\n// ========== Mutation Hooks ==========\r\n\r\n/**\r\n * Hook: archive a team\r\n */\r\nexport function useArchiveTeam() {\r\n const queryClient = useQueryClient();\r\n\r\n const mutation = useMutation({\r\n mutationFn: archiveTeam,\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: teamKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n archiveTeam: mutation.mutateAsync,\r\n isArchiving: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\n/**\r\n * Hook: unarchive a team\r\n */\r\nexport function useUnarchiveTeam() {\r\n const queryClient = useQueryClient();\r\n\r\n const mutation = useMutation({\r\n mutationFn: unarchiveTeam,\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: teamKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n unarchiveTeam: mutation.mutateAsync,\r\n isUnarchiving: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\n/**\r\n * Hook: delete a team\r\n */\r\nexport function useDeleteTeam() {\r\n const queryClient = useQueryClient();\r\n\r\n const mutation = useMutation({\r\n mutationFn: deleteTeam,\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: teamKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n deleteTeam: mutation.mutateAsync,\r\n isDeleting: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n","// ========================================\r\n// TeamHeader Component\r\n// ========================================\r\n// Detail view header with back button, stats, and controls\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { Users, MessageSquare, RefreshCw, ArrowLeft, GitBranch } from 'lucide-react';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Switch } from '@/components/ui/Switch';\r\nimport { Label } from '@/components/ui/Label';\r\nimport type { TeamMember } from '@/types/team';\r\n\r\ninterface TeamHeaderProps {\r\n selectedTeam: string | null;\r\n onBack: () => void;\r\n members: TeamMember[];\r\n totalMessages: number;\r\n autoRefresh: boolean;\r\n onToggleAutoRefresh: () => void;\r\n skillType?: string;\r\n pipelineMode?: string;\r\n}\r\n\r\nexport function TeamHeader({\r\n selectedTeam,\r\n onBack,\r\n members,\r\n totalMessages,\r\n autoRefresh,\r\n onToggleAutoRefresh,\r\n skillType,\r\n pipelineMode,\r\n}: TeamHeaderProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n return (\r\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\r\n <div className=\"flex items-center gap-3 flex-wrap\">\r\n {/* Back button */}\r\n <Button variant=\"ghost\" size=\"sm\" onClick={onBack} className=\"gap-1\">\r\n <ArrowLeft className=\"h-4 w-4\" />\r\n {formatMessage({ id: 'team.detail.backToList' })}\r\n </Button>\r\n\r\n {/* Team name */}\r\n {selectedTeam && (\r\n <>\r\n <h2 className=\"text-lg font-semibold\">{selectedTeam}</h2>\r\n\r\n {/* Stats chips */}\r\n <div className=\"flex items-center gap-2\">\r\n <Badge variant=\"secondary\" className=\"gap-1\">\r\n <Users className=\"w-3 h-3\" />\r\n {formatMessage({ id: 'team.members' })}: {members.length}\r\n </Badge>\r\n <Badge variant=\"secondary\" className=\"gap-1\">\r\n <MessageSquare className=\"w-3 h-3\" />\r\n {formatMessage({ id: 'team.messages' })}: {totalMessages}\r\n </Badge>\r\n </div>\r\n\r\n {/* Skill type and pipeline mode badges */}\r\n {(skillType || pipelineMode) && (\r\n <div className=\"flex items-center gap-2\">\r\n {skillType && (\r\n <Badge variant=\"outline\" className=\"gap-1\">\r\n {skillType}\r\n </Badge>\r\n )}\r\n {pipelineMode && (\r\n <Badge variant=\"default\" className=\"gap-1\">\r\n <GitBranch className=\"w-3 h-3\" />\r\n {pipelineMode}\r\n </Badge>\r\n )}\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n\r\n {/* Controls */}\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"flex items-center gap-2\">\r\n <Switch\r\n id=\"auto-refresh\"\r\n checked={autoRefresh}\r\n onCheckedChange={onToggleAutoRefresh}\r\n />\r\n <Label htmlFor=\"auto-refresh\" className=\"text-sm text-muted-foreground cursor-pointer\">\r\n {formatMessage({ id: 'team.autoRefresh' })}\r\n </Label>\r\n {autoRefresh && (\r\n <RefreshCw className=\"w-3.5 h-3.5 text-primary animate-spin\" style={{ animationDuration: '3s' }} />\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// DynamicPipeline Component\r\n// ========================================\r\n// Dynamic pipeline stage visualization with fallback to static TeamPipeline\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { CheckCircle2, Circle, Loader2, Ban, SkipForward } from 'lucide-react';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { cn } from '@/lib/utils';\r\nimport type { DynamicStage, DynamicStageStatus, PhaseInfo } from '@/types/team';\r\n\r\ninterface DynamicPipelineProps {\r\n stages: DynamicStage[];\r\n phaseInfo?: PhaseInfo | null;\r\n}\r\n\r\nconst statusConfig: Record<DynamicStageStatus, { icon: typeof CheckCircle2; color: string; bg: string; animate?: boolean }> = {\r\n completed: { icon: CheckCircle2, color: 'text-green-500', bg: 'bg-green-500/10 border-green-500/30' },\r\n in_progress: { icon: Loader2, color: 'text-blue-500', bg: 'bg-blue-500/10 border-blue-500/30', animate: true },\r\n pending: { icon: Circle, color: 'text-muted-foreground', bg: 'bg-muted border-border' },\r\n blocked: { icon: Ban, color: 'text-red-500', bg: 'bg-red-500/10 border-red-500/30' },\r\n skipped: { icon: SkipForward, color: 'text-yellow-500', bg: 'bg-yellow-500/10 border-yellow-500/30' },\r\n};\r\n\r\nconst LEGEND_STATUSES: DynamicStageStatus[] = ['completed', 'in_progress', 'pending', 'blocked', 'skipped'];\r\n\r\nfunction StageNode({ stage }: { stage: DynamicStage }) {\r\n const { formatMessage } = useIntl();\r\n const config = statusConfig[stage.status];\r\n const Icon = config.icon;\r\n\r\n const statusKey = stage.status === 'in_progress' ? 'inProgress' : stage.status;\r\n\r\n return (\r\n <div\r\n className={cn(\r\n 'flex flex-col items-center gap-1.5 px-4 py-3 rounded-lg border-2 min-w-[90px] transition-all',\r\n config.bg\r\n )}\r\n >\r\n <Icon\r\n className={cn('w-5 h-5', config.color, config.animate && 'animate-spin')}\r\n style={config.animate ? { animationDuration: '2s' } : undefined}\r\n />\r\n <span className=\"text-xs font-medium\">\r\n {stage.label}\r\n </span>\r\n <span className={cn('text-[10px]', config.color)}>\r\n {formatMessage({ id: `team.pipeline.${statusKey}` })}\r\n </span>\r\n {stage.role && (\r\n <span className=\"text-[10px] text-muted-foreground truncate max-w-[80px]\">\r\n {stage.role}\r\n </span>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction Arrow() {\r\n return (\r\n <div className=\"flex items-center px-1\">\r\n <div className=\"w-6 h-0.5 bg-border\" />\r\n <div className=\"w-0 h-0 border-t-[4px] border-t-transparent border-b-[4px] border-b-transparent border-l-[6px] border-l-border\" />\r\n </div>\r\n );\r\n}\r\n\r\nexport function DynamicPipeline({ stages, phaseInfo }: DynamicPipelineProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n // Fallback: empty state when no dynamic stages are available\r\n if (stages.length === 0) {\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n <h3 className=\"text-sm font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'team.pipeline.title' })}\r\n </h3>\r\n <p className=\"text-xs text-muted-foreground text-center py-8\">\r\n {formatMessage({ id: 'team.pipeline.noStages' })}\r\n </p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n <div className=\"space-y-3 flex-1\">\r\n <h3 className=\"text-sm font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'team.pipeline.title' })}\r\n </h3>\r\n\r\n {/* Phase header */}\r\n {phaseInfo && (\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <Badge variant=\"secondary\">\r\n {formatMessage({ id: 'team.coordinates.phase' })}: {phaseInfo.currentPhase}\r\n {phaseInfo.totalPhases != null && `/${phaseInfo.totalPhases}`}\r\n </Badge>\r\n {phaseInfo.currentStep && (\r\n <Badge variant=\"secondary\">\r\n {formatMessage({ id: 'team.coordinates.step' })}: {phaseInfo.currentStep}\r\n </Badge>\r\n )}\r\n {phaseInfo.gapIteration > 0 && (\r\n <Badge variant=\"outline\">\r\n {formatMessage({ id: 'team.coordinates.gap' })}: {phaseInfo.gapIteration}\r\n </Badge>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Desktop: horizontal layout */}\r\n <div className=\"hidden sm:flex items-center gap-0\">\r\n {stages.map((stage, idx) => (\r\n <div key={stage.id} className=\"flex items-center\">\r\n {idx > 0 && <Arrow />}\r\n <StageNode stage={stage} />\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Mobile: vertical layout */}\r\n <div className=\"flex sm:hidden flex-col items-center gap-2\">\r\n {stages.map((stage) => (\r\n <StageNode key={stage.id} stage={stage} />\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Legend */}\r\n <div className=\"flex flex-wrap gap-3 text-[10px] text-muted-foreground mt-auto pt-3 border-t border-border\">\r\n {LEGEND_STATUSES.map((s) => {\r\n const cfg = statusConfig[s];\r\n const Icon = cfg.icon;\r\n const statusKey = s === 'in_progress' ? 'inProgress' : s;\r\n return (\r\n <span key={s} className=\"flex items-center gap-1\">\r\n <Icon className={cn('w-3 h-3', cfg.color)} />\r\n {formatMessage({ id: `team.pipeline.${statusKey}` })}\r\n </span>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// TeamMembersPanel Component\r\n// ========================================\r\n// Card-based member status display\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { cn } from '@/lib/utils';\r\nimport type { TeamMember } from '@/types/team';\r\n\r\ninterface TeamMembersPanelProps {\r\n members: TeamMember[];\r\n}\r\n\r\nfunction formatRelativeTime(isoString: string): string {\r\n if (!isoString) return '';\r\n const now = Date.now();\r\n const then = new Date(isoString).getTime();\r\n const diffMs = now - then;\r\n\r\n if (diffMs < 0) return 'now';\r\n const seconds = Math.floor(diffMs / 1000);\r\n if (seconds < 60) return `${seconds}s`;\r\n const minutes = Math.floor(seconds / 60);\r\n if (minutes < 60) return `${minutes}m`;\r\n const hours = Math.floor(minutes / 60);\r\n if (hours < 24) return `${hours}h`;\r\n const days = Math.floor(hours / 24);\r\n return `${days}d`;\r\n}\r\n\r\nfunction getMemberStatus(member: TeamMember): 'active' | 'idle' {\r\n if (!member.lastSeen) return 'idle';\r\n const diffMs = Date.now() - new Date(member.lastSeen).getTime();\r\n // Active if seen in last 2 minutes\r\n return diffMs < 2 * 60 * 1000 ? 'active' : 'idle';\r\n}\r\n\r\nexport function TeamMembersPanel({ members }: TeamMembersPanelProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n <h3 className=\"text-sm font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'team.membersPanel.title' })}\r\n </h3>\r\n <div className=\"space-y-2\">\r\n {members.map((m) => {\r\n const status = getMemberStatus(m);\r\n const isActive = status === 'active';\r\n\r\n return (\r\n <Card key={m.member} className=\"overflow-hidden\">\r\n <CardContent className=\"p-3\">\r\n <div className=\"flex items-start gap-3\">\r\n {/* Status indicator */}\r\n <div className=\"pt-0.5\">\r\n <div\r\n className={cn(\r\n 'w-2.5 h-2.5 rounded-full',\r\n isActive\r\n ? 'bg-green-500 shadow-[0_0_6px_rgba(34,197,94,0.5)]'\r\n : 'bg-muted-foreground/40'\r\n )}\r\n />\r\n </div>\r\n\r\n <div className=\"flex-1 min-w-0 space-y-1\">\r\n {/* Name + status badge */}\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium truncate\">{m.member}</span>\r\n <Badge\r\n variant={isActive ? 'success' : 'secondary'}\r\n className=\"text-[10px] px-1.5 py-0\"\r\n >\r\n {formatMessage({ id: `team.membersPanel.${status}` })}\r\n </Badge>\r\n </div>\r\n\r\n {/* Last action */}\r\n {m.lastAction && (\r\n <p className=\"text-xs text-muted-foreground truncate\">\r\n {m.lastAction}\r\n </p>\r\n )}\r\n\r\n {/* Stats row */}\r\n <div className=\"flex items-center gap-3 text-[10px] text-muted-foreground\">\r\n <span>\r\n {m.messageCount} {formatMessage({ id: 'team.messages' }).toLowerCase()}\r\n </span>\r\n {m.lastSeen && (\r\n <span>\r\n {formatRelativeTime(m.lastSeen)} {formatMessage({ id: 'team.membersPanel.ago' })}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n })}\r\n\r\n {members.length === 0 && (\r\n <p className=\"text-xs text-muted-foreground text-center py-4\">\r\n {formatMessage({ id: 'team.empty.noMessages' })}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// TeamRolePanel Component\r\n// ========================================\r\n// Member-to-pipeline-role mapping with fallback to TeamMembersPanel\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { cn } from '@/lib/utils';\r\nimport { TeamMembersPanel } from './TeamMembersPanel';\r\nimport type { TeamMember, DynamicStage } from '@/types/team';\r\n\r\ninterface TeamRolePanelProps {\r\n members: TeamMember[];\r\n stages: DynamicStage[];\r\n roleState?: Record<string, Record<string, unknown>>;\r\n}\r\n\r\nfunction formatRelativeTime(isoString: string): string {\r\n if (!isoString) return '';\r\n const now = Date.now();\r\n const then = new Date(isoString).getTime();\r\n const diffMs = now - then;\r\n if (diffMs < 0) return 'now';\r\n const seconds = Math.floor(diffMs / 1000);\r\n if (seconds < 60) return `${seconds}s`;\r\n const minutes = Math.floor(seconds / 60);\r\n if (minutes < 60) return `${minutes}m`;\r\n const hours = Math.floor(minutes / 60);\r\n if (hours < 24) return `${hours}h`;\r\n const days = Math.floor(hours / 24);\r\n return `${days}d`;\r\n}\r\n\r\nfunction getMemberStatus(member: TeamMember): 'active' | 'idle' {\r\n if (!member.lastSeen) return 'idle';\r\n const diffMs = Date.now() - new Date(member.lastSeen).getTime();\r\n // Active if seen in last 2 minutes\r\n return diffMs < 2 * 60 * 1000 ? 'active' : 'idle';\r\n}\r\n\r\n/** Find the matching dynamic stage for a member */\r\nfunction findMatchingStage(member: TeamMember, stages: DynamicStage[]): DynamicStage | undefined {\r\n const memberLower = member.member.toLowerCase();\r\n return stages.find(\r\n (stage) =>\r\n (stage.role && stage.role.toLowerCase() === memberLower) ||\r\n stage.id.toLowerCase() === memberLower\r\n );\r\n}\r\n\r\nconst stageBadgeVariant: Record<string, 'success' | 'info' | 'secondary' | 'destructive' | 'warning'> = {\r\n completed: 'success',\r\n in_progress: 'info',\r\n pending: 'secondary',\r\n blocked: 'destructive',\r\n skipped: 'warning',\r\n};\r\n\r\nexport function TeamRolePanel({ members, stages, roleState: _roleState }: TeamRolePanelProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n // Fallback to static members panel when no dynamic stages\r\n if (stages.length === 0) {\r\n return <TeamMembersPanel members={members} />;\r\n }\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n <h3 className=\"text-sm font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'team.membersPanel.title' })}\r\n </h3>\r\n <div className=\"space-y-2\">\r\n {members.map((m) => {\r\n const status = getMemberStatus(m);\r\n const isActive = status === 'active';\r\n const matchedStage = findMatchingStage(m, stages);\r\n\r\n return (\r\n <Card key={m.member} className=\"overflow-hidden\">\r\n <CardContent className=\"p-3\">\r\n <div className=\"flex items-start gap-3\">\r\n {/* Status indicator */}\r\n <div className=\"pt-0.5\">\r\n <div\r\n className={cn(\r\n 'w-2.5 h-2.5 rounded-full',\r\n isActive\r\n ? 'bg-green-500 shadow-[0_0_6px_rgba(34,197,94,0.5)]'\r\n : 'bg-muted-foreground/40'\r\n )}\r\n />\r\n </div>\r\n\r\n <div className=\"flex-1 min-w-0 space-y-1\">\r\n {/* Name + status badge + stage badge */}\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span className=\"text-sm font-medium truncate\">{m.member}</span>\r\n <Badge\r\n variant={isActive ? 'success' : 'secondary'}\r\n className=\"text-[10px] px-1.5 py-0\"\r\n >\r\n {formatMessage({ id: `team.membersPanel.${status}` })}\r\n </Badge>\r\n {matchedStage && (\r\n <Badge\r\n variant={stageBadgeVariant[matchedStage.status] ?? 'secondary'}\r\n className=\"text-[10px] px-1.5 py-0\"\r\n >\r\n {matchedStage.label}\r\n </Badge>\r\n )}\r\n </div>\r\n\r\n {/* Last action */}\r\n {m.lastAction && (\r\n <p className=\"text-xs text-muted-foreground truncate\">\r\n {m.lastAction}\r\n </p>\r\n )}\r\n\r\n {/* Stats row */}\r\n <div className=\"flex items-center gap-3 text-[10px] text-muted-foreground\">\r\n <span>\r\n {m.messageCount} {formatMessage({ id: 'team.messages' }).toLowerCase()}\r\n </span>\r\n {m.lastSeen && (\r\n <span>\r\n {formatRelativeTime(m.lastSeen)} {formatMessage({ id: 'team.membersPanel.ago' })}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n })}\r\n\r\n {members.length === 0 && (\r\n <p className=\"text-xs text-muted-foreground text-center py-4\">\r\n {formatMessage({ id: 'team.empty.noMessages' })}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// SessionCoordinates Component\r\n// ========================================\r\n// Compact inline display of phase/step/gap using Badge components\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport type { PhaseInfo } from '@/types/team';\r\n\r\ninterface SessionCoordinatesProps {\r\n phaseInfo: PhaseInfo;\r\n}\r\n\r\nexport function SessionCoordinates({ phaseInfo }: SessionCoordinatesProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n return (\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <Badge variant=\"secondary\">\r\n {formatMessage({ id: 'team.coordinates.phase' })}: {phaseInfo.currentPhase}\r\n {phaseInfo.totalPhases != null && `/${phaseInfo.totalPhases}`}\r\n </Badge>\r\n {phaseInfo.currentStep && (\r\n <Badge variant=\"secondary\">\r\n {formatMessage({ id: 'team.coordinates.step' })}: {phaseInfo.currentStep}\r\n </Badge>\r\n )}\r\n {phaseInfo.gapIteration > 0 && (\r\n <Badge variant=\"outline\">\r\n {formatMessage({ id: 'team.coordinates.gap' })}: {phaseInfo.gapIteration}\r\n </Badge>\r\n )}\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// TeamMessageFeed Component\r\n// ========================================\r\n// Message timeline with filtering and pagination\r\n\r\nimport { useState, useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { ChevronDown, ChevronUp, FileText, Filter, X } from 'lucide-react';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport {\r\n Select,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n} from '@/components/ui/Select';\r\nimport { cn } from '@/lib/utils';\r\nimport type { TeamMessage, TeamMessageFilter } from '@/types/team';\r\n\r\ninterface TeamMessageFeedProps {\r\n messages: TeamMessage[];\r\n total: number;\r\n filter: TeamMessageFilter;\r\n onFilterChange: (filter: Partial<TeamMessageFilter>) => void;\r\n onClearFilter: () => void;\r\n expanded: boolean;\r\n onExpandedChange: (expanded: boolean) => void;\r\n}\r\n\r\n// Message type → color mapping\r\nconst typeColorMap: Record<string, string> = {\r\n plan_ready: 'bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-500/30',\r\n plan_approved: 'bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-500/30',\r\n plan_revision: 'bg-amber-500/15 text-amber-600 dark:text-amber-400 border-amber-500/30',\r\n task_unblocked: 'bg-cyan-500/15 text-cyan-600 dark:text-cyan-400 border-cyan-500/30',\r\n impl_complete: 'bg-primary/15 text-primary border-primary/30',\r\n impl_progress: 'bg-primary/15 text-primary border-primary/30',\r\n test_result: 'bg-green-500/15 text-green-600 dark:text-green-400 border-green-500/30',\r\n review_result: 'bg-purple-500/15 text-purple-600 dark:text-purple-400 border-purple-500/30',\r\n fix_required: 'bg-red-500/15 text-red-600 dark:text-red-400 border-red-500/30',\r\n error: 'bg-red-500/15 text-red-600 dark:text-red-400 border-red-500/30',\r\n shutdown: 'bg-muted text-muted-foreground border-border',\r\n message: 'bg-muted text-muted-foreground border-border',\r\n};\r\n\r\nfunction MessageTypeBadge({ type }: { type: string }) {\r\n const { formatMessage } = useIntl();\r\n const color = typeColorMap[type] || typeColorMap.message;\r\n const labelKey = `team.messageType.${type}`;\r\n\r\n let label: string;\r\n try {\r\n label = formatMessage({ id: labelKey });\r\n } catch {\r\n label = type;\r\n }\r\n\r\n return (\r\n <span className={cn('text-[10px] px-1.5 py-0.5 rounded border font-medium', color)}>\r\n {label}\r\n </span>\r\n );\r\n}\r\n\r\nfunction MessageRow({ msg }: { msg: TeamMessage }) {\r\n const [dataExpanded, setDataExpanded] = useState(false);\r\n const time = msg.ts ? msg.ts.substring(11, 19) : '';\r\n\r\n return (\r\n <div className=\"flex gap-3 py-2.5 border-b border-border last:border-b-0 animate-in fade-in slide-in-from-top-1 duration-300\">\r\n {/* Timestamp */}\r\n <span className=\"text-[10px] font-mono text-muted-foreground w-16 shrink-0 pt-0.5\">\r\n {time}\r\n </span>\r\n\r\n {/* Content */}\r\n <div className=\"flex-1 min-w-0 space-y-1\">\r\n {/* Header: from → to + type */}\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span className=\"text-xs font-medium\">{msg.from}</span>\r\n <span className=\"text-[10px] text-muted-foreground\">&rarr;</span>\r\n <span className=\"text-xs font-medium\">{msg.to}</span>\r\n <MessageTypeBadge type={msg.type} />\r\n {msg.id && (\r\n <span className=\"text-[10px] text-muted-foreground\">{msg.id}</span>\r\n )}\r\n </div>\r\n\r\n {/* Summary */}\r\n <p className=\"text-xs text-foreground/80\">{msg.summary}</p>\r\n\r\n {/* Ref link (supports both legacy msg.ref and new data.ref) */}\r\n {(msg.ref || (msg.data?.ref as string)) && (\r\n <div className=\"flex items-center gap-1 text-[10px] text-muted-foreground\">\r\n <FileText className=\"w-3 h-3\" />\r\n <span className=\"font-mono truncate\">{msg.ref || (msg.data?.ref as string)}</span>\r\n </div>\r\n )}\r\n\r\n {/* Data toggle */}\r\n {msg.data && Object.keys(msg.data).length > 0 && (\r\n <div>\r\n <button\r\n onClick={() => setDataExpanded(!dataExpanded)}\r\n className=\"text-[10px] text-primary hover:underline flex items-center gap-0.5\"\r\n >\r\n {dataExpanded ? (\r\n <>\r\n <ChevronUp className=\"w-3 h-3\" /> collapse\r\n </>\r\n ) : (\r\n <>\r\n <ChevronDown className=\"w-3 h-3\" /> data\r\n </>\r\n )}\r\n </button>\r\n {dataExpanded && (\r\n <pre className=\"text-[10px] bg-muted p-2 rounded mt-1 overflow-x-auto max-h-40\">\r\n {JSON.stringify(msg.data, null, 2)}\r\n </pre>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport function TeamMessageFeed({\r\n messages,\r\n total,\r\n filter,\r\n onFilterChange,\r\n onClearFilter,\r\n expanded,\r\n onExpandedChange,\r\n}: TeamMessageFeedProps) {\r\n const { formatMessage } = useIntl();\r\n const hasFilter = !!(filter.from || filter.to || filter.type);\r\n\r\n // Extract unique senders/receivers for filter dropdowns\r\n const { senders, receivers, types } = useMemo(() => {\r\n const s = new Set<string>();\r\n const r = new Set<string>();\r\n const t = new Set<string>();\r\n for (const m of messages) {\r\n s.add(m.from);\r\n r.add(m.to);\r\n t.add(m.type);\r\n }\r\n return {\r\n senders: Array.from(s).sort(),\r\n receivers: Array.from(r).sort(),\r\n types: Array.from(t).sort(),\r\n };\r\n }, [messages]);\r\n\r\n // Reverse for newest-first display\r\n const displayMessages = [...messages].reverse();\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <button\r\n onClick={() => onExpandedChange(!expanded)}\r\n className=\"flex items-center gap-2 text-sm font-medium text-muted-foreground hover:text-foreground transition-colors\"\r\n >\r\n {expanded ? <ChevronUp className=\"w-4 h-4\" /> : <ChevronDown className=\"w-4 h-4\" />}\r\n {formatMessage({ id: 'team.timeline.title' })}\r\n <span className=\"text-xs font-normal\">\r\n ({formatMessage({ id: 'team.timeline.showing' }, { showing: messages.length, total })})\r\n </span>\r\n </button>\r\n\r\n {hasFilter && (\r\n <Button variant=\"ghost\" size=\"sm\" onClick={onClearFilter} className=\"h-6 text-xs gap-1\">\r\n <X className=\"w-3 h-3\" />\r\n {formatMessage({ id: 'team.timeline.clearFilters' })}\r\n </Button>\r\n )}\r\n </div>\r\n\r\n {expanded && (\r\n <>\r\n {/* Filters */}\r\n <div className=\"flex flex-wrap gap-2\">\r\n <Select\r\n value={filter.from ?? '__all__'}\r\n onValueChange={(v) => onFilterChange({ from: v === '__all__' ? undefined : v })}\r\n >\r\n <SelectTrigger className=\"w-[130px] h-7 text-xs\">\r\n <Filter className=\"w-3 h-3 mr-1\" />\r\n <SelectValue placeholder={formatMessage({ id: 'team.timeline.filterFrom' })} />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"__all__\">{formatMessage({ id: 'team.filterAll' })}</SelectItem>\r\n {senders.map((s) => (\r\n <SelectItem key={s} value={s}>{s}</SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n\r\n <Select\r\n value={filter.to ?? '__all__'}\r\n onValueChange={(v) => onFilterChange({ to: v === '__all__' ? undefined : v })}\r\n >\r\n <SelectTrigger className=\"w-[130px] h-7 text-xs\">\r\n <SelectValue placeholder={formatMessage({ id: 'team.timeline.filterTo' })} />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"__all__\">{formatMessage({ id: 'team.filterAll' })}</SelectItem>\r\n {receivers.map((r) => (\r\n <SelectItem key={r} value={r}>{r}</SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n\r\n <Select\r\n value={filter.type ?? '__all__'}\r\n onValueChange={(v) => onFilterChange({ type: v === '__all__' ? undefined : v })}\r\n >\r\n <SelectTrigger className=\"w-[150px] h-7 text-xs\">\r\n <SelectValue placeholder={formatMessage({ id: 'team.timeline.filterType' })} />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"__all__\">{formatMessage({ id: 'team.filterAll' })}</SelectItem>\r\n {types.map((t) => (\r\n <SelectItem key={t} value={t}>{t}</SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n\r\n {/* Messages list */}\r\n <Card>\r\n <CardContent className=\"p-3\">\r\n {displayMessages.length > 0 ? (\r\n <div className=\"divide-y-0\">\r\n {displayMessages.map((msg) => (\r\n <MessageRow key={msg.id} msg={msg} />\r\n ))}\r\n </div>\r\n ) : (\r\n <div className=\"text-center py-8\">\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'team.empty.noMessages' })}\r\n </p>\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'team.empty.noMessagesHint' })}\r\n </p>\r\n </div>\r\n )}\r\n </CardContent>\r\n </Card>\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// TeamArtifacts Component\r\n// ========================================\r\n// Displays team artifacts with hybrid layout: tree navigation + file preview\r\n\r\nimport * as React from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n ChevronDown,\r\n ChevronRight,\r\n Folder,\r\n FileText,\r\n FileJson,\r\n Package,\r\n Loader2,\r\n} from 'lucide-react';\r\nimport { fetchTeamArtifacts, fetchArtifactContent } from '@/lib/api';\r\nimport { cn } from '@/lib/utils';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport type { ArtifactNode, ContentType } from '@/types/team';\r\n\r\n// ========================================\r\n// Types\r\n// ========================================\r\n\r\ninterface TeamArtifactsProps {\r\n teamName: string;\r\n}\r\n\r\n// ========================================\r\n// Helpers\r\n// ========================================\r\n\r\nfunction getContentTypeFromPath(path: string): ContentType {\r\n if (path.endsWith('.json')) return 'json';\r\n if (path.endsWith('.md')) return 'markdown';\r\n if (path.endsWith('.txt') || path.endsWith('.log') || path.endsWith('.tsv') || path.endsWith('.csv')) return 'text';\r\n return 'unknown';\r\n}\r\n\r\nfunction formatSize(bytes?: number): string {\r\n if (!bytes) return '';\r\n if (bytes < 1024) return `${bytes} B`;\r\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\r\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\r\n}\r\n\r\nfunction formatDate(ts?: string): string {\r\n if (!ts) return '';\r\n try {\r\n const date = new Date(ts);\r\n return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });\r\n } catch {\r\n return '';\r\n }\r\n}\r\n\r\n// ========================================\r\n// Sub-components\r\n// ========================================\r\n\r\nfunction FileIcon({ contentType }: { contentType?: ContentType }) {\r\n if (contentType === 'json') {\r\n return <FileJson className=\"w-4 h-4 text-blue-500\" />;\r\n }\r\n return <FileText className=\"w-4 h-4 text-gray-500\" />;\r\n}\r\n\r\ninterface TreeNodeProps {\r\n node: ArtifactNode;\r\n depth: number;\r\n expanded: Set<string>;\r\n selectedPath?: string;\r\n onToggle: (path: string) => void;\r\n onSelect: (node: ArtifactNode) => void;\r\n}\r\n\r\nfunction TreeNode({\r\n node,\r\n depth,\r\n expanded,\r\n selectedPath,\r\n onToggle,\r\n onSelect,\r\n}: TreeNodeProps) {\r\n if (node.type === 'directory') {\r\n const isExpanded = expanded.has(node.path);\r\n return (\r\n <div key={node.path}>\r\n <div\r\n className=\"flex items-center gap-1 py-1.5 px-2 cursor-pointer hover:bg-accent/50 rounded transition-colors\"\r\n style={{ paddingLeft: depth * 16 + 8 }}\r\n onClick={() => onToggle(node.path)}\r\n >\r\n {isExpanded ? (\r\n <ChevronDown className=\"w-4 h-4 text-muted-foreground\" />\r\n ) : (\r\n <ChevronRight className=\"w-4 h-4 text-muted-foreground\" />\r\n )}\r\n <Folder\r\n className={cn(\r\n 'w-4 h-4',\r\n isExpanded ? 'text-amber-500' : 'text-amber-400'\r\n )}\r\n />\r\n <span className=\"text-sm truncate\">{node.name}</span>\r\n </div>\r\n {isExpanded && node.children && (\r\n <div>\r\n {node.children.map((child) => (\r\n <TreeNode\r\n key={child.path}\r\n node={child}\r\n depth={depth + 1}\r\n expanded={expanded}\r\n selectedPath={selectedPath}\r\n onToggle={onToggle}\r\n onSelect={onSelect}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n }\r\n\r\n // File node\r\n const isSelected = selectedPath === node.path;\r\n const contentType = node.contentType || getContentTypeFromPath(node.path);\r\n\r\n return (\r\n <div\r\n key={node.path}\r\n className={cn(\r\n 'flex items-center gap-1 py-1.5 px-2 cursor-pointer hover:bg-accent/50 rounded transition-colors',\r\n isSelected && 'bg-accent'\r\n )}\r\n style={{ paddingLeft: depth * 16 + 28 }}\r\n onClick={() => onSelect(node)}\r\n >\r\n <FileIcon contentType={contentType} />\r\n <span className=\"text-sm truncate flex-1\">{node.name}</span>\r\n {node.size !== undefined && (\r\n <span className=\"text-xs text-muted-foreground ml-2\">\r\n {formatSize(node.size)}\r\n </span>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n// ========================================\r\n// Main Component\r\n// ========================================\r\n\r\nexport function TeamArtifacts({ teamName }: TeamArtifactsProps) {\r\n const { formatMessage } = useIntl();\r\n const [tree, setTree] = React.useState<ArtifactNode[]>([]);\r\n const [expanded, setExpanded] = React.useState<Set<string>>(new Set());\r\n const [selectedFile, setSelectedFile] = React.useState<ArtifactNode | null>(null);\r\n const [content, setContent] = React.useState<string>('');\r\n const [loading, setLoading] = React.useState(false);\r\n const [treeLoading, setTreeLoading] = React.useState(true);\r\n const [error, setError] = React.useState<string | null>(null);\r\n\r\n // Load artifacts tree\r\n React.useEffect(() => {\r\n if (!teamName) return;\r\n\r\n setTreeLoading(true);\r\n setError(null);\r\n\r\n fetchTeamArtifacts(teamName)\r\n .then((data) => {\r\n setTree(data.tree || []);\r\n // Auto-expand first level directories\r\n const firstLevelDirs = (data.tree || [])\r\n .filter((n) => n.type === 'directory')\r\n .map((n) => n.path);\r\n setExpanded(new Set(firstLevelDirs));\r\n })\r\n .catch((err) => {\r\n console.error('Failed to load artifacts:', err);\r\n setError(formatMessage({ id: 'team.artifacts.loadError', defaultMessage: 'Failed to load artifacts' }));\r\n })\r\n .finally(() => {\r\n setTreeLoading(false);\r\n });\r\n }, [teamName, formatMessage]);\r\n\r\n const handleToggle = React.useCallback((path: string) => {\r\n setExpanded((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(path)) {\r\n next.delete(path);\r\n } else {\r\n next.add(path);\r\n }\r\n return next;\r\n });\r\n }, []);\r\n\r\n const handleSelect = React.useCallback(\r\n async (node: ArtifactNode) => {\r\n if (node.type === 'directory') return;\r\n\r\n setSelectedFile(node);\r\n setLoading(true);\r\n setContent('');\r\n\r\n try {\r\n const result = await fetchArtifactContent(teamName, node.path);\r\n setContent(result.content);\r\n } catch (err) {\r\n console.error('Failed to load file content:', err);\r\n setContent(formatMessage({ id: 'team.artifacts.contentError', defaultMessage: 'Failed to load file content' }));\r\n } finally {\r\n setLoading(false);\r\n }\r\n },\r\n [teamName, formatMessage]\r\n );\r\n\r\n // Get content type for preview\r\n const previewContentType = selectedFile\r\n ? selectedFile.contentType || getContentTypeFromPath(selectedFile.path)\r\n : 'text';\r\n\r\n // Map to MarkdownModal content type\r\n const modalContentType: 'markdown' | 'json' | 'text' =\r\n previewContentType === 'json' ? 'json' : previewContentType === 'markdown' ? 'markdown' : 'text';\r\n\r\n // Loading state\r\n if (treeLoading) {\r\n return (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\r\n <span className=\"ml-3 text-muted-foreground\">\r\n {formatMessage({ id: 'team.artifacts.loading', defaultMessage: 'Loading artifacts...' })}\r\n </span>\r\n </div>\r\n );\r\n }\r\n\r\n // Error state\r\n if (error) {\r\n return (\r\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\r\n <Package className=\"h-12 w-12 text-destructive mb-4\" />\r\n <p className=\"text-muted-foreground\">{error}</p>\r\n </div>\r\n );\r\n }\r\n\r\n // Empty state\r\n if (tree.length === 0) {\r\n return (\r\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\r\n <Package className=\"h-12 w-12 text-muted-foreground mb-4\" />\r\n <h3 className=\"text-lg font-medium text-foreground mb-2\">\r\n {formatMessage({ id: 'team.artifacts.noArtifacts', defaultMessage: 'No artifacts yet' })}\r\n </h3>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'team.artifacts.emptyHint', defaultMessage: 'Artifacts will appear here when the team generates them' })}\r\n </p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"flex h-[600px] border rounded-lg overflow-hidden\">\r\n {/* Left: Tree Navigation */}\r\n <div className=\"w-72 shrink-0 border-r bg-muted/30 flex flex-col\">\r\n <div className=\"p-3 border-b bg-background shrink-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <Package className=\"w-4 h-4 text-muted-foreground\" />\r\n <span className=\"text-sm font-medium\">\r\n {formatMessage({ id: 'team.artifacts.title', defaultMessage: 'Artifacts' })}\r\n </span>\r\n </div>\r\n </div>\r\n <div className=\"flex-1 overflow-y-auto py-2\">\r\n {tree.map((node) => (\r\n <TreeNode\r\n key={node.path}\r\n node={node}\r\n depth={0}\r\n expanded={expanded}\r\n selectedPath={selectedFile?.path}\r\n onToggle={handleToggle}\r\n onSelect={handleSelect}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Right: File Preview */}\r\n <div className=\"flex-1 flex flex-col min-w-0\">\r\n {selectedFile ? (\r\n <>\r\n <div className=\"p-3 border-b bg-muted/30 shrink-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <FileIcon contentType={previewContentType} />\r\n <span className=\"text-sm font-medium truncate\">\r\n {selectedFile.name}\r\n </span>\r\n {selectedFile.size !== undefined && (\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatSize(selectedFile.size)}\r\n </span>\r\n )}\r\n {selectedFile.modifiedAt && (\r\n <span className=\"text-xs text-muted-foreground ml-auto\">\r\n {formatDate(selectedFile.modifiedAt)}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n <div className=\"flex-1 overflow-y-auto p-4\">\r\n {loading ? (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"h-6 w-6 animate-spin text-muted-foreground\" />\r\n </div>\r\n ) : (\r\n <PreviewContent\r\n content={content}\r\n contentType={modalContentType}\r\n />\r\n )}\r\n </div>\r\n </>\r\n ) : (\r\n <div className=\"flex-1 flex items-center justify-center text-center p-8\">\r\n <div>\r\n <FileText className=\"h-12 w-12 text-muted-foreground mx-auto mb-4\" />\r\n <p className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'team.artifacts.selectFile', defaultMessage: 'Select a file to preview' })}\r\n </p>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ========================================\r\n// JSON Card Viewer\r\n// ========================================\r\n\r\nfunction JsonCardViewer({ data, depth = 0 }: { data: unknown; depth?: number }) {\r\n // Primitive values\r\n if (data === null) {\r\n return <span className=\"text-red-500 font-mono text-sm\">null</span>;\r\n }\r\n if (data === undefined) {\r\n return <span className=\"text-muted-foreground font-mono text-sm\">undefined</span>;\r\n }\r\n if (typeof data === 'boolean') {\r\n return (\r\n <span className={cn('font-mono text-sm', data ? 'text-orange-500' : 'text-red-500')}>\r\n {data ? 'true' : 'false'}\r\n </span>\r\n );\r\n }\r\n if (typeof data === 'number') {\r\n return <span className=\"text-blue-500 font-mono text-sm\">{data}</span>;\r\n }\r\n if (typeof data === 'string') {\r\n // Check if it's a long string that should be truncated\r\n if (data.length > 200) {\r\n return (\r\n <span className=\"text-green-600 dark:text-green-400 font-mono text-sm break-all\">\r\n \"{data.slice(0, 200)}...\"\r\n </span>\r\n );\r\n }\r\n return <span className=\"text-green-600 dark:text-green-400 font-mono text-sm\">\"{data}\"</span>;\r\n }\r\n\r\n // Array\r\n if (Array.isArray(data)) {\r\n if (data.length === 0) {\r\n return <span className=\"text-muted-foreground text-sm\">[]</span>;\r\n }\r\n return (\r\n <div className=\"space-y-2\">\r\n {data.map((item, index) => (\r\n <div key={index} className=\"flex items-start gap-2\">\r\n <Badge variant=\"outline\" className=\"text-xs shrink-0 mt-0.5\">\r\n {index}\r\n </Badge>\r\n <div className=\"flex-1 min-w-0\">\r\n {typeof item === 'object' && item !== null ? (\r\n <div className=\"bg-muted/30 rounded-lg p-2 border\">\r\n <JsonCardViewer data={item} depth={depth + 1} />\r\n </div>\r\n ) : (\r\n <JsonCardViewer data={item} depth={depth + 1} />\r\n )}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n }\r\n\r\n // Object\r\n if (typeof data === 'object') {\r\n const entries = Object.entries(data);\r\n if (entries.length === 0) {\r\n return <span className=\"text-muted-foreground text-sm\">{'{}'}</span>;\r\n }\r\n\r\n return (\r\n <div className={cn('space-y-2', depth > 0 && 'pl-2 border-l-2 border-border')}>\r\n {entries.map(([key, value]) => {\r\n const isExpandable = typeof value === 'object' && value !== null;\r\n const isArray = Array.isArray(value);\r\n const itemCount = isArray ? value.length : isExpandable ? Object.keys(value).length : 0;\r\n\r\n return (\r\n <div key={key} className=\"group\">\r\n <div className=\"flex items-center gap-2 py-1\">\r\n <span className=\"text-purple-600 dark:text-purple-400 font-medium text-sm shrink-0\">\r\n {key}\r\n </span>\r\n {isExpandable && (\r\n <Badge variant=\"secondary\" className=\"text-[10px] h-4 px-1\">\r\n {isArray ? `${itemCount} items` : `${itemCount} fields`}\r\n </Badge>\r\n )}\r\n </div>\r\n <div className=\"ml-3\">\r\n {isExpandable ? (\r\n <div className=\"bg-muted/20 rounded-md p-2 border\">\r\n <JsonCardViewer data={value} depth={depth + 1} />\r\n </div>\r\n ) : (\r\n <JsonCardViewer data={value} depth={depth + 1} />\r\n )}\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n }\r\n\r\n return <span className=\"text-sm\">{String(data)}</span>;\r\n}\r\n\r\n// ========================================\r\n// JSON Summary Card\r\n// ========================================\r\n\r\nfunction JsonSummaryCard({ data }: { data: unknown }) {\r\n const stats = React.useMemo(() => {\r\n const result = {\r\n type: '',\r\n fields: 0,\r\n items: 0,\r\n depth: 0,\r\n };\r\n\r\n const analyze = (obj: unknown, currentDepth: number): void => {\r\n result.depth = Math.max(result.depth, currentDepth);\r\n\r\n if (Array.isArray(obj)) {\r\n result.type = 'Array';\r\n result.items = obj.length;\r\n obj.forEach(item => analyze(item, currentDepth + 1));\r\n } else if (typeof obj === 'object' && obj !== null) {\r\n result.type = 'Object';\r\n result.fields = Object.keys(obj).length;\r\n Object.values(obj).forEach(val => analyze(val, currentDepth + 1));\r\n }\r\n };\r\n\r\n analyze(data, 0);\r\n return result;\r\n }, [data]);\r\n\r\n return (\r\n <div className=\"flex items-center gap-4 p-3 bg-muted/50 rounded-lg mb-4 text-sm\">\r\n <div className=\"flex items-center gap-2\">\r\n <Badge variant=\"outline\">{stats.type}</Badge>\r\n </div>\r\n {stats.type === 'Object' && (\r\n <div className=\"text-muted-foreground\">\r\n <span className=\"font-medium text-foreground\">{stats.fields}</span> fields\r\n </div>\r\n )}\r\n {stats.type === 'Array' && (\r\n <div className=\"text-muted-foreground\">\r\n <span className=\"font-medium text-foreground\">{stats.items}</span> items\r\n </div>\r\n )}\r\n <div className=\"text-muted-foreground\">\r\n <span className=\"font-medium text-foreground\">{stats.depth}</span> levels deep\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ========================================\r\n// Preview Content Component\r\n// ========================================\r\n\r\nfunction PreviewContent({\r\n content,\r\n contentType,\r\n}: {\r\n content: string;\r\n contentType: 'markdown' | 'json' | 'text';\r\n}) {\r\n if (!content) {\r\n return (\r\n <div className=\"text-muted-foreground text-sm\">\r\n No content\r\n </div>\r\n );\r\n }\r\n\r\n if (contentType === 'json') {\r\n try {\r\n const parsed = JSON.parse(content);\r\n return (\r\n <div className=\"space-y-2\">\r\n <JsonSummaryCard data={parsed} />\r\n <div className=\"bg-card rounded-lg\">\r\n <JsonCardViewer data={parsed} />\r\n </div>\r\n </div>\r\n );\r\n } catch {\r\n return (\r\n <pre className=\"text-xs bg-muted/50 p-4 rounded-lg overflow-auto font-mono whitespace-pre-wrap break-words border\">\r\n {content}\r\n </pre>\r\n );\r\n }\r\n }\r\n\r\n if (contentType === 'markdown') {\r\n return (\r\n <div className=\"prose prose-sm dark:prose-invert max-w-none\">\r\n <pre className=\"whitespace-pre-wrap break-words font-sans text-sm leading-relaxed bg-transparent p-0\">\r\n {content}\r\n </pre>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <pre className=\"text-xs bg-muted/50 p-4 rounded-lg overflow-auto font-mono whitespace-pre-wrap break-words border\">\r\n {content}\r\n </pre>\r\n );\r\n}\r\n\r\nexport default TeamArtifacts;\r\n","// ========================================\r\n// TeamCard Component\r\n// ========================================\r\n// Team card with status badge and action menu\r\n\r\nimport * as React from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { cn } from '@/lib/utils';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { Button } from '@/components/ui/Button';\r\nimport {\r\n DropdownMenu,\r\n DropdownMenuTrigger,\r\n DropdownMenuContent,\r\n DropdownMenuItem,\r\n DropdownMenuSeparator,\r\n} from '@/components/ui/Dropdown';\r\nimport {\r\n Users,\r\n MessageSquare,\r\n MoreVertical,\r\n Eye,\r\n Archive,\r\n ArchiveRestore,\r\n Trash2,\r\n Clock,\r\n GitBranch,\r\n} from 'lucide-react';\r\nimport type { TeamSummaryExtended, TeamStatus } from '@/types/team';\r\n\r\nexport interface TeamCardProps {\r\n team: TeamSummaryExtended;\r\n onClick?: (name: string) => void;\r\n onArchive?: (name: string) => void;\r\n onUnarchive?: (name: string) => void;\r\n onDelete?: (name: string) => void;\r\n showActions?: boolean;\r\n actionsDisabled?: boolean;\r\n className?: string;\r\n}\r\n\r\nconst statusVariantConfig: Record<\r\n TeamStatus,\r\n { variant: 'default' | 'secondary' | 'success' | 'info' }\r\n> = {\r\n active: { variant: 'info' },\r\n completed: { variant: 'success' },\r\n archived: { variant: 'secondary' },\r\n};\r\n\r\nconst statusLabelKeys: Record<TeamStatus, string> = {\r\n active: 'team.status.active',\r\n completed: 'team.status.completed',\r\n archived: 'team.status.archived',\r\n};\r\n\r\nfunction formatDate(dateString: string | undefined): string {\r\n if (!dateString) return '';\r\n try {\r\n const date = new Date(dateString);\r\n return date.toLocaleDateString(undefined, {\r\n year: 'numeric',\r\n month: 'short',\r\n day: 'numeric',\r\n });\r\n } catch {\r\n return '';\r\n }\r\n}\r\n\r\nexport function TeamCard({\r\n team,\r\n onClick,\r\n onArchive,\r\n onUnarchive,\r\n onDelete,\r\n showActions = true,\r\n actionsDisabled = false,\r\n className,\r\n}: TeamCardProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n const { variant: statusVariant } = statusVariantConfig[team.status] || { variant: 'default' as const };\r\n const statusLabel = statusLabelKeys[team.status]\r\n ? formatMessage({ id: statusLabelKeys[team.status] })\r\n : team.status;\r\n\r\n const isArchived = team.status === 'archived';\r\n\r\n const handleCardClick = (e: React.MouseEvent) => {\r\n if ((e.target as HTMLElement).closest('[data-radix-popper-content-wrapper]')) return;\r\n onClick?.(team.name);\r\n };\r\n\r\n const handleAction = (e: React.MouseEvent, action: 'view' | 'archive' | 'unarchive' | 'delete') => {\r\n e.stopPropagation();\r\n switch (action) {\r\n case 'view':\r\n onClick?.(team.name);\r\n break;\r\n case 'archive':\r\n onArchive?.(team.name);\r\n break;\r\n case 'unarchive':\r\n onUnarchive?.(team.name);\r\n break;\r\n case 'delete':\r\n onDelete?.(team.name);\r\n break;\r\n }\r\n };\r\n\r\n return (\r\n <Card\r\n className={cn(\r\n 'group cursor-pointer transition-all duration-200 hover:shadow-md hover:border-primary/30',\r\n className\r\n )}\r\n onClick={handleCardClick}\r\n >\r\n <CardContent className=\"p-4\">\r\n {/* Header: team name + status + actions */}\r\n <div className=\"flex items-start justify-between gap-2 mb-2\">\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2 mb-1\">\r\n <h3 className=\"font-bold text-card-foreground text-sm tracking-wide truncate\">\r\n {team.name}\r\n </h3>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2 flex-shrink-0\">\r\n <Badge variant={statusVariant}>{statusLabel}</Badge>\r\n {team.pipeline_mode && (\r\n <Badge variant=\"default\" className=\"gap-1\">\r\n <GitBranch className=\"h-3 w-3\" />\r\n {team.pipeline_mode}\r\n </Badge>\r\n )}\r\n {showActions && (\r\n <DropdownMenu>\r\n <DropdownMenuTrigger asChild>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"h-8 w-8 opacity-0 group-hover:opacity-100 transition-opacity\"\r\n onClick={(e) => e.stopPropagation()}\r\n disabled={actionsDisabled}\r\n >\r\n <MoreVertical className=\"h-4 w-4\" />\r\n </Button>\r\n </DropdownMenuTrigger>\r\n <DropdownMenuContent align=\"end\">\r\n <DropdownMenuItem onClick={(e) => handleAction(e, 'view')}>\r\n <Eye className=\"mr-2 h-4 w-4\" />\r\n {formatMessage({ id: 'team.actions.viewDetails' })}\r\n </DropdownMenuItem>\r\n <DropdownMenuSeparator />\r\n {isArchived ? (\r\n <DropdownMenuItem onClick={(e) => handleAction(e, 'unarchive')}>\r\n <ArchiveRestore className=\"mr-2 h-4 w-4\" />\r\n {formatMessage({ id: 'team.actions.unarchive' })}\r\n </DropdownMenuItem>\r\n ) : (\r\n <DropdownMenuItem onClick={(e) => handleAction(e, 'archive')}>\r\n <Archive className=\"mr-2 h-4 w-4\" />\r\n {formatMessage({ id: 'team.actions.archive' })}\r\n </DropdownMenuItem>\r\n )}\r\n <DropdownMenuSeparator />\r\n <DropdownMenuItem\r\n onClick={(e) => handleAction(e, 'delete')}\r\n className=\"text-destructive focus:text-destructive\"\r\n >\r\n <Trash2 className=\"mr-2 h-4 w-4\" />\r\n {formatMessage({ id: 'team.actions.delete' })}\r\n </DropdownMenuItem>\r\n </DropdownMenuContent>\r\n </DropdownMenu>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Meta info row */}\r\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-muted-foreground\">\r\n <span className=\"flex items-center gap-1\">\r\n <MessageSquare className=\"h-3.5 w-3.5\" />\r\n {team.messageCount} {formatMessage({ id: 'team.card.messages' })}\r\n </span>\r\n {team.lastActivity && (\r\n <span className=\"flex items-center gap-1\">\r\n <Clock className=\"h-3.5 w-3.5\" />\r\n {formatDate(team.lastActivity)}\r\n </span>\r\n )}\r\n </div>\r\n\r\n {/* Members row */}\r\n {team.members && team.members.length > 0 && (\r\n <div className=\"flex items-center gap-1.5 mt-2 flex-wrap\">\r\n <Users className=\"h-3.5 w-3.5 text-muted-foreground shrink-0\" />\r\n {team.members.map((name) => (\r\n <Badge key={name} variant=\"outline\" className=\"text-[10px] px-1.5 py-0 font-normal\">\r\n {name}\r\n </Badge>\r\n ))}\r\n </div>\r\n )}\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n\r\n/**\r\n * Skeleton loader for TeamCard\r\n */\r\nexport function TeamCardSkeleton({ 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-5 w-32 rounded bg-muted\" />\r\n </div>\r\n <div className=\"h-5 w-16 rounded-full bg-muted\" />\r\n </div>\r\n <div className=\"mt-3 flex gap-4\">\r\n <div className=\"h-4 w-24 rounded bg-muted\" />\r\n <div className=\"h-4 w-20 rounded bg-muted\" />\r\n <div className=\"h-4 w-20 rounded bg-muted\" />\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n","// ========================================\r\n// TeamListView Component\r\n// ========================================\r\n// Team card grid with tabs, search, and actions\r\n\r\nimport * as React from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n RefreshCw,\r\n Search,\r\n Users,\r\n X,\r\n} from 'lucide-react';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { TabsNavigation } from '@/components/ui/TabsNavigation';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogDescription,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport { cn } from '@/lib/utils';\r\nimport { TeamCard, TeamCardSkeleton } from './TeamCard';\r\nimport { useTeamStore } from '@/stores/teamStore';\r\nimport { useTeams, useArchiveTeam, useUnarchiveTeam, useDeleteTeam } from '@/hooks/useTeamData';\r\n\r\nexport function TeamListView() {\r\n const { formatMessage } = useIntl();\r\n const {\r\n locationFilter,\r\n setLocationFilter,\r\n searchQuery,\r\n setSearchQuery,\r\n selectTeamAndShowDetail,\r\n } = useTeamStore();\r\n\r\n // Dialog state\r\n const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false);\r\n const [teamToDelete, setTeamToDelete] = React.useState<string | null>(null);\r\n\r\n // Data\r\n const { teams, isLoading, isFetching, refetch } = useTeams(locationFilter);\r\n const { archiveTeam, isArchiving } = useArchiveTeam();\r\n const { unarchiveTeam, isUnarchiving } = useUnarchiveTeam();\r\n const { deleteTeam, isDeleting } = useDeleteTeam();\r\n\r\n const isMutating = isArchiving || isUnarchiving || isDeleting;\r\n\r\n // Client-side search filter\r\n const filteredTeams = React.useMemo(() => {\r\n if (!searchQuery) return teams;\r\n const q = searchQuery.toLowerCase();\r\n return teams.filter((t) => t.name.toLowerCase().includes(q));\r\n }, [teams, searchQuery]);\r\n\r\n // Handlers\r\n const handleArchive = async (name: string) => {\r\n try {\r\n await archiveTeam(name);\r\n } catch (err) {\r\n console.error('Failed to archive team:', err);\r\n }\r\n };\r\n\r\n const handleUnarchive = async (name: string) => {\r\n try {\r\n await unarchiveTeam(name);\r\n } catch (err) {\r\n console.error('Failed to unarchive team:', err);\r\n }\r\n };\r\n\r\n const handleDeleteClick = (name: string) => {\r\n setTeamToDelete(name);\r\n setDeleteDialogOpen(true);\r\n };\r\n\r\n const handleConfirmDelete = async () => {\r\n if (!teamToDelete) return;\r\n try {\r\n await deleteTeam(teamToDelete);\r\n setDeleteDialogOpen(false);\r\n setTeamToDelete(null);\r\n } catch (err) {\r\n console.error('Failed to delete team:', err);\r\n }\r\n };\r\n\r\n const handleClearSearch = () => setSearchQuery('');\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Header */}\r\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\r\n <div>\r\n <div className=\"flex items-center gap-2\">\r\n <Users className=\"w-5 h-5\" />\r\n <h1 className=\"text-2xl font-semibold text-foreground\">\r\n {formatMessage({ id: 'team.title' })}\r\n </h1>\r\n </div>\r\n <p className=\"text-sm text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'team.description' })}\r\n </p>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => refetch()}\r\n disabled={isFetching}\r\n >\r\n <RefreshCw className={cn('h-4 w-4 mr-2', isFetching && 'animate-spin')} />\r\n {formatMessage({ id: 'common.actions.refresh' })}\r\n </Button>\r\n </div>\r\n </div>\r\n\r\n {/* Filters */}\r\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center\">\r\n {/* Location tabs */}\r\n <TabsNavigation\r\n value={locationFilter}\r\n onValueChange={(v) => setLocationFilter(v as 'active' | 'archived' | 'all')}\r\n tabs={[\r\n { value: 'active', label: formatMessage({ id: 'team.filters.active' }) },\r\n { value: 'archived', label: formatMessage({ id: 'team.filters.archived' }) },\r\n { value: 'all', label: formatMessage({ id: 'team.filters.all' }) },\r\n ]}\r\n />\r\n\r\n {/* Search input */}\r\n <div className=\"flex-1 max-w-sm relative\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground\" />\r\n <Input\r\n placeholder={formatMessage({ id: 'team.searchPlaceholder' })}\r\n value={searchQuery}\r\n onChange={(e) => setSearchQuery(e.target.value)}\r\n className=\"pl-9 pr-9\"\r\n />\r\n {searchQuery && (\r\n <button\r\n onClick={handleClearSearch}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground\"\r\n >\r\n <X className=\"h-4 w-4\" />\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Team grid */}\r\n {isLoading ? (\r\n <div className=\"grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3\">\r\n {Array.from({ length: 6 }).map((_, i) => (\r\n <TeamCardSkeleton key={i} />\r\n ))}\r\n </div>\r\n ) : filteredTeams.length === 0 ? (\r\n <div className=\"flex flex-col items-center justify-center py-16 px-4 border border-dashed border-border rounded-lg\">\r\n <Users className=\"h-12 w-12 text-muted-foreground mb-4\" />\r\n <h3 className=\"text-lg font-medium text-foreground mb-1\">\r\n {searchQuery\r\n ? formatMessage({ id: 'team.emptyState.noMatching' })\r\n : formatMessage({ id: 'team.emptyState.noTeams' })}\r\n </h3>\r\n <p className=\"text-sm text-muted-foreground text-center max-w-sm mb-4\">\r\n {searchQuery\r\n ? formatMessage({ id: 'team.emptyState.noMatchingDescription' })\r\n : formatMessage({ id: 'team.emptyState.noTeamsDescription' })}\r\n </p>\r\n {searchQuery && (\r\n <Button variant=\"outline\" onClick={handleClearSearch}>\r\n {formatMessage({ id: 'common.actions.clearFilters' })}\r\n </Button>\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3\">\r\n {filteredTeams.map((team) => (\r\n <TeamCard\r\n key={team.name}\r\n team={team}\r\n onClick={selectTeamAndShowDetail}\r\n onArchive={handleArchive}\r\n onUnarchive={handleUnarchive}\r\n onDelete={handleDeleteClick}\r\n actionsDisabled={isMutating}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Delete Confirmation Dialog */}\r\n <Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>\r\n <DialogContent>\r\n <DialogHeader>\r\n <DialogTitle>{formatMessage({ id: 'team.dialog.deleteTeam' })}</DialogTitle>\r\n <DialogDescription>\r\n {formatMessage({ id: 'team.dialog.deleteConfirm' })}\r\n </DialogDescription>\r\n </DialogHeader>\r\n <DialogFooter>\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => {\r\n setDeleteDialogOpen(false);\r\n setTeamToDelete(null);\r\n }}\r\n >\r\n {formatMessage({ id: 'team.dialog.cancel' })}\r\n </Button>\r\n <Button\r\n variant=\"destructive\"\r\n onClick={handleConfirmDelete}\r\n disabled={isDeleting}\r\n >\r\n {isDeleting\r\n ? formatMessage({ id: 'team.dialog.deleting' })\r\n : formatMessage({ id: 'team.actions.delete' })}\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n </div>\r\n );\r\n}\r\n","import type { TeamMessage, DynamicStage, DynamicStageStatus, PhaseInfo } from '@/types/team';\r\n\r\nconst LEGACY_STAGES = ['plan', 'impl', 'test', 'review'] as const;\r\n\r\n/**\r\n * Capitalize first letter, lowercase rest.\r\n * \"SCAN\" -> \"Scan\", \"review\" -> \"Review\"\r\n */\r\nexport function formatStageLabel(stageId: string): string {\r\n if (!stageId) return '';\r\n return stageId.charAt(0).toUpperCase() + stageId.slice(1).toLowerCase();\r\n}\r\n\r\n/**\r\n * Derive the status of a pipeline stage from the message history.\r\n *\r\n * Matches messages whose `from` field equals or starts with `roleOrStage`\r\n * (case-insensitive). The status is determined by the LAST matching message's type.\r\n */\r\nexport function deriveStageStatus(\r\n roleOrStage: string,\r\n messages: TeamMessage[],\r\n): DynamicStageStatus {\r\n const needle = roleOrStage.toLowerCase();\r\n const matching = messages.filter((m) => {\r\n const from = m.from.toLowerCase();\r\n return from === needle || from.startsWith(needle);\r\n });\r\n\r\n if (matching.length === 0) return 'pending';\r\n\r\n const last = matching[matching.length - 1];\r\n const completionTypes: string[] = ['shutdown', 'impl_complete', 'review_result', 'test_result'];\r\n\r\n if (completionTypes.includes(last.type)) return 'completed';\r\n if (last.type === 'error') return 'blocked';\r\n return 'in_progress';\r\n}\r\n\r\n/**\r\n * Four-tier pipeline stage detection.\r\n *\r\n * Tier 1 - explicit `pipeline_stages` from meta\r\n * Tier 2 - explicit `roles` list from meta (excluding coordinator)\r\n * Tier 3 - inferred from message senders (excluding \"coordinator\")\r\n * Tier 4 - legacy 4-stage fallback\r\n */\r\nexport function derivePipelineStages(\r\n meta: {\r\n pipeline_stages?: string[];\r\n role_state?: Record<string, Record<string, unknown>>;\r\n roles?: string[];\r\n },\r\n messages: TeamMessage[],\r\n): DynamicStage[] {\r\n // Tier 1: explicit pipeline_stages\r\n if (meta.pipeline_stages && meta.pipeline_stages.length > 0) {\r\n return meta.pipeline_stages.map((stage) => {\r\n const id = stage.toUpperCase();\r\n const lowerStage = stage.toLowerCase();\r\n const role = meta.roles?.find((r) => r.toLowerCase().startsWith(lowerStage));\r\n return {\r\n id,\r\n label: formatStageLabel(stage),\r\n role,\r\n status: deriveStageStatus(stage, messages),\r\n };\r\n });\r\n }\r\n\r\n // Tier 2: explicit roles list from meta (authoritative source from coordinator)\r\n if (meta.roles && meta.roles.length > 0) {\r\n const workerRoles = meta.roles.filter((r) => r.toLowerCase() !== 'coordinator');\r\n if (workerRoles.length > 0) {\r\n return workerRoles.map((role) => ({\r\n id: role.toUpperCase(),\r\n label: formatStageLabel(role),\r\n role,\r\n status: deriveStageStatus(role, messages),\r\n }));\r\n }\r\n }\r\n\r\n // Tier 3: extract from message senders\r\n if (messages.length > 0) {\r\n const seen = new Map<string, string>(); // lowercase sender -> original sender\r\n for (const msg of messages) {\r\n const sender = msg.from;\r\n if (sender.toLowerCase() === 'coordinator') continue;\r\n const key = sender.toLowerCase();\r\n if (!seen.has(key)) {\r\n seen.set(key, sender);\r\n }\r\n }\r\n\r\n if (seen.size > 0) {\r\n return Array.from(seen.entries()).map(([, sender]) => ({\r\n id: sender.toUpperCase(),\r\n label: formatStageLabel(sender),\r\n role: sender,\r\n status: deriveStageStatus(sender, messages),\r\n }));\r\n }\r\n }\r\n\r\n // Tier 4: legacy fallback\r\n return LEGACY_STAGES.map((stage) => ({\r\n id: stage.toUpperCase(),\r\n label: formatStageLabel(stage),\r\n role: undefined,\r\n status: deriveStageStatus(stage, messages),\r\n }));\r\n}\r\n\r\n/**\r\n * Detect multi-phase execution from coordinator role state.\r\n * Returns PhaseInfo when the coordinator reports `current_phase`, otherwise null.\r\n */\r\nexport function detectMultiPhase(\r\n roleState?: Record<string, Record<string, unknown>>,\r\n): PhaseInfo | null {\r\n if (!roleState || Object.keys(roleState).length === 0) return null;\r\n\r\n const coordinator = roleState['coordinator'];\r\n if (!coordinator || typeof coordinator.current_phase !== 'number') return null;\r\n\r\n return {\r\n currentPhase: coordinator.current_phase as number,\r\n totalPhases: typeof coordinator.total_phases === 'number' ? coordinator.total_phases : null,\r\n currentStep: typeof coordinator.current_step === 'string' ? coordinator.current_step : null,\r\n gapIteration: typeof coordinator.gap_iteration === 'number' ? coordinator.gap_iteration : 0,\r\n };\r\n}\r\n","// ========================================\r\n// TeamPage\r\n// ========================================\r\n// Main page for team execution - list/detail dual view with tabbed detail\r\n\r\nimport { useMemo, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { Package, MessageSquare, Maximize2, Minimize2, GitBranch, AlertTriangle } from 'lucide-react';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { cn } from '@/lib/utils';\r\nimport { useAppStore, selectIsImmersiveMode } from '@/stores/appStore';\r\nimport { TabsNavigation, type TabItem } from '@/components/ui/TabsNavigation';\r\nimport { useTeamStore } from '@/stores/teamStore';\r\nimport type { TeamDetailTab } from '@/stores/teamStore';\r\nimport { useTeams, useTeamMessages, useTeamStatus } from '@/hooks/useTeamData';\r\nimport { TeamHeader } from '@/components/team/TeamHeader';\r\nimport { DynamicPipeline } from '@/components/team/DynamicPipeline';\r\nimport { TeamRolePanel } from '@/components/team/TeamRolePanel';\r\nimport { SessionCoordinates } from '@/components/team/SessionCoordinates';\r\nimport { TeamMessageFeed } from '@/components/team/TeamMessageFeed';\r\nimport { TeamArtifacts } from '@/components/team/TeamArtifacts';\r\nimport { TeamListView } from '@/components/team/TeamListView';\r\nimport { derivePipelineStages, detectMultiPhase } from '@/lib/pipeline-utils';\r\n\r\nexport function TeamPage() {\r\n const { formatMessage } = useIntl();\r\n const {\r\n selectedTeam,\r\n viewMode,\r\n autoRefresh,\r\n toggleAutoRefresh,\r\n messageFilter,\r\n setMessageFilter,\r\n clearMessageFilter,\r\n timelineExpanded,\r\n setTimelineExpanded,\r\n detailTab,\r\n setDetailTab,\r\n backToList,\r\n locationFilter,\r\n } = useTeamStore();\r\n const isImmersiveMode = useAppStore(selectIsImmersiveMode);\r\n const toggleImmersiveMode = useAppStore((s) => s.toggleImmersiveMode);\r\n\r\n // Data hooks\r\n const { teams, error: teamsError, isLoading: teamsLoading } = useTeams(locationFilter);\r\n const { messages, total: messageTotal } = useTeamMessages(\r\n viewMode === 'detail' ? selectedTeam : null,\r\n messageFilter\r\n );\r\n const { members, totalMessages } = useTeamStatus(\r\n viewMode === 'detail' ? selectedTeam : null\r\n );\r\n\r\n // Find enriched team data from list response\r\n const teamData = useMemo(\r\n () => teams.find((t) => t.name === selectedTeam),\r\n [teams, selectedTeam]\r\n );\r\n\r\n // Auto-reset to list view when in detail mode but team data is missing after loading\r\n useEffect(() => {\r\n if (viewMode === 'detail' && selectedTeam && !teamsLoading && teams.length > 0 && !teamData) {\r\n // Team no longer exists or is filtered out, return to list\r\n backToList();\r\n }\r\n }, [viewMode, selectedTeam, teamsLoading, teams.length, teamData, backToList]);\r\n\r\n // Derive dynamic pipeline stages and multi-phase info\r\n const stages = useMemo(\r\n () =>\r\n derivePipelineStages(\r\n {\r\n pipeline_stages: teamData?.pipeline_stages,\r\n role_state: teamData?.role_state,\r\n roles: teamData?.roles,\r\n },\r\n messages\r\n ),\r\n [teamData?.pipeline_stages, teamData?.role_state, teamData?.roles, messages]\r\n );\r\n\r\n const phaseInfo = useMemo(\r\n () => detectMultiPhase(teamData?.role_state),\r\n [teamData?.role_state]\r\n );\r\n\r\n // Error state - show error page with back button when API fails\r\n if (teamsError && viewMode === 'detail') {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px] p-8\">\r\n <div className=\"text-center max-w-md\">\r\n <div className=\"mb-4\">\r\n <AlertTriangle className=\"w-16 h-16 mx-auto text-destructive\" />\r\n </div>\r\n <h2 className=\"text-xl font-semibold mb-2\">\r\n {formatMessage({ id: 'team.error.loadFailed' })}\r\n </h2>\r\n <p className=\"text-muted-foreground mb-6\">\r\n {teamsError instanceof Error ? teamsError.message : String(teamsError)}\r\n </p>\r\n <div className=\"flex gap-3 justify-center\">\r\n <Button onClick={backToList} variant=\"default\">\r\n {formatMessage({ id: 'team.detail.backToList' })}\r\n </Button>\r\n <Button\r\n onClick={() => window.location.reload()}\r\n variant=\"outline\"\r\n >\r\n {formatMessage({ id: 'common.actions.retry' })}\r\n </Button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // List view (also fallback when selected team data is not available)\r\n if (viewMode === 'list' || !selectedTeam || (viewMode === 'detail' && teams.length > 0 && !teamData)) {\r\n return (\r\n <div className=\"space-y-6\">\r\n <TeamListView />\r\n </div>\r\n );\r\n }\r\n\r\n const tabs: TabItem[] = [\r\n {\r\n value: 'pipeline',\r\n label: formatMessage({ id: 'team.tabs.pipeline' }),\r\n icon: <GitBranch className=\"h-4 w-4\" />,\r\n },\r\n {\r\n value: 'artifacts',\r\n label: formatMessage({ id: 'team.tabs.artifacts' }),\r\n icon: <Package className=\"h-4 w-4\" />,\r\n },\r\n {\r\n value: 'messages',\r\n label: formatMessage({ id: 'team.tabs.messages' }),\r\n icon: <MessageSquare className=\"h-4 w-4\" />,\r\n },\r\n ];\r\n\r\n // Detail view\r\n return (\r\n <div className={cn(\"space-y-6\", isImmersiveMode && \"h-screen overflow-hidden\")}>\r\n {/* Detail Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <TeamHeader\r\n selectedTeam={selectedTeam}\r\n onBack={backToList}\r\n members={members}\r\n totalMessages={totalMessages}\r\n autoRefresh={autoRefresh}\r\n onToggleAutoRefresh={toggleAutoRefresh}\r\n skillType={teamData?.team_name ? `team-${teamData.team_name}` : undefined}\r\n pipelineMode={teamData?.pipeline_mode}\r\n />\r\n <button\r\n onClick={toggleImmersiveMode}\r\n className={cn(\r\n 'p-2 rounded-md transition-colors',\r\n isImmersiveMode\r\n ? 'bg-primary/10 text-primary'\r\n : 'text-muted-foreground hover:text-foreground hover:bg-muted'\r\n )}\r\n title={isImmersiveMode ? 'Exit Fullscreen' : 'Fullscreen'}\r\n >\r\n {isImmersiveMode ? <Minimize2 className=\"w-4 h-4\" /> : <Maximize2 className=\"w-4 h-4\" />}\r\n </button>\r\n </div>\r\n\r\n {/* Overview: DynamicPipeline + TeamRolePanel */}\r\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\r\n <Card className=\"lg:col-span-2 flex flex-col\">\r\n <CardContent className=\"p-4 flex-1\">\r\n <DynamicPipeline stages={stages} phaseInfo={phaseInfo} />\r\n </CardContent>\r\n </Card>\r\n <Card>\r\n <CardContent className=\"p-4\">\r\n <TeamRolePanel\r\n members={members}\r\n stages={stages}\r\n roleState={teamData?.role_state}\r\n />\r\n </CardContent>\r\n </Card>\r\n </div>\r\n\r\n {/* Session Coordinates (only for multi-phase sessions) */}\r\n {phaseInfo && (\r\n <SessionCoordinates phaseInfo={phaseInfo} />\r\n )}\r\n\r\n {/* Tab Navigation */}\r\n <TabsNavigation\r\n value={detailTab}\r\n onValueChange={(v) => setDetailTab(v as TeamDetailTab)}\r\n tabs={tabs}\r\n />\r\n\r\n {/* Pipeline Tab - shows role details */}\r\n {detailTab === 'pipeline' && (\r\n <Card>\r\n <CardContent className=\"p-6\">\r\n <TeamRolePanel\r\n members={members}\r\n stages={stages}\r\n roleState={teamData?.role_state}\r\n />\r\n </CardContent>\r\n </Card>\r\n )}\r\n\r\n {/* Artifacts Tab */}\r\n {detailTab === 'artifacts' && (\r\n <TeamArtifacts teamName={selectedTeam} />\r\n )}\r\n\r\n {/* Messages Tab */}\r\n {detailTab === 'messages' && (\r\n <TeamMessageFeed\r\n messages={messages}\r\n total={messageTotal}\r\n filter={messageFilter}\r\n onFilterChange={setMessageFilter}\r\n onClearFilter={clearMessageFilter}\r\n expanded={timelineExpanded}\r\n onExpandedChange={setTimelineExpanded}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default TeamPage;\r\n"],"names":["useTeamStore","create","devtools","persist","set","name","s","filter","expanded","mode","query","tab","teamKeys","location","team","useTeams","autoRefresh","effectiveLocation","useQuery","fetchTeams","_a","useTeamMessages","teamName","options","data","fetchTeamMessages","_b","useTeamStatus","fetchTeamStatus","useArchiveTeam","queryClient","useQueryClient","mutation","useMutation","archiveTeam","useUnarchiveTeam","unarchiveTeam","useDeleteTeam","deleteTeam","TeamHeader","selectedTeam","onBack","members","totalMessages","onToggleAutoRefresh","skillType","pipelineMode","formatMessage","useIntl","jsxs","Button","jsx","ArrowLeft","Fragment","Badge","Users","MessageSquare","GitBranch","Switch","Label","RefreshCw","statusConfig","CheckCircle2","Loader2","Circle","Ban","SkipForward","LEGEND_STATUSES","StageNode","stage","config","Icon","statusKey","cn","Arrow","DynamicPipeline","stages","phaseInfo","idx","cfg","formatRelativeTime","isoString","now","then","diffMs","seconds","minutes","hours","getMemberStatus","member","TeamMembersPanel","m","status","isActive","Card","CardContent","findMatchingStage","memberLower","stageBadgeVariant","TeamRolePanel","_roleState","matchedStage","SessionCoordinates","typeColorMap","MessageTypeBadge","type","color","labelKey","label","MessageRow","msg","dataExpanded","setDataExpanded","useState","time","FileText","ChevronUp","ChevronDown","TeamMessageFeed","messages","total","onFilterChange","onClearFilter","onExpandedChange","hasFilter","senders","receivers","types","useMemo","r","t","displayMessages","X","Select","v","SelectTrigger","Filter","SelectValue","SelectContent","SelectItem","getContentTypeFromPath","path","formatSize","bytes","formatDate","ts","FileIcon","contentType","FileJson","TreeNode","node","depth","selectedPath","onToggle","onSelect","isExpanded","ChevronRight","Folder","child","isSelected","TeamArtifacts","tree","setTree","React.useState","setExpanded","selectedFile","setSelectedFile","content","setContent","loading","setLoading","treeLoading","setTreeLoading","error","setError","React.useEffect","fetchTeamArtifacts","firstLevelDirs","n","err","handleToggle","React.useCallback","prev","next","handleSelect","result","fetchArtifactContent","previewContentType","modalContentType","Package","PreviewContent","JsonCardViewer","item","index","entries","key","value","isExpandable","isArray","itemCount","JsonSummaryCard","stats","React.useMemo","analyze","obj","currentDepth","val","parsed","statusVariantConfig","statusLabelKeys","dateString","TeamCard","onClick","onArchive","onUnarchive","onDelete","showActions","actionsDisabled","className","statusVariant","statusLabel","isArchived","handleCardClick","e","handleAction","action","DropdownMenu","DropdownMenuTrigger","MoreVertical","DropdownMenuContent","DropdownMenuItem","Eye","DropdownMenuSeparator","ArchiveRestore","Archive","Trash2","Clock","TeamCardSkeleton","TeamListView","locationFilter","setLocationFilter","searchQuery","setSearchQuery","selectTeamAndShowDetail","deleteDialogOpen","setDeleteDialogOpen","teamToDelete","setTeamToDelete","teams","isLoading","isFetching","refetch","isArchiving","isUnarchiving","isDeleting","isMutating","filteredTeams","q","handleArchive","handleUnarchive","handleDeleteClick","handleConfirmDelete","handleClearSearch","TabsNavigation","Search","Input","_","i","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","DialogFooter","LEGACY_STAGES","formatStageLabel","stageId","deriveStageStatus","roleOrStage","needle","matching","from","last","derivePipelineStages","meta","id","lowerStage","role","workerRoles","seen","sender","detectMultiPhase","roleState","coordinator","TeamPage","viewMode","toggleAutoRefresh","messageFilter","setMessageFilter","clearMessageFilter","timelineExpanded","setTimelineExpanded","detailTab","setDetailTab","backToList","isImmersiveMode","useAppStore","selectIsImmersiveMode","toggleImmersiveMode","teamsError","teamsLoading","messageTotal","teamData","useEffect","AlertTriangle","tabs","Minimize2","Maximize2"],"mappings":"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"}