claude-code-workflow 7.2.10 → 7.2.11

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 (322) hide show
  1. package/.claude/agents/cli-planning-agent.md +3 -0
  2. package/.claude/agents/debug-explore-agent.md +1 -0
  3. package/.claude/agents/tdd-developer.md +1 -0
  4. package/.claude/agents/team-worker.md +1 -1
  5. package/.claude/agents/test-action-planning-agent.md +3 -0
  6. package/.claude/agents/test-context-search-agent.md +1 -0
  7. package/.claude/agents/test-fix-agent.md +3 -0
  8. package/.claude/skills/review-code/SKILL.md +2 -0
  9. package/.claude/skills/review-cycle/SKILL.md +4 -0
  10. package/.claude/skills/skill-simplify/phases/02-optimize.md +4 -0
  11. package/.claude/skills/spec-generator/phases/05-epics-stories.md +4 -0
  12. package/.claude/skills/team-arch-opt/specs/team-config.json +5 -5
  13. package/.claude/skills/team-frontend-debug/roles/analyzer/role.md +3 -2
  14. package/.claude/skills/team-perf-opt/roles/coordinator/commands/monitor.md +1 -1
  15. package/.claude/skills/team-perf-opt/specs/team-config.json +5 -5
  16. package/.claude/skills/team-quality-assurance/roles/executor/role.md +2 -1
  17. package/.claude/skills/team-review/roles/reviewer/role.md +2 -1
  18. package/.claude/skills/team-tech-debt/roles/scanner/role.md +2 -1
  19. package/.claude/skills/team-testing/roles/executor/role.md +2 -1
  20. package/.claude/skills/team-testing/roles/generator/role.md +2 -1
  21. package/.claude/skills/team-ultra-analyze/roles/explorer/role.md +2 -1
  22. package/.claude/skills/team-ux-improve/specs/team-config.json +6 -6
  23. package/.claude/skills/workflow-execute/phases/06-review.md +4 -4
  24. package/.claude/skills/workflow-lite-test-review/SKILL.md +2 -0
  25. package/.claude/skills/workflow-plan/phases/05-plan-verify.md +4 -0
  26. package/.claude/skills/workflow-tdd-plan/phases/02-context-gathering.md +1 -0
  27. package/.claude/skills/workflow-tdd-plan/phases/05-tdd-task-generation.md +2 -1
  28. package/.claude/skills/workflow-test-fix/phases/02-test-context-gather.md +1 -0
  29. package/.claude/skills/workflow-test-fix/phases/05-test-cycle-execute.md +2 -1
  30. package/.claude/skills/workflow-tune/SKILL.md +487 -0
  31. package/.claude/skills/workflow-tune/phases/01-setup.md +548 -0
  32. package/.claude/skills/workflow-tune/phases/02-step-execute.md +197 -0
  33. package/.claude/skills/workflow-tune/phases/03-step-analyze.md +386 -0
  34. package/.claude/skills/workflow-tune/phases/04-synthesize.md +257 -0
  35. package/.claude/skills/workflow-tune/phases/05-optimize-report.md +246 -0
  36. package/.claude/skills/workflow-tune/specs/workflow-eval-criteria.md +57 -0
  37. package/.claude/skills/workflow-tune/templates/step-analysis-prompt.md +88 -0
  38. package/.claude/skills/workflow-tune/templates/synthesis-prompt.md +90 -0
  39. package/.codex/skills/analyze-with-file/SKILL.md +2 -0
  40. package/.codex/skills/debug-with-file/SKILL.md +4 -0
  41. package/.codex/skills/issue-discover/SKILL.md +1 -0
  42. package/.codex/skills/review-cycle/phases/02-parallel-review.md +3 -0
  43. package/.codex/skills/team-designer/agents/validation-reporter.md +186 -0
  44. package/.codex/skills/team-iterdev/agents/gc-controller.md +193 -0
  45. package/.codex/skills/team-iterdev/agents/task-analyzer.md +206 -0
  46. package/.codex/skills/team-lifecycle-v4/agents/quality-gate.md +165 -0
  47. package/.codex/skills/team-lifecycle-v4/agents/requirement-clarifier.md +163 -0
  48. package/.codex/skills/team-lifecycle-v4/agents/supervisor.md +182 -0
  49. package/.codex/skills/team-uidesign/agents/completion-handler.md +177 -0
  50. package/.codex/skills/team-uidesign/agents/gc-loop-handler.md +162 -0
  51. package/.codex/skills/workflow-test-fix-cycle/phases/01-test-fix-gen.md +4 -0
  52. package/.codex/skills/workflow-test-fix-cycle/phases/02-test-cycle-execute.md +2 -0
  53. package/ccw/dist/commands/spec.d.ts.map +1 -1
  54. package/ccw/dist/commands/spec.js +9 -4
  55. package/ccw/dist/commands/spec.js.map +1 -1
  56. package/ccw/dist/core/routes/codexlens-routes.d.ts.map +1 -1
  57. package/ccw/dist/core/routes/codexlens-routes.js +3 -1
  58. package/ccw/dist/core/routes/codexlens-routes.js.map +1 -1
  59. package/ccw/dist/tools/spec-index-builder.d.ts +8 -4
  60. package/ccw/dist/tools/spec-index-builder.d.ts.map +1 -1
  61. package/ccw/dist/tools/spec-index-builder.js +8 -4
  62. package/ccw/dist/tools/spec-index-builder.js.map +1 -1
  63. package/ccw/dist/tools/spec-init.d.ts +1 -1
  64. package/ccw/dist/tools/spec-init.d.ts.map +1 -1
  65. package/ccw/dist/tools/spec-init.js +127 -0
  66. package/ccw/dist/tools/spec-init.js.map +1 -1
  67. package/ccw/dist/tools/spec-loader.d.ts.map +1 -1
  68. package/ccw/dist/tools/spec-loader.js +2 -1
  69. package/ccw/dist/tools/spec-loader.js.map +1 -1
  70. package/ccw/frontend/dist/assets/{AlertDialog-gTMl4gSG.js → AlertDialog-BW9jiZ-p.js} +2 -2
  71. package/ccw/frontend/dist/assets/{AlertDialog-gTMl4gSG.js.map → AlertDialog-BW9jiZ-p.js.map} +1 -1
  72. package/ccw/frontend/dist/assets/{AnalysisPage-Bc4p4SvJ.js → AnalysisPage-ds-w_nVO.js} +2 -2
  73. package/ccw/frontend/dist/assets/{AnalysisPage-Bc4p4SvJ.js.map → AnalysisPage-ds-w_nVO.js.map} +1 -1
  74. package/ccw/frontend/dist/assets/{ApiSettingsPage-CVK108u2.js → ApiSettingsPage-DlCbXxTz.js} +2 -2
  75. package/ccw/frontend/dist/assets/{ApiSettingsPage-CVK108u2.js.map → ApiSettingsPage-DlCbXxTz.js.map} +1 -1
  76. package/ccw/frontend/dist/assets/{CliModeToggle-34Sjwl05.js → CliModeToggle-Dq3nL4fF.js} +2 -2
  77. package/ccw/frontend/dist/assets/{CliModeToggle-34Sjwl05.js.map → CliModeToggle-Dq3nL4fF.js.map} +1 -1
  78. package/ccw/frontend/dist/assets/{CliSessionSharePage-bJZAYI38.js → CliSessionSharePage-BNDkEE4u.js} +2 -2
  79. package/ccw/frontend/dist/assets/{CliSessionSharePage-bJZAYI38.js.map → CliSessionSharePage-BNDkEE4u.js.map} +1 -1
  80. package/ccw/frontend/dist/assets/{CliViewerPage-VYnQGjxU.js → CliViewerPage-ChM-uNx_.js} +2 -2
  81. package/ccw/frontend/dist/assets/{CliViewerPage-VYnQGjxU.js.map → CliViewerPage-ChM-uNx_.js.map} +1 -1
  82. package/ccw/frontend/dist/assets/CodexLensPage-DOcsYNQk.js +2 -0
  83. package/ccw/frontend/dist/assets/CodexLensPage-DOcsYNQk.js.map +1 -0
  84. package/ccw/frontend/dist/assets/{Collapsible-B_xd1Qbg.js → Collapsible-CRNbykXN.js} +2 -2
  85. package/ccw/frontend/dist/assets/{Collapsible-B_xd1Qbg.js.map → Collapsible-CRNbykXN.js.map} +1 -1
  86. package/ccw/frontend/dist/assets/{CommandsManagerPage-Bjx1bPbH.js → CommandsManagerPage-C2JWcemF.js} +2 -2
  87. package/ccw/frontend/dist/assets/{CommandsManagerPage-Bjx1bPbH.js.map → CommandsManagerPage-C2JWcemF.js.map} +1 -1
  88. package/ccw/frontend/dist/assets/{DeepWikiPage-EgHsHvAH.js → DeepWikiPage-CvleOtJy.js} +2 -2
  89. package/ccw/frontend/dist/assets/{DeepWikiPage-EgHsHvAH.js.map → DeepWikiPage-CvleOtJy.js.map} +1 -1
  90. package/ccw/frontend/dist/assets/{EndpointsPage-CuwpbCzK.js → EndpointsPage-CMOWQG64.js} +2 -2
  91. package/ccw/frontend/dist/assets/{EndpointsPage-CuwpbCzK.js.map → EndpointsPage-CMOWQG64.js.map} +1 -1
  92. package/ccw/frontend/dist/assets/{ExplorerPage-cvlx0Zw0.js → ExplorerPage-DaFPRlNo.js} +2 -2
  93. package/ccw/frontend/dist/assets/{ExplorerPage-cvlx0Zw0.js.map → ExplorerPage-DaFPRlNo.js.map} +1 -1
  94. package/ccw/frontend/dist/assets/{FixSessionPage-C74-MPza.js → FixSessionPage-CC4p04Az.js} +2 -2
  95. package/ccw/frontend/dist/assets/{FixSessionPage-C74-MPza.js.map → FixSessionPage-CC4p04Az.js.map} +1 -1
  96. package/ccw/frontend/dist/assets/{FloatingFileBrowser-x_-6y_n2.js → FloatingFileBrowser-DROn1xZ5.js} +2 -2
  97. package/ccw/frontend/dist/assets/{FloatingFileBrowser-x_-6y_n2.js.map → FloatingFileBrowser-DROn1xZ5.js.map} +1 -1
  98. package/ccw/frontend/dist/assets/{FloatingPanel-BGwmbJR1.js → FloatingPanel-CmL_yhDv.js} +2 -2
  99. package/ccw/frontend/dist/assets/{FloatingPanel-BGwmbJR1.js.map → FloatingPanel-CmL_yhDv.js.map} +1 -1
  100. package/ccw/frontend/dist/assets/{GraphExplorerPage-Bg5-aQxi.js → GraphExplorerPage-DCV5ybKE.js} +2 -2
  101. package/ccw/frontend/dist/assets/{GraphExplorerPage-Bg5-aQxi.js.map → GraphExplorerPage-DCV5ybKE.js.map} +1 -1
  102. package/ccw/frontend/dist/assets/{HistoryPage-C00fh0HE.js → HistoryPage-D0fYQZgc.js} +2 -2
  103. package/ccw/frontend/dist/assets/{HistoryPage-C00fh0HE.js.map → HistoryPage-D0fYQZgc.js.map} +1 -1
  104. package/ccw/frontend/dist/assets/{HookManagerPage-CtVTB_ae.js → HookManagerPage-D2FuJfsM.js} +2 -2
  105. package/ccw/frontend/dist/assets/{HookManagerPage-CtVTB_ae.js.map → HookManagerPage-D2FuJfsM.js.map} +1 -1
  106. package/ccw/frontend/dist/assets/{InstallationsPage-CYuMQDbC.js → InstallationsPage-tjklillZ.js} +2 -2
  107. package/ccw/frontend/dist/assets/{InstallationsPage-CYuMQDbC.js.map → InstallationsPage-tjklillZ.js.map} +1 -1
  108. package/ccw/frontend/dist/assets/{IssueHubPage-T_VSvUMh.js → IssueHubPage-E4JVrhO1.js} +2 -2
  109. package/ccw/frontend/dist/assets/{IssueHubPage-T_VSvUMh.js.map → IssueHubPage-E4JVrhO1.js.map} +1 -1
  110. package/ccw/frontend/dist/assets/{LiteTasksPage-DmcgvIvi.js → LiteTasksPage-aJuRoyLt.js} +2 -2
  111. package/ccw/frontend/dist/assets/{LiteTasksPage-DmcgvIvi.js.map → LiteTasksPage-aJuRoyLt.js.map} +1 -1
  112. package/ccw/frontend/dist/assets/{McpManagerPage-C_a7QSKz.js → McpManagerPage-BJeuWJv1.js} +2 -2
  113. package/ccw/frontend/dist/assets/{McpManagerPage-C_a7QSKz.js.map → McpManagerPage-BJeuWJv1.js.map} +1 -1
  114. package/ccw/frontend/dist/assets/{MemoryPage-CWKmXY5k.js → MemoryPage-BI4FAXhs.js} +2 -2
  115. package/ccw/frontend/dist/assets/{MemoryPage-CWKmXY5k.js.map → MemoryPage-BI4FAXhs.js.map} +1 -1
  116. package/ccw/frontend/dist/assets/{NotFoundPage-B1duXK6r.js → NotFoundPage-DD2svchp.js} +2 -2
  117. package/ccw/frontend/dist/assets/{NotFoundPage-B1duXK6r.js.map → NotFoundPage-DD2svchp.js.map} +1 -1
  118. package/ccw/frontend/dist/assets/{OrchestratorPage-Ib9TM6HE.js → OrchestratorPage-FC__7yYa.js} +2 -2
  119. package/ccw/frontend/dist/assets/{OrchestratorPage-Ib9TM6HE.js.map → OrchestratorPage-FC__7yYa.js.map} +1 -1
  120. package/ccw/frontend/dist/assets/{ProjectOverviewPage-sXSWMbF8.js → ProjectOverviewPage-DBB_-FzV.js} +2 -2
  121. package/ccw/frontend/dist/assets/{ProjectOverviewPage-sXSWMbF8.js.map → ProjectOverviewPage-DBB_-FzV.js.map} +1 -1
  122. package/ccw/frontend/dist/assets/{PromptHistoryPage-B6jaqG12.js → PromptHistoryPage-BwOAvCH8.js} +2 -2
  123. package/ccw/frontend/dist/assets/{PromptHistoryPage-B6jaqG12.js.map → PromptHistoryPage-BwOAvCH8.js.map} +1 -1
  124. package/ccw/frontend/dist/assets/{ReviewSessionPage-D5qJyr3s.js → ReviewSessionPage-Dd1-g_gp.js} +2 -2
  125. package/ccw/frontend/dist/assets/{ReviewSessionPage-D5qJyr3s.js.map → ReviewSessionPage-Dd1-g_gp.js.map} +1 -1
  126. package/ccw/frontend/dist/assets/{RulesManagerPage-DyawK8QE.js → RulesManagerPage-B3RGdsKD.js} +2 -2
  127. package/ccw/frontend/dist/assets/{RulesManagerPage-DyawK8QE.js.map → RulesManagerPage-B3RGdsKD.js.map} +1 -1
  128. package/ccw/frontend/dist/assets/{SessionDetailPage-Cym_RvC9.js → SessionDetailPage-DM-W5R8K.js} +2 -2
  129. package/ccw/frontend/dist/assets/{SessionDetailPage-Cym_RvC9.js.map → SessionDetailPage-DM-W5R8K.js.map} +1 -1
  130. package/ccw/frontend/dist/assets/{SessionsPage-Dkc1Hv8W.js → SessionsPage-BVz1KCc7.js} +2 -2
  131. package/ccw/frontend/dist/assets/{SessionsPage-Dkc1Hv8W.js.map → SessionsPage-BVz1KCc7.js.map} +1 -1
  132. package/ccw/frontend/dist/assets/{SettingsPage-Rik9cUIj.js → SettingsPage-ComW7EZS.js} +4 -4
  133. package/ccw/frontend/dist/assets/{SettingsPage-Rik9cUIj.js.map → SettingsPage-ComW7EZS.js.map} +1 -1
  134. package/ccw/frontend/dist/assets/{SkillsManagerPage-BGDWYAyI.js → SkillsManagerPage-CKom9XwV.js} +2 -2
  135. package/ccw/frontend/dist/assets/{SkillsManagerPage-BGDWYAyI.js.map → SkillsManagerPage-CKom9XwV.js.map} +1 -1
  136. package/ccw/frontend/dist/assets/{SpecsSettingsPage-CTiA1DMP.js → SpecsSettingsPage-DQz7WP2s.js} +2 -2
  137. package/ccw/frontend/dist/assets/{SpecsSettingsPage-CTiA1DMP.js.map → SpecsSettingsPage-DQz7WP2s.js.map} +1 -1
  138. package/ccw/frontend/dist/assets/{Switch-BgAFC-Wk.js → Switch-BPMdND9H.js} +2 -2
  139. package/ccw/frontend/dist/assets/{Switch-BgAFC-Wk.js.map → Switch-BPMdND9H.js.map} +1 -1
  140. package/ccw/frontend/dist/assets/{TabsNavigation-drSnu5jn.js → TabsNavigation-qqt70VYL.js} +2 -2
  141. package/ccw/frontend/dist/assets/{TabsNavigation-drSnu5jn.js.map → TabsNavigation-qqt70VYL.js.map} +1 -1
  142. package/ccw/frontend/dist/assets/{TaskDrawer-ePC__6-P.js → TaskDrawer-BqK_qiHX.js} +2 -2
  143. package/ccw/frontend/dist/assets/{TaskDrawer-ePC__6-P.js.map → TaskDrawer-BqK_qiHX.js.map} +1 -1
  144. package/ccw/frontend/dist/assets/{TeamPage-C6bdFWn8.js → TeamPage-u5_i0Rgh.js} +2 -2
  145. package/ccw/frontend/dist/assets/{TeamPage-C6bdFWn8.js.map → TeamPage-u5_i0Rgh.js.map} +1 -1
  146. package/ccw/frontend/dist/assets/{TerminalDashboardPage-Zofi_DZM.js → TerminalDashboardPage-rUtC9e40.js} +2 -2
  147. package/ccw/frontend/dist/assets/{TerminalDashboardPage-Zofi_DZM.js.map → TerminalDashboardPage-rUtC9e40.js.map} +1 -1
  148. package/ccw/frontend/dist/assets/{archive-Bza1KlB9.js → archive-C3u8YNQF.js} +2 -2
  149. package/ccw/frontend/dist/assets/{archive-Bza1KlB9.js.map → archive-C3u8YNQF.js.map} +1 -1
  150. package/ccw/frontend/dist/assets/{archive-restore-CpsDm-cG.js → archive-restore-DfQ998g5.js} +2 -2
  151. package/ccw/frontend/dist/assets/{archive-restore-CpsDm-cG.js.map → archive-restore-DfQ998g5.js.map} +1 -1
  152. package/ccw/frontend/dist/assets/{arrow-right-CibG_LVO.js → arrow-right-BshJM9Po.js} +2 -2
  153. package/ccw/frontend/dist/assets/{arrow-right-CibG_LVO.js.map → arrow-right-BshJM9Po.js.map} +1 -1
  154. package/ccw/frontend/dist/assets/{bookmark-plus-BheO8EgG.js → bookmark-plus-D03qJyOZ.js} +2 -2
  155. package/ccw/frontend/dist/assets/{bookmark-plus-BheO8EgG.js.map → bookmark-plus-D03qJyOZ.js.map} +1 -1
  156. package/ccw/frontend/dist/assets/{bot-BlhM0Nl0.js → bot-CyzWuwq0.js} +2 -2
  157. package/ccw/frontend/dist/assets/{bot-BlhM0Nl0.js.map → bot-CyzWuwq0.js.map} +1 -1
  158. package/ccw/frontend/dist/assets/{braces-Dqjg_eCO.js → braces-BPgtyjsG.js} +2 -2
  159. package/ccw/frontend/dist/assets/{braces-Dqjg_eCO.js.map → braces-BPgtyjsG.js.map} +1 -1
  160. package/ccw/frontend/dist/assets/{circle-stop-DYZSLYU0.js → circle-stop-Dix1AOmw.js} +2 -2
  161. package/ccw/frontend/dist/assets/{circle-stop-DYZSLYU0.js.map → circle-stop-Dix1AOmw.js.map} +1 -1
  162. package/ccw/frontend/dist/assets/{cpu-DWCyAOAv.js → cpu-CCQ4Q0Zh.js} +2 -2
  163. package/ccw/frontend/dist/assets/{cpu-DWCyAOAv.js.map → cpu-CCQ4Q0Zh.js.map} +1 -1
  164. package/ccw/frontend/dist/assets/{ellipsis-vertical-DIyoSEHx.js → ellipsis-vertical-BpTysg-Y.js} +2 -2
  165. package/ccw/frontend/dist/assets/{ellipsis-vertical-DIyoSEHx.js.map → ellipsis-vertical-BpTysg-Y.js.map} +1 -1
  166. package/ccw/frontend/dist/assets/{eye-DUy7aLEx.js → eye-DGY1rAZs.js} +2 -2
  167. package/ccw/frontend/dist/assets/{eye-DUy7aLEx.js.map → eye-DGY1rAZs.js.map} +1 -1
  168. package/ccw/frontend/dist/assets/{eye-off-CGRUVRDR.js → eye-off-D8t3JfWG.js} +2 -2
  169. package/ccw/frontend/dist/assets/{eye-off-CGRUVRDR.js.map → eye-off-D8t3JfWG.js.map} +1 -1
  170. package/ccw/frontend/dist/assets/{file-json-BxLBtU9d.js → file-json-BAdJb0n8.js} +2 -2
  171. package/ccw/frontend/dist/assets/{file-json-BxLBtU9d.js.map → file-json-BAdJb0n8.js.map} +1 -1
  172. package/ccw/frontend/dist/assets/{file-text-BoHsW2es.js → file-text-DrJFiOUB.js} +2 -2
  173. package/ccw/frontend/dist/assets/{file-text-BoHsW2es.js.map → file-text-DrJFiOUB.js.map} +1 -1
  174. package/ccw/frontend/dist/assets/{filter-B4vOqP6B.js → filter-CKqzYbz7.js} +2 -2
  175. package/ccw/frontend/dist/assets/{filter-B4vOqP6B.js.map → filter-CKqzYbz7.js.map} +1 -1
  176. package/ccw/frontend/dist/assets/{folder-BKhwCNFG.js → folder-CV8511y9.js} +2 -2
  177. package/ccw/frontend/dist/assets/{folder-BKhwCNFG.js.map → folder-CV8511y9.js.map} +1 -1
  178. package/ccw/frontend/dist/assets/{gauge-Dgf64gkT.js → gauge-XKvmu_uU.js} +2 -2
  179. package/ccw/frontend/dist/assets/{gauge-Dgf64gkT.js.map → gauge-XKvmu_uU.js.map} +1 -1
  180. package/ccw/frontend/dist/assets/{globe-Cus_S6Ux.js → globe-C56cDUzX.js} +2 -2
  181. package/ccw/frontend/dist/assets/{globe-Cus_S6Ux.js.map → globe-C56cDUzX.js.map} +1 -1
  182. package/ccw/frontend/dist/assets/{grid-3x3-DM08hpAN.js → grid-3x3-Bya-suFW.js} +2 -2
  183. package/ccw/frontend/dist/assets/{grid-3x3-DM08hpAN.js.map → grid-3x3-Bya-suFW.js.map} +1 -1
  184. package/ccw/frontend/dist/assets/{hard-drive-eCtll84F.js → hard-drive-CmuTZpsB.js} +2 -2
  185. package/ccw/frontend/dist/assets/{hard-drive-eCtll84F.js.map → hard-drive-CmuTZpsB.js.map} +1 -1
  186. package/ccw/frontend/dist/assets/{hash-Bd1RD285.js → hash-CRPT_tJQ.js} +2 -2
  187. package/ccw/frontend/dist/assets/{hash-Bd1RD285.js.map → hash-CRPT_tJQ.js.map} +1 -1
  188. package/ccw/frontend/dist/assets/{history-eyyCQA6b.js → history-C1pJZQCL.js} +2 -2
  189. package/ccw/frontend/dist/assets/{history-eyyCQA6b.js.map → history-C1pJZQCL.js.map} +1 -1
  190. package/ccw/frontend/dist/assets/{index-ZnmWxcZg.js → index-B6TpijCe.js} +2 -2
  191. package/ccw/frontend/dist/assets/{index-ZnmWxcZg.js.map → index-B6TpijCe.js.map} +1 -1
  192. package/ccw/frontend/dist/assets/{index-b2C0iFd1.js → index-Bcq-7r6F.js} +2 -2
  193. package/ccw/frontend/dist/assets/{index-b2C0iFd1.js.map → index-Bcq-7r6F.js.map} +1 -1
  194. package/ccw/frontend/dist/assets/{index-Cs2ShCCy.js → index-CI8-rBff.js} +2 -2
  195. package/ccw/frontend/dist/assets/{index-Cs2ShCCy.js.map → index-CI8-rBff.js.map} +1 -1
  196. package/ccw/frontend/dist/assets/{index-CY6Lueph.js → index-Dmt9OiEf.js} +2 -2
  197. package/ccw/frontend/dist/assets/{index-CY6Lueph.js.map → index-Dmt9OiEf.js.map} +1 -1
  198. package/ccw/frontend/dist/assets/{index-DfeBbFXo.js → index-anSMmEF8.js} +2 -2
  199. package/ccw/frontend/dist/assets/{index-DfeBbFXo.js.map → index-anSMmEF8.js.map} +1 -1
  200. package/ccw/frontend/dist/assets/{index-B6I7GQC5.js → index-dWT2M6Ef.js} +4 -4
  201. package/ccw/frontend/dist/assets/{index-B6I7GQC5.js.map → index-dWT2M6Ef.js.map} +1 -1
  202. package/ccw/frontend/dist/assets/{layout-grid-ChrTrCby.js → layout-grid-TSO0BFQE.js} +2 -2
  203. package/ccw/frontend/dist/assets/{layout-grid-ChrTrCby.js.map → layout-grid-TSO0BFQE.js.map} +1 -1
  204. package/ccw/frontend/dist/assets/{lightbulb-CvXiTlzN.js → lightbulb-Caj6fIQD.js} +2 -2
  205. package/ccw/frontend/dist/assets/{lightbulb-CvXiTlzN.js.map → lightbulb-Caj6fIQD.js.map} +1 -1
  206. package/ccw/frontend/dist/assets/{link-2-W0Nl17ec.js → link-2-DE9lMxa-.js} +2 -2
  207. package/ccw/frontend/dist/assets/{link-2-W0Nl17ec.js.map → link-2-DE9lMxa-.js.map} +1 -1
  208. package/ccw/frontend/dist/assets/{link-CL4JmoHb.js → link-BZtPgLW0.js} +2 -2
  209. package/ccw/frontend/dist/assets/{link-CL4JmoHb.js.map → link-BZtPgLW0.js.map} +1 -1
  210. package/ccw/frontend/dist/assets/{list-CDmYFcio.js → list-DubWyY-U.js} +2 -2
  211. package/ccw/frontend/dist/assets/{list-CDmYFcio.js.map → list-DubWyY-U.js.map} +1 -1
  212. package/ccw/frontend/dist/assets/{map-pin-0Mfsw_3d.js → map-pin-DwN_48AF.js} +2 -2
  213. package/ccw/frontend/dist/assets/{map-pin-0Mfsw_3d.js.map → map-pin-DwN_48AF.js.map} +1 -1
  214. package/ccw/frontend/dist/assets/{messages-square-C6h08ple.js → messages-square-bjxvaiM9.js} +2 -2
  215. package/ccw/frontend/dist/assets/{messages-square-C6h08ple.js.map → messages-square-bjxvaiM9.js.map} +1 -1
  216. package/ccw/frontend/dist/assets/{minimize-2-Cbu2yRzi.js → minimize-2-CGfBKD_V.js} +2 -2
  217. package/ccw/frontend/dist/assets/{minimize-2-Cbu2yRzi.js.map → minimize-2-CGfBKD_V.js.map} +1 -1
  218. package/ccw/frontend/dist/assets/{package-CoLVUZGJ.js → package-nzWY6ilt.js} +2 -2
  219. package/ccw/frontend/dist/assets/{package-CoLVUZGJ.js.map → package-nzWY6ilt.js.map} +1 -1
  220. package/ccw/frontend/dist/assets/{plug-BYTYqsw1.js → plug-CiLce49C.js} +2 -2
  221. package/ccw/frontend/dist/assets/{plug-BYTYqsw1.js.map → plug-CiLce49C.js.map} +1 -1
  222. package/ccw/frontend/dist/assets/{power-DmIojFl-.js → power-CFLmB-U9.js} +2 -2
  223. package/ccw/frontend/dist/assets/{power-DmIojFl-.js.map → power-CFLmB-U9.js.map} +1 -1
  224. package/ccw/frontend/dist/assets/{save-BFa03OnG.js → save-DuO6OF0C.js} +2 -2
  225. package/ccw/frontend/dist/assets/{save-BFa03OnG.js.map → save-DuO6OF0C.js.map} +1 -1
  226. package/ccw/frontend/dist/assets/{send-Vet3sN4J.js → send-CZk9p0mM.js} +2 -2
  227. package/ccw/frontend/dist/assets/{send-Vet3sN4J.js.map → send-CZk9p0mM.js.map} +1 -1
  228. package/ccw/frontend/dist/assets/{square-check-big-B9nzZRfE.js → square-check-big-BY_1YQQg.js} +2 -2
  229. package/ccw/frontend/dist/assets/{square-check-big-B9nzZRfE.js.map → square-check-big-BY_1YQQg.js.map} +1 -1
  230. package/ccw/frontend/dist/assets/{square-pen-C7K13x4Z.js → square-pen-CnZgm6g-.js} +2 -2
  231. package/ccw/frontend/dist/assets/{square-pen-C7K13x4Z.js.map → square-pen-CnZgm6g-.js.map} +1 -1
  232. package/ccw/frontend/dist/assets/{star-BCQHcnSe.js → star-Cn1F0qy7.js} +2 -2
  233. package/ccw/frontend/dist/assets/{star-BCQHcnSe.js.map → star-Cn1F0qy7.js.map} +1 -1
  234. package/ccw/frontend/dist/assets/{style-CJsrp48L.js → style-Dxs1iXCV.js} +2 -2
  235. package/ccw/frontend/dist/assets/{style-CJsrp48L.js.map → style-Dxs1iXCV.js.map} +1 -1
  236. package/ccw/frontend/dist/assets/{target-CBzCJCB1.js → target-Bz1fLRKH.js} +2 -2
  237. package/ccw/frontend/dist/assets/{target-CBzCJCB1.js.map → target-Bz1fLRKH.js.map} +1 -1
  238. package/ccw/frontend/dist/assets/{test-tube-BYTc5mvQ.js → test-tube-C6qCYlDr.js} +2 -2
  239. package/ccw/frontend/dist/assets/{test-tube-BYTc5mvQ.js.map → test-tube-C6qCYlDr.js.map} +1 -1
  240. package/ccw/frontend/dist/assets/{upload-DzyQj7ib.js → upload-C71kd4Qs.js} +2 -2
  241. package/ccw/frontend/dist/assets/{upload-DzyQj7ib.js.map → upload-C71kd4Qs.js.map} +1 -1
  242. package/ccw/frontend/dist/assets/{useApiSettings-CFPww7gU.js → useApiSettings-CqP2BAJ7.js} +2 -2
  243. package/ccw/frontend/dist/assets/{useApiSettings-CFPww7gU.js.map → useApiSettings-CqP2BAJ7.js.map} +1 -1
  244. package/ccw/frontend/dist/assets/{useCli-ByL_a5CD.js → useCli-PCoPoVeM.js} +2 -2
  245. package/ccw/frontend/dist/assets/{useCli-ByL_a5CD.js.map → useCli-PCoPoVeM.js.map} +1 -1
  246. package/ccw/frontend/dist/assets/{useCommands-BvKIoOzB.js → useCommands-3OfPQPw4.js} +2 -2
  247. package/ccw/frontend/dist/assets/{useCommands-BvKIoOzB.js.map → useCommands-3OfPQPw4.js.map} +1 -1
  248. package/ccw/frontend/dist/assets/{useDebounce-CmKmoP7n.js → useDebounce-bXiFhQx9.js} +2 -2
  249. package/ccw/frontend/dist/assets/{useDebounce-CmKmoP7n.js.map → useDebounce-bXiFhQx9.js.map} +1 -1
  250. package/ccw/frontend/dist/assets/{useFileExplorer-G5UoArCU.js → useFileExplorer-DEyUm46_.js} +2 -2
  251. package/ccw/frontend/dist/assets/{useFileExplorer-G5UoArCU.js.map → useFileExplorer-DEyUm46_.js.map} +1 -1
  252. package/ccw/frontend/dist/assets/{useLocale-D2iHK44M.js → useLocale-sXTrdxcJ.js} +2 -2
  253. package/ccw/frontend/dist/assets/{useLocale-D2iHK44M.js.map → useLocale-sXTrdxcJ.js.map} +1 -1
  254. package/ccw/frontend/dist/assets/{useSkills-CYU4zqhm.js → useSkills-D0W0kXYm.js} +3 -3
  255. package/ccw/frontend/dist/assets/{useSkills-CYU4zqhm.js.map → useSkills-D0W0kXYm.js.map} +1 -1
  256. package/ccw/frontend/dist/assets/{useSystemSettings-JznNpij7.js → useSystemSettings-DZ-8lZsG.js} +2 -2
  257. package/ccw/frontend/dist/assets/{useSystemSettings-JznNpij7.js.map → useSystemSettings-DZ-8lZsG.js.map} +1 -1
  258. package/ccw/frontend/dist/assets/{wand-sparkles-DqS0VCeN.js → wand-sparkles-83GmAYuw.js} +2 -2
  259. package/ccw/frontend/dist/assets/{wand-sparkles-DqS0VCeN.js.map → wand-sparkles-83GmAYuw.js.map} +1 -1
  260. package/ccw/frontend/dist/index.html +1 -1
  261. package/package.json +1 -1
  262. package/.claude/skills/team-arch-opt/role-specs/analyzer.md +0 -80
  263. package/.claude/skills/team-arch-opt/role-specs/designer.md +0 -118
  264. package/.claude/skills/team-arch-opt/role-specs/refactorer.md +0 -106
  265. package/.claude/skills/team-arch-opt/role-specs/reviewer.md +0 -116
  266. package/.claude/skills/team-arch-opt/role-specs/validator.md +0 -117
  267. package/.claude/skills/team-brainstorm/role-specs/challenger.md +0 -63
  268. package/.claude/skills/team-brainstorm/role-specs/evaluator.md +0 -58
  269. package/.claude/skills/team-brainstorm/role-specs/ideator.md +0 -71
  270. package/.claude/skills/team-brainstorm/role-specs/synthesizer.md +0 -59
  271. package/.claude/skills/team-frontend/role-specs/analyst.md +0 -91
  272. package/.claude/skills/team-frontend/role-specs/architect.md +0 -85
  273. package/.claude/skills/team-frontend/role-specs/developer.md +0 -92
  274. package/.claude/skills/team-frontend/role-specs/qa.md +0 -78
  275. package/.claude/skills/team-issue/role-specs/explorer.md +0 -95
  276. package/.claude/skills/team-issue/role-specs/implementer.md +0 -89
  277. package/.claude/skills/team-issue/role-specs/integrator.md +0 -86
  278. package/.claude/skills/team-issue/role-specs/planner.md +0 -83
  279. package/.claude/skills/team-issue/role-specs/reviewer.md +0 -89
  280. package/.claude/skills/team-iterdev/role-specs/architect.md +0 -64
  281. package/.claude/skills/team-iterdev/role-specs/developer.md +0 -73
  282. package/.claude/skills/team-iterdev/role-specs/reviewer.md +0 -65
  283. package/.claude/skills/team-iterdev/role-specs/tester.md +0 -87
  284. package/.claude/skills/team-perf-opt/role-specs/benchmarker.md +0 -110
  285. package/.claude/skills/team-perf-opt/role-specs/optimizer.md +0 -102
  286. package/.claude/skills/team-perf-opt/role-specs/profiler.md +0 -73
  287. package/.claude/skills/team-perf-opt/role-specs/reviewer.md +0 -91
  288. package/.claude/skills/team-perf-opt/role-specs/strategist.md +0 -114
  289. package/.claude/skills/team-planex/role-specs/executor.md +0 -90
  290. package/.claude/skills/team-planex/role-specs/planner.md +0 -110
  291. package/.claude/skills/team-quality-assurance/role-specs/analyst.md +0 -79
  292. package/.claude/skills/team-quality-assurance/role-specs/executor.md +0 -64
  293. package/.claude/skills/team-quality-assurance/role-specs/generator.md +0 -67
  294. package/.claude/skills/team-quality-assurance/role-specs/scout.md +0 -66
  295. package/.claude/skills/team-quality-assurance/role-specs/strategist.md +0 -70
  296. package/.claude/skills/team-review/role-specs/fixer.md +0 -75
  297. package/.claude/skills/team-review/role-specs/reviewer.md +0 -66
  298. package/.claude/skills/team-review/role-specs/scanner.md +0 -70
  299. package/.claude/skills/team-roadmap-dev/role-specs/executor.md +0 -71
  300. package/.claude/skills/team-roadmap-dev/role-specs/planner.md +0 -77
  301. package/.claude/skills/team-roadmap-dev/role-specs/verifier.md +0 -73
  302. package/.claude/skills/team-tech-debt/role-specs/assessor.md +0 -70
  303. package/.claude/skills/team-tech-debt/role-specs/executor.md +0 -80
  304. package/.claude/skills/team-tech-debt/role-specs/planner.md +0 -71
  305. package/.claude/skills/team-tech-debt/role-specs/scanner.md +0 -85
  306. package/.claude/skills/team-tech-debt/role-specs/validator.md +0 -83
  307. package/.claude/skills/team-testing/role-specs/analyst.md +0 -94
  308. package/.claude/skills/team-testing/role-specs/executor.md +0 -97
  309. package/.claude/skills/team-testing/role-specs/generator.md +0 -96
  310. package/.claude/skills/team-testing/role-specs/strategist.md +0 -82
  311. package/.claude/skills/team-uidesign/role-specs/designer.md +0 -72
  312. package/.claude/skills/team-uidesign/role-specs/implementer.md +0 -74
  313. package/.claude/skills/team-uidesign/role-specs/researcher.md +0 -84
  314. package/.claude/skills/team-uidesign/role-specs/reviewer.md +0 -70
  315. package/.claude/skills/team-ux-improve/role-specs/designer.md +0 -191
  316. package/.claude/skills/team-ux-improve/role-specs/diagnoser.md +0 -110
  317. package/.claude/skills/team-ux-improve/role-specs/explorer.md +0 -109
  318. package/.claude/skills/team-ux-improve/role-specs/implementer.md +0 -164
  319. package/.claude/skills/team-ux-improve/role-specs/scanner.md +0 -117
  320. package/.claude/skills/team-ux-improve/role-specs/tester.md +0 -163
  321. package/ccw/frontend/dist/assets/CodexLensPage-My6DnfN6.js +0 -2
  322. package/ccw/frontend/dist/assets/CodexLensPage-My6DnfN6.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"HookManagerPage-CtVTB_ae.js","sources":["../../../../node_modules/lucide-react/dist/esm/icons/file-chart-column-increasing.js","../../src/components/hook/HookCard.tsx","../../src/components/hook/HookFormDialog.tsx","../../src/components/hook/HookQuickTemplates.tsx","../../src/utils/platformUtils.ts","../../src/components/hook/HookWizard.tsx","../../src/pages/HookManagerPage.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileChartColumnIncreasing = createLucideIcon(\"FileChartColumnIncreasing\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"path\", { d: \"M8 18v-2\", key: \"qcmpov\" }],\n [\"path\", { d: \"M12 18v-4\", key: \"q1q25u\" }],\n [\"path\", { d: \"M16 18v-6\", key: \"15y0np\" }]\n]);\n\nexport { FileChartColumnIncreasing as default };\n//# sourceMappingURL=file-chart-column-increasing.js.map\n","// ========================================\r\n// Hook Card Component\r\n// ========================================\r\n// Individual hook display card with actions\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n GitFork,\r\n Power,\r\n PowerOff,\r\n Edit,\r\n Trash2,\r\n ChevronDown,\r\n ChevronUp,\r\n} from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport {\r\n AlertDialog,\r\n AlertDialogContent,\r\n AlertDialogHeader,\r\n AlertDialogTitle,\r\n AlertDialogDescription,\r\n AlertDialogFooter,\r\n AlertDialogAction,\r\n AlertDialogCancel,\r\n} from '@/components/ui/AlertDialog';\r\nimport { cn } from '@/lib/utils';\r\n\r\n// ========== Types ==========\r\n\r\nexport type HookTriggerType = 'SessionStart' | 'UserPromptSubmit' | 'PreToolUse' | 'PostToolUse' | 'Stop' | 'Notification' | 'SubagentStart' | 'SubagentStop' | 'PreCompact' | 'SessionEnd' | 'PostToolUseFailure' | 'PermissionRequest';\r\n\r\nexport interface HookCardData {\r\n name: string;\r\n description?: string;\r\n enabled: boolean;\r\n trigger: HookTriggerType;\r\n matcher?: string;\r\n command?: string;\r\n script?: string;\r\n scope?: 'global' | 'project';\r\n index?: number;\r\n}\r\n\r\nexport interface HookCardProps {\r\n hook: HookCardData;\r\n isExpanded: boolean;\r\n onToggleExpand: () => void;\r\n onToggle: (hookName: string, enabled: boolean) => void;\r\n onEdit: (hook: HookCardData) => void;\r\n onDelete: (hookName: string) => void;\r\n}\r\n\r\n// ========== Helper Functions ==========\r\n\r\nfunction getTriggerIcon(trigger: HookTriggerType) {\r\n switch (trigger) {\r\n case 'SessionStart':\r\n return '🎬';\r\n case 'UserPromptSubmit':\r\n return '⚡';\r\n case 'PreToolUse':\r\n return '🔧';\r\n case 'PostToolUse':\r\n return '✅';\r\n case 'Stop':\r\n return '🛑';\r\n case 'Notification':\r\n return '🔔';\r\n case 'SubagentStart':\r\n return '🚀';\r\n case 'SubagentStop':\r\n return '🏁';\r\n case 'PreCompact':\r\n return '📦';\r\n case 'SessionEnd':\r\n return '👋';\r\n case 'PostToolUseFailure':\r\n return '❌';\r\n case 'PermissionRequest':\r\n return '🔐';\r\n default:\r\n return '📌';\r\n }\r\n}\r\n\r\nfunction getTriggerVariant(trigger: HookTriggerType): 'default' | 'secondary' | 'outline' {\r\n switch (trigger) {\r\n case 'SessionStart':\r\n case 'UserPromptSubmit':\r\n case 'SubagentStart':\r\n return 'default';\r\n case 'PreToolUse':\r\n case 'Stop':\r\n case 'PreCompact':\r\n case 'PermissionRequest':\r\n return 'secondary';\r\n case 'PostToolUse':\r\n case 'Notification':\r\n case 'SubagentStop':\r\n case 'SessionEnd':\r\n case 'PostToolUseFailure':\r\n return 'outline';\r\n default:\r\n return 'outline';\r\n }\r\n}\r\n\r\n// ========== Component ==========\r\n\r\n// ========== Hook Name Translation ==========\r\n// Mapping from display name to template ID for translation lookup\r\nconst DISPLAY_NAME_TO_TEMPLATE_ID: Record<string, string> = {\r\n // Notification hooks\r\n 'Session Start Notify': 'session-start-notify',\r\n 'Session State Watch': 'session-state-watch',\r\n 'Stop Notify': 'stop-notify',\r\n // Automation hooks\r\n 'Auto Format on Write': 'auto-format-on-write',\r\n 'Auto Lint on Write': 'auto-lint-on-write',\r\n 'Block Sensitive Files': 'block-sensitive-files',\r\n 'Git Auto Stage': 'git-auto-stage',\r\n // Indexing hooks\r\n 'Post Edit Index': 'post-edit-index',\r\n 'Session End Summary': 'session-end-summary',\r\n 'Project State Inject': 'project-state-inject',\r\n // Memory V2 hooks\r\n 'Memory V2 Extract': 'memory-v2-extract',\r\n 'Memory V2 Auto Consolidate': 'memory-v2-auto-consolidate',\r\n 'Memory Sync Dashboard': 'memory-sync-dashboard',\r\n};\r\n\r\n/**\r\n * Get translated hook name if available\r\n * Falls back to original name if no translation exists\r\n */\r\nfunction getHookDisplayName(name: string, formatMessage: (msg: { id: string }) => string): string {\r\n // First try direct translation with the name (for template IDs)\r\n const translationKey = `cliHooks.templates.templates.${name}.name`;\r\n try {\r\n const translated = formatMessage({ id: translationKey });\r\n if (translated && !translated.includes('cliHooks.templates.templates')) {\r\n return translated;\r\n }\r\n } catch {\r\n // Direct translation not found\r\n }\r\n\r\n // Try mapping display name to template ID\r\n const templateId = DISPLAY_NAME_TO_TEMPLATE_ID[name];\r\n if (templateId) {\r\n const mappedKey = `cliHooks.templates.templates.${templateId}.name`;\r\n try {\r\n const translated = formatMessage({ id: mappedKey });\r\n if (translated && !translated.includes('cliHooks.templates.templates')) {\r\n return translated;\r\n }\r\n } catch {\r\n // Mapping found but no translation\r\n }\r\n }\r\n\r\n return name;\r\n}\r\n\r\n// ========== Component ==========\r\n\r\nexport function HookCard({\r\n hook,\r\n isExpanded,\r\n onToggleExpand,\r\n onToggle,\r\n onEdit,\r\n onDelete,\r\n}: HookCardProps) {\r\n const { formatMessage } = useIntl();\r\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\r\n\r\n // Get translated hook name\r\n const displayName = getHookDisplayName(hook.name, formatMessage);\r\n\r\n const handleToggle = () => {\r\n onToggle(hook.name, !hook.enabled);\r\n };\r\n\r\n const handleEdit = () => {\r\n onEdit(hook);\r\n };\r\n\r\n const handleDelete = () => {\r\n setShowDeleteConfirm(true);\r\n };\r\n\r\n const handleConfirmDelete = () => {\r\n setShowDeleteConfirm(false);\r\n onDelete(hook.name);\r\n };\r\n\r\n const handleCancelDelete = () => {\r\n setShowDeleteConfirm(false);\r\n };\r\n\r\n return (\r\n <>\r\n <Card className={cn('overflow-hidden', !hook.enabled && 'opacity-60')}>\r\n {/* Header */}\r\n <div className=\"p-4\">\r\n <div className=\"flex items-start justify-between gap-3\">\r\n <div className=\"flex items-center gap-3 flex-1 min-w-0\">\r\n <div className={cn(\r\n 'p-2 rounded-lg flex-shrink-0',\r\n hook.enabled ? 'bg-primary/10' : 'bg-muted'\r\n )}>\r\n <GitFork className={cn(\r\n 'w-4 h-4',\r\n hook.enabled ? 'text-primary' : 'text-muted-foreground'\r\n )} />\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span className=\"text-sm font-medium text-foreground truncate\">\r\n {displayName}\r\n </span>\r\n <Badge\r\n variant={getTriggerVariant(hook.trigger)}\r\n className=\"text-xs flex-shrink-0\"\r\n >\r\n <span className=\"mr-1\">{getTriggerIcon(hook.trigger)}</span>\r\n {formatMessage({ id: `cliHooks.trigger.${hook.trigger}` })}\r\n </Badge>\r\n <Badge\r\n variant={hook.enabled ? 'default' : 'secondary'}\r\n className=\"text-xs flex-shrink-0\"\r\n >\r\n {hook.enabled\r\n ? formatMessage({ id: 'common.status.enabled' })\r\n : formatMessage({ id: 'common.status.disabled' })\r\n }\r\n </Badge>\r\n </div>\r\n {hook.description && (\r\n <p className=\"text-xs text-muted-foreground mt-0.5 truncate\">\r\n {hook.description}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Action Buttons */}\r\n <div className=\"flex items-center gap-1 flex-shrink-0\">\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-8 w-8 p-0\"\r\n onClick={handleToggle}\r\n title={hook.enabled\r\n ? formatMessage({ id: 'cliHooks.actions.disable' })\r\n : formatMessage({ id: 'cliHooks.actions.enable' })\r\n }\r\n >\r\n {hook.enabled ? (\r\n <Power className=\"w-4 h-4 text-success\" />\r\n ) : (\r\n <PowerOff className=\"w-4 h-4 text-muted-foreground\" />\r\n )}\r\n </Button>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-8 w-8 p-0\"\r\n onClick={handleEdit}\r\n title={formatMessage({ id: 'common.actions.edit' })}\r\n >\r\n <Edit className=\"w-4 h-4\" />\r\n </Button>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-8 w-8 p-0 text-destructive hover:text-destructive hover:bg-destructive/10\"\r\n onClick={handleDelete}\r\n title={formatMessage({ id: 'common.actions.delete' })}\r\n >\r\n <Trash2 className=\"w-4 h-4 text-destructive\" />\r\n </Button>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-8 w-8 p-0\"\r\n onClick={onToggleExpand}\r\n title={isExpanded\r\n ? formatMessage({ id: 'cliHooks.actions.collapse' })\r\n : formatMessage({ id: 'cliHooks.actions.expand' })\r\n }\r\n >\r\n {isExpanded ? (\r\n <ChevronUp className=\"w-4 h-4\" />\r\n ) : (\r\n <ChevronDown className=\"w-4 h-4\" />\r\n )}\r\n </Button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Expanded Content */}\r\n {isExpanded && (\r\n <div className=\"border-t border-border bg-muted/30 p-4 space-y-3\">\r\n {hook.description && (\r\n <div>\r\n <label className=\"text-xs font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.description' })}\r\n </label>\r\n <p className=\"text-sm text-foreground mt-1\">{hook.description}</p>\r\n </div>\r\n )}\r\n\r\n <div>\r\n <label className=\"text-xs font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.matcher' })}\r\n </label>\r\n <p className=\"text-sm text-foreground mt-1 font-mono bg-muted px-2 py-1 rounded\">\r\n {hook.matcher || formatMessage({ id: 'cliHooks.allTools' })}\r\n </p>\r\n </div>\r\n\r\n <div>\r\n <label className=\"text-xs font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.command' })}\r\n </label>\r\n <p className=\"text-sm text-foreground mt-1 font-mono bg-muted px-2 py-1 rounded break-all max-h-32 overflow-y-auto\">\r\n {hook.command || hook.script || 'N/A'}\r\n </p>\r\n </div>\r\n </div>\r\n )}\r\n </Card>\r\n\r\n {/* Delete Confirmation Dialog */}\r\n <AlertDialog open={showDeleteConfirm} onOpenChange={setShowDeleteConfirm}>\r\n <AlertDialogContent>\r\n <AlertDialogHeader>\r\n <AlertDialogTitle>Delete CLI Hook?</AlertDialogTitle>\r\n <AlertDialogDescription>\r\n This action cannot be undone. The hook \"{displayName}\" will be permanently deleted.\r\n </AlertDialogDescription>\r\n </AlertDialogHeader>\r\n <AlertDialogFooter>\r\n <AlertDialogCancel onClick={handleCancelDelete}>Cancel</AlertDialogCancel>\r\n <AlertDialogAction onClick={handleConfirmDelete}>Delete</AlertDialogAction>\r\n </AlertDialogFooter>\r\n </AlertDialogContent>\r\n </AlertDialog>\r\n </>\r\n );\r\n}\r\n\r\nexport default HookCard;\r\n","// ========================================\r\n// Hook Form Dialog Component\r\n// ========================================\r\n// Dialog for creating and editing hooks\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Textarea } from '@/components/ui/Textarea';\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 type { HookCardData, HookTriggerType } from './HookCard';\r\n\r\n// ========== Types ==========\r\n\r\nexport type HookFormMode = 'create' | 'edit';\r\n\r\nexport interface HookFormData {\r\n name: string;\r\n description: string;\r\n trigger: HookTriggerType;\r\n matcher: string;\r\n command: string;\r\n}\r\n\r\nexport interface HookFormDialogProps {\r\n mode: HookFormMode;\r\n hook?: HookCardData;\r\n open: boolean;\r\n onClose: () => void;\r\n onSave: (data: HookFormData) => Promise<void>;\r\n}\r\n\r\n// ========== Helper: Form Validation ==========\r\n\r\ninterface FormErrors {\r\n name?: string;\r\n trigger?: string;\r\n command?: string;\r\n}\r\n\r\nfunction validateForm(data: HookFormData): FormErrors {\r\n const errors: FormErrors = {};\r\n\r\n if (!data.name.trim()) {\r\n errors.name = 'validation.nameRequired';\r\n } else if (!/^[a-zA-Z0-9_-]+$/.test(data.name)) {\r\n errors.name = 'validation.nameInvalid';\r\n }\r\n\r\n if (!data.trigger) {\r\n errors.trigger = 'validation.triggerRequired';\r\n }\r\n\r\n if (!data.command.trim()) {\r\n errors.command = 'validation.commandRequired';\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n// ========== Component ==========\r\n\r\nexport function HookFormDialog({\r\n mode,\r\n hook,\r\n open,\r\n onClose,\r\n onSave,\r\n}: HookFormDialogProps) {\r\n const { formatMessage } = useIntl();\r\n const [formData, setFormData] = useState<HookFormData>({\r\n name: '',\r\n description: '',\r\n trigger: 'PostToolUse',\r\n matcher: '',\r\n command: '',\r\n });\r\n const [errors, setErrors] = useState<FormErrors>({});\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n\r\n // Reset form when dialog opens or hook changes\r\n useEffect(() => {\r\n if (open) {\r\n if (mode === 'edit' && hook) {\r\n setFormData({\r\n name: hook.name,\r\n description: hook.description || '',\r\n trigger: hook.trigger,\r\n matcher: hook.matcher || '',\r\n command: hook.command || hook.script || '',\r\n });\r\n } else {\r\n setFormData({\r\n name: '',\r\n description: '',\r\n trigger: 'PostToolUse',\r\n matcher: '',\r\n command: '',\r\n });\r\n }\r\n setErrors({});\r\n }\r\n }, [open, mode, hook]);\r\n\r\n const handleFieldChange = (\r\n field: keyof HookFormData,\r\n value: string\r\n ) => {\r\n setFormData((prev) => ({ ...prev, [field]: value }));\r\n // Clear error for this field when user starts typing\r\n if (errors[field as keyof FormErrors]) {\r\n setErrors((prev) => ({ ...prev, [field]: undefined }));\r\n }\r\n };\r\n\r\n const handleSubmit = async () => {\r\n // Validate form\r\n const validationErrors = validateForm(formData);\r\n if (Object.keys(validationErrors).length > 0) {\r\n setErrors(validationErrors);\r\n return;\r\n }\r\n\r\n setIsSubmitting(true);\r\n try {\r\n await onSave(formData);\r\n onClose();\r\n } catch (error) {\r\n console.error('Failed to save hook:', error);\r\n } finally {\r\n setIsSubmitting(false);\r\n }\r\n };\r\n\r\n const TRIGGER_OPTIONS: { value: HookTriggerType; label: string }[] = [\r\n { value: 'SessionStart', label: 'cliHooks.trigger.SessionStart' },\r\n { value: 'UserPromptSubmit', label: 'cliHooks.trigger.UserPromptSubmit' },\r\n { value: 'PreToolUse', label: 'cliHooks.trigger.PreToolUse' },\r\n { value: 'PostToolUse', label: 'cliHooks.trigger.PostToolUse' },\r\n { value: 'Stop', label: 'cliHooks.trigger.Stop' },\r\n { value: 'Notification', label: 'cliHooks.trigger.Notification' },\r\n { value: 'SubagentStart', label: 'cliHooks.trigger.SubagentStart' },\r\n { value: 'SubagentStop', label: 'cliHooks.trigger.SubagentStop' },\r\n { value: 'PreCompact', label: 'cliHooks.trigger.PreCompact' },\r\n { value: 'SessionEnd', label: 'cliHooks.trigger.SessionEnd' },\r\n { value: 'PostToolUseFailure', label: 'cliHooks.trigger.PostToolUseFailure' },\r\n { value: 'PermissionRequest', label: 'cliHooks.trigger.PermissionRequest' },\r\n ];\r\n\r\n return (\r\n <Dialog open={open} onOpenChange={onClose}>\r\n <DialogContent className=\"sm:max-w-[600px]\">\r\n <DialogHeader>\r\n <DialogTitle>\r\n {mode === 'create'\r\n ? formatMessage({ id: 'cliHooks.dialog.createTitle' })\r\n : formatMessage({ id: 'cliHooks.dialog.editTitle' }, { hookName: hook?.name })\r\n }\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <div className=\"space-y-4 py-4\">\r\n {/* Name */}\r\n <div>\r\n <label htmlFor=\"hook-name\" className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.name' })} *\r\n </label>\r\n <Input\r\n id=\"hook-name\"\r\n value={formData.name}\r\n onChange={(e) => handleFieldChange('name', e.target.value)}\r\n placeholder={formatMessage({ id: 'cliHooks.form.namePlaceholder' })}\r\n className=\"mt-1\"\r\n error={!!errors.name}\r\n />\r\n {errors.name && (\r\n <p className=\"text-xs text-destructive mt-1\">\r\n {formatMessage({ id: `cliHooks.${errors.name}` })}\r\n </p>\r\n )}\r\n </div>\r\n\r\n {/* Description */}\r\n <div>\r\n <label htmlFor=\"hook-description\" className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.description' })}\r\n </label>\r\n <Textarea\r\n id=\"hook-description\"\r\n value={formData.description}\r\n onChange={(e) => handleFieldChange('description', e.target.value)}\r\n placeholder={formatMessage({ id: 'cliHooks.form.descriptionPlaceholder' })}\r\n className=\"mt-1\"\r\n rows={2}\r\n />\r\n </div>\r\n\r\n {/* Trigger */}\r\n <div>\r\n <label htmlFor=\"hook-trigger\" className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.trigger' })} *\r\n </label>\r\n <Select\r\n value={formData.trigger}\r\n onValueChange={(value) => handleFieldChange('trigger', value as HookTriggerType)}\r\n >\r\n <SelectTrigger className=\"mt-1\" id=\"hook-trigger\">\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n {TRIGGER_OPTIONS.map((option) => (\r\n <SelectItem key={option.value} value={option.value}>\r\n {formatMessage({ id: option.label })}\r\n </SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n {errors.trigger && (\r\n <p className=\"text-xs text-destructive mt-1\">\r\n {formatMessage({ id: `cliHooks.${errors.trigger}` })}\r\n </p>\r\n )}\r\n </div>\r\n\r\n {/* Matcher */}\r\n <div>\r\n <label htmlFor=\"hook-matcher\" className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.matcher' })}\r\n </label>\r\n <Input\r\n id=\"hook-matcher\"\r\n value={formData.matcher}\r\n onChange={(e) => handleFieldChange('matcher', e.target.value)}\r\n placeholder={formatMessage({ id: 'cliHooks.form.matcherPlaceholder' })}\r\n className=\"mt-1 font-mono\"\r\n />\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'cliHooks.form.matcherHelp' })}\r\n </p>\r\n </div>\r\n\r\n {/* Command */}\r\n <div>\r\n <label htmlFor=\"hook-command\" className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.command' })} *\r\n </label>\r\n <Textarea\r\n id=\"hook-command\"\r\n value={formData.command}\r\n onChange={(e) => handleFieldChange('command', e.target.value)}\r\n placeholder={formatMessage({ id: 'cliHooks.form.commandPlaceholder' })}\r\n className=\"mt-1 font-mono text-sm\"\r\n rows={4}\r\n error={!!errors.command}\r\n />\r\n {errors.command && (\r\n <p className=\"text-xs text-destructive mt-1\">\r\n {formatMessage({ id: `cliHooks.${errors.command}` })}\r\n </p>\r\n )}\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'cliHooks.form.commandHelp' })}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n <DialogFooter>\r\n <Button variant=\"outline\" onClick={onClose} disabled={isSubmitting}>\r\n {formatMessage({ id: 'common.actions.cancel' })}\r\n </Button>\r\n <Button onClick={handleSubmit} disabled={isSubmitting}>\r\n {isSubmitting\r\n ? formatMessage({ id: 'common.actions.saving' })\r\n : formatMessage({ id: 'common.actions.save' })\r\n }\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n );\r\n}\r\n\r\nexport default HookFormDialog;\r\n","// ========================================\r\n// Hook Quick Templates Component\r\n// ========================================\r\n// Frontend component for displaying and installing hook templates\r\n// Templates are defined in backend: ccw/src/core/hooks/hook-templates.ts\r\n// All templates use `ccw hook template exec <id> --stdin` to avoid Windows quote issues\r\n\r\nimport { useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Bell,\r\n Database,\r\n Wrench,\r\n Check,\r\n Zap,\r\n Download,\r\n Loader2,\r\n Shield,\r\n FileCode,\r\n FileSearch,\r\n GitBranch,\r\n Send,\r\n FileBarChart,\r\n Settings,\r\n} from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { cn } from '@/lib/utils';\r\nimport type { HookTriggerType } from './HookCard';\r\n\r\n// ========== Types ==========\r\n\r\n/**\r\n * Template category type\r\n */\r\nexport type TemplateCategory = 'notification' | 'indexing' | 'automation' | 'utility' | 'protection';\r\n\r\n/**\r\n * Hook template definition (frontend view of backend templates)\r\n */\r\nexport interface HookTemplate {\r\n id: string;\r\n name: string;\r\n description: string;\r\n category: TemplateCategory;\r\n trigger: HookTriggerType;\r\n matcher?: string;\r\n}\r\n\r\n/**\r\n * Component props\r\n */\r\nexport interface HookQuickTemplatesProps {\r\n /** Callback when install button is clicked */\r\n onInstallTemplate: (templateId: string) => Promise<void>;\r\n /** Array of installed template IDs */\r\n installedTemplates: string[];\r\n /** Optional loading state */\r\n isLoading?: boolean;\r\n /** ID of the template currently being installed */\r\n installingTemplateId?: string | null;\r\n}\r\n\r\n// ========== Hook Templates ==========\r\n// NOTE: Templates are defined in backend (ccw/src/core/hooks/hook-templates.ts)\r\n// This is a copy for frontend display purposes.\r\n// All templates use `ccw hook template exec <id> --stdin` format.\r\n\r\n/**\r\n * Predefined hook templates for quick installation\r\n * These mirror the backend templates in ccw/src/core/hooks/hook-templates.ts\r\n */\r\nexport const HOOK_TEMPLATES: readonly HookTemplate[] = [\r\n // ============ Notification ============\r\n {\r\n id: 'session-start-notify',\r\n name: 'Session Start Notify',\r\n description: 'Notify dashboard when a new workflow session is created',\r\n category: 'notification',\r\n trigger: 'SessionStart',\r\n },\r\n {\r\n id: 'session-state-watch',\r\n name: 'Session State Watch',\r\n description: 'Watch for session metadata file changes (workflow-session.json)',\r\n category: 'notification',\r\n trigger: 'PostToolUse',\r\n matcher: 'Write|Edit',\r\n },\r\n {\r\n id: 'stop-notify',\r\n name: 'Stop Notify',\r\n description: 'Notify dashboard when Claude finishes responding',\r\n category: 'notification',\r\n trigger: 'Stop',\r\n },\r\n {\r\n id: 'memory-sync-dashboard',\r\n name: 'Memory Sync Dashboard',\r\n description: 'Sync memory V2 status to dashboard on changes',\r\n category: 'notification',\r\n trigger: 'PostToolUse',\r\n matcher: 'mcp__ccw-tools__core_memory',\r\n },\r\n\r\n // ============ Automation ============\r\n {\r\n id: 'auto-format-on-write',\r\n name: 'Auto Format on Write',\r\n description: 'Auto-format files after Claude writes or edits them',\r\n category: 'automation',\r\n trigger: 'PostToolUse',\r\n matcher: 'Write|Edit',\r\n },\r\n {\r\n id: 'auto-lint-on-write',\r\n name: 'Auto Lint on Write',\r\n description: 'Auto-lint files after Claude writes or edits them',\r\n category: 'automation',\r\n trigger: 'PostToolUse',\r\n matcher: 'Write|Edit',\r\n },\r\n {\r\n id: 'git-auto-stage',\r\n name: 'Git Auto Stage',\r\n description: 'Auto stage all modified files when Claude finishes responding',\r\n category: 'automation',\r\n trigger: 'Stop',\r\n },\r\n\r\n // ============ Protection ============\r\n {\r\n id: 'block-sensitive-files',\r\n name: 'Block Sensitive Files',\r\n description: 'Block modifications to sensitive files (.env, secrets, credentials)',\r\n category: 'protection',\r\n trigger: 'PreToolUse',\r\n matcher: 'Write|Edit',\r\n },\r\n {\r\n id: 'danger-bash-confirm',\r\n name: 'Danger Bash Confirm',\r\n description: 'Require confirmation for dangerous bash commands',\r\n category: 'protection',\r\n trigger: 'PreToolUse',\r\n matcher: 'Bash',\r\n },\r\n {\r\n id: 'danger-file-protection',\r\n name: 'Danger File Protection',\r\n description: 'Block modifications to protected files',\r\n category: 'protection',\r\n trigger: 'PreToolUse',\r\n matcher: 'Write|Edit',\r\n },\r\n {\r\n id: 'danger-git-destructive',\r\n name: 'Danger Git Destructive',\r\n description: 'Require confirmation for destructive git operations',\r\n category: 'protection',\r\n trigger: 'PreToolUse',\r\n matcher: 'Bash',\r\n },\r\n {\r\n id: 'danger-network-confirm',\r\n name: 'Danger Network Confirm',\r\n description: 'Require confirmation for network operations',\r\n category: 'protection',\r\n trigger: 'PreToolUse',\r\n matcher: 'Bash|WebFetch',\r\n },\r\n {\r\n id: 'danger-system-paths',\r\n name: 'Danger System Paths',\r\n description: 'Block modifications to system paths',\r\n category: 'protection',\r\n trigger: 'PreToolUse',\r\n matcher: 'Write|Edit|Bash',\r\n },\r\n {\r\n id: 'danger-permission-change',\r\n name: 'Danger Permission Change',\r\n description: 'Require confirmation for permission changes',\r\n category: 'protection',\r\n trigger: 'PreToolUse',\r\n matcher: 'Bash',\r\n },\r\n\r\n // ============ Indexing ============\r\n {\r\n id: 'post-edit-index',\r\n name: 'Post Edit Index',\r\n description: 'Notify indexing service when files are modified',\r\n category: 'indexing',\r\n trigger: 'PostToolUse',\r\n matcher: 'Write|Edit',\r\n },\r\n {\r\n id: 'session-end-summary',\r\n name: 'Session End Summary',\r\n description: 'Send session summary to dashboard on session end',\r\n category: 'indexing',\r\n trigger: 'Stop',\r\n },\r\n\r\n // ============ Utility ============\r\n {\r\n id: 'memory-auto-compress',\r\n name: 'Auto Memory Compress',\r\n description: 'Automatically compress memory when entries exceed threshold',\r\n category: 'utility',\r\n trigger: 'Stop',\r\n },\r\n {\r\n id: 'memory-preview-extract',\r\n name: 'Memory Preview & Extract',\r\n description: 'Preview extraction queue and extract eligible sessions',\r\n category: 'utility',\r\n trigger: 'SessionStart',\r\n },\r\n {\r\n id: 'memory-status-check',\r\n name: 'Memory Status Check',\r\n description: 'Check memory extraction and consolidation status',\r\n category: 'utility',\r\n trigger: 'SessionStart',\r\n },\r\n {\r\n id: 'memory-v2-extract',\r\n name: 'Memory V2 Extract',\r\n description: 'Trigger Phase 1 extraction when session ends',\r\n category: 'utility',\r\n trigger: 'Stop',\r\n },\r\n {\r\n id: 'memory-v2-auto-consolidate',\r\n name: 'Memory V2 Auto Consolidate',\r\n description: 'Trigger Phase 2 consolidation after extraction jobs complete',\r\n category: 'utility',\r\n trigger: 'Stop',\r\n },\r\n] as const;\r\n\r\n// ========== Category Icons ==========\r\n\r\nconst CATEGORY_ICONS: Record<TemplateCategory, { icon: typeof Bell; color: string; bg: string }> = {\r\n notification: { icon: Bell, color: 'text-blue-500', bg: 'bg-blue-500/10' },\r\n indexing: { icon: Database, color: 'text-purple-500', bg: 'bg-purple-500/10' },\r\n automation: { icon: Wrench, color: 'text-orange-500', bg: 'bg-orange-500/10' },\r\n utility: { icon: Settings, color: 'text-gray-500', bg: 'bg-gray-500/10' },\r\n protection: { icon: Shield, color: 'text-red-500', bg: 'bg-red-500/10' },\r\n};\r\n\r\n// ========== Template Icons ==========\r\n\r\nconst TEMPLATE_ICONS: Record<string, typeof Bell> = {\r\n 'session-start-notify': Send,\r\n 'session-state-watch': FileBarChart,\r\n 'stop-notify': Bell,\r\n 'auto-format-on-write': FileCode,\r\n 'auto-lint-on-write': FileSearch,\r\n 'block-sensitive-files': Shield,\r\n 'git-auto-stage': GitBranch,\r\n 'post-edit-index': Database,\r\n 'session-end-summary': FileBarChart,\r\n 'project-state-inject': FileBarChart,\r\n};\r\n\r\n// ========== Category Names ==========\r\n\r\nfunction getCategoryName(category: TemplateCategory, formatMessage: ReturnType<typeof useIntl>['formatMessage']): string {\r\n const names: Record<TemplateCategory, string> = {\r\n notification: formatMessage({ id: 'cliHooks.templates.categories.notification' }),\r\n indexing: formatMessage({ id: 'cliHooks.templates.categories.indexing' }),\r\n automation: formatMessage({ id: 'cliHooks.templates.categories.automation' }),\r\n utility: formatMessage({ id: 'cliHooks.templates.categories.utility' }),\r\n protection: formatMessage({ id: 'cliHooks.templates.categories.protection' }),\r\n };\r\n return names[category];\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\n/**\r\n * HookQuickTemplates - Display predefined hook templates for quick installation\r\n */\r\nexport function HookQuickTemplates({\r\n onInstallTemplate,\r\n installedTemplates,\r\n isLoading: _isLoading = false,\r\n installingTemplateId = null\r\n}: HookQuickTemplatesProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n // Group templates by category\r\n const templatesByCategory = useMemo(() => {\r\n return HOOK_TEMPLATES.reduce((acc, template) => {\r\n if (!acc[template.category]) {\r\n acc[template.category] = [];\r\n }\r\n acc[template.category].push(template);\r\n return acc;\r\n }, {} as Record<TemplateCategory, HookTemplate[]>);\r\n }, []);\r\n\r\n // Define category order\r\n const categoryOrder: TemplateCategory[] = ['notification', 'indexing', 'automation', 'protection', 'utility'];\r\n\r\n const handleInstall = async (templateId: string) => {\r\n await onInstallTemplate(templateId);\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Header */}\r\n <div className=\"flex items-center gap-3\">\r\n <Zap className=\"w-5 h-5 text-primary\" />\r\n <div>\r\n <h2 className=\"text-lg font-semibold text-foreground\">\r\n {formatMessage({ id: 'cliHooks.templates.title' })}\r\n </h2>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.templates.description' })}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* Categories */}\r\n {categoryOrder.map((category) => {\r\n const templates = templatesByCategory[category];\r\n if (!templates || templates.length === 0) return null;\r\n\r\n const { icon: CategoryIcon, color } = CATEGORY_ICONS[category];\r\n\r\n return (\r\n <div key={category} className=\"space-y-3\">\r\n {/* Category Header */}\r\n <div className=\"flex items-center gap-2\">\r\n <CategoryIcon className={cn('w-4 h-4', color)} />\r\n <h3 className=\"text-sm font-medium text-foreground\">\r\n {getCategoryName(category, formatMessage)}\r\n </h3>\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {templates.length}\r\n </Badge>\r\n </div>\r\n\r\n {/* Template Card Grid */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3\">\r\n {templates.map((template) => {\r\n const isInstalled = installedTemplates.includes(template.id);\r\n const isInstalling = installingTemplateId === template.id;\r\n const TemplateIcon = TEMPLATE_ICONS[template.id] || Zap;\r\n const { color: catColor, bg: catBg } = CATEGORY_ICONS[template.category];\r\n\r\n return (\r\n <Card\r\n key={template.id}\r\n className={cn(\r\n 'p-4 flex flex-col gap-2 transition-colors',\r\n isInstalled && 'opacity-70'\r\n )}\r\n >\r\n {/* Card Header: Icon + Name + Install */}\r\n <div className=\"flex items-start gap-3\">\r\n <div className={cn('p-2 rounded-lg shrink-0', catBg)}>\r\n <TemplateIcon className={cn('w-4 h-4', catColor)} />\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <h4 className=\"text-sm font-medium text-foreground leading-tight\">\r\n {formatMessage(\r\n { id: `cliHooks.templates.templates.${template.id}.name`, defaultMessage: template.name }\r\n )}\r\n </h4>\r\n <div className=\"flex items-center gap-1.5 mt-1 flex-wrap\">\r\n <Badge variant=\"secondary\" className=\"text-[10px] px-1.5 py-0\">\r\n {formatMessage({ id: `cliHooks.trigger.${template.trigger}` })}\r\n </Badge>\r\n {template.matcher && (\r\n <Badge variant=\"outline\" className=\"text-[10px] px-1.5 py-0 font-mono\">\r\n {template.matcher}\r\n </Badge>\r\n )}\r\n </div>\r\n </div>\r\n {/* Icon Install Button */}\r\n <Button\r\n size=\"sm\"\r\n variant=\"ghost\"\r\n disabled={isInstalled || isInstalling}\r\n onClick={() => handleInstall(template.id)}\r\n className={cn(\r\n 'h-8 w-8 p-0 shrink-0 rounded-full',\r\n isInstalled\r\n ? 'text-green-500 hover:text-green-500'\r\n : 'text-primary hover:bg-primary/10'\r\n )}\r\n title={isInstalled\r\n ? formatMessage({ id: 'cliHooks.templates.actions.installed' })\r\n : formatMessage({ id: 'cliHooks.templates.actions.install' })\r\n }\r\n >\r\n {isInstalling ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : isInstalled ? (\r\n <Check className=\"w-4 h-4\" />\r\n ) : (\r\n <Download className=\"w-4 h-4\" />\r\n )}\r\n </Button>\r\n </div>\r\n\r\n {/* Description */}\r\n <p className=\"text-xs text-muted-foreground leading-relaxed flex-1 pl-11\">\r\n {formatMessage(\r\n { id: `cliHooks.templates.templates.${template.id}.description`, defaultMessage: template.description }\r\n )}\r\n </p>\r\n </Card>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n}\r\n\r\nexport default HookQuickTemplates;\r\n","// ========================================\r\n// Platform Utilities\r\n// ========================================\r\n// Platform detection and compatibility checking for hooks\r\n\r\n// ========== Types ==========\r\n\r\n/**\r\n * Detected platform type\r\n */\r\nexport type Platform = 'windows' | 'macos' | 'linux';\r\n\r\n/**\r\n * Available shell types by platform\r\n */\r\nexport type ShellType = 'cmd' | 'bash' | 'powershell' | 'zsh';\r\n\r\n/**\r\n * Compatibility check result\r\n */\r\nexport interface CompatibilityCheck {\r\n compatible: boolean;\r\n issues: string[];\r\n warnings: string[];\r\n}\r\n\r\n/**\r\n * Platform requirements for a hook template\r\n */\r\nexport interface PlatformRequirements {\r\n requiredPlatforms?: Platform[];\r\n optionalPlatforms?: Platform[];\r\n incompatiblePlatforms?: Platform[];\r\n}\r\n\r\n// ========== Platform Detection ==========\r\n\r\n/**\r\n * Detect the current platform from user agent\r\n * @returns Detected platform type\r\n */\r\nexport function detect(): Platform {\r\n if (typeof window === 'undefined' || typeof window.navigator === 'undefined') {\r\n return 'linux'; // Default for server-side\r\n }\r\n\r\n const userAgent = window.navigator.userAgent;\r\n\r\n if (userAgent.includes('Win')) {\r\n return 'windows';\r\n } else if (userAgent.includes('Mac')) {\r\n return 'macos';\r\n } else {\r\n return 'linux';\r\n }\r\n}\r\n\r\n/**\r\n * Get the default shell for the current platform\r\n * @param platform - Optional platform override, otherwise auto-detects\r\n * @returns Shell type for the platform\r\n */\r\nexport function getShell(platform?: Platform): ShellType {\r\n const detectedPlatform = platform ?? detect();\r\n\r\n switch (detectedPlatform) {\r\n case 'windows':\r\n return 'cmd';\r\n case 'macos':\r\n return 'zsh';\r\n case 'linux':\r\n return 'bash';\r\n default:\r\n return 'bash';\r\n }\r\n}\r\n\r\n/**\r\n * Get the shell command prefix for executing scripts\r\n * @param shell - Shell type, defaults to detected platform\r\n * @returns Command prefix array (command, args...)\r\n */\r\nexport function getShellCommand(shell?: ShellType): string[] {\r\n const detectedShell = shell ?? getShell();\r\n\r\n switch (detectedShell) {\r\n case 'cmd':\r\n return ['cmd', '/c'];\r\n case 'powershell':\r\n return ['powershell', '-Command'];\r\n case 'bash':\r\n return ['bash', '-c'];\r\n case 'zsh':\r\n return ['zsh', '-c'];\r\n default:\r\n return ['bash', '-c'];\r\n }\r\n}\r\n\r\n/**\r\n * Get platform display name\r\n * @param platform - Platform type\r\n * @returns Human-readable platform name\r\n */\r\nexport function getPlatformName(platform: Platform): string {\r\n const names: Record<Platform, string> = {\r\n windows: 'Windows',\r\n macos: 'macOS',\r\n linux: 'Linux'\r\n };\r\n return names[platform];\r\n}\r\n\r\n/**\r\n * Get shell display name\r\n * @param shell - Shell type\r\n * @returns Human-readable shell name\r\n */\r\nexport function getShellName(shell: ShellType): string {\r\n const names: Record<ShellType, string> = {\r\n cmd: 'Command Prompt (cmd.exe)',\r\n bash: 'Bash',\r\n powershell: 'PowerShell',\r\n zsh: 'Zsh'\r\n };\r\n return names[shell];\r\n}\r\n\r\n// ========== Compatibility Checking ==========\r\n\r\n/**\r\n * Check if a hook template is compatible with the current platform\r\n * @param requirements - Platform requirements for the template\r\n * @param platform - Optional platform override, otherwise auto-detects\r\n * @returns Compatibility check result with issues and warnings\r\n */\r\nexport function checkCompatibility(\r\n requirements: PlatformRequirements,\r\n platform?: Platform\r\n): CompatibilityCheck {\r\n const detectedPlatform = platform ?? detect();\r\n const issues: string[] = [];\r\n const warnings: string[] = [];\r\n\r\n // Check for incompatible platforms\r\n if (requirements.incompatiblePlatforms?.includes(detectedPlatform)) {\r\n issues.push(\r\n `This hook is not compatible with ${getPlatformName(detectedPlatform)}. ` +\r\n `Incompatible platform detected.`\r\n );\r\n return { compatible: false, issues, warnings };\r\n }\r\n\r\n // Check for required platforms\r\n if (requirements.requiredPlatforms && requirements.requiredPlatforms.length > 0) {\r\n if (!requirements.requiredPlatforms.includes(detectedPlatform)) {\r\n const requiredNames = requirements.requiredPlatforms.map(getPlatformName).join(', ');\r\n issues.push(\r\n `This hook requires one of: ${requiredNames}. ` +\r\n `Current platform: ${getPlatformName(detectedPlatform)}.`\r\n );\r\n return { compatible: false, issues, warnings };\r\n }\r\n }\r\n\r\n // Check for optional platforms and add warning\r\n if (requirements.optionalPlatforms && requirements.optionalPlatforms.length > 0) {\r\n if (!requirements.optionalPlatforms.includes(detectedPlatform)) {\r\n const optionalNames = requirements.optionalPlatforms.map(getPlatformName).join(', ');\r\n warnings.push(\r\n `This hook has optional features for: ${optionalNames}. ` +\r\n `Some features may not work on ${getPlatformName(detectedPlatform)}.`\r\n );\r\n }\r\n }\r\n\r\n // All checks passed\r\n return { compatible: true, issues, warnings };\r\n}\r\n\r\n/**\r\n * Get platform-specific hook template adjustment\r\n * @param templateCommand - Base template command\r\n * @param platform - Optional platform override\r\n * @returns Adjusted command with platform-specific shell prefix\r\n */\r\nexport function adjustCommandForPlatform(\r\n templateCommand: string,\r\n platform?: Platform\r\n): string[] {\r\n const shellCmd = getShellCommand(getShell(platform));\r\n return [...shellCmd, templateCommand];\r\n}\r\n\r\n// ========== Default Platform Requirements ==========\r\n\r\n/**\r\n * Default platform requirements for common hook types\r\n */\r\nexport const DEFAULT_PLATFORM_REQUIREMENTS: Record<string, PlatformRequirements> = {\r\n 'memory-update': {\r\n // Works on all platforms\r\n requiredPlatforms: undefined,\r\n optionalPlatforms: undefined,\r\n incompatiblePlatforms: []\r\n },\r\n 'danger-protection': {\r\n // Works on all platforms\r\n requiredPlatforms: undefined,\r\n optionalPlatforms: undefined,\r\n incompatiblePlatforms: []\r\n },\r\n 'skill-context': {\r\n // Requires skills API - works on all platforms\r\n requiredPlatforms: undefined,\r\n optionalPlatforms: undefined,\r\n incompatiblePlatforms: []\r\n },\r\n 'git-operations': {\r\n // Git operations work on all platforms\r\n requiredPlatforms: undefined,\r\n optionalPlatforms: undefined,\r\n incompatiblePlatforms: []\r\n },\r\n 'file-operations': {\r\n // File operations need adjustment for Windows paths\r\n requiredPlatforms: undefined,\r\n optionalPlatforms: ['linux', 'macos'],\r\n incompatiblePlatforms: []\r\n },\r\n 'windows-specific': {\r\n // Windows-only hooks (e.g., PowerShell scripts)\r\n requiredPlatforms: ['windows'],\r\n optionalPlatforms: undefined,\r\n incompatiblePlatforms: []\r\n },\r\n 'unix-specific': {\r\n // Unix-only hooks (bash scripts with shebang)\r\n requiredPlatforms: ['linux', 'macos'],\r\n optionalPlatforms: undefined,\r\n incompatiblePlatforms: ['windows']\r\n }\r\n};\r\n","// ========================================\r\n// Hook Wizard Component\r\n// ========================================\r\n// Multi-step wizard for creating common hook patterns\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\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 {\r\n ChevronLeft,\r\n ChevronRight,\r\n Brain,\r\n Shield,\r\n Sparkles,\r\n CheckCircle,\r\n AlertTriangle,\r\n Plus,\r\n Trash2,\r\n} from 'lucide-react';\r\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\r\nimport { fetchSkills, type Skill, type SkillsResponse, saveHook } from '@/lib/api';\r\nimport { cn } from '@/lib/utils';\r\nimport {\r\n detect,\r\n getShell,\r\n getShellName,\r\n checkCompatibility,\r\n getPlatformName,\r\n DEFAULT_PLATFORM_REQUIREMENTS,\r\n type Platform,\r\n} from '@/utils/platformUtils';\r\n\r\n// ========== Types ==========\r\n\r\nexport type WizardType = 'memory-update' | 'danger-protection' | 'skill-context';\r\n\r\ntype WizardStep = 1 | 2 | 3;\r\n\r\nexport interface HookWizardProps {\r\n wizardType: WizardType;\r\n open: boolean;\r\n onClose: () => void;\r\n}\r\n\r\ninterface MemoryUpdateConfig {\r\n tool: 'gemini' | 'qwen' | 'codex' | 'opencode';\r\n threshold: number;\r\n timeout: number;\r\n}\r\n\r\ninterface DangerProtectionConfig {\r\n selectedOptions: string[];\r\n}\r\n\r\ninterface SkillContextConfig {\r\n mode: 'keyword' | 'auto';\r\n skillConfigs: Array<{ skill: string; keywords: string }>;\r\n}\r\n\r\n// ========== Hook Templates ==========\r\n// Templates are now defined in backend: ccw/src/core/hooks/hook-templates.ts\r\n// All templates use `ccw hook template exec <id> --stdin` format\r\n// This avoids Windows Git Bash quote handling issues\r\n\r\n// Template IDs that map to backend templates\r\nconst TEMPLATE_IDS = {\r\n 'memory-update-queue': 'memory-auto-compress',\r\n 'danger-bash-confirm': 'danger-bash-confirm',\r\n 'danger-file-protection': 'danger-file-protection',\r\n 'danger-git-destructive': 'danger-git-destructive',\r\n 'danger-network-confirm': 'danger-network-confirm',\r\n 'danger-system-paths': 'danger-system-paths',\r\n 'danger-permission-change': 'danger-permission-change',\r\n} as const;\r\n\r\n// Danger protection option definitions\r\nconst DANGER_OPTIONS = [\r\n { id: 'bash-confirm', templateId: 'danger-bash-confirm', labelKey: 'cliHooks.wizards.dangerProtection.options.bashConfirm', descKey: 'cliHooks.wizards.dangerProtection.options.bashConfirmDesc' },\r\n { id: 'file-protection', templateId: 'danger-file-protection', labelKey: 'cliHooks.wizards.dangerProtection.options.fileProtection', descKey: 'cliHooks.wizards.dangerProtection.options.fileProtectionDesc' },\r\n { id: 'git-destructive', templateId: 'danger-git-destructive', labelKey: 'cliHooks.wizards.dangerProtection.options.gitDestructive', descKey: 'cliHooks.wizards.dangerProtection.options.gitDestructiveDesc' },\r\n { id: 'network-confirm', templateId: 'danger-network-confirm', labelKey: 'cliHooks.wizards.dangerProtection.options.networkConfirm', descKey: 'cliHooks.wizards.dangerProtection.options.networkConfirmDesc' },\r\n { id: 'system-paths', templateId: 'danger-system-paths', labelKey: 'cliHooks.wizards.dangerProtection.options.systemPaths', descKey: 'cliHooks.wizards.dangerProtection.options.systemPathsDesc' },\r\n { id: 'permission-change', templateId: 'danger-permission-change', labelKey: 'cliHooks.wizards.dangerProtection.options.permissionChange', descKey: 'cliHooks.wizards.dangerProtection.options.permissionChangeDesc' },\r\n] as const;\r\n\r\n// ========== Wizard Definitions ==========\r\n\r\nconst WIZARD_METADATA = {\r\n 'memory-update': {\r\n title: 'cliHooks.wizards.memoryUpdate.title',\r\n description: 'cliHooks.wizards.memoryUpdate.description',\r\n icon: Brain,\r\n trigger: 'Stop' as const,\r\n platformRequirements: DEFAULT_PLATFORM_REQUIREMENTS['memory-update'],\r\n },\r\n 'danger-protection': {\r\n title: 'cliHooks.wizards.dangerProtection.title',\r\n description: 'cliHooks.wizards.dangerProtection.description',\r\n icon: Shield,\r\n trigger: 'PreToolUse' as const,\r\n platformRequirements: DEFAULT_PLATFORM_REQUIREMENTS['danger-protection'],\r\n },\r\n 'skill-context': {\r\n title: 'cliHooks.wizards.skillContext.title',\r\n description: 'cliHooks.wizards.skillContext.description',\r\n icon: Sparkles,\r\n trigger: 'UserPromptSubmit' as const,\r\n platformRequirements: DEFAULT_PLATFORM_REQUIREMENTS['skill-context'],\r\n },\r\n} as const;\r\n\r\n// ========== Main Component ==========\r\n\r\nexport function HookWizard({\r\n wizardType,\r\n open,\r\n onClose,\r\n}: HookWizardProps) {\r\n const { formatMessage } = useIntl();\r\n const queryClient = useQueryClient();\r\n const [currentStep, setCurrentStep] = useState<WizardStep>(1);\r\n const [detectedPlatform, setDetectedPlatform] = useState<Platform>('linux');\r\n const [scope, setScope] = useState<'project' | 'global'>('project');\r\n const [saving, setSaving] = useState(false);\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n // Fetch available skills for skill-context wizard\r\n const { data: skillsData, isLoading: skillsLoading } = useQuery<SkillsResponse>({\r\n queryKey: ['skills'],\r\n queryFn: () => fetchSkills(),\r\n enabled: open && wizardType === 'skill-context',\r\n });\r\n\r\n // Detect platform on mount\r\n useEffect(() => {\r\n if (open) {\r\n setDetectedPlatform(detect());\r\n }\r\n }, [open]);\r\n\r\n // Wizard configuration state\r\n const [memoryConfig, setMemoryConfig] = useState<MemoryUpdateConfig>({\r\n tool: 'gemini',\r\n threshold: 5,\r\n timeout: 300,\r\n });\r\n\r\n const [dangerConfig, setDangerConfig] = useState<DangerProtectionConfig>({\r\n selectedOptions: ['bash-confirm', 'file-protection', 'git-destructive'],\r\n });\r\n\r\n const [skillConfig, setSkillConfig] = useState<SkillContextConfig>({\r\n mode: 'keyword',\r\n skillConfigs: [{ skill: '', keywords: '' }],\r\n });\r\n\r\n // Check platform compatibility\r\n const wizardMetadata = WIZARD_METADATA[wizardType];\r\n const compatibilityCheck = checkCompatibility(\r\n wizardMetadata.platformRequirements,\r\n detectedPlatform\r\n );\r\n\r\n // Handlers\r\n const handleNext = () => {\r\n if (currentStep < 3) {\r\n setCurrentStep((prev) => (prev + 1) as WizardStep);\r\n }\r\n };\r\n\r\n const handlePrevious = () => {\r\n if (currentStep > 1) {\r\n setCurrentStep((prev) => (prev - 1) as WizardStep);\r\n }\r\n };\r\n\r\n const handleClose = () => {\r\n setCurrentStep(1);\r\n onClose();\r\n };\r\n\r\n const handleComplete = async () => {\r\n setSaving(true);\r\n try {\r\n switch (wizardType) {\r\n case 'memory-update': {\r\n // Use backend template API to install memory template\r\n const response = await fetch('/api/hooks/templates/install', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n templateId: 'memory-auto-compress',\r\n scope,\r\n projectPath,\r\n }),\r\n });\r\n const result = await response.json();\r\n if (!result.success) {\r\n throw new Error(result.error || 'Failed to install template');\r\n }\r\n break;\r\n }\r\n\r\n case 'danger-protection': {\r\n // Install each selected protection template via backend API\r\n for (const optionId of dangerConfig.selectedOptions) {\r\n const option = DANGER_OPTIONS.find(o => o.id === optionId);\r\n if (!option) continue;\r\n const templateId = TEMPLATE_IDS[option.templateId as keyof typeof TEMPLATE_IDS] || option.templateId;\r\n\r\n const response = await fetch('/api/hooks/templates/install', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n templateId,\r\n scope,\r\n projectPath,\r\n }),\r\n });\r\n const result = await response.json();\r\n if (!result.success) {\r\n console.warn(`Failed to install template ${templateId}:`, result.error);\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case 'skill-context': {\r\n // Use ccw hook command directly for skill context\r\n const hookData = skillConfig.mode === 'auto'\r\n ? {\r\n _templateId: 'skill-context-auto',\r\n matcher: '',\r\n hooks: [{\r\n type: 'command',\r\n command: 'ccw hook keyword --stdin',\r\n }],\r\n }\r\n : {\r\n _templateId: 'skill-context-keyword',\r\n matcher: '',\r\n hooks: [{\r\n type: 'command',\r\n command: 'ccw hook keyword --stdin',\r\n }],\r\n };\r\n await saveHook(scope, 'UserPromptSubmit', hookData);\r\n break;\r\n }\r\n }\r\n\r\n queryClient.invalidateQueries({ queryKey: ['hooks'] });\r\n handleClose();\r\n } catch (err) {\r\n console.error('Failed to create hook:', err);\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n // ========== Step Renderers ==========\r\n\r\n const renderStep1 = () => {\r\n const WizardIcon = WIZARD_METADATA[wizardType].icon;\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n <div className=\"flex items-center gap-3 pb-4 border-b\">\r\n <div className=\"p-3 rounded-lg bg-primary/10\">\r\n <WizardIcon className=\"w-6 h-6 text-primary\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <h3 className=\"text-lg font-semibold text-foreground\">\r\n {formatMessage({ id: WIZARD_METADATA[wizardType].title })}\r\n </h3>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: WIZARD_METADATA[wizardType].description })}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n <Card className=\"p-4\">\r\n <div className=\"flex items-center gap-3\">\r\n <CheckCircle className={cn(\r\n 'w-5 h-5',\r\n compatibilityCheck.compatible ? 'text-green-500' : 'text-destructive'\r\n )} />\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.platform.detected' })}\r\n </p>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {getPlatformName(detectedPlatform)} ({getShellName(getShell(detectedPlatform))})\r\n </p>\r\n </div>\r\n <Badge variant={compatibilityCheck.compatible ? 'default' : 'destructive'}>\r\n {compatibilityCheck.compatible\r\n ? formatMessage({ id: 'cliHooks.wizards.platform.compatible' })\r\n : formatMessage({ id: 'cliHooks.wizards.platform.incompatible' })\r\n }\r\n </Badge>\r\n </div>\r\n\r\n {!compatibilityCheck.compatible && compatibilityCheck.issues.length > 0 && (\r\n <div className=\"mt-3 flex items-start gap-2 p-3 bg-destructive/10 rounded-lg\">\r\n <AlertTriangle className=\"w-4 h-4 text-destructive shrink-0 mt-0.5\" />\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium text-destructive\">\r\n {formatMessage({ id: 'cliHooks.wizards.platform.compatibilityError' })}\r\n </p>\r\n <ul className=\"mt-1 space-y-1\">\r\n {compatibilityCheck.issues.map((issue, i) => (\r\n <li key={i} className=\"text-xs text-destructive/80\">{issue}</li>\r\n ))}\r\n </ul>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {compatibilityCheck.warnings.length > 0 && (\r\n <div className=\"mt-3 flex items-start gap-2 p-3 bg-yellow-500/10 rounded-lg\">\r\n <AlertTriangle className=\"w-4 h-4 text-yellow-600 shrink-0 mt-0.5\" />\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium text-yellow-600\">\r\n {formatMessage({ id: 'cliHooks.wizards.platform.compatibilityWarning' })}\r\n </p>\r\n <ul className=\"mt-1 space-y-1\">\r\n {compatibilityCheck.warnings.map((warning, i) => (\r\n <li key={i} className=\"text-xs text-yellow-600/80\">{warning}</li>\r\n ))}\r\n </ul>\r\n </div>\r\n </div>\r\n )}\r\n </Card>\r\n\r\n <Card className=\"p-4\">\r\n <p className=\"text-sm text-muted-foreground mb-2\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.triggerEvent' })}\r\n </p>\r\n <Badge variant=\"secondary\">\r\n {formatMessage({ id: `cliHooks.trigger.${wizardMetadata.trigger}` })}\r\n </Badge>\r\n </Card>\r\n </div>\r\n );\r\n };\r\n\r\n const renderStep2 = () => {\r\n switch (wizardType) {\r\n case 'memory-update':\r\n return renderMemoryUpdateConfig();\r\n case 'danger-protection':\r\n return renderDangerProtectionConfig();\r\n case 'skill-context':\r\n return renderSkillContextConfig();\r\n default:\r\n return null;\r\n }\r\n };\r\n\r\n const renderStep3 = () => {\r\n return (\r\n <div className=\"space-y-4\">\r\n <div className=\"text-center pb-4 border-b\">\r\n <CheckCircle className=\"w-12 h-12 text-green-500 mx-auto mb-3\" />\r\n <h3 className=\"text-lg font-semibold text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.title' })}\r\n </h3>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.description' })}\r\n </p>\r\n </div>\r\n\r\n <Card className=\"p-4 space-y-3\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.hookType' })}\r\n </span>\r\n <span className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: WIZARD_METADATA[wizardType].title })}\r\n </span>\r\n </div>\r\n\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.trigger' })}\r\n </span>\r\n <Badge variant=\"secondary\" className=\"text-xs\">\r\n {formatMessage({ id: `cliHooks.trigger.${wizardMetadata.trigger}` })}\r\n </Badge>\r\n </div>\r\n\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.platform' })}\r\n </span>\r\n <span className=\"text-sm text-foreground\">\r\n {getPlatformName(detectedPlatform)}\r\n </span>\r\n </div>\r\n\r\n {renderConfigSummary()}\r\n </Card>\r\n\r\n {/* Scope Selection */}\r\n <Card className=\"p-4\">\r\n <p className=\"text-sm font-medium text-foreground mb-3\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.installTo' })}\r\n </p>\r\n <div className=\"flex gap-4\">\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"wizardScope\"\r\n value=\"project\"\r\n checked={scope === 'project'}\r\n onChange={() => setScope('project')}\r\n className=\"accent-primary\"\r\n />\r\n <span className=\"text-sm text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.scopeProject' })}\r\n </span>\r\n <span className=\"text-xs text-muted-foreground\">(.claude/settings.json)</span>\r\n </label>\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"wizardScope\"\r\n value=\"global\"\r\n checked={scope === 'global'}\r\n onChange={() => setScope('global')}\r\n className=\"accent-primary\"\r\n />\r\n <span className=\"text-sm text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.scopeGlobal' })}\r\n </span>\r\n <span className=\"text-xs text-muted-foreground\">(~/.claude/settings.json)</span>\r\n </label>\r\n </div>\r\n </Card>\r\n\r\n {/* Command Preview */}\r\n <Card className=\"p-4\">\r\n <p className=\"text-xs text-muted-foreground mb-2\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.commandPreview' })}\r\n </p>\r\n <pre className=\"text-xs font-mono bg-muted p-3 rounded-lg overflow-x-auto whitespace-pre-wrap break-all\">\r\n {getPreviewCommand()}\r\n </pre>\r\n </Card>\r\n </div>\r\n );\r\n };\r\n\r\n // ========== Configuration Renderers ==========\r\n\r\n const renderMemoryUpdateConfig = () => (\r\n <div className=\"space-y-4\">\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.memoryUpdate.cliTool' })}\r\n </label>\r\n <Select\r\n value={memoryConfig.tool}\r\n onValueChange={(value: MemoryUpdateConfig['tool']) => setMemoryConfig({ ...memoryConfig, tool: value })}\r\n >\r\n <SelectTrigger className=\"mt-1\">\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"gemini\">Gemini</SelectItem>\r\n <SelectItem value=\"qwen\">Qwen</SelectItem>\r\n <SelectItem value=\"codex\">Codex</SelectItem>\r\n <SelectItem value=\"opencode\">OpenCode</SelectItem>\r\n </SelectContent>\r\n </Select>\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'cliHooks.wizards.memoryUpdate.cliToolHelp' })}\r\n </p>\r\n </div>\r\n\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.memoryUpdate.threshold' })}\r\n </label>\r\n <Input\r\n type=\"number\"\r\n value={memoryConfig.threshold}\r\n onChange={(e) => setMemoryConfig({ ...memoryConfig, threshold: Math.max(1, Math.min(20, parseInt(e.target.value) || 1)) })}\r\n min={1}\r\n max={20}\r\n className=\"mt-1\"\r\n />\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'cliHooks.wizards.memoryUpdate.thresholdHelp' })}\r\n </p>\r\n </div>\r\n\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.memoryUpdate.timeout' })}\r\n </label>\r\n <Input\r\n type=\"number\"\r\n value={memoryConfig.timeout}\r\n onChange={(e) => setMemoryConfig({ ...memoryConfig, timeout: Math.max(60, Math.min(1800, parseInt(e.target.value) || 60)) })}\r\n min={60}\r\n max={1800}\r\n step={60}\r\n className=\"mt-1\"\r\n />\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'cliHooks.wizards.memoryUpdate.timeoutHelp' })}\r\n </p>\r\n </div>\r\n </div>\r\n );\r\n\r\n const renderDangerProtectionConfig = () => {\r\n const toggleOption = (optionId: string) => {\r\n setDangerConfig(prev => {\r\n const selected = prev.selectedOptions.includes(optionId)\r\n ? prev.selectedOptions.filter(id => id !== optionId)\r\n : [...prev.selectedOptions, optionId];\r\n return { selectedOptions: selected };\r\n });\r\n };\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.dangerProtection.selectProtections' })}\r\n </p>\r\n {DANGER_OPTIONS.map(option => (\r\n <label\r\n key={option.id}\r\n className={cn(\r\n 'flex items-start gap-3 p-3 rounded-lg border cursor-pointer transition-colors',\r\n dangerConfig.selectedOptions.includes(option.id)\r\n ? 'border-primary bg-primary/5'\r\n : 'border-border hover:border-primary/50'\r\n )}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={dangerConfig.selectedOptions.includes(option.id)}\r\n onChange={() => toggleOption(option.id)}\r\n className=\"mt-0.5 accent-primary\"\r\n />\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: option.labelKey })}\r\n </p>\r\n <p className=\"text-xs text-muted-foreground mt-0.5\">\r\n {formatMessage({ id: option.descKey })}\r\n </p>\r\n </div>\r\n </label>\r\n ))}\r\n </div>\r\n );\r\n };\r\n\r\n const renderSkillContextConfig = () => {\r\n const skills: Skill[] = skillsData?.skills ?? [];\r\n\r\n const addConfig = () => {\r\n setSkillConfig(prev => ({\r\n ...prev,\r\n skillConfigs: [...prev.skillConfigs, { skill: '', keywords: '' }],\r\n }));\r\n };\r\n\r\n const removeConfig = (index: number) => {\r\n setSkillConfig(prev => ({\r\n ...prev,\r\n skillConfigs: prev.skillConfigs.filter((_, i) => i !== index),\r\n }));\r\n };\r\n\r\n const updateConfig = (index: number, field: 'skill' | 'keywords', value: string) => {\r\n setSkillConfig(prev => {\r\n const newConfigs = [...prev.skillConfigs];\r\n newConfigs[index] = { ...newConfigs[index], [field]: value };\r\n return { ...prev, skillConfigs: newConfigs };\r\n });\r\n };\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Mode Selection */}\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.skillContext.mode' })}\r\n </label>\r\n <div className=\"flex gap-3 mt-2\">\r\n <label className={cn(\r\n 'flex-1 flex items-center gap-2 p-3 rounded-lg border cursor-pointer transition-colors',\r\n skillConfig.mode === 'keyword' ? 'border-primary bg-primary/5' : 'border-border'\r\n )}>\r\n <input\r\n type=\"radio\"\r\n name=\"skillMode\"\r\n value=\"keyword\"\r\n checked={skillConfig.mode === 'keyword'}\r\n onChange={() => setSkillConfig(prev => ({ ...prev, mode: 'keyword' }))}\r\n className=\"accent-primary\"\r\n />\r\n <div>\r\n <p className=\"text-sm font-medium\">{formatMessage({ id: 'cliHooks.wizards.skillContext.modeKeyword' })}</p>\r\n <p className=\"text-xs text-muted-foreground\">{formatMessage({ id: 'cliHooks.wizards.skillContext.modeKeywordDesc' })}</p>\r\n </div>\r\n </label>\r\n <label className={cn(\r\n 'flex-1 flex items-center gap-2 p-3 rounded-lg border cursor-pointer transition-colors',\r\n skillConfig.mode === 'auto' ? 'border-primary bg-primary/5' : 'border-border'\r\n )}>\r\n <input\r\n type=\"radio\"\r\n name=\"skillMode\"\r\n value=\"auto\"\r\n checked={skillConfig.mode === 'auto'}\r\n onChange={() => setSkillConfig(prev => ({ ...prev, mode: 'auto' }))}\r\n className=\"accent-primary\"\r\n />\r\n <div>\r\n <p className=\"text-sm font-medium\">{formatMessage({ id: 'cliHooks.wizards.skillContext.modeAuto' })}</p>\r\n <p className=\"text-xs text-muted-foreground\">{formatMessage({ id: 'cliHooks.wizards.skillContext.modeAutoDesc' })}</p>\r\n </div>\r\n </label>\r\n </div>\r\n </div>\r\n\r\n {/* Keyword mode: skill config list */}\r\n {skillConfig.mode === 'keyword' && (\r\n <>\r\n {skillsLoading ? (\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.skillContext.loadingSkills' })}\r\n </p>\r\n ) : (\r\n <div className=\"space-y-3\">\r\n {skillConfig.skillConfigs.map((config, index) => (\r\n <div key={index} className=\"flex items-center gap-2\">\r\n <Select value={config.skill} onValueChange={(value) => updateConfig(index, 'skill', value)}>\r\n <SelectTrigger className=\"w-[160px]\">\r\n <SelectValue placeholder={formatMessage({ id: 'cliHooks.wizards.skillContext.selectSkill' })} />\r\n </SelectTrigger>\r\n <SelectContent>\r\n {skills.map((skill) => (\r\n <SelectItem key={skill.name} value={skill.name}>\r\n {skill.name}\r\n </SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n <Input\r\n value={config.keywords}\r\n onChange={(e) => updateConfig(index, 'keywords', e.target.value)}\r\n placeholder={formatMessage({ id: 'cliHooks.wizards.skillContext.keywordsPlaceholder' })}\r\n className=\"flex-1\"\r\n />\r\n {skillConfig.skillConfigs.length > 1 && (\r\n <Button variant=\"ghost\" size=\"icon\" onClick={() => removeConfig(index)}>\r\n <Trash2 className=\"w-4 h-4\" />\r\n </Button>\r\n )}\r\n </div>\r\n ))}\r\n <Button variant=\"outline\" size=\"sm\" onClick={addConfig} className=\"w-full\">\r\n <Plus className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'cliHooks.wizards.skillContext.addPair' })}\r\n </Button>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n\r\n {/* Auto mode: info display */}\r\n {skillConfig.mode === 'auto' && (\r\n <Card className=\"p-4 bg-muted/30\">\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.skillContext.autoDescription' })}\r\n </p>\r\n {!skillsLoading && skills.length > 0 && (\r\n <div className=\"mt-2 flex flex-wrap gap-1\">\r\n {skills.map(s => (\r\n <Badge key={s.name} variant=\"secondary\" className=\"text-xs\">{s.name}</Badge>\r\n ))}\r\n </div>\r\n )}\r\n </Card>\r\n )}\r\n </div>\r\n );\r\n };\r\n\r\n // ========== Config Summary ==========\r\n\r\n const renderConfigSummary = () => {\r\n switch (wizardType) {\r\n case 'memory-update':\r\n return (\r\n <div className=\"space-y-2 text-sm\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-muted-foreground\">CLI Tool</span>\r\n <Badge variant=\"secondary\">{memoryConfig.tool}</Badge>\r\n </div>\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-muted-foreground\">Threshold</span>\r\n <span>{memoryConfig.threshold} paths</span>\r\n </div>\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-muted-foreground\">Timeout</span>\r\n <span>{memoryConfig.timeout}s</span>\r\n </div>\r\n </div>\r\n );\r\n\r\n case 'danger-protection':\r\n return (\r\n <div className=\"space-y-2 text-sm\">\r\n <span className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.dangerProtection.selectedProtections' })}:\r\n </span>\r\n <div className=\"mt-1 flex flex-wrap gap-1\">\r\n {dangerConfig.selectedOptions.map(id => {\r\n const opt = DANGER_OPTIONS.find(o => o.id === id);\r\n return opt ? (\r\n <Badge key={id} variant=\"secondary\" className=\"text-xs\">\r\n {formatMessage({ id: opt.labelKey })}\r\n </Badge>\r\n ) : null;\r\n })}\r\n </div>\r\n </div>\r\n );\r\n\r\n case 'skill-context':\r\n return (\r\n <div className=\"space-y-2 text-sm\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.skillContext.mode' })}\r\n </span>\r\n <Badge variant=\"secondary\">\r\n {skillConfig.mode === 'auto'\r\n ? formatMessage({ id: 'cliHooks.wizards.skillContext.modeAuto' })\r\n : formatMessage({ id: 'cliHooks.wizards.skillContext.modeKeyword' })\r\n }\r\n </Badge>\r\n </div>\r\n {skillConfig.mode === 'keyword' && (\r\n <div>\r\n <span className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.skillContext.keywordMappings' })}:\r\n </span>\r\n <div className=\"mt-1 space-y-1\">\r\n {skillConfig.skillConfigs\r\n .filter(c => c.skill && c.keywords)\r\n .map((config, i) => (\r\n <div key={i} className=\"flex items-center gap-2 text-xs\">\r\n <Badge variant=\"outline\">{config.keywords}</Badge>\r\n <span className=\"text-muted-foreground\">{'->'}</span>\r\n <Badge variant=\"secondary\">{config.skill}</Badge>\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n\r\n default:\r\n return null;\r\n }\r\n };\r\n\r\n // ========== Command Preview ==========\r\n\r\n const getPreviewCommand = (): string => {\r\n switch (wizardType) {\r\n case 'memory-update': {\r\n return `ccw hook template exec memory-auto-compress --stdin`;\r\n }\r\n case 'danger-protection': {\r\n const templates = dangerConfig.selectedOptions\r\n .map(id => DANGER_OPTIONS.find(o => o.id === id))\r\n .filter(Boolean)\r\n .map(opt => {\r\n const templateId = TEMPLATE_IDS[opt!.templateId as keyof typeof TEMPLATE_IDS] || opt!.templateId;\r\n return `ccw hook template exec ${templateId} --stdin`;\r\n });\r\n return templates.length > 0\r\n ? templates.join('\\n')\r\n : '# No protections selected';\r\n }\r\n case 'skill-context': {\r\n return `ccw hook keyword --stdin`;\r\n }\r\n default:\r\n return '';\r\n }\r\n };\r\n\r\n // ========== Navigation ==========\r\n\r\n const renderNavigation = () => (\r\n <DialogFooter className=\"gap-2\">\r\n {currentStep > 1 && (\r\n <Button variant=\"outline\" onClick={handlePrevious} disabled={saving}>\r\n <ChevronLeft className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'cliHooks.wizards.navigation.previous' })}\r\n </Button>\r\n )}\r\n {currentStep < 3 ? (\r\n <Button onClick={handleNext} disabled={!compatibilityCheck.compatible}>\r\n {formatMessage({ id: 'cliHooks.wizards.navigation.next' })}\r\n <ChevronRight className=\"w-4 h-4 ml-1\" />\r\n </Button>\r\n ) : (\r\n <Button onClick={handleComplete} disabled={saving}>\r\n {saving\r\n ? formatMessage({ id: 'cliHooks.wizards.navigation.creating' })\r\n : formatMessage({ id: 'cliHooks.wizards.navigation.create' })\r\n }\r\n </Button>\r\n )}\r\n </DialogFooter>\r\n );\r\n\r\n // ========== Step Indicator ==========\r\n\r\n const renderStepIndicator = () => (\r\n <div className=\"flex items-center justify-center gap-2 pb-4\">\r\n {[1, 2, 3].map((step) => (\r\n <div key={step} className=\"flex items-center\">\r\n <div\r\n className={cn(\r\n 'w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium',\r\n currentStep === step\r\n ? 'bg-primary text-primary-foreground'\r\n : currentStep > step\r\n ? 'bg-green-500 text-white'\r\n : 'bg-muted text-muted-foreground'\r\n )}\r\n >\r\n {currentStep > step ? <CheckCircle className=\"w-4 h-4\" /> : step}\r\n </div>\r\n {step < 3 && (\r\n <div\r\n className={cn(\r\n 'w-12 h-0.5 mx-1',\r\n currentStep > step ? 'bg-green-500' : 'bg-muted'\r\n )}\r\n />\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n\r\n return (\r\n <Dialog open={open} onOpenChange={handleClose}>\r\n <DialogContent className=\"sm:max-w-[600px]\">\r\n <DialogHeader>\r\n <DialogTitle className=\"flex items-center gap-2\">\r\n {formatMessage({ id: 'cliHooks.wizards.title' })}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <div className=\"w-full bg-muted h-1 rounded-full my-4\">\r\n <div\r\n className=\"bg-primary h-1 rounded-full transition-all duration-300\"\r\n style={{ width: `${(currentStep / 3) * 100}%` }}\r\n />\r\n </div>\r\n\r\n {renderStepIndicator()}\r\n\r\n <div className=\"min-h-[300px]\">\r\n {currentStep === 1 && renderStep1()}\r\n {currentStep === 2 && renderStep2()}\r\n {currentStep === 3 && renderStep3()}\r\n </div>\r\n\r\n {renderNavigation()}\r\n </DialogContent>\r\n </Dialog>\r\n );\r\n}\r\n\r\nexport default HookWizard;\r\n","// ========================================\r\n// Hook Manager Page\r\n// ========================================\r\n// Full CRUD page for managing CLI hooks\r\n\r\nimport { useState, useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\nimport {\r\n GitFork,\r\n Plus,\r\n Search,\r\n RefreshCw,\r\n Play,\r\n Zap,\r\n Wrench,\r\n CheckCircle,\r\n StopCircle,\r\n Wand2,\r\n Brain,\r\n Shield,\r\n Sparkles,\r\n ChevronDown,\r\n ChevronUp,\r\n} from 'lucide-react';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { HookCard, HookFormDialog, HookQuickTemplates, HookWizard, type HookCardData, type HookFormData, type HookTriggerType, HOOK_TEMPLATES, type WizardType } from '@/components/hook';\r\nimport { useHooks, useToggleHook, useDeleteHook } from '@/hooks';\r\nimport { cn } from '@/lib/utils';\r\n\r\n// ========== Types ==========\r\n\r\ninterface HooksByTrigger {\r\n SessionStart: HookCardData[];\r\n UserPromptSubmit: HookCardData[];\r\n PreToolUse: HookCardData[];\r\n PostToolUse: HookCardData[];\r\n Stop: HookCardData[];\r\n Notification: HookCardData[];\r\n SubagentStart: HookCardData[];\r\n SubagentStop: HookCardData[];\r\n PreCompact: HookCardData[];\r\n SessionEnd: HookCardData[];\r\n PostToolUseFailure: HookCardData[];\r\n PermissionRequest: HookCardData[];\r\n}\r\n\r\n// ========== Helper Functions ==========\r\n\r\nfunction isHookTriggerType(value: string): value is HookTriggerType {\r\n return ['SessionStart', 'UserPromptSubmit', 'PreToolUse', 'PostToolUse', 'Stop', 'Notification', 'SubagentStart', 'SubagentStop', 'PreCompact', 'SessionEnd', 'PostToolUseFailure', 'PermissionRequest'].includes(value);\r\n}\r\n\r\nfunction toHookCardData(hook: { name: string; description?: string; enabled: boolean; trigger: string; matcher?: string; command?: string; script?: string; scope?: 'global' | 'project'; index?: number }): HookCardData | null {\r\n if (!isHookTriggerType(hook.trigger)) {\r\n return null;\r\n }\r\n return {\r\n name: hook.name,\r\n description: hook.description,\r\n enabled: hook.enabled,\r\n trigger: hook.trigger,\r\n matcher: hook.matcher,\r\n command: hook.command || hook.script,\r\n scope: hook.scope,\r\n index: hook.index,\r\n };\r\n}\r\n\r\nfunction groupHooksByTrigger(hooks: HookCardData[]): HooksByTrigger {\r\n return {\r\n SessionStart: hooks.filter((h) => h.trigger === 'SessionStart'),\r\n UserPromptSubmit: hooks.filter((h) => h.trigger === 'UserPromptSubmit'),\r\n PreToolUse: hooks.filter((h) => h.trigger === 'PreToolUse'),\r\n PostToolUse: hooks.filter((h) => h.trigger === 'PostToolUse'),\r\n Stop: hooks.filter((h) => h.trigger === 'Stop'),\r\n Notification: hooks.filter((h) => h.trigger === 'Notification'),\r\n SubagentStart: hooks.filter((h) => h.trigger === 'SubagentStart'),\r\n SubagentStop: hooks.filter((h) => h.trigger === 'SubagentStop'),\r\n PreCompact: hooks.filter((h) => h.trigger === 'PreCompact'),\r\n SessionEnd: hooks.filter((h) => h.trigger === 'SessionEnd'),\r\n PostToolUseFailure: hooks.filter((h) => h.trigger === 'PostToolUseFailure'),\r\n PermissionRequest: hooks.filter((h) => h.trigger === 'PermissionRequest'),\r\n };\r\n}\r\n\r\nfunction getTriggerStats(hooksByTrigger: HooksByTrigger) {\r\n return {\r\n SessionStart: {\r\n total: hooksByTrigger.SessionStart.length,\r\n enabled: hooksByTrigger.SessionStart.filter((h) => h.enabled).length,\r\n },\r\n UserPromptSubmit: {\r\n total: hooksByTrigger.UserPromptSubmit.length,\r\n enabled: hooksByTrigger.UserPromptSubmit.filter((h) => h.enabled).length,\r\n },\r\n PreToolUse: {\r\n total: hooksByTrigger.PreToolUse.length,\r\n enabled: hooksByTrigger.PreToolUse.filter((h) => h.enabled).length,\r\n },\r\n PostToolUse: {\r\n total: hooksByTrigger.PostToolUse.length,\r\n enabled: hooksByTrigger.PostToolUse.filter((h) => h.enabled).length,\r\n },\r\n Stop: {\r\n total: hooksByTrigger.Stop.length,\r\n enabled: hooksByTrigger.Stop.filter((h) => h.enabled).length,\r\n },\r\n Notification: {\r\n total: hooksByTrigger.Notification.length,\r\n enabled: hooksByTrigger.Notification.filter((h) => h.enabled).length,\r\n },\r\n SubagentStart: {\r\n total: hooksByTrigger.SubagentStart.length,\r\n enabled: hooksByTrigger.SubagentStart.filter((h) => h.enabled).length,\r\n },\r\n SubagentStop: {\r\n total: hooksByTrigger.SubagentStop.length,\r\n enabled: hooksByTrigger.SubagentStop.filter((h) => h.enabled).length,\r\n },\r\n PreCompact: {\r\n total: hooksByTrigger.PreCompact.length,\r\n enabled: hooksByTrigger.PreCompact.filter((h) => h.enabled).length,\r\n },\r\n SessionEnd: {\r\n total: hooksByTrigger.SessionEnd.length,\r\n enabled: hooksByTrigger.SessionEnd.filter((h) => h.enabled).length,\r\n },\r\n PostToolUseFailure: {\r\n total: hooksByTrigger.PostToolUseFailure.length,\r\n enabled: hooksByTrigger.PostToolUseFailure.filter((h) => h.enabled).length,\r\n },\r\n PermissionRequest: {\r\n total: hooksByTrigger.PermissionRequest.length,\r\n enabled: hooksByTrigger.PermissionRequest.filter((h) => h.enabled).length,\r\n },\r\n };\r\n}\r\n\r\n// ========== Main Page Component ==========\r\n\r\nexport function HookManagerPage() {\r\n const { formatMessage } = useIntl();\r\n const [searchQuery, setSearchQuery] = useState('');\r\n const [selectedTrigger, setSelectedTrigger] = useState<HookTriggerType | 'all'>('all');\r\n const [dialogOpen, setDialogOpen] = useState(false);\r\n const [dialogMode, setDialogMode] = useState<'create' | 'edit'>('create');\r\n const [editingHook, setEditingHook] = useState<HookCardData | undefined>();\r\n const [wizardOpen, setWizardOpen] = useState(false);\r\n const [wizardType, setWizardType] = useState<WizardType>('memory-update');\r\n const [expandedHooks, setExpandedHooks] = useState<Set<string>>(new Set());\r\n const [templatesExpanded, setTemplatesExpanded] = useState(false);\r\n const [wizardsExpanded, setWizardsExpanded] = useState(false);\r\n\r\n const { hooks, enabledCount, totalCount, isLoading, refetch } = useHooks();\r\n const { toggleHook } = useToggleHook();\r\n const { deleteHook } = useDeleteHook();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n // Convert hooks to HookCardData and filter by search query and trigger type\r\n const filteredHooks = useMemo(() => {\r\n let validHooks = hooks.map(toHookCardData).filter((h): h is HookCardData => h !== null);\r\n\r\n // Filter by trigger type\r\n if (selectedTrigger !== 'all') {\r\n validHooks = validHooks.filter(h => h.trigger === selectedTrigger);\r\n }\r\n\r\n // Filter by search query\r\n if (searchQuery.trim()) {\r\n const query = searchQuery.toLowerCase();\r\n validHooks = validHooks.filter(\r\n (h) =>\r\n h.name.toLowerCase().includes(query) ||\r\n (h.description && h.description.toLowerCase().includes(query)) ||\r\n h.trigger.toLowerCase().includes(query) ||\r\n (h.command && h.command.toLowerCase().includes(query))\r\n );\r\n }\r\n\r\n return validHooks;\r\n }, [hooks, searchQuery, selectedTrigger]);\r\n\r\n // Group hooks by trigger type\r\n const hooksByTrigger = useMemo(() => groupHooksByTrigger(filteredHooks), [filteredHooks]);\r\n\r\n // Get stats for each trigger type\r\n const triggerStats = useMemo(() => getTriggerStats(hooksByTrigger), [hooksByTrigger]);\r\n\r\n // Handlers\r\n const handleAddClick = () => {\r\n setDialogMode('create');\r\n setEditingHook(undefined);\r\n setDialogOpen(true);\r\n };\r\n\r\n const handleEditClick = (hook: HookCardData) => {\r\n setDialogMode('edit');\r\n setEditingHook(hook);\r\n setDialogOpen(true);\r\n };\r\n\r\n const handleDeleteClick = async (hookName: string) => {\r\n // Find the hook in filteredHooks to get scope and index\r\n const hook = filteredHooks.find(h => h.name === hookName);\r\n if (!hook) {\r\n console.error('Hook not found:', hookName);\r\n return;\r\n }\r\n try {\r\n await deleteHook({\r\n name: hook.name,\r\n scope: hook.scope,\r\n trigger: hook.trigger,\r\n index: hook.index,\r\n });\r\n } catch (error) {\r\n console.error('Failed to delete hook:', error);\r\n }\r\n };\r\n\r\n const handleSave = async (data: HookFormData) => {\r\n // This will be implemented when create/update APIs are added\r\n console.log('Save hook:', data);\r\n await refetch();\r\n };\r\n\r\n const handleToggleHookExpand = (hookName: string) => {\r\n setExpandedHooks((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(hookName)) {\r\n next.delete(hookName);\r\n } else {\r\n next.add(hookName);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n // ========== Wizard Handlers ==========\r\n\r\n const wizardTypes: Array<{ type: WizardType; icon: typeof Brain; label: string; description: string }> = [\r\n {\r\n type: 'memory-update',\r\n icon: Brain,\r\n label: formatMessage({ id: 'cliHooks.wizards.memoryUpdate.title' }),\r\n description: formatMessage({ id: 'cliHooks.wizards.memoryUpdate.shortDescription' }),\r\n },\r\n {\r\n type: 'danger-protection',\r\n icon: Shield,\r\n label: formatMessage({ id: 'cliHooks.wizards.dangerProtection.title' }),\r\n description: formatMessage({ id: 'cliHooks.wizards.dangerProtection.shortDescription' }),\r\n },\r\n {\r\n type: 'skill-context',\r\n icon: Sparkles,\r\n label: formatMessage({ id: 'cliHooks.wizards.skillContext.title' }),\r\n description: formatMessage({ id: 'cliHooks.wizards.skillContext.shortDescription' }),\r\n },\r\n ];\r\n\r\n const handleLaunchWizard = (type: WizardType) => {\r\n setWizardType(type);\r\n setWizardOpen(true);\r\n };\r\n\r\n // ========== Quick Templates Logic ==========\r\n\r\n // Determine which templates are already installed\r\n const installedTemplates = useMemo(() => {\r\n return HOOK_TEMPLATES.filter(template => {\r\n return hooks.some(hook => hook.templateId === template.id);\r\n }).map(t => t.id);\r\n }, [hooks]);\r\n\r\n // Track per-template installing state\r\n const [installingTemplateId, setInstallingTemplateId] = useState<string | null>(null);\r\n\r\n const handleInstallTemplate = async (templateId: string) => {\r\n const template = HOOK_TEMPLATES.find(t => t.id === templateId);\r\n if (!template) return;\r\n\r\n setInstallingTemplateId(templateId);\r\n try {\r\n // Use backend API to install template\r\n const response = await fetch('/api/hooks/templates/install', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n templateId,\r\n scope: 'project',\r\n projectPath,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`Failed to install template: ${response.statusText}`);\r\n }\r\n\r\n const result = await response.json();\r\n if (!result.success) {\r\n throw new Error(result.error || 'Unknown error');\r\n }\r\n\r\n await refetch();\r\n } catch (error) {\r\n console.error('Failed to install template:', error);\r\n } finally {\r\n setInstallingTemplateId(null);\r\n }\r\n };\r\n\r\n const FILTER_OPTIONS: Array<{ type: HookTriggerType | 'all'; icon: typeof Zap; label: string }> = [\r\n { type: 'all', icon: GitFork, label: formatMessage({ id: 'common.all' }) },\r\n { type: 'SessionStart', icon: Play, label: formatMessage({ id: 'cliHooks.trigger.SessionStart' }) },\r\n { type: 'UserPromptSubmit', icon: Zap, label: formatMessage({ id: 'cliHooks.trigger.UserPromptSubmit' }) },\r\n { type: 'PreToolUse', icon: Wrench, label: formatMessage({ id: 'cliHooks.trigger.PreToolUse' }) },\r\n { type: 'PostToolUse', icon: CheckCircle, label: formatMessage({ id: 'cliHooks.trigger.PostToolUse' }) },\r\n { type: 'Stop', icon: StopCircle, label: formatMessage({ id: 'cliHooks.trigger.Stop' }) },\r\n ];\r\n\r\n return (\r\n <div className=\"max-w-6xl mx-auto space-y-6\">\r\n {/* Page Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-foreground flex items-center gap-2\">\r\n <GitFork className=\"w-6 h-6 text-primary\" />\r\n {formatMessage({ id: 'cliHooks.title' })}\r\n </h1>\r\n <p className=\"text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'cliHooks.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={isLoading}\r\n >\r\n <RefreshCw className={cn('w-4 h-4 mr-1', isLoading && 'animate-spin')} />\r\n {formatMessage({ id: 'common.actions.refresh' })}\r\n </Button>\r\n <Button variant=\"outline\" size=\"sm\" onClick={handleAddClick}>\r\n <Plus className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'cliHooks.actions.add' })}\r\n </Button>\r\n <Button size=\"sm\" onClick={() => handleLaunchWizard('memory-update')} variant=\"secondary\">\r\n <Wand2 className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'cliHooks.wizards.launch' })}\r\n </Button>\r\n </div>\r\n </div>\r\n\r\n {/* Search and Filters */}\r\n <Card className=\"p-4\">\r\n <div className=\"space-y-4\">\r\n {/* Search Bar */}\r\n <div className=\"flex items-center justify-between gap-4\">\r\n <div className=\"relative flex-1 max-w-md\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground\" />\r\n <Input\r\n placeholder={formatMessage({ id: 'cliHooks.filters.searchPlaceholder' })}\r\n value={searchQuery}\r\n onChange={(e) => setSearchQuery(e.target.value)}\r\n className=\"pl-9\"\r\n />\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <Badge variant=\"outline\" className=\"text-sm\">\r\n {formatMessage({ id: 'cliHooks.stats.total' }, { count: totalCount })}\r\n </Badge>\r\n <Badge variant=\"default\" className=\"text-sm\">\r\n {formatMessage({ id: 'cliHooks.stats.enabled' }, { count: enabledCount })}\r\n </Badge>\r\n </div>\r\n </div>\r\n\r\n {/* Trigger Type Filters */}\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n {FILTER_OPTIONS.map(({ type, icon: Icon, label }) => {\r\n const isSelected = selectedTrigger === type;\r\n const stats = type === 'all'\r\n ? { enabled: enabledCount, total: totalCount }\r\n : triggerStats[type as HookTriggerType];\r\n\r\n return (\r\n <Button\r\n key={type}\r\n variant={isSelected ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => setSelectedTrigger(type)}\r\n className=\"gap-2\"\r\n >\r\n <Icon className=\"w-4 h-4\" />\r\n {label}\r\n <Badge\r\n variant={isSelected ? 'secondary' : 'outline'}\r\n className=\"ml-1\"\r\n >\r\n {stats.enabled}/{stats.total}\r\n </Badge>\r\n </Button>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n </Card>\r\n\r\n {/* Hook Cards Grid */}\r\n {filteredHooks.length > 0 && (\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\r\n {filteredHooks.map((hook) => (\r\n <HookCard\r\n key={hook.name}\r\n hook={hook}\r\n isExpanded={expandedHooks.has(hook.name)}\r\n onToggleExpand={() => handleToggleHookExpand(hook.name)}\r\n onToggle={toggleHook}\r\n onEdit={handleEditClick}\r\n onDelete={handleDeleteClick}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Quick Templates */}\r\n <Card className=\"overflow-hidden\">\r\n <div\r\n className=\"p-4 cursor-pointer hover:bg-muted/50 transition-colors flex items-center justify-between border-b border-border\"\r\n onClick={() => setTemplatesExpanded(!templatesExpanded)}\r\n >\r\n <div className=\"flex items-center gap-3\">\r\n <Zap className=\"w-5 h-5 text-primary\" />\r\n <h2 className=\"text-base font-semibold text-foreground\">\r\n {formatMessage({ id: 'cliHooks.quickTemplates.title' })}\r\n </h2>\r\n </div>\r\n <Button variant=\"ghost\" size=\"sm\" className=\"h-8 w-8 p-0\">\r\n {templatesExpanded ? (\r\n <ChevronUp className=\"w-4 h-4\" />\r\n ) : (\r\n <ChevronDown className=\"w-4 h-4\" />\r\n )}\r\n </Button>\r\n </div>\r\n {templatesExpanded && (\r\n <div className=\"p-6\">\r\n <HookQuickTemplates\r\n onInstallTemplate={handleInstallTemplate}\r\n installedTemplates={installedTemplates}\r\n isLoading={!!installingTemplateId}\r\n installingTemplateId={installingTemplateId}\r\n />\r\n </div>\r\n )}\r\n </Card>\r\n\r\n {/* Wizard Launchers */}\r\n <Card className=\"overflow-hidden\">\r\n <div\r\n className=\"p-4 cursor-pointer hover:bg-muted/50 transition-colors flex items-center justify-between\"\r\n onClick={() => setWizardsExpanded(!wizardsExpanded)}\r\n >\r\n <div className=\"flex items-center gap-3\">\r\n <Wand2 className=\"w-5 h-5 text-primary\" />\r\n <div>\r\n <h2 className=\"text-base font-semibold text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.sectionTitle' })}\r\n </h2>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.sectionDescription' })}\r\n </p>\r\n </div>\r\n </div>\r\n <Button variant=\"ghost\" size=\"sm\" className=\"h-8 w-8 p-0\">\r\n {wizardsExpanded ? (\r\n <ChevronUp className=\"w-4 h-4\" />\r\n ) : (\r\n <ChevronDown className=\"w-4 h-4\" />\r\n )}\r\n </Button>\r\n </div>\r\n {wizardsExpanded && (\r\n <div className=\"border-t border-border p-6\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\r\n {wizardTypes.map(({ type, icon: Icon, label, description }) => (\r\n <Card key={type} className=\"p-4 cursor-pointer hover:bg-muted/50 transition-colors\" onClick={() => handleLaunchWizard(type)}>\r\n <div className=\"flex items-start gap-3\">\r\n <div className=\"p-2 rounded-lg bg-primary/10 shrink-0\">\r\n <Icon className=\"w-5 h-5 text-primary\" />\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <h3 className=\"text-sm font-medium text-foreground mb-1\">\r\n {label}\r\n </h3>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {description}\r\n </p>\r\n </div>\r\n </div>\r\n </Card>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </Card>\r\n\r\n {/* Empty State */}\r\n {!isLoading && filteredHooks.length === 0 && (\r\n <Card className=\"p-12 text-center\">\r\n <GitFork className=\"w-16 h-16 mx-auto text-muted-foreground/30 mb-4\" />\r\n <h3 className=\"text-lg font-semibold text-foreground mb-2\">\r\n {formatMessage({ id: 'cliHooks.empty.title' })}\r\n </h3>\r\n <p className=\"text-muted-foreground mb-6\">\r\n {formatMessage({ id: 'cliHooks.empty.description' })}\r\n </p>\r\n <Button onClick={handleAddClick}>\r\n <Plus className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'cliHooks.actions.addFirst' })}\r\n </Button>\r\n </Card>\r\n )}\r\n\r\n {/* Form Dialog */}\r\n <HookFormDialog\r\n mode={dialogMode}\r\n hook={editingHook}\r\n open={dialogOpen}\r\n onClose={() => setDialogOpen(false)}\r\n onSave={handleSave}\r\n />\r\n\r\n {/* Hook Wizard */}\r\n <HookWizard\r\n wizardType={wizardType}\r\n open={wizardOpen}\r\n onClose={() => setWizardOpen(false)}\r\n />\r\n </div>\r\n );\r\n}\r\n\r\nexport default HookManagerPage;\r\n"],"names":["FileChartColumnIncreasing","createLucideIcon","getTriggerIcon","trigger","getTriggerVariant","DISPLAY_NAME_TO_TEMPLATE_ID","getHookDisplayName","name","formatMessage","translationKey","translated","templateId","mappedKey","HookCard","hook","isExpanded","onToggleExpand","onToggle","onEdit","onDelete","useIntl","showDeleteConfirm","setShowDeleteConfirm","useState","displayName","handleToggle","handleEdit","handleDelete","handleConfirmDelete","handleCancelDelete","jsxs","Fragment","Card","cn","jsx","GitFork","Badge","Button","Power","PowerOff","Edit","Trash2","ChevronUp","ChevronDown","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","validateForm","data","errors","HookFormDialog","mode","open","onClose","onSave","formData","setFormData","setErrors","isSubmitting","setIsSubmitting","useEffect","handleFieldChange","field","value","prev","handleSubmit","validationErrors","error","TRIGGER_OPTIONS","Dialog","DialogContent","DialogHeader","DialogTitle","Input","e","Textarea","Select","SelectTrigger","SelectValue","SelectContent","option","SelectItem","DialogFooter","HOOK_TEMPLATES","CATEGORY_ICONS","Bell","Database","Wrench","Settings","Shield","TEMPLATE_ICONS","Send","FileBarChart","FileCode","FileSearch","GitBranch","getCategoryName","category","HookQuickTemplates","onInstallTemplate","installedTemplates","_isLoading","installingTemplateId","templatesByCategory","useMemo","acc","template","categoryOrder","handleInstall","Zap","templates","CategoryIcon","color","isInstalled","isInstalling","TemplateIcon","catColor","catBg","Loader2","Check","Download","detect","userAgent","getShell","platform","getPlatformName","getShellName","shell","checkCompatibility","requirements","detectedPlatform","issues","warnings","_a","requiredNames","optionalNames","DEFAULT_PLATFORM_REQUIREMENTS","TEMPLATE_IDS","DANGER_OPTIONS","WIZARD_METADATA","Brain","Sparkles","HookWizard","wizardType","queryClient","useQueryClient","currentStep","setCurrentStep","setDetectedPlatform","scope","setScope","saving","setSaving","projectPath","useWorkflowStore","selectProjectPath","skillsData","skillsLoading","useQuery","fetchSkills","memoryConfig","setMemoryConfig","dangerConfig","setDangerConfig","skillConfig","setSkillConfig","wizardMetadata","compatibilityCheck","handleNext","handlePrevious","handleClose","handleComplete","result","optionId","o","hookData","saveHook","err","renderStep1","WizardIcon","CheckCircle","AlertTriangle","issue","i","warning","renderStep2","renderMemoryUpdateConfig","renderDangerProtectionConfig","renderSkillContextConfig","renderStep3","renderConfigSummary","toggleOption","id","skills","addConfig","removeConfig","index","_","updateConfig","newConfigs","config","skill","Plus","s","opt","c","getPreviewCommand","renderNavigation","ChevronLeft","ChevronRight","renderStepIndicator","step","isHookTriggerType","toHookCardData","groupHooksByTrigger","hooks","h","getTriggerStats","hooksByTrigger","HookManagerPage","searchQuery","setSearchQuery","selectedTrigger","setSelectedTrigger","dialogOpen","setDialogOpen","dialogMode","setDialogMode","editingHook","setEditingHook","wizardOpen","setWizardOpen","setWizardType","expandedHooks","setExpandedHooks","templatesExpanded","setTemplatesExpanded","wizardsExpanded","setWizardsExpanded","enabledCount","totalCount","isLoading","refetch","useHooks","toggleHook","useToggleHook","deleteHook","useDeleteHook","filteredHooks","validHooks","query","triggerStats","handleAddClick","handleEditClick","handleDeleteClick","hookName","handleSave","handleToggleHookExpand","next","wizardTypes","handleLaunchWizard","type","t","setInstallingTemplateId","handleInstallTemplate","response","FILTER_OPTIONS","Play","StopCircle","RefreshCw","Wand2","Search","Icon","label","isSelected","stats","description"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"HookManagerPage-D2FuJfsM.js","sources":["../../../../node_modules/lucide-react/dist/esm/icons/file-chart-column-increasing.js","../../src/components/hook/HookCard.tsx","../../src/components/hook/HookFormDialog.tsx","../../src/components/hook/HookQuickTemplates.tsx","../../src/utils/platformUtils.ts","../../src/components/hook/HookWizard.tsx","../../src/pages/HookManagerPage.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileChartColumnIncreasing = createLucideIcon(\"FileChartColumnIncreasing\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"path\", { d: \"M8 18v-2\", key: \"qcmpov\" }],\n [\"path\", { d: \"M12 18v-4\", key: \"q1q25u\" }],\n [\"path\", { d: \"M16 18v-6\", key: \"15y0np\" }]\n]);\n\nexport { FileChartColumnIncreasing as default };\n//# sourceMappingURL=file-chart-column-increasing.js.map\n","// ========================================\r\n// Hook Card Component\r\n// ========================================\r\n// Individual hook display card with actions\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n GitFork,\r\n Power,\r\n PowerOff,\r\n Edit,\r\n Trash2,\r\n ChevronDown,\r\n ChevronUp,\r\n} from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport {\r\n AlertDialog,\r\n AlertDialogContent,\r\n AlertDialogHeader,\r\n AlertDialogTitle,\r\n AlertDialogDescription,\r\n AlertDialogFooter,\r\n AlertDialogAction,\r\n AlertDialogCancel,\r\n} from '@/components/ui/AlertDialog';\r\nimport { cn } from '@/lib/utils';\r\n\r\n// ========== Types ==========\r\n\r\nexport type HookTriggerType = 'SessionStart' | 'UserPromptSubmit' | 'PreToolUse' | 'PostToolUse' | 'Stop' | 'Notification' | 'SubagentStart' | 'SubagentStop' | 'PreCompact' | 'SessionEnd' | 'PostToolUseFailure' | 'PermissionRequest';\r\n\r\nexport interface HookCardData {\r\n name: string;\r\n description?: string;\r\n enabled: boolean;\r\n trigger: HookTriggerType;\r\n matcher?: string;\r\n command?: string;\r\n script?: string;\r\n scope?: 'global' | 'project';\r\n index?: number;\r\n}\r\n\r\nexport interface HookCardProps {\r\n hook: HookCardData;\r\n isExpanded: boolean;\r\n onToggleExpand: () => void;\r\n onToggle: (hookName: string, enabled: boolean) => void;\r\n onEdit: (hook: HookCardData) => void;\r\n onDelete: (hookName: string) => void;\r\n}\r\n\r\n// ========== Helper Functions ==========\r\n\r\nfunction getTriggerIcon(trigger: HookTriggerType) {\r\n switch (trigger) {\r\n case 'SessionStart':\r\n return '🎬';\r\n case 'UserPromptSubmit':\r\n return '⚡';\r\n case 'PreToolUse':\r\n return '🔧';\r\n case 'PostToolUse':\r\n return '✅';\r\n case 'Stop':\r\n return '🛑';\r\n case 'Notification':\r\n return '🔔';\r\n case 'SubagentStart':\r\n return '🚀';\r\n case 'SubagentStop':\r\n return '🏁';\r\n case 'PreCompact':\r\n return '📦';\r\n case 'SessionEnd':\r\n return '👋';\r\n case 'PostToolUseFailure':\r\n return '❌';\r\n case 'PermissionRequest':\r\n return '🔐';\r\n default:\r\n return '📌';\r\n }\r\n}\r\n\r\nfunction getTriggerVariant(trigger: HookTriggerType): 'default' | 'secondary' | 'outline' {\r\n switch (trigger) {\r\n case 'SessionStart':\r\n case 'UserPromptSubmit':\r\n case 'SubagentStart':\r\n return 'default';\r\n case 'PreToolUse':\r\n case 'Stop':\r\n case 'PreCompact':\r\n case 'PermissionRequest':\r\n return 'secondary';\r\n case 'PostToolUse':\r\n case 'Notification':\r\n case 'SubagentStop':\r\n case 'SessionEnd':\r\n case 'PostToolUseFailure':\r\n return 'outline';\r\n default:\r\n return 'outline';\r\n }\r\n}\r\n\r\n// ========== Component ==========\r\n\r\n// ========== Hook Name Translation ==========\r\n// Mapping from display name to template ID for translation lookup\r\nconst DISPLAY_NAME_TO_TEMPLATE_ID: Record<string, string> = {\r\n // Notification hooks\r\n 'Session Start Notify': 'session-start-notify',\r\n 'Session State Watch': 'session-state-watch',\r\n 'Stop Notify': 'stop-notify',\r\n // Automation hooks\r\n 'Auto Format on Write': 'auto-format-on-write',\r\n 'Auto Lint on Write': 'auto-lint-on-write',\r\n 'Block Sensitive Files': 'block-sensitive-files',\r\n 'Git Auto Stage': 'git-auto-stage',\r\n // Indexing hooks\r\n 'Post Edit Index': 'post-edit-index',\r\n 'Session End Summary': 'session-end-summary',\r\n 'Project State Inject': 'project-state-inject',\r\n // Memory V2 hooks\r\n 'Memory V2 Extract': 'memory-v2-extract',\r\n 'Memory V2 Auto Consolidate': 'memory-v2-auto-consolidate',\r\n 'Memory Sync Dashboard': 'memory-sync-dashboard',\r\n};\r\n\r\n/**\r\n * Get translated hook name if available\r\n * Falls back to original name if no translation exists\r\n */\r\nfunction getHookDisplayName(name: string, formatMessage: (msg: { id: string }) => string): string {\r\n // First try direct translation with the name (for template IDs)\r\n const translationKey = `cliHooks.templates.templates.${name}.name`;\r\n try {\r\n const translated = formatMessage({ id: translationKey });\r\n if (translated && !translated.includes('cliHooks.templates.templates')) {\r\n return translated;\r\n }\r\n } catch {\r\n // Direct translation not found\r\n }\r\n\r\n // Try mapping display name to template ID\r\n const templateId = DISPLAY_NAME_TO_TEMPLATE_ID[name];\r\n if (templateId) {\r\n const mappedKey = `cliHooks.templates.templates.${templateId}.name`;\r\n try {\r\n const translated = formatMessage({ id: mappedKey });\r\n if (translated && !translated.includes('cliHooks.templates.templates')) {\r\n return translated;\r\n }\r\n } catch {\r\n // Mapping found but no translation\r\n }\r\n }\r\n\r\n return name;\r\n}\r\n\r\n// ========== Component ==========\r\n\r\nexport function HookCard({\r\n hook,\r\n isExpanded,\r\n onToggleExpand,\r\n onToggle,\r\n onEdit,\r\n onDelete,\r\n}: HookCardProps) {\r\n const { formatMessage } = useIntl();\r\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\r\n\r\n // Get translated hook name\r\n const displayName = getHookDisplayName(hook.name, formatMessage);\r\n\r\n const handleToggle = () => {\r\n onToggle(hook.name, !hook.enabled);\r\n };\r\n\r\n const handleEdit = () => {\r\n onEdit(hook);\r\n };\r\n\r\n const handleDelete = () => {\r\n setShowDeleteConfirm(true);\r\n };\r\n\r\n const handleConfirmDelete = () => {\r\n setShowDeleteConfirm(false);\r\n onDelete(hook.name);\r\n };\r\n\r\n const handleCancelDelete = () => {\r\n setShowDeleteConfirm(false);\r\n };\r\n\r\n return (\r\n <>\r\n <Card className={cn('overflow-hidden', !hook.enabled && 'opacity-60')}>\r\n {/* Header */}\r\n <div className=\"p-4\">\r\n <div className=\"flex items-start justify-between gap-3\">\r\n <div className=\"flex items-center gap-3 flex-1 min-w-0\">\r\n <div className={cn(\r\n 'p-2 rounded-lg flex-shrink-0',\r\n hook.enabled ? 'bg-primary/10' : 'bg-muted'\r\n )}>\r\n <GitFork className={cn(\r\n 'w-4 h-4',\r\n hook.enabled ? 'text-primary' : 'text-muted-foreground'\r\n )} />\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span className=\"text-sm font-medium text-foreground truncate\">\r\n {displayName}\r\n </span>\r\n <Badge\r\n variant={getTriggerVariant(hook.trigger)}\r\n className=\"text-xs flex-shrink-0\"\r\n >\r\n <span className=\"mr-1\">{getTriggerIcon(hook.trigger)}</span>\r\n {formatMessage({ id: `cliHooks.trigger.${hook.trigger}` })}\r\n </Badge>\r\n <Badge\r\n variant={hook.enabled ? 'default' : 'secondary'}\r\n className=\"text-xs flex-shrink-0\"\r\n >\r\n {hook.enabled\r\n ? formatMessage({ id: 'common.status.enabled' })\r\n : formatMessage({ id: 'common.status.disabled' })\r\n }\r\n </Badge>\r\n </div>\r\n {hook.description && (\r\n <p className=\"text-xs text-muted-foreground mt-0.5 truncate\">\r\n {hook.description}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Action Buttons */}\r\n <div className=\"flex items-center gap-1 flex-shrink-0\">\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-8 w-8 p-0\"\r\n onClick={handleToggle}\r\n title={hook.enabled\r\n ? formatMessage({ id: 'cliHooks.actions.disable' })\r\n : formatMessage({ id: 'cliHooks.actions.enable' })\r\n }\r\n >\r\n {hook.enabled ? (\r\n <Power className=\"w-4 h-4 text-success\" />\r\n ) : (\r\n <PowerOff className=\"w-4 h-4 text-muted-foreground\" />\r\n )}\r\n </Button>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-8 w-8 p-0\"\r\n onClick={handleEdit}\r\n title={formatMessage({ id: 'common.actions.edit' })}\r\n >\r\n <Edit className=\"w-4 h-4\" />\r\n </Button>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-8 w-8 p-0 text-destructive hover:text-destructive hover:bg-destructive/10\"\r\n onClick={handleDelete}\r\n title={formatMessage({ id: 'common.actions.delete' })}\r\n >\r\n <Trash2 className=\"w-4 h-4 text-destructive\" />\r\n </Button>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-8 w-8 p-0\"\r\n onClick={onToggleExpand}\r\n title={isExpanded\r\n ? formatMessage({ id: 'cliHooks.actions.collapse' })\r\n : formatMessage({ id: 'cliHooks.actions.expand' })\r\n }\r\n >\r\n {isExpanded ? (\r\n <ChevronUp className=\"w-4 h-4\" />\r\n ) : (\r\n <ChevronDown className=\"w-4 h-4\" />\r\n )}\r\n </Button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Expanded Content */}\r\n {isExpanded && (\r\n <div className=\"border-t border-border bg-muted/30 p-4 space-y-3\">\r\n {hook.description && (\r\n <div>\r\n <label className=\"text-xs font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.description' })}\r\n </label>\r\n <p className=\"text-sm text-foreground mt-1\">{hook.description}</p>\r\n </div>\r\n )}\r\n\r\n <div>\r\n <label className=\"text-xs font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.matcher' })}\r\n </label>\r\n <p className=\"text-sm text-foreground mt-1 font-mono bg-muted px-2 py-1 rounded\">\r\n {hook.matcher || formatMessage({ id: 'cliHooks.allTools' })}\r\n </p>\r\n </div>\r\n\r\n <div>\r\n <label className=\"text-xs font-medium text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.command' })}\r\n </label>\r\n <p className=\"text-sm text-foreground mt-1 font-mono bg-muted px-2 py-1 rounded break-all max-h-32 overflow-y-auto\">\r\n {hook.command || hook.script || 'N/A'}\r\n </p>\r\n </div>\r\n </div>\r\n )}\r\n </Card>\r\n\r\n {/* Delete Confirmation Dialog */}\r\n <AlertDialog open={showDeleteConfirm} onOpenChange={setShowDeleteConfirm}>\r\n <AlertDialogContent>\r\n <AlertDialogHeader>\r\n <AlertDialogTitle>Delete CLI Hook?</AlertDialogTitle>\r\n <AlertDialogDescription>\r\n This action cannot be undone. The hook \"{displayName}\" will be permanently deleted.\r\n </AlertDialogDescription>\r\n </AlertDialogHeader>\r\n <AlertDialogFooter>\r\n <AlertDialogCancel onClick={handleCancelDelete}>Cancel</AlertDialogCancel>\r\n <AlertDialogAction onClick={handleConfirmDelete}>Delete</AlertDialogAction>\r\n </AlertDialogFooter>\r\n </AlertDialogContent>\r\n </AlertDialog>\r\n </>\r\n );\r\n}\r\n\r\nexport default HookCard;\r\n","// ========================================\r\n// Hook Form Dialog Component\r\n// ========================================\r\n// Dialog for creating and editing hooks\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Textarea } from '@/components/ui/Textarea';\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 type { HookCardData, HookTriggerType } from './HookCard';\r\n\r\n// ========== Types ==========\r\n\r\nexport type HookFormMode = 'create' | 'edit';\r\n\r\nexport interface HookFormData {\r\n name: string;\r\n description: string;\r\n trigger: HookTriggerType;\r\n matcher: string;\r\n command: string;\r\n}\r\n\r\nexport interface HookFormDialogProps {\r\n mode: HookFormMode;\r\n hook?: HookCardData;\r\n open: boolean;\r\n onClose: () => void;\r\n onSave: (data: HookFormData) => Promise<void>;\r\n}\r\n\r\n// ========== Helper: Form Validation ==========\r\n\r\ninterface FormErrors {\r\n name?: string;\r\n trigger?: string;\r\n command?: string;\r\n}\r\n\r\nfunction validateForm(data: HookFormData): FormErrors {\r\n const errors: FormErrors = {};\r\n\r\n if (!data.name.trim()) {\r\n errors.name = 'validation.nameRequired';\r\n } else if (!/^[a-zA-Z0-9_-]+$/.test(data.name)) {\r\n errors.name = 'validation.nameInvalid';\r\n }\r\n\r\n if (!data.trigger) {\r\n errors.trigger = 'validation.triggerRequired';\r\n }\r\n\r\n if (!data.command.trim()) {\r\n errors.command = 'validation.commandRequired';\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n// ========== Component ==========\r\n\r\nexport function HookFormDialog({\r\n mode,\r\n hook,\r\n open,\r\n onClose,\r\n onSave,\r\n}: HookFormDialogProps) {\r\n const { formatMessage } = useIntl();\r\n const [formData, setFormData] = useState<HookFormData>({\r\n name: '',\r\n description: '',\r\n trigger: 'PostToolUse',\r\n matcher: '',\r\n command: '',\r\n });\r\n const [errors, setErrors] = useState<FormErrors>({});\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n\r\n // Reset form when dialog opens or hook changes\r\n useEffect(() => {\r\n if (open) {\r\n if (mode === 'edit' && hook) {\r\n setFormData({\r\n name: hook.name,\r\n description: hook.description || '',\r\n trigger: hook.trigger,\r\n matcher: hook.matcher || '',\r\n command: hook.command || hook.script || '',\r\n });\r\n } else {\r\n setFormData({\r\n name: '',\r\n description: '',\r\n trigger: 'PostToolUse',\r\n matcher: '',\r\n command: '',\r\n });\r\n }\r\n setErrors({});\r\n }\r\n }, [open, mode, hook]);\r\n\r\n const handleFieldChange = (\r\n field: keyof HookFormData,\r\n value: string\r\n ) => {\r\n setFormData((prev) => ({ ...prev, [field]: value }));\r\n // Clear error for this field when user starts typing\r\n if (errors[field as keyof FormErrors]) {\r\n setErrors((prev) => ({ ...prev, [field]: undefined }));\r\n }\r\n };\r\n\r\n const handleSubmit = async () => {\r\n // Validate form\r\n const validationErrors = validateForm(formData);\r\n if (Object.keys(validationErrors).length > 0) {\r\n setErrors(validationErrors);\r\n return;\r\n }\r\n\r\n setIsSubmitting(true);\r\n try {\r\n await onSave(formData);\r\n onClose();\r\n } catch (error) {\r\n console.error('Failed to save hook:', error);\r\n } finally {\r\n setIsSubmitting(false);\r\n }\r\n };\r\n\r\n const TRIGGER_OPTIONS: { value: HookTriggerType; label: string }[] = [\r\n { value: 'SessionStart', label: 'cliHooks.trigger.SessionStart' },\r\n { value: 'UserPromptSubmit', label: 'cliHooks.trigger.UserPromptSubmit' },\r\n { value: 'PreToolUse', label: 'cliHooks.trigger.PreToolUse' },\r\n { value: 'PostToolUse', label: 'cliHooks.trigger.PostToolUse' },\r\n { value: 'Stop', label: 'cliHooks.trigger.Stop' },\r\n { value: 'Notification', label: 'cliHooks.trigger.Notification' },\r\n { value: 'SubagentStart', label: 'cliHooks.trigger.SubagentStart' },\r\n { value: 'SubagentStop', label: 'cliHooks.trigger.SubagentStop' },\r\n { value: 'PreCompact', label: 'cliHooks.trigger.PreCompact' },\r\n { value: 'SessionEnd', label: 'cliHooks.trigger.SessionEnd' },\r\n { value: 'PostToolUseFailure', label: 'cliHooks.trigger.PostToolUseFailure' },\r\n { value: 'PermissionRequest', label: 'cliHooks.trigger.PermissionRequest' },\r\n ];\r\n\r\n return (\r\n <Dialog open={open} onOpenChange={onClose}>\r\n <DialogContent className=\"sm:max-w-[600px]\">\r\n <DialogHeader>\r\n <DialogTitle>\r\n {mode === 'create'\r\n ? formatMessage({ id: 'cliHooks.dialog.createTitle' })\r\n : formatMessage({ id: 'cliHooks.dialog.editTitle' }, { hookName: hook?.name })\r\n }\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <div className=\"space-y-4 py-4\">\r\n {/* Name */}\r\n <div>\r\n <label htmlFor=\"hook-name\" className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.name' })} *\r\n </label>\r\n <Input\r\n id=\"hook-name\"\r\n value={formData.name}\r\n onChange={(e) => handleFieldChange('name', e.target.value)}\r\n placeholder={formatMessage({ id: 'cliHooks.form.namePlaceholder' })}\r\n className=\"mt-1\"\r\n error={!!errors.name}\r\n />\r\n {errors.name && (\r\n <p className=\"text-xs text-destructive mt-1\">\r\n {formatMessage({ id: `cliHooks.${errors.name}` })}\r\n </p>\r\n )}\r\n </div>\r\n\r\n {/* Description */}\r\n <div>\r\n <label htmlFor=\"hook-description\" className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.description' })}\r\n </label>\r\n <Textarea\r\n id=\"hook-description\"\r\n value={formData.description}\r\n onChange={(e) => handleFieldChange('description', e.target.value)}\r\n placeholder={formatMessage({ id: 'cliHooks.form.descriptionPlaceholder' })}\r\n className=\"mt-1\"\r\n rows={2}\r\n />\r\n </div>\r\n\r\n {/* Trigger */}\r\n <div>\r\n <label htmlFor=\"hook-trigger\" className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.trigger' })} *\r\n </label>\r\n <Select\r\n value={formData.trigger}\r\n onValueChange={(value) => handleFieldChange('trigger', value as HookTriggerType)}\r\n >\r\n <SelectTrigger className=\"mt-1\" id=\"hook-trigger\">\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n {TRIGGER_OPTIONS.map((option) => (\r\n <SelectItem key={option.value} value={option.value}>\r\n {formatMessage({ id: option.label })}\r\n </SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n {errors.trigger && (\r\n <p className=\"text-xs text-destructive mt-1\">\r\n {formatMessage({ id: `cliHooks.${errors.trigger}` })}\r\n </p>\r\n )}\r\n </div>\r\n\r\n {/* Matcher */}\r\n <div>\r\n <label htmlFor=\"hook-matcher\" className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.matcher' })}\r\n </label>\r\n <Input\r\n id=\"hook-matcher\"\r\n value={formData.matcher}\r\n onChange={(e) => handleFieldChange('matcher', e.target.value)}\r\n placeholder={formatMessage({ id: 'cliHooks.form.matcherPlaceholder' })}\r\n className=\"mt-1 font-mono\"\r\n />\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'cliHooks.form.matcherHelp' })}\r\n </p>\r\n </div>\r\n\r\n {/* Command */}\r\n <div>\r\n <label htmlFor=\"hook-command\" className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.form.command' })} *\r\n </label>\r\n <Textarea\r\n id=\"hook-command\"\r\n value={formData.command}\r\n onChange={(e) => handleFieldChange('command', e.target.value)}\r\n placeholder={formatMessage({ id: 'cliHooks.form.commandPlaceholder' })}\r\n className=\"mt-1 font-mono text-sm\"\r\n rows={4}\r\n error={!!errors.command}\r\n />\r\n {errors.command && (\r\n <p className=\"text-xs text-destructive mt-1\">\r\n {formatMessage({ id: `cliHooks.${errors.command}` })}\r\n </p>\r\n )}\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'cliHooks.form.commandHelp' })}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n <DialogFooter>\r\n <Button variant=\"outline\" onClick={onClose} disabled={isSubmitting}>\r\n {formatMessage({ id: 'common.actions.cancel' })}\r\n </Button>\r\n <Button onClick={handleSubmit} disabled={isSubmitting}>\r\n {isSubmitting\r\n ? formatMessage({ id: 'common.actions.saving' })\r\n : formatMessage({ id: 'common.actions.save' })\r\n }\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n );\r\n}\r\n\r\nexport default HookFormDialog;\r\n","// ========================================\r\n// Hook Quick Templates Component\r\n// ========================================\r\n// Frontend component for displaying and installing hook templates\r\n// Templates are defined in backend: ccw/src/core/hooks/hook-templates.ts\r\n// All templates use `ccw hook template exec <id> --stdin` to avoid Windows quote issues\r\n\r\nimport { useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Bell,\r\n Database,\r\n Wrench,\r\n Check,\r\n Zap,\r\n Download,\r\n Loader2,\r\n Shield,\r\n FileCode,\r\n FileSearch,\r\n GitBranch,\r\n Send,\r\n FileBarChart,\r\n Settings,\r\n} from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { cn } from '@/lib/utils';\r\nimport type { HookTriggerType } from './HookCard';\r\n\r\n// ========== Types ==========\r\n\r\n/**\r\n * Template category type\r\n */\r\nexport type TemplateCategory = 'notification' | 'indexing' | 'automation' | 'utility' | 'protection';\r\n\r\n/**\r\n * Hook template definition (frontend view of backend templates)\r\n */\r\nexport interface HookTemplate {\r\n id: string;\r\n name: string;\r\n description: string;\r\n category: TemplateCategory;\r\n trigger: HookTriggerType;\r\n matcher?: string;\r\n}\r\n\r\n/**\r\n * Component props\r\n */\r\nexport interface HookQuickTemplatesProps {\r\n /** Callback when install button is clicked */\r\n onInstallTemplate: (templateId: string) => Promise<void>;\r\n /** Array of installed template IDs */\r\n installedTemplates: string[];\r\n /** Optional loading state */\r\n isLoading?: boolean;\r\n /** ID of the template currently being installed */\r\n installingTemplateId?: string | null;\r\n}\r\n\r\n// ========== Hook Templates ==========\r\n// NOTE: Templates are defined in backend (ccw/src/core/hooks/hook-templates.ts)\r\n// This is a copy for frontend display purposes.\r\n// All templates use `ccw hook template exec <id> --stdin` format.\r\n\r\n/**\r\n * Predefined hook templates for quick installation\r\n * These mirror the backend templates in ccw/src/core/hooks/hook-templates.ts\r\n */\r\nexport const HOOK_TEMPLATES: readonly HookTemplate[] = [\r\n // ============ Notification ============\r\n {\r\n id: 'session-start-notify',\r\n name: 'Session Start Notify',\r\n description: 'Notify dashboard when a new workflow session is created',\r\n category: 'notification',\r\n trigger: 'SessionStart',\r\n },\r\n {\r\n id: 'session-state-watch',\r\n name: 'Session State Watch',\r\n description: 'Watch for session metadata file changes (workflow-session.json)',\r\n category: 'notification',\r\n trigger: 'PostToolUse',\r\n matcher: 'Write|Edit',\r\n },\r\n {\r\n id: 'stop-notify',\r\n name: 'Stop Notify',\r\n description: 'Notify dashboard when Claude finishes responding',\r\n category: 'notification',\r\n trigger: 'Stop',\r\n },\r\n {\r\n id: 'memory-sync-dashboard',\r\n name: 'Memory Sync Dashboard',\r\n description: 'Sync memory V2 status to dashboard on changes',\r\n category: 'notification',\r\n trigger: 'PostToolUse',\r\n matcher: 'mcp__ccw-tools__core_memory',\r\n },\r\n\r\n // ============ Automation ============\r\n {\r\n id: 'auto-format-on-write',\r\n name: 'Auto Format on Write',\r\n description: 'Auto-format files after Claude writes or edits them',\r\n category: 'automation',\r\n trigger: 'PostToolUse',\r\n matcher: 'Write|Edit',\r\n },\r\n {\r\n id: 'auto-lint-on-write',\r\n name: 'Auto Lint on Write',\r\n description: 'Auto-lint files after Claude writes or edits them',\r\n category: 'automation',\r\n trigger: 'PostToolUse',\r\n matcher: 'Write|Edit',\r\n },\r\n {\r\n id: 'git-auto-stage',\r\n name: 'Git Auto Stage',\r\n description: 'Auto stage all modified files when Claude finishes responding',\r\n category: 'automation',\r\n trigger: 'Stop',\r\n },\r\n\r\n // ============ Protection ============\r\n {\r\n id: 'block-sensitive-files',\r\n name: 'Block Sensitive Files',\r\n description: 'Block modifications to sensitive files (.env, secrets, credentials)',\r\n category: 'protection',\r\n trigger: 'PreToolUse',\r\n matcher: 'Write|Edit',\r\n },\r\n {\r\n id: 'danger-bash-confirm',\r\n name: 'Danger Bash Confirm',\r\n description: 'Require confirmation for dangerous bash commands',\r\n category: 'protection',\r\n trigger: 'PreToolUse',\r\n matcher: 'Bash',\r\n },\r\n {\r\n id: 'danger-file-protection',\r\n name: 'Danger File Protection',\r\n description: 'Block modifications to protected files',\r\n category: 'protection',\r\n trigger: 'PreToolUse',\r\n matcher: 'Write|Edit',\r\n },\r\n {\r\n id: 'danger-git-destructive',\r\n name: 'Danger Git Destructive',\r\n description: 'Require confirmation for destructive git operations',\r\n category: 'protection',\r\n trigger: 'PreToolUse',\r\n matcher: 'Bash',\r\n },\r\n {\r\n id: 'danger-network-confirm',\r\n name: 'Danger Network Confirm',\r\n description: 'Require confirmation for network operations',\r\n category: 'protection',\r\n trigger: 'PreToolUse',\r\n matcher: 'Bash|WebFetch',\r\n },\r\n {\r\n id: 'danger-system-paths',\r\n name: 'Danger System Paths',\r\n description: 'Block modifications to system paths',\r\n category: 'protection',\r\n trigger: 'PreToolUse',\r\n matcher: 'Write|Edit|Bash',\r\n },\r\n {\r\n id: 'danger-permission-change',\r\n name: 'Danger Permission Change',\r\n description: 'Require confirmation for permission changes',\r\n category: 'protection',\r\n trigger: 'PreToolUse',\r\n matcher: 'Bash',\r\n },\r\n\r\n // ============ Indexing ============\r\n {\r\n id: 'post-edit-index',\r\n name: 'Post Edit Index',\r\n description: 'Notify indexing service when files are modified',\r\n category: 'indexing',\r\n trigger: 'PostToolUse',\r\n matcher: 'Write|Edit',\r\n },\r\n {\r\n id: 'session-end-summary',\r\n name: 'Session End Summary',\r\n description: 'Send session summary to dashboard on session end',\r\n category: 'indexing',\r\n trigger: 'Stop',\r\n },\r\n\r\n // ============ Utility ============\r\n {\r\n id: 'memory-auto-compress',\r\n name: 'Auto Memory Compress',\r\n description: 'Automatically compress memory when entries exceed threshold',\r\n category: 'utility',\r\n trigger: 'Stop',\r\n },\r\n {\r\n id: 'memory-preview-extract',\r\n name: 'Memory Preview & Extract',\r\n description: 'Preview extraction queue and extract eligible sessions',\r\n category: 'utility',\r\n trigger: 'SessionStart',\r\n },\r\n {\r\n id: 'memory-status-check',\r\n name: 'Memory Status Check',\r\n description: 'Check memory extraction and consolidation status',\r\n category: 'utility',\r\n trigger: 'SessionStart',\r\n },\r\n {\r\n id: 'memory-v2-extract',\r\n name: 'Memory V2 Extract',\r\n description: 'Trigger Phase 1 extraction when session ends',\r\n category: 'utility',\r\n trigger: 'Stop',\r\n },\r\n {\r\n id: 'memory-v2-auto-consolidate',\r\n name: 'Memory V2 Auto Consolidate',\r\n description: 'Trigger Phase 2 consolidation after extraction jobs complete',\r\n category: 'utility',\r\n trigger: 'Stop',\r\n },\r\n] as const;\r\n\r\n// ========== Category Icons ==========\r\n\r\nconst CATEGORY_ICONS: Record<TemplateCategory, { icon: typeof Bell; color: string; bg: string }> = {\r\n notification: { icon: Bell, color: 'text-blue-500', bg: 'bg-blue-500/10' },\r\n indexing: { icon: Database, color: 'text-purple-500', bg: 'bg-purple-500/10' },\r\n automation: { icon: Wrench, color: 'text-orange-500', bg: 'bg-orange-500/10' },\r\n utility: { icon: Settings, color: 'text-gray-500', bg: 'bg-gray-500/10' },\r\n protection: { icon: Shield, color: 'text-red-500', bg: 'bg-red-500/10' },\r\n};\r\n\r\n// ========== Template Icons ==========\r\n\r\nconst TEMPLATE_ICONS: Record<string, typeof Bell> = {\r\n 'session-start-notify': Send,\r\n 'session-state-watch': FileBarChart,\r\n 'stop-notify': Bell,\r\n 'auto-format-on-write': FileCode,\r\n 'auto-lint-on-write': FileSearch,\r\n 'block-sensitive-files': Shield,\r\n 'git-auto-stage': GitBranch,\r\n 'post-edit-index': Database,\r\n 'session-end-summary': FileBarChart,\r\n 'project-state-inject': FileBarChart,\r\n};\r\n\r\n// ========== Category Names ==========\r\n\r\nfunction getCategoryName(category: TemplateCategory, formatMessage: ReturnType<typeof useIntl>['formatMessage']): string {\r\n const names: Record<TemplateCategory, string> = {\r\n notification: formatMessage({ id: 'cliHooks.templates.categories.notification' }),\r\n indexing: formatMessage({ id: 'cliHooks.templates.categories.indexing' }),\r\n automation: formatMessage({ id: 'cliHooks.templates.categories.automation' }),\r\n utility: formatMessage({ id: 'cliHooks.templates.categories.utility' }),\r\n protection: formatMessage({ id: 'cliHooks.templates.categories.protection' }),\r\n };\r\n return names[category];\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\n/**\r\n * HookQuickTemplates - Display predefined hook templates for quick installation\r\n */\r\nexport function HookQuickTemplates({\r\n onInstallTemplate,\r\n installedTemplates,\r\n isLoading: _isLoading = false,\r\n installingTemplateId = null\r\n}: HookQuickTemplatesProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n // Group templates by category\r\n const templatesByCategory = useMemo(() => {\r\n return HOOK_TEMPLATES.reduce((acc, template) => {\r\n if (!acc[template.category]) {\r\n acc[template.category] = [];\r\n }\r\n acc[template.category].push(template);\r\n return acc;\r\n }, {} as Record<TemplateCategory, HookTemplate[]>);\r\n }, []);\r\n\r\n // Define category order\r\n const categoryOrder: TemplateCategory[] = ['notification', 'indexing', 'automation', 'protection', 'utility'];\r\n\r\n const handleInstall = async (templateId: string) => {\r\n await onInstallTemplate(templateId);\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Header */}\r\n <div className=\"flex items-center gap-3\">\r\n <Zap className=\"w-5 h-5 text-primary\" />\r\n <div>\r\n <h2 className=\"text-lg font-semibold text-foreground\">\r\n {formatMessage({ id: 'cliHooks.templates.title' })}\r\n </h2>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.templates.description' })}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* Categories */}\r\n {categoryOrder.map((category) => {\r\n const templates = templatesByCategory[category];\r\n if (!templates || templates.length === 0) return null;\r\n\r\n const { icon: CategoryIcon, color } = CATEGORY_ICONS[category];\r\n\r\n return (\r\n <div key={category} className=\"space-y-3\">\r\n {/* Category Header */}\r\n <div className=\"flex items-center gap-2\">\r\n <CategoryIcon className={cn('w-4 h-4', color)} />\r\n <h3 className=\"text-sm font-medium text-foreground\">\r\n {getCategoryName(category, formatMessage)}\r\n </h3>\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {templates.length}\r\n </Badge>\r\n </div>\r\n\r\n {/* Template Card Grid */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3\">\r\n {templates.map((template) => {\r\n const isInstalled = installedTemplates.includes(template.id);\r\n const isInstalling = installingTemplateId === template.id;\r\n const TemplateIcon = TEMPLATE_ICONS[template.id] || Zap;\r\n const { color: catColor, bg: catBg } = CATEGORY_ICONS[template.category];\r\n\r\n return (\r\n <Card\r\n key={template.id}\r\n className={cn(\r\n 'p-4 flex flex-col gap-2 transition-colors',\r\n isInstalled && 'opacity-70'\r\n )}\r\n >\r\n {/* Card Header: Icon + Name + Install */}\r\n <div className=\"flex items-start gap-3\">\r\n <div className={cn('p-2 rounded-lg shrink-0', catBg)}>\r\n <TemplateIcon className={cn('w-4 h-4', catColor)} />\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <h4 className=\"text-sm font-medium text-foreground leading-tight\">\r\n {formatMessage(\r\n { id: `cliHooks.templates.templates.${template.id}.name`, defaultMessage: template.name }\r\n )}\r\n </h4>\r\n <div className=\"flex items-center gap-1.5 mt-1 flex-wrap\">\r\n <Badge variant=\"secondary\" className=\"text-[10px] px-1.5 py-0\">\r\n {formatMessage({ id: `cliHooks.trigger.${template.trigger}` })}\r\n </Badge>\r\n {template.matcher && (\r\n <Badge variant=\"outline\" className=\"text-[10px] px-1.5 py-0 font-mono\">\r\n {template.matcher}\r\n </Badge>\r\n )}\r\n </div>\r\n </div>\r\n {/* Icon Install Button */}\r\n <Button\r\n size=\"sm\"\r\n variant=\"ghost\"\r\n disabled={isInstalled || isInstalling}\r\n onClick={() => handleInstall(template.id)}\r\n className={cn(\r\n 'h-8 w-8 p-0 shrink-0 rounded-full',\r\n isInstalled\r\n ? 'text-green-500 hover:text-green-500'\r\n : 'text-primary hover:bg-primary/10'\r\n )}\r\n title={isInstalled\r\n ? formatMessage({ id: 'cliHooks.templates.actions.installed' })\r\n : formatMessage({ id: 'cliHooks.templates.actions.install' })\r\n }\r\n >\r\n {isInstalling ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : isInstalled ? (\r\n <Check className=\"w-4 h-4\" />\r\n ) : (\r\n <Download className=\"w-4 h-4\" />\r\n )}\r\n </Button>\r\n </div>\r\n\r\n {/* Description */}\r\n <p className=\"text-xs text-muted-foreground leading-relaxed flex-1 pl-11\">\r\n {formatMessage(\r\n { id: `cliHooks.templates.templates.${template.id}.description`, defaultMessage: template.description }\r\n )}\r\n </p>\r\n </Card>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n}\r\n\r\nexport default HookQuickTemplates;\r\n","// ========================================\r\n// Platform Utilities\r\n// ========================================\r\n// Platform detection and compatibility checking for hooks\r\n\r\n// ========== Types ==========\r\n\r\n/**\r\n * Detected platform type\r\n */\r\nexport type Platform = 'windows' | 'macos' | 'linux';\r\n\r\n/**\r\n * Available shell types by platform\r\n */\r\nexport type ShellType = 'cmd' | 'bash' | 'powershell' | 'zsh';\r\n\r\n/**\r\n * Compatibility check result\r\n */\r\nexport interface CompatibilityCheck {\r\n compatible: boolean;\r\n issues: string[];\r\n warnings: string[];\r\n}\r\n\r\n/**\r\n * Platform requirements for a hook template\r\n */\r\nexport interface PlatformRequirements {\r\n requiredPlatforms?: Platform[];\r\n optionalPlatforms?: Platform[];\r\n incompatiblePlatforms?: Platform[];\r\n}\r\n\r\n// ========== Platform Detection ==========\r\n\r\n/**\r\n * Detect the current platform from user agent\r\n * @returns Detected platform type\r\n */\r\nexport function detect(): Platform {\r\n if (typeof window === 'undefined' || typeof window.navigator === 'undefined') {\r\n return 'linux'; // Default for server-side\r\n }\r\n\r\n const userAgent = window.navigator.userAgent;\r\n\r\n if (userAgent.includes('Win')) {\r\n return 'windows';\r\n } else if (userAgent.includes('Mac')) {\r\n return 'macos';\r\n } else {\r\n return 'linux';\r\n }\r\n}\r\n\r\n/**\r\n * Get the default shell for the current platform\r\n * @param platform - Optional platform override, otherwise auto-detects\r\n * @returns Shell type for the platform\r\n */\r\nexport function getShell(platform?: Platform): ShellType {\r\n const detectedPlatform = platform ?? detect();\r\n\r\n switch (detectedPlatform) {\r\n case 'windows':\r\n return 'cmd';\r\n case 'macos':\r\n return 'zsh';\r\n case 'linux':\r\n return 'bash';\r\n default:\r\n return 'bash';\r\n }\r\n}\r\n\r\n/**\r\n * Get the shell command prefix for executing scripts\r\n * @param shell - Shell type, defaults to detected platform\r\n * @returns Command prefix array (command, args...)\r\n */\r\nexport function getShellCommand(shell?: ShellType): string[] {\r\n const detectedShell = shell ?? getShell();\r\n\r\n switch (detectedShell) {\r\n case 'cmd':\r\n return ['cmd', '/c'];\r\n case 'powershell':\r\n return ['powershell', '-Command'];\r\n case 'bash':\r\n return ['bash', '-c'];\r\n case 'zsh':\r\n return ['zsh', '-c'];\r\n default:\r\n return ['bash', '-c'];\r\n }\r\n}\r\n\r\n/**\r\n * Get platform display name\r\n * @param platform - Platform type\r\n * @returns Human-readable platform name\r\n */\r\nexport function getPlatformName(platform: Platform): string {\r\n const names: Record<Platform, string> = {\r\n windows: 'Windows',\r\n macos: 'macOS',\r\n linux: 'Linux'\r\n };\r\n return names[platform];\r\n}\r\n\r\n/**\r\n * Get shell display name\r\n * @param shell - Shell type\r\n * @returns Human-readable shell name\r\n */\r\nexport function getShellName(shell: ShellType): string {\r\n const names: Record<ShellType, string> = {\r\n cmd: 'Command Prompt (cmd.exe)',\r\n bash: 'Bash',\r\n powershell: 'PowerShell',\r\n zsh: 'Zsh'\r\n };\r\n return names[shell];\r\n}\r\n\r\n// ========== Compatibility Checking ==========\r\n\r\n/**\r\n * Check if a hook template is compatible with the current platform\r\n * @param requirements - Platform requirements for the template\r\n * @param platform - Optional platform override, otherwise auto-detects\r\n * @returns Compatibility check result with issues and warnings\r\n */\r\nexport function checkCompatibility(\r\n requirements: PlatformRequirements,\r\n platform?: Platform\r\n): CompatibilityCheck {\r\n const detectedPlatform = platform ?? detect();\r\n const issues: string[] = [];\r\n const warnings: string[] = [];\r\n\r\n // Check for incompatible platforms\r\n if (requirements.incompatiblePlatforms?.includes(detectedPlatform)) {\r\n issues.push(\r\n `This hook is not compatible with ${getPlatformName(detectedPlatform)}. ` +\r\n `Incompatible platform detected.`\r\n );\r\n return { compatible: false, issues, warnings };\r\n }\r\n\r\n // Check for required platforms\r\n if (requirements.requiredPlatforms && requirements.requiredPlatforms.length > 0) {\r\n if (!requirements.requiredPlatforms.includes(detectedPlatform)) {\r\n const requiredNames = requirements.requiredPlatforms.map(getPlatformName).join(', ');\r\n issues.push(\r\n `This hook requires one of: ${requiredNames}. ` +\r\n `Current platform: ${getPlatformName(detectedPlatform)}.`\r\n );\r\n return { compatible: false, issues, warnings };\r\n }\r\n }\r\n\r\n // Check for optional platforms and add warning\r\n if (requirements.optionalPlatforms && requirements.optionalPlatforms.length > 0) {\r\n if (!requirements.optionalPlatforms.includes(detectedPlatform)) {\r\n const optionalNames = requirements.optionalPlatforms.map(getPlatformName).join(', ');\r\n warnings.push(\r\n `This hook has optional features for: ${optionalNames}. ` +\r\n `Some features may not work on ${getPlatformName(detectedPlatform)}.`\r\n );\r\n }\r\n }\r\n\r\n // All checks passed\r\n return { compatible: true, issues, warnings };\r\n}\r\n\r\n/**\r\n * Get platform-specific hook template adjustment\r\n * @param templateCommand - Base template command\r\n * @param platform - Optional platform override\r\n * @returns Adjusted command with platform-specific shell prefix\r\n */\r\nexport function adjustCommandForPlatform(\r\n templateCommand: string,\r\n platform?: Platform\r\n): string[] {\r\n const shellCmd = getShellCommand(getShell(platform));\r\n return [...shellCmd, templateCommand];\r\n}\r\n\r\n// ========== Default Platform Requirements ==========\r\n\r\n/**\r\n * Default platform requirements for common hook types\r\n */\r\nexport const DEFAULT_PLATFORM_REQUIREMENTS: Record<string, PlatformRequirements> = {\r\n 'memory-update': {\r\n // Works on all platforms\r\n requiredPlatforms: undefined,\r\n optionalPlatforms: undefined,\r\n incompatiblePlatforms: []\r\n },\r\n 'danger-protection': {\r\n // Works on all platforms\r\n requiredPlatforms: undefined,\r\n optionalPlatforms: undefined,\r\n incompatiblePlatforms: []\r\n },\r\n 'skill-context': {\r\n // Requires skills API - works on all platforms\r\n requiredPlatforms: undefined,\r\n optionalPlatforms: undefined,\r\n incompatiblePlatforms: []\r\n },\r\n 'git-operations': {\r\n // Git operations work on all platforms\r\n requiredPlatforms: undefined,\r\n optionalPlatforms: undefined,\r\n incompatiblePlatforms: []\r\n },\r\n 'file-operations': {\r\n // File operations need adjustment for Windows paths\r\n requiredPlatforms: undefined,\r\n optionalPlatforms: ['linux', 'macos'],\r\n incompatiblePlatforms: []\r\n },\r\n 'windows-specific': {\r\n // Windows-only hooks (e.g., PowerShell scripts)\r\n requiredPlatforms: ['windows'],\r\n optionalPlatforms: undefined,\r\n incompatiblePlatforms: []\r\n },\r\n 'unix-specific': {\r\n // Unix-only hooks (bash scripts with shebang)\r\n requiredPlatforms: ['linux', 'macos'],\r\n optionalPlatforms: undefined,\r\n incompatiblePlatforms: ['windows']\r\n }\r\n};\r\n","// ========================================\r\n// Hook Wizard Component\r\n// ========================================\r\n// Multi-step wizard for creating common hook patterns\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\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 {\r\n ChevronLeft,\r\n ChevronRight,\r\n Brain,\r\n Shield,\r\n Sparkles,\r\n CheckCircle,\r\n AlertTriangle,\r\n Plus,\r\n Trash2,\r\n} from 'lucide-react';\r\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\r\nimport { fetchSkills, type Skill, type SkillsResponse, saveHook } from '@/lib/api';\r\nimport { cn } from '@/lib/utils';\r\nimport {\r\n detect,\r\n getShell,\r\n getShellName,\r\n checkCompatibility,\r\n getPlatformName,\r\n DEFAULT_PLATFORM_REQUIREMENTS,\r\n type Platform,\r\n} from '@/utils/platformUtils';\r\n\r\n// ========== Types ==========\r\n\r\nexport type WizardType = 'memory-update' | 'danger-protection' | 'skill-context';\r\n\r\ntype WizardStep = 1 | 2 | 3;\r\n\r\nexport interface HookWizardProps {\r\n wizardType: WizardType;\r\n open: boolean;\r\n onClose: () => void;\r\n}\r\n\r\ninterface MemoryUpdateConfig {\r\n tool: 'gemini' | 'qwen' | 'codex' | 'opencode';\r\n threshold: number;\r\n timeout: number;\r\n}\r\n\r\ninterface DangerProtectionConfig {\r\n selectedOptions: string[];\r\n}\r\n\r\ninterface SkillContextConfig {\r\n mode: 'keyword' | 'auto';\r\n skillConfigs: Array<{ skill: string; keywords: string }>;\r\n}\r\n\r\n// ========== Hook Templates ==========\r\n// Templates are now defined in backend: ccw/src/core/hooks/hook-templates.ts\r\n// All templates use `ccw hook template exec <id> --stdin` format\r\n// This avoids Windows Git Bash quote handling issues\r\n\r\n// Template IDs that map to backend templates\r\nconst TEMPLATE_IDS = {\r\n 'memory-update-queue': 'memory-auto-compress',\r\n 'danger-bash-confirm': 'danger-bash-confirm',\r\n 'danger-file-protection': 'danger-file-protection',\r\n 'danger-git-destructive': 'danger-git-destructive',\r\n 'danger-network-confirm': 'danger-network-confirm',\r\n 'danger-system-paths': 'danger-system-paths',\r\n 'danger-permission-change': 'danger-permission-change',\r\n} as const;\r\n\r\n// Danger protection option definitions\r\nconst DANGER_OPTIONS = [\r\n { id: 'bash-confirm', templateId: 'danger-bash-confirm', labelKey: 'cliHooks.wizards.dangerProtection.options.bashConfirm', descKey: 'cliHooks.wizards.dangerProtection.options.bashConfirmDesc' },\r\n { id: 'file-protection', templateId: 'danger-file-protection', labelKey: 'cliHooks.wizards.dangerProtection.options.fileProtection', descKey: 'cliHooks.wizards.dangerProtection.options.fileProtectionDesc' },\r\n { id: 'git-destructive', templateId: 'danger-git-destructive', labelKey: 'cliHooks.wizards.dangerProtection.options.gitDestructive', descKey: 'cliHooks.wizards.dangerProtection.options.gitDestructiveDesc' },\r\n { id: 'network-confirm', templateId: 'danger-network-confirm', labelKey: 'cliHooks.wizards.dangerProtection.options.networkConfirm', descKey: 'cliHooks.wizards.dangerProtection.options.networkConfirmDesc' },\r\n { id: 'system-paths', templateId: 'danger-system-paths', labelKey: 'cliHooks.wizards.dangerProtection.options.systemPaths', descKey: 'cliHooks.wizards.dangerProtection.options.systemPathsDesc' },\r\n { id: 'permission-change', templateId: 'danger-permission-change', labelKey: 'cliHooks.wizards.dangerProtection.options.permissionChange', descKey: 'cliHooks.wizards.dangerProtection.options.permissionChangeDesc' },\r\n] as const;\r\n\r\n// ========== Wizard Definitions ==========\r\n\r\nconst WIZARD_METADATA = {\r\n 'memory-update': {\r\n title: 'cliHooks.wizards.memoryUpdate.title',\r\n description: 'cliHooks.wizards.memoryUpdate.description',\r\n icon: Brain,\r\n trigger: 'Stop' as const,\r\n platformRequirements: DEFAULT_PLATFORM_REQUIREMENTS['memory-update'],\r\n },\r\n 'danger-protection': {\r\n title: 'cliHooks.wizards.dangerProtection.title',\r\n description: 'cliHooks.wizards.dangerProtection.description',\r\n icon: Shield,\r\n trigger: 'PreToolUse' as const,\r\n platformRequirements: DEFAULT_PLATFORM_REQUIREMENTS['danger-protection'],\r\n },\r\n 'skill-context': {\r\n title: 'cliHooks.wizards.skillContext.title',\r\n description: 'cliHooks.wizards.skillContext.description',\r\n icon: Sparkles,\r\n trigger: 'UserPromptSubmit' as const,\r\n platformRequirements: DEFAULT_PLATFORM_REQUIREMENTS['skill-context'],\r\n },\r\n} as const;\r\n\r\n// ========== Main Component ==========\r\n\r\nexport function HookWizard({\r\n wizardType,\r\n open,\r\n onClose,\r\n}: HookWizardProps) {\r\n const { formatMessage } = useIntl();\r\n const queryClient = useQueryClient();\r\n const [currentStep, setCurrentStep] = useState<WizardStep>(1);\r\n const [detectedPlatform, setDetectedPlatform] = useState<Platform>('linux');\r\n const [scope, setScope] = useState<'project' | 'global'>('project');\r\n const [saving, setSaving] = useState(false);\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n // Fetch available skills for skill-context wizard\r\n const { data: skillsData, isLoading: skillsLoading } = useQuery<SkillsResponse>({\r\n queryKey: ['skills'],\r\n queryFn: () => fetchSkills(),\r\n enabled: open && wizardType === 'skill-context',\r\n });\r\n\r\n // Detect platform on mount\r\n useEffect(() => {\r\n if (open) {\r\n setDetectedPlatform(detect());\r\n }\r\n }, [open]);\r\n\r\n // Wizard configuration state\r\n const [memoryConfig, setMemoryConfig] = useState<MemoryUpdateConfig>({\r\n tool: 'gemini',\r\n threshold: 5,\r\n timeout: 300,\r\n });\r\n\r\n const [dangerConfig, setDangerConfig] = useState<DangerProtectionConfig>({\r\n selectedOptions: ['bash-confirm', 'file-protection', 'git-destructive'],\r\n });\r\n\r\n const [skillConfig, setSkillConfig] = useState<SkillContextConfig>({\r\n mode: 'keyword',\r\n skillConfigs: [{ skill: '', keywords: '' }],\r\n });\r\n\r\n // Check platform compatibility\r\n const wizardMetadata = WIZARD_METADATA[wizardType];\r\n const compatibilityCheck = checkCompatibility(\r\n wizardMetadata.platformRequirements,\r\n detectedPlatform\r\n );\r\n\r\n // Handlers\r\n const handleNext = () => {\r\n if (currentStep < 3) {\r\n setCurrentStep((prev) => (prev + 1) as WizardStep);\r\n }\r\n };\r\n\r\n const handlePrevious = () => {\r\n if (currentStep > 1) {\r\n setCurrentStep((prev) => (prev - 1) as WizardStep);\r\n }\r\n };\r\n\r\n const handleClose = () => {\r\n setCurrentStep(1);\r\n onClose();\r\n };\r\n\r\n const handleComplete = async () => {\r\n setSaving(true);\r\n try {\r\n switch (wizardType) {\r\n case 'memory-update': {\r\n // Use backend template API to install memory template\r\n const response = await fetch('/api/hooks/templates/install', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n templateId: 'memory-auto-compress',\r\n scope,\r\n projectPath,\r\n }),\r\n });\r\n const result = await response.json();\r\n if (!result.success) {\r\n throw new Error(result.error || 'Failed to install template');\r\n }\r\n break;\r\n }\r\n\r\n case 'danger-protection': {\r\n // Install each selected protection template via backend API\r\n for (const optionId of dangerConfig.selectedOptions) {\r\n const option = DANGER_OPTIONS.find(o => o.id === optionId);\r\n if (!option) continue;\r\n const templateId = TEMPLATE_IDS[option.templateId as keyof typeof TEMPLATE_IDS] || option.templateId;\r\n\r\n const response = await fetch('/api/hooks/templates/install', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n templateId,\r\n scope,\r\n projectPath,\r\n }),\r\n });\r\n const result = await response.json();\r\n if (!result.success) {\r\n console.warn(`Failed to install template ${templateId}:`, result.error);\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case 'skill-context': {\r\n // Use ccw hook command directly for skill context\r\n const hookData = skillConfig.mode === 'auto'\r\n ? {\r\n _templateId: 'skill-context-auto',\r\n matcher: '',\r\n hooks: [{\r\n type: 'command',\r\n command: 'ccw hook keyword --stdin',\r\n }],\r\n }\r\n : {\r\n _templateId: 'skill-context-keyword',\r\n matcher: '',\r\n hooks: [{\r\n type: 'command',\r\n command: 'ccw hook keyword --stdin',\r\n }],\r\n };\r\n await saveHook(scope, 'UserPromptSubmit', hookData);\r\n break;\r\n }\r\n }\r\n\r\n queryClient.invalidateQueries({ queryKey: ['hooks'] });\r\n handleClose();\r\n } catch (err) {\r\n console.error('Failed to create hook:', err);\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n // ========== Step Renderers ==========\r\n\r\n const renderStep1 = () => {\r\n const WizardIcon = WIZARD_METADATA[wizardType].icon;\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n <div className=\"flex items-center gap-3 pb-4 border-b\">\r\n <div className=\"p-3 rounded-lg bg-primary/10\">\r\n <WizardIcon className=\"w-6 h-6 text-primary\" />\r\n </div>\r\n <div className=\"flex-1\">\r\n <h3 className=\"text-lg font-semibold text-foreground\">\r\n {formatMessage({ id: WIZARD_METADATA[wizardType].title })}\r\n </h3>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: WIZARD_METADATA[wizardType].description })}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n <Card className=\"p-4\">\r\n <div className=\"flex items-center gap-3\">\r\n <CheckCircle className={cn(\r\n 'w-5 h-5',\r\n compatibilityCheck.compatible ? 'text-green-500' : 'text-destructive'\r\n )} />\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.platform.detected' })}\r\n </p>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {getPlatformName(detectedPlatform)} ({getShellName(getShell(detectedPlatform))})\r\n </p>\r\n </div>\r\n <Badge variant={compatibilityCheck.compatible ? 'default' : 'destructive'}>\r\n {compatibilityCheck.compatible\r\n ? formatMessage({ id: 'cliHooks.wizards.platform.compatible' })\r\n : formatMessage({ id: 'cliHooks.wizards.platform.incompatible' })\r\n }\r\n </Badge>\r\n </div>\r\n\r\n {!compatibilityCheck.compatible && compatibilityCheck.issues.length > 0 && (\r\n <div className=\"mt-3 flex items-start gap-2 p-3 bg-destructive/10 rounded-lg\">\r\n <AlertTriangle className=\"w-4 h-4 text-destructive shrink-0 mt-0.5\" />\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium text-destructive\">\r\n {formatMessage({ id: 'cliHooks.wizards.platform.compatibilityError' })}\r\n </p>\r\n <ul className=\"mt-1 space-y-1\">\r\n {compatibilityCheck.issues.map((issue, i) => (\r\n <li key={i} className=\"text-xs text-destructive/80\">{issue}</li>\r\n ))}\r\n </ul>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {compatibilityCheck.warnings.length > 0 && (\r\n <div className=\"mt-3 flex items-start gap-2 p-3 bg-yellow-500/10 rounded-lg\">\r\n <AlertTriangle className=\"w-4 h-4 text-yellow-600 shrink-0 mt-0.5\" />\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium text-yellow-600\">\r\n {formatMessage({ id: 'cliHooks.wizards.platform.compatibilityWarning' })}\r\n </p>\r\n <ul className=\"mt-1 space-y-1\">\r\n {compatibilityCheck.warnings.map((warning, i) => (\r\n <li key={i} className=\"text-xs text-yellow-600/80\">{warning}</li>\r\n ))}\r\n </ul>\r\n </div>\r\n </div>\r\n )}\r\n </Card>\r\n\r\n <Card className=\"p-4\">\r\n <p className=\"text-sm text-muted-foreground mb-2\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.triggerEvent' })}\r\n </p>\r\n <Badge variant=\"secondary\">\r\n {formatMessage({ id: `cliHooks.trigger.${wizardMetadata.trigger}` })}\r\n </Badge>\r\n </Card>\r\n </div>\r\n );\r\n };\r\n\r\n const renderStep2 = () => {\r\n switch (wizardType) {\r\n case 'memory-update':\r\n return renderMemoryUpdateConfig();\r\n case 'danger-protection':\r\n return renderDangerProtectionConfig();\r\n case 'skill-context':\r\n return renderSkillContextConfig();\r\n default:\r\n return null;\r\n }\r\n };\r\n\r\n const renderStep3 = () => {\r\n return (\r\n <div className=\"space-y-4\">\r\n <div className=\"text-center pb-4 border-b\">\r\n <CheckCircle className=\"w-12 h-12 text-green-500 mx-auto mb-3\" />\r\n <h3 className=\"text-lg font-semibold text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.title' })}\r\n </h3>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.description' })}\r\n </p>\r\n </div>\r\n\r\n <Card className=\"p-4 space-y-3\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.hookType' })}\r\n </span>\r\n <span className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: WIZARD_METADATA[wizardType].title })}\r\n </span>\r\n </div>\r\n\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.trigger' })}\r\n </span>\r\n <Badge variant=\"secondary\" className=\"text-xs\">\r\n {formatMessage({ id: `cliHooks.trigger.${wizardMetadata.trigger}` })}\r\n </Badge>\r\n </div>\r\n\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.platform' })}\r\n </span>\r\n <span className=\"text-sm text-foreground\">\r\n {getPlatformName(detectedPlatform)}\r\n </span>\r\n </div>\r\n\r\n {renderConfigSummary()}\r\n </Card>\r\n\r\n {/* Scope Selection */}\r\n <Card className=\"p-4\">\r\n <p className=\"text-sm font-medium text-foreground mb-3\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.installTo' })}\r\n </p>\r\n <div className=\"flex gap-4\">\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"wizardScope\"\r\n value=\"project\"\r\n checked={scope === 'project'}\r\n onChange={() => setScope('project')}\r\n className=\"accent-primary\"\r\n />\r\n <span className=\"text-sm text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.scopeProject' })}\r\n </span>\r\n <span className=\"text-xs text-muted-foreground\">(.claude/settings.json)</span>\r\n </label>\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"wizardScope\"\r\n value=\"global\"\r\n checked={scope === 'global'}\r\n onChange={() => setScope('global')}\r\n className=\"accent-primary\"\r\n />\r\n <span className=\"text-sm text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.scopeGlobal' })}\r\n </span>\r\n <span className=\"text-xs text-muted-foreground\">(~/.claude/settings.json)</span>\r\n </label>\r\n </div>\r\n </Card>\r\n\r\n {/* Command Preview */}\r\n <Card className=\"p-4\">\r\n <p className=\"text-xs text-muted-foreground mb-2\">\r\n {formatMessage({ id: 'cliHooks.wizards.steps.review.commandPreview' })}\r\n </p>\r\n <pre className=\"text-xs font-mono bg-muted p-3 rounded-lg overflow-x-auto whitespace-pre-wrap break-all\">\r\n {getPreviewCommand()}\r\n </pre>\r\n </Card>\r\n </div>\r\n );\r\n };\r\n\r\n // ========== Configuration Renderers ==========\r\n\r\n const renderMemoryUpdateConfig = () => (\r\n <div className=\"space-y-4\">\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.memoryUpdate.cliTool' })}\r\n </label>\r\n <Select\r\n value={memoryConfig.tool}\r\n onValueChange={(value: MemoryUpdateConfig['tool']) => setMemoryConfig({ ...memoryConfig, tool: value })}\r\n >\r\n <SelectTrigger className=\"mt-1\">\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"gemini\">Gemini</SelectItem>\r\n <SelectItem value=\"qwen\">Qwen</SelectItem>\r\n <SelectItem value=\"codex\">Codex</SelectItem>\r\n <SelectItem value=\"opencode\">OpenCode</SelectItem>\r\n </SelectContent>\r\n </Select>\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'cliHooks.wizards.memoryUpdate.cliToolHelp' })}\r\n </p>\r\n </div>\r\n\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.memoryUpdate.threshold' })}\r\n </label>\r\n <Input\r\n type=\"number\"\r\n value={memoryConfig.threshold}\r\n onChange={(e) => setMemoryConfig({ ...memoryConfig, threshold: Math.max(1, Math.min(20, parseInt(e.target.value) || 1)) })}\r\n min={1}\r\n max={20}\r\n className=\"mt-1\"\r\n />\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'cliHooks.wizards.memoryUpdate.thresholdHelp' })}\r\n </p>\r\n </div>\r\n\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.memoryUpdate.timeout' })}\r\n </label>\r\n <Input\r\n type=\"number\"\r\n value={memoryConfig.timeout}\r\n onChange={(e) => setMemoryConfig({ ...memoryConfig, timeout: Math.max(60, Math.min(1800, parseInt(e.target.value) || 60)) })}\r\n min={60}\r\n max={1800}\r\n step={60}\r\n className=\"mt-1\"\r\n />\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'cliHooks.wizards.memoryUpdate.timeoutHelp' })}\r\n </p>\r\n </div>\r\n </div>\r\n );\r\n\r\n const renderDangerProtectionConfig = () => {\r\n const toggleOption = (optionId: string) => {\r\n setDangerConfig(prev => {\r\n const selected = prev.selectedOptions.includes(optionId)\r\n ? prev.selectedOptions.filter(id => id !== optionId)\r\n : [...prev.selectedOptions, optionId];\r\n return { selectedOptions: selected };\r\n });\r\n };\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.dangerProtection.selectProtections' })}\r\n </p>\r\n {DANGER_OPTIONS.map(option => (\r\n <label\r\n key={option.id}\r\n className={cn(\r\n 'flex items-start gap-3 p-3 rounded-lg border cursor-pointer transition-colors',\r\n dangerConfig.selectedOptions.includes(option.id)\r\n ? 'border-primary bg-primary/5'\r\n : 'border-border hover:border-primary/50'\r\n )}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={dangerConfig.selectedOptions.includes(option.id)}\r\n onChange={() => toggleOption(option.id)}\r\n className=\"mt-0.5 accent-primary\"\r\n />\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: option.labelKey })}\r\n </p>\r\n <p className=\"text-xs text-muted-foreground mt-0.5\">\r\n {formatMessage({ id: option.descKey })}\r\n </p>\r\n </div>\r\n </label>\r\n ))}\r\n </div>\r\n );\r\n };\r\n\r\n const renderSkillContextConfig = () => {\r\n const skills: Skill[] = skillsData?.skills ?? [];\r\n\r\n const addConfig = () => {\r\n setSkillConfig(prev => ({\r\n ...prev,\r\n skillConfigs: [...prev.skillConfigs, { skill: '', keywords: '' }],\r\n }));\r\n };\r\n\r\n const removeConfig = (index: number) => {\r\n setSkillConfig(prev => ({\r\n ...prev,\r\n skillConfigs: prev.skillConfigs.filter((_, i) => i !== index),\r\n }));\r\n };\r\n\r\n const updateConfig = (index: number, field: 'skill' | 'keywords', value: string) => {\r\n setSkillConfig(prev => {\r\n const newConfigs = [...prev.skillConfigs];\r\n newConfigs[index] = { ...newConfigs[index], [field]: value };\r\n return { ...prev, skillConfigs: newConfigs };\r\n });\r\n };\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Mode Selection */}\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.skillContext.mode' })}\r\n </label>\r\n <div className=\"flex gap-3 mt-2\">\r\n <label className={cn(\r\n 'flex-1 flex items-center gap-2 p-3 rounded-lg border cursor-pointer transition-colors',\r\n skillConfig.mode === 'keyword' ? 'border-primary bg-primary/5' : 'border-border'\r\n )}>\r\n <input\r\n type=\"radio\"\r\n name=\"skillMode\"\r\n value=\"keyword\"\r\n checked={skillConfig.mode === 'keyword'}\r\n onChange={() => setSkillConfig(prev => ({ ...prev, mode: 'keyword' }))}\r\n className=\"accent-primary\"\r\n />\r\n <div>\r\n <p className=\"text-sm font-medium\">{formatMessage({ id: 'cliHooks.wizards.skillContext.modeKeyword' })}</p>\r\n <p className=\"text-xs text-muted-foreground\">{formatMessage({ id: 'cliHooks.wizards.skillContext.modeKeywordDesc' })}</p>\r\n </div>\r\n </label>\r\n <label className={cn(\r\n 'flex-1 flex items-center gap-2 p-3 rounded-lg border cursor-pointer transition-colors',\r\n skillConfig.mode === 'auto' ? 'border-primary bg-primary/5' : 'border-border'\r\n )}>\r\n <input\r\n type=\"radio\"\r\n name=\"skillMode\"\r\n value=\"auto\"\r\n checked={skillConfig.mode === 'auto'}\r\n onChange={() => setSkillConfig(prev => ({ ...prev, mode: 'auto' }))}\r\n className=\"accent-primary\"\r\n />\r\n <div>\r\n <p className=\"text-sm font-medium\">{formatMessage({ id: 'cliHooks.wizards.skillContext.modeAuto' })}</p>\r\n <p className=\"text-xs text-muted-foreground\">{formatMessage({ id: 'cliHooks.wizards.skillContext.modeAutoDesc' })}</p>\r\n </div>\r\n </label>\r\n </div>\r\n </div>\r\n\r\n {/* Keyword mode: skill config list */}\r\n {skillConfig.mode === 'keyword' && (\r\n <>\r\n {skillsLoading ? (\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.skillContext.loadingSkills' })}\r\n </p>\r\n ) : (\r\n <div className=\"space-y-3\">\r\n {skillConfig.skillConfigs.map((config, index) => (\r\n <div key={index} className=\"flex items-center gap-2\">\r\n <Select value={config.skill} onValueChange={(value) => updateConfig(index, 'skill', value)}>\r\n <SelectTrigger className=\"w-[160px]\">\r\n <SelectValue placeholder={formatMessage({ id: 'cliHooks.wizards.skillContext.selectSkill' })} />\r\n </SelectTrigger>\r\n <SelectContent>\r\n {skills.map((skill) => (\r\n <SelectItem key={skill.name} value={skill.name}>\r\n {skill.name}\r\n </SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n <Input\r\n value={config.keywords}\r\n onChange={(e) => updateConfig(index, 'keywords', e.target.value)}\r\n placeholder={formatMessage({ id: 'cliHooks.wizards.skillContext.keywordsPlaceholder' })}\r\n className=\"flex-1\"\r\n />\r\n {skillConfig.skillConfigs.length > 1 && (\r\n <Button variant=\"ghost\" size=\"icon\" onClick={() => removeConfig(index)}>\r\n <Trash2 className=\"w-4 h-4\" />\r\n </Button>\r\n )}\r\n </div>\r\n ))}\r\n <Button variant=\"outline\" size=\"sm\" onClick={addConfig} className=\"w-full\">\r\n <Plus className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'cliHooks.wizards.skillContext.addPair' })}\r\n </Button>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n\r\n {/* Auto mode: info display */}\r\n {skillConfig.mode === 'auto' && (\r\n <Card className=\"p-4 bg-muted/30\">\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.skillContext.autoDescription' })}\r\n </p>\r\n {!skillsLoading && skills.length > 0 && (\r\n <div className=\"mt-2 flex flex-wrap gap-1\">\r\n {skills.map(s => (\r\n <Badge key={s.name} variant=\"secondary\" className=\"text-xs\">{s.name}</Badge>\r\n ))}\r\n </div>\r\n )}\r\n </Card>\r\n )}\r\n </div>\r\n );\r\n };\r\n\r\n // ========== Config Summary ==========\r\n\r\n const renderConfigSummary = () => {\r\n switch (wizardType) {\r\n case 'memory-update':\r\n return (\r\n <div className=\"space-y-2 text-sm\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-muted-foreground\">CLI Tool</span>\r\n <Badge variant=\"secondary\">{memoryConfig.tool}</Badge>\r\n </div>\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-muted-foreground\">Threshold</span>\r\n <span>{memoryConfig.threshold} paths</span>\r\n </div>\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-muted-foreground\">Timeout</span>\r\n <span>{memoryConfig.timeout}s</span>\r\n </div>\r\n </div>\r\n );\r\n\r\n case 'danger-protection':\r\n return (\r\n <div className=\"space-y-2 text-sm\">\r\n <span className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.dangerProtection.selectedProtections' })}:\r\n </span>\r\n <div className=\"mt-1 flex flex-wrap gap-1\">\r\n {dangerConfig.selectedOptions.map(id => {\r\n const opt = DANGER_OPTIONS.find(o => o.id === id);\r\n return opt ? (\r\n <Badge key={id} variant=\"secondary\" className=\"text-xs\">\r\n {formatMessage({ id: opt.labelKey })}\r\n </Badge>\r\n ) : null;\r\n })}\r\n </div>\r\n </div>\r\n );\r\n\r\n case 'skill-context':\r\n return (\r\n <div className=\"space-y-2 text-sm\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.skillContext.mode' })}\r\n </span>\r\n <Badge variant=\"secondary\">\r\n {skillConfig.mode === 'auto'\r\n ? formatMessage({ id: 'cliHooks.wizards.skillContext.modeAuto' })\r\n : formatMessage({ id: 'cliHooks.wizards.skillContext.modeKeyword' })\r\n }\r\n </Badge>\r\n </div>\r\n {skillConfig.mode === 'keyword' && (\r\n <div>\r\n <span className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.skillContext.keywordMappings' })}:\r\n </span>\r\n <div className=\"mt-1 space-y-1\">\r\n {skillConfig.skillConfigs\r\n .filter(c => c.skill && c.keywords)\r\n .map((config, i) => (\r\n <div key={i} className=\"flex items-center gap-2 text-xs\">\r\n <Badge variant=\"outline\">{config.keywords}</Badge>\r\n <span className=\"text-muted-foreground\">{'->'}</span>\r\n <Badge variant=\"secondary\">{config.skill}</Badge>\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n\r\n default:\r\n return null;\r\n }\r\n };\r\n\r\n // ========== Command Preview ==========\r\n\r\n const getPreviewCommand = (): string => {\r\n switch (wizardType) {\r\n case 'memory-update': {\r\n return `ccw hook template exec memory-auto-compress --stdin`;\r\n }\r\n case 'danger-protection': {\r\n const templates = dangerConfig.selectedOptions\r\n .map(id => DANGER_OPTIONS.find(o => o.id === id))\r\n .filter(Boolean)\r\n .map(opt => {\r\n const templateId = TEMPLATE_IDS[opt!.templateId as keyof typeof TEMPLATE_IDS] || opt!.templateId;\r\n return `ccw hook template exec ${templateId} --stdin`;\r\n });\r\n return templates.length > 0\r\n ? templates.join('\\n')\r\n : '# No protections selected';\r\n }\r\n case 'skill-context': {\r\n return `ccw hook keyword --stdin`;\r\n }\r\n default:\r\n return '';\r\n }\r\n };\r\n\r\n // ========== Navigation ==========\r\n\r\n const renderNavigation = () => (\r\n <DialogFooter className=\"gap-2\">\r\n {currentStep > 1 && (\r\n <Button variant=\"outline\" onClick={handlePrevious} disabled={saving}>\r\n <ChevronLeft className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'cliHooks.wizards.navigation.previous' })}\r\n </Button>\r\n )}\r\n {currentStep < 3 ? (\r\n <Button onClick={handleNext} disabled={!compatibilityCheck.compatible}>\r\n {formatMessage({ id: 'cliHooks.wizards.navigation.next' })}\r\n <ChevronRight className=\"w-4 h-4 ml-1\" />\r\n </Button>\r\n ) : (\r\n <Button onClick={handleComplete} disabled={saving}>\r\n {saving\r\n ? formatMessage({ id: 'cliHooks.wizards.navigation.creating' })\r\n : formatMessage({ id: 'cliHooks.wizards.navigation.create' })\r\n }\r\n </Button>\r\n )}\r\n </DialogFooter>\r\n );\r\n\r\n // ========== Step Indicator ==========\r\n\r\n const renderStepIndicator = () => (\r\n <div className=\"flex items-center justify-center gap-2 pb-4\">\r\n {[1, 2, 3].map((step) => (\r\n <div key={step} className=\"flex items-center\">\r\n <div\r\n className={cn(\r\n 'w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium',\r\n currentStep === step\r\n ? 'bg-primary text-primary-foreground'\r\n : currentStep > step\r\n ? 'bg-green-500 text-white'\r\n : 'bg-muted text-muted-foreground'\r\n )}\r\n >\r\n {currentStep > step ? <CheckCircle className=\"w-4 h-4\" /> : step}\r\n </div>\r\n {step < 3 && (\r\n <div\r\n className={cn(\r\n 'w-12 h-0.5 mx-1',\r\n currentStep > step ? 'bg-green-500' : 'bg-muted'\r\n )}\r\n />\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n\r\n return (\r\n <Dialog open={open} onOpenChange={handleClose}>\r\n <DialogContent className=\"sm:max-w-[600px]\">\r\n <DialogHeader>\r\n <DialogTitle className=\"flex items-center gap-2\">\r\n {formatMessage({ id: 'cliHooks.wizards.title' })}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <div className=\"w-full bg-muted h-1 rounded-full my-4\">\r\n <div\r\n className=\"bg-primary h-1 rounded-full transition-all duration-300\"\r\n style={{ width: `${(currentStep / 3) * 100}%` }}\r\n />\r\n </div>\r\n\r\n {renderStepIndicator()}\r\n\r\n <div className=\"min-h-[300px]\">\r\n {currentStep === 1 && renderStep1()}\r\n {currentStep === 2 && renderStep2()}\r\n {currentStep === 3 && renderStep3()}\r\n </div>\r\n\r\n {renderNavigation()}\r\n </DialogContent>\r\n </Dialog>\r\n );\r\n}\r\n\r\nexport default HookWizard;\r\n","// ========================================\r\n// Hook Manager Page\r\n// ========================================\r\n// Full CRUD page for managing CLI hooks\r\n\r\nimport { useState, useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\nimport {\r\n GitFork,\r\n Plus,\r\n Search,\r\n RefreshCw,\r\n Play,\r\n Zap,\r\n Wrench,\r\n CheckCircle,\r\n StopCircle,\r\n Wand2,\r\n Brain,\r\n Shield,\r\n Sparkles,\r\n ChevronDown,\r\n ChevronUp,\r\n} from 'lucide-react';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { HookCard, HookFormDialog, HookQuickTemplates, HookWizard, type HookCardData, type HookFormData, type HookTriggerType, HOOK_TEMPLATES, type WizardType } from '@/components/hook';\r\nimport { useHooks, useToggleHook, useDeleteHook } from '@/hooks';\r\nimport { cn } from '@/lib/utils';\r\n\r\n// ========== Types ==========\r\n\r\ninterface HooksByTrigger {\r\n SessionStart: HookCardData[];\r\n UserPromptSubmit: HookCardData[];\r\n PreToolUse: HookCardData[];\r\n PostToolUse: HookCardData[];\r\n Stop: HookCardData[];\r\n Notification: HookCardData[];\r\n SubagentStart: HookCardData[];\r\n SubagentStop: HookCardData[];\r\n PreCompact: HookCardData[];\r\n SessionEnd: HookCardData[];\r\n PostToolUseFailure: HookCardData[];\r\n PermissionRequest: HookCardData[];\r\n}\r\n\r\n// ========== Helper Functions ==========\r\n\r\nfunction isHookTriggerType(value: string): value is HookTriggerType {\r\n return ['SessionStart', 'UserPromptSubmit', 'PreToolUse', 'PostToolUse', 'Stop', 'Notification', 'SubagentStart', 'SubagentStop', 'PreCompact', 'SessionEnd', 'PostToolUseFailure', 'PermissionRequest'].includes(value);\r\n}\r\n\r\nfunction toHookCardData(hook: { name: string; description?: string; enabled: boolean; trigger: string; matcher?: string; command?: string; script?: string; scope?: 'global' | 'project'; index?: number }): HookCardData | null {\r\n if (!isHookTriggerType(hook.trigger)) {\r\n return null;\r\n }\r\n return {\r\n name: hook.name,\r\n description: hook.description,\r\n enabled: hook.enabled,\r\n trigger: hook.trigger,\r\n matcher: hook.matcher,\r\n command: hook.command || hook.script,\r\n scope: hook.scope,\r\n index: hook.index,\r\n };\r\n}\r\n\r\nfunction groupHooksByTrigger(hooks: HookCardData[]): HooksByTrigger {\r\n return {\r\n SessionStart: hooks.filter((h) => h.trigger === 'SessionStart'),\r\n UserPromptSubmit: hooks.filter((h) => h.trigger === 'UserPromptSubmit'),\r\n PreToolUse: hooks.filter((h) => h.trigger === 'PreToolUse'),\r\n PostToolUse: hooks.filter((h) => h.trigger === 'PostToolUse'),\r\n Stop: hooks.filter((h) => h.trigger === 'Stop'),\r\n Notification: hooks.filter((h) => h.trigger === 'Notification'),\r\n SubagentStart: hooks.filter((h) => h.trigger === 'SubagentStart'),\r\n SubagentStop: hooks.filter((h) => h.trigger === 'SubagentStop'),\r\n PreCompact: hooks.filter((h) => h.trigger === 'PreCompact'),\r\n SessionEnd: hooks.filter((h) => h.trigger === 'SessionEnd'),\r\n PostToolUseFailure: hooks.filter((h) => h.trigger === 'PostToolUseFailure'),\r\n PermissionRequest: hooks.filter((h) => h.trigger === 'PermissionRequest'),\r\n };\r\n}\r\n\r\nfunction getTriggerStats(hooksByTrigger: HooksByTrigger) {\r\n return {\r\n SessionStart: {\r\n total: hooksByTrigger.SessionStart.length,\r\n enabled: hooksByTrigger.SessionStart.filter((h) => h.enabled).length,\r\n },\r\n UserPromptSubmit: {\r\n total: hooksByTrigger.UserPromptSubmit.length,\r\n enabled: hooksByTrigger.UserPromptSubmit.filter((h) => h.enabled).length,\r\n },\r\n PreToolUse: {\r\n total: hooksByTrigger.PreToolUse.length,\r\n enabled: hooksByTrigger.PreToolUse.filter((h) => h.enabled).length,\r\n },\r\n PostToolUse: {\r\n total: hooksByTrigger.PostToolUse.length,\r\n enabled: hooksByTrigger.PostToolUse.filter((h) => h.enabled).length,\r\n },\r\n Stop: {\r\n total: hooksByTrigger.Stop.length,\r\n enabled: hooksByTrigger.Stop.filter((h) => h.enabled).length,\r\n },\r\n Notification: {\r\n total: hooksByTrigger.Notification.length,\r\n enabled: hooksByTrigger.Notification.filter((h) => h.enabled).length,\r\n },\r\n SubagentStart: {\r\n total: hooksByTrigger.SubagentStart.length,\r\n enabled: hooksByTrigger.SubagentStart.filter((h) => h.enabled).length,\r\n },\r\n SubagentStop: {\r\n total: hooksByTrigger.SubagentStop.length,\r\n enabled: hooksByTrigger.SubagentStop.filter((h) => h.enabled).length,\r\n },\r\n PreCompact: {\r\n total: hooksByTrigger.PreCompact.length,\r\n enabled: hooksByTrigger.PreCompact.filter((h) => h.enabled).length,\r\n },\r\n SessionEnd: {\r\n total: hooksByTrigger.SessionEnd.length,\r\n enabled: hooksByTrigger.SessionEnd.filter((h) => h.enabled).length,\r\n },\r\n PostToolUseFailure: {\r\n total: hooksByTrigger.PostToolUseFailure.length,\r\n enabled: hooksByTrigger.PostToolUseFailure.filter((h) => h.enabled).length,\r\n },\r\n PermissionRequest: {\r\n total: hooksByTrigger.PermissionRequest.length,\r\n enabled: hooksByTrigger.PermissionRequest.filter((h) => h.enabled).length,\r\n },\r\n };\r\n}\r\n\r\n// ========== Main Page Component ==========\r\n\r\nexport function HookManagerPage() {\r\n const { formatMessage } = useIntl();\r\n const [searchQuery, setSearchQuery] = useState('');\r\n const [selectedTrigger, setSelectedTrigger] = useState<HookTriggerType | 'all'>('all');\r\n const [dialogOpen, setDialogOpen] = useState(false);\r\n const [dialogMode, setDialogMode] = useState<'create' | 'edit'>('create');\r\n const [editingHook, setEditingHook] = useState<HookCardData | undefined>();\r\n const [wizardOpen, setWizardOpen] = useState(false);\r\n const [wizardType, setWizardType] = useState<WizardType>('memory-update');\r\n const [expandedHooks, setExpandedHooks] = useState<Set<string>>(new Set());\r\n const [templatesExpanded, setTemplatesExpanded] = useState(false);\r\n const [wizardsExpanded, setWizardsExpanded] = useState(false);\r\n\r\n const { hooks, enabledCount, totalCount, isLoading, refetch } = useHooks();\r\n const { toggleHook } = useToggleHook();\r\n const { deleteHook } = useDeleteHook();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n // Convert hooks to HookCardData and filter by search query and trigger type\r\n const filteredHooks = useMemo(() => {\r\n let validHooks = hooks.map(toHookCardData).filter((h): h is HookCardData => h !== null);\r\n\r\n // Filter by trigger type\r\n if (selectedTrigger !== 'all') {\r\n validHooks = validHooks.filter(h => h.trigger === selectedTrigger);\r\n }\r\n\r\n // Filter by search query\r\n if (searchQuery.trim()) {\r\n const query = searchQuery.toLowerCase();\r\n validHooks = validHooks.filter(\r\n (h) =>\r\n h.name.toLowerCase().includes(query) ||\r\n (h.description && h.description.toLowerCase().includes(query)) ||\r\n h.trigger.toLowerCase().includes(query) ||\r\n (h.command && h.command.toLowerCase().includes(query))\r\n );\r\n }\r\n\r\n return validHooks;\r\n }, [hooks, searchQuery, selectedTrigger]);\r\n\r\n // Group hooks by trigger type\r\n const hooksByTrigger = useMemo(() => groupHooksByTrigger(filteredHooks), [filteredHooks]);\r\n\r\n // Get stats for each trigger type\r\n const triggerStats = useMemo(() => getTriggerStats(hooksByTrigger), [hooksByTrigger]);\r\n\r\n // Handlers\r\n const handleAddClick = () => {\r\n setDialogMode('create');\r\n setEditingHook(undefined);\r\n setDialogOpen(true);\r\n };\r\n\r\n const handleEditClick = (hook: HookCardData) => {\r\n setDialogMode('edit');\r\n setEditingHook(hook);\r\n setDialogOpen(true);\r\n };\r\n\r\n const handleDeleteClick = async (hookName: string) => {\r\n // Find the hook in filteredHooks to get scope and index\r\n const hook = filteredHooks.find(h => h.name === hookName);\r\n if (!hook) {\r\n console.error('Hook not found:', hookName);\r\n return;\r\n }\r\n try {\r\n await deleteHook({\r\n name: hook.name,\r\n scope: hook.scope,\r\n trigger: hook.trigger,\r\n index: hook.index,\r\n });\r\n } catch (error) {\r\n console.error('Failed to delete hook:', error);\r\n }\r\n };\r\n\r\n const handleSave = async (data: HookFormData) => {\r\n // This will be implemented when create/update APIs are added\r\n console.log('Save hook:', data);\r\n await refetch();\r\n };\r\n\r\n const handleToggleHookExpand = (hookName: string) => {\r\n setExpandedHooks((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(hookName)) {\r\n next.delete(hookName);\r\n } else {\r\n next.add(hookName);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n // ========== Wizard Handlers ==========\r\n\r\n const wizardTypes: Array<{ type: WizardType; icon: typeof Brain; label: string; description: string }> = [\r\n {\r\n type: 'memory-update',\r\n icon: Brain,\r\n label: formatMessage({ id: 'cliHooks.wizards.memoryUpdate.title' }),\r\n description: formatMessage({ id: 'cliHooks.wizards.memoryUpdate.shortDescription' }),\r\n },\r\n {\r\n type: 'danger-protection',\r\n icon: Shield,\r\n label: formatMessage({ id: 'cliHooks.wizards.dangerProtection.title' }),\r\n description: formatMessage({ id: 'cliHooks.wizards.dangerProtection.shortDescription' }),\r\n },\r\n {\r\n type: 'skill-context',\r\n icon: Sparkles,\r\n label: formatMessage({ id: 'cliHooks.wizards.skillContext.title' }),\r\n description: formatMessage({ id: 'cliHooks.wizards.skillContext.shortDescription' }),\r\n },\r\n ];\r\n\r\n const handleLaunchWizard = (type: WizardType) => {\r\n setWizardType(type);\r\n setWizardOpen(true);\r\n };\r\n\r\n // ========== Quick Templates Logic ==========\r\n\r\n // Determine which templates are already installed\r\n const installedTemplates = useMemo(() => {\r\n return HOOK_TEMPLATES.filter(template => {\r\n return hooks.some(hook => hook.templateId === template.id);\r\n }).map(t => t.id);\r\n }, [hooks]);\r\n\r\n // Track per-template installing state\r\n const [installingTemplateId, setInstallingTemplateId] = useState<string | null>(null);\r\n\r\n const handleInstallTemplate = async (templateId: string) => {\r\n const template = HOOK_TEMPLATES.find(t => t.id === templateId);\r\n if (!template) return;\r\n\r\n setInstallingTemplateId(templateId);\r\n try {\r\n // Use backend API to install template\r\n const response = await fetch('/api/hooks/templates/install', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n templateId,\r\n scope: 'project',\r\n projectPath,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`Failed to install template: ${response.statusText}`);\r\n }\r\n\r\n const result = await response.json();\r\n if (!result.success) {\r\n throw new Error(result.error || 'Unknown error');\r\n }\r\n\r\n await refetch();\r\n } catch (error) {\r\n console.error('Failed to install template:', error);\r\n } finally {\r\n setInstallingTemplateId(null);\r\n }\r\n };\r\n\r\n const FILTER_OPTIONS: Array<{ type: HookTriggerType | 'all'; icon: typeof Zap; label: string }> = [\r\n { type: 'all', icon: GitFork, label: formatMessage({ id: 'common.all' }) },\r\n { type: 'SessionStart', icon: Play, label: formatMessage({ id: 'cliHooks.trigger.SessionStart' }) },\r\n { type: 'UserPromptSubmit', icon: Zap, label: formatMessage({ id: 'cliHooks.trigger.UserPromptSubmit' }) },\r\n { type: 'PreToolUse', icon: Wrench, label: formatMessage({ id: 'cliHooks.trigger.PreToolUse' }) },\r\n { type: 'PostToolUse', icon: CheckCircle, label: formatMessage({ id: 'cliHooks.trigger.PostToolUse' }) },\r\n { type: 'Stop', icon: StopCircle, label: formatMessage({ id: 'cliHooks.trigger.Stop' }) },\r\n ];\r\n\r\n return (\r\n <div className=\"max-w-6xl mx-auto space-y-6\">\r\n {/* Page Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-foreground flex items-center gap-2\">\r\n <GitFork className=\"w-6 h-6 text-primary\" />\r\n {formatMessage({ id: 'cliHooks.title' })}\r\n </h1>\r\n <p className=\"text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'cliHooks.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={isLoading}\r\n >\r\n <RefreshCw className={cn('w-4 h-4 mr-1', isLoading && 'animate-spin')} />\r\n {formatMessage({ id: 'common.actions.refresh' })}\r\n </Button>\r\n <Button variant=\"outline\" size=\"sm\" onClick={handleAddClick}>\r\n <Plus className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'cliHooks.actions.add' })}\r\n </Button>\r\n <Button size=\"sm\" onClick={() => handleLaunchWizard('memory-update')} variant=\"secondary\">\r\n <Wand2 className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'cliHooks.wizards.launch' })}\r\n </Button>\r\n </div>\r\n </div>\r\n\r\n {/* Search and Filters */}\r\n <Card className=\"p-4\">\r\n <div className=\"space-y-4\">\r\n {/* Search Bar */}\r\n <div className=\"flex items-center justify-between gap-4\">\r\n <div className=\"relative flex-1 max-w-md\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground\" />\r\n <Input\r\n placeholder={formatMessage({ id: 'cliHooks.filters.searchPlaceholder' })}\r\n value={searchQuery}\r\n onChange={(e) => setSearchQuery(e.target.value)}\r\n className=\"pl-9\"\r\n />\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <Badge variant=\"outline\" className=\"text-sm\">\r\n {formatMessage({ id: 'cliHooks.stats.total' }, { count: totalCount })}\r\n </Badge>\r\n <Badge variant=\"default\" className=\"text-sm\">\r\n {formatMessage({ id: 'cliHooks.stats.enabled' }, { count: enabledCount })}\r\n </Badge>\r\n </div>\r\n </div>\r\n\r\n {/* Trigger Type Filters */}\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n {FILTER_OPTIONS.map(({ type, icon: Icon, label }) => {\r\n const isSelected = selectedTrigger === type;\r\n const stats = type === 'all'\r\n ? { enabled: enabledCount, total: totalCount }\r\n : triggerStats[type as HookTriggerType];\r\n\r\n return (\r\n <Button\r\n key={type}\r\n variant={isSelected ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => setSelectedTrigger(type)}\r\n className=\"gap-2\"\r\n >\r\n <Icon className=\"w-4 h-4\" />\r\n {label}\r\n <Badge\r\n variant={isSelected ? 'secondary' : 'outline'}\r\n className=\"ml-1\"\r\n >\r\n {stats.enabled}/{stats.total}\r\n </Badge>\r\n </Button>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n </Card>\r\n\r\n {/* Hook Cards Grid */}\r\n {filteredHooks.length > 0 && (\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\r\n {filteredHooks.map((hook) => (\r\n <HookCard\r\n key={hook.name}\r\n hook={hook}\r\n isExpanded={expandedHooks.has(hook.name)}\r\n onToggleExpand={() => handleToggleHookExpand(hook.name)}\r\n onToggle={toggleHook}\r\n onEdit={handleEditClick}\r\n onDelete={handleDeleteClick}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Quick Templates */}\r\n <Card className=\"overflow-hidden\">\r\n <div\r\n className=\"p-4 cursor-pointer hover:bg-muted/50 transition-colors flex items-center justify-between border-b border-border\"\r\n onClick={() => setTemplatesExpanded(!templatesExpanded)}\r\n >\r\n <div className=\"flex items-center gap-3\">\r\n <Zap className=\"w-5 h-5 text-primary\" />\r\n <h2 className=\"text-base font-semibold text-foreground\">\r\n {formatMessage({ id: 'cliHooks.quickTemplates.title' })}\r\n </h2>\r\n </div>\r\n <Button variant=\"ghost\" size=\"sm\" className=\"h-8 w-8 p-0\">\r\n {templatesExpanded ? (\r\n <ChevronUp className=\"w-4 h-4\" />\r\n ) : (\r\n <ChevronDown className=\"w-4 h-4\" />\r\n )}\r\n </Button>\r\n </div>\r\n {templatesExpanded && (\r\n <div className=\"p-6\">\r\n <HookQuickTemplates\r\n onInstallTemplate={handleInstallTemplate}\r\n installedTemplates={installedTemplates}\r\n isLoading={!!installingTemplateId}\r\n installingTemplateId={installingTemplateId}\r\n />\r\n </div>\r\n )}\r\n </Card>\r\n\r\n {/* Wizard Launchers */}\r\n <Card className=\"overflow-hidden\">\r\n <div\r\n className=\"p-4 cursor-pointer hover:bg-muted/50 transition-colors flex items-center justify-between\"\r\n onClick={() => setWizardsExpanded(!wizardsExpanded)}\r\n >\r\n <div className=\"flex items-center gap-3\">\r\n <Wand2 className=\"w-5 h-5 text-primary\" />\r\n <div>\r\n <h2 className=\"text-base font-semibold text-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.sectionTitle' })}\r\n </h2>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'cliHooks.wizards.sectionDescription' })}\r\n </p>\r\n </div>\r\n </div>\r\n <Button variant=\"ghost\" size=\"sm\" className=\"h-8 w-8 p-0\">\r\n {wizardsExpanded ? (\r\n <ChevronUp className=\"w-4 h-4\" />\r\n ) : (\r\n <ChevronDown className=\"w-4 h-4\" />\r\n )}\r\n </Button>\r\n </div>\r\n {wizardsExpanded && (\r\n <div className=\"border-t border-border p-6\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\r\n {wizardTypes.map(({ type, icon: Icon, label, description }) => (\r\n <Card key={type} className=\"p-4 cursor-pointer hover:bg-muted/50 transition-colors\" onClick={() => handleLaunchWizard(type)}>\r\n <div className=\"flex items-start gap-3\">\r\n <div className=\"p-2 rounded-lg bg-primary/10 shrink-0\">\r\n <Icon className=\"w-5 h-5 text-primary\" />\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <h3 className=\"text-sm font-medium text-foreground mb-1\">\r\n {label}\r\n </h3>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {description}\r\n </p>\r\n </div>\r\n </div>\r\n </Card>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </Card>\r\n\r\n {/* Empty State */}\r\n {!isLoading && filteredHooks.length === 0 && (\r\n <Card className=\"p-12 text-center\">\r\n <GitFork className=\"w-16 h-16 mx-auto text-muted-foreground/30 mb-4\" />\r\n <h3 className=\"text-lg font-semibold text-foreground mb-2\">\r\n {formatMessage({ id: 'cliHooks.empty.title' })}\r\n </h3>\r\n <p className=\"text-muted-foreground mb-6\">\r\n {formatMessage({ id: 'cliHooks.empty.description' })}\r\n </p>\r\n <Button onClick={handleAddClick}>\r\n <Plus className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'cliHooks.actions.addFirst' })}\r\n </Button>\r\n </Card>\r\n )}\r\n\r\n {/* Form Dialog */}\r\n <HookFormDialog\r\n mode={dialogMode}\r\n hook={editingHook}\r\n open={dialogOpen}\r\n onClose={() => setDialogOpen(false)}\r\n onSave={handleSave}\r\n />\r\n\r\n {/* Hook Wizard */}\r\n <HookWizard\r\n wizardType={wizardType}\r\n open={wizardOpen}\r\n onClose={() => setWizardOpen(false)}\r\n />\r\n </div>\r\n );\r\n}\r\n\r\nexport default HookManagerPage;\r\n"],"names":["FileChartColumnIncreasing","createLucideIcon","getTriggerIcon","trigger","getTriggerVariant","DISPLAY_NAME_TO_TEMPLATE_ID","getHookDisplayName","name","formatMessage","translationKey","translated","templateId","mappedKey","HookCard","hook","isExpanded","onToggleExpand","onToggle","onEdit","onDelete","useIntl","showDeleteConfirm","setShowDeleteConfirm","useState","displayName","handleToggle","handleEdit","handleDelete","handleConfirmDelete","handleCancelDelete","jsxs","Fragment","Card","cn","jsx","GitFork","Badge","Button","Power","PowerOff","Edit","Trash2","ChevronUp","ChevronDown","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","validateForm","data","errors","HookFormDialog","mode","open","onClose","onSave","formData","setFormData","setErrors","isSubmitting","setIsSubmitting","useEffect","handleFieldChange","field","value","prev","handleSubmit","validationErrors","error","TRIGGER_OPTIONS","Dialog","DialogContent","DialogHeader","DialogTitle","Input","e","Textarea","Select","SelectTrigger","SelectValue","SelectContent","option","SelectItem","DialogFooter","HOOK_TEMPLATES","CATEGORY_ICONS","Bell","Database","Wrench","Settings","Shield","TEMPLATE_ICONS","Send","FileBarChart","FileCode","FileSearch","GitBranch","getCategoryName","category","HookQuickTemplates","onInstallTemplate","installedTemplates","_isLoading","installingTemplateId","templatesByCategory","useMemo","acc","template","categoryOrder","handleInstall","Zap","templates","CategoryIcon","color","isInstalled","isInstalling","TemplateIcon","catColor","catBg","Loader2","Check","Download","detect","userAgent","getShell","platform","getPlatformName","getShellName","shell","checkCompatibility","requirements","detectedPlatform","issues","warnings","_a","requiredNames","optionalNames","DEFAULT_PLATFORM_REQUIREMENTS","TEMPLATE_IDS","DANGER_OPTIONS","WIZARD_METADATA","Brain","Sparkles","HookWizard","wizardType","queryClient","useQueryClient","currentStep","setCurrentStep","setDetectedPlatform","scope","setScope","saving","setSaving","projectPath","useWorkflowStore","selectProjectPath","skillsData","skillsLoading","useQuery","fetchSkills","memoryConfig","setMemoryConfig","dangerConfig","setDangerConfig","skillConfig","setSkillConfig","wizardMetadata","compatibilityCheck","handleNext","handlePrevious","handleClose","handleComplete","result","optionId","o","hookData","saveHook","err","renderStep1","WizardIcon","CheckCircle","AlertTriangle","issue","i","warning","renderStep2","renderMemoryUpdateConfig","renderDangerProtectionConfig","renderSkillContextConfig","renderStep3","renderConfigSummary","toggleOption","id","skills","addConfig","removeConfig","index","_","updateConfig","newConfigs","config","skill","Plus","s","opt","c","getPreviewCommand","renderNavigation","ChevronLeft","ChevronRight","renderStepIndicator","step","isHookTriggerType","toHookCardData","groupHooksByTrigger","hooks","h","getTriggerStats","hooksByTrigger","HookManagerPage","searchQuery","setSearchQuery","selectedTrigger","setSelectedTrigger","dialogOpen","setDialogOpen","dialogMode","setDialogMode","editingHook","setEditingHook","wizardOpen","setWizardOpen","setWizardType","expandedHooks","setExpandedHooks","templatesExpanded","setTemplatesExpanded","wizardsExpanded","setWizardsExpanded","enabledCount","totalCount","isLoading","refetch","useHooks","toggleHook","useToggleHook","deleteHook","useDeleteHook","filteredHooks","validHooks","query","triggerStats","handleAddClick","handleEditClick","handleDeleteClick","hookName","handleSave","handleToggleHookExpand","next","wizardTypes","handleLaunchWizard","type","t","setInstallingTemplateId","handleInstallTemplate","response","FILTER_OPTIONS","Play","StopCircle","RefreshCw","Wand2","Search","Icon","label","isSelected","stats","description"],"mappings":"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","x_google_ignoreList":[0]}