devflow-kit 0.9.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (397) hide show
  1. package/CHANGELOG.md +167 -29
  2. package/LICENSE +1 -1
  3. package/README.md +179 -310
  4. package/dist/cli.js +3 -1
  5. package/dist/commands/init.d.ts +21 -0
  6. package/dist/commands/init.js +311 -576
  7. package/dist/commands/list.d.ts +3 -0
  8. package/dist/commands/list.js +20 -0
  9. package/dist/commands/uninstall.d.ts +10 -0
  10. package/dist/commands/uninstall.js +351 -78
  11. package/dist/plugins.d.ts +46 -0
  12. package/dist/plugins.js +162 -0
  13. package/dist/utils/cli.d.ts +5 -0
  14. package/dist/utils/cli.js +14 -0
  15. package/dist/utils/installer.d.ts +41 -0
  16. package/dist/utils/installer.js +177 -0
  17. package/dist/utils/paths.d.ts +10 -0
  18. package/dist/utils/paths.js +23 -3
  19. package/dist/utils/post-install.d.ts +68 -0
  20. package/dist/utils/post-install.js +427 -0
  21. package/dist/utils/safe-delete-install.d.ts +22 -0
  22. package/dist/utils/safe-delete-install.js +156 -0
  23. package/dist/utils/safe-delete.d.ts +12 -0
  24. package/dist/utils/safe-delete.js +83 -0
  25. package/package.json +18 -8
  26. package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +7 -0
  27. package/plugins/devflow-audit-claude/README.md +46 -0
  28. package/plugins/devflow-audit-claude/agents/claude-md-auditor.md +134 -0
  29. package/plugins/devflow-audit-claude/commands/audit-claude.md +85 -0
  30. package/plugins/devflow-code-review/.claude-plugin/plugin.json +31 -0
  31. package/plugins/devflow-code-review/README.md +73 -0
  32. package/plugins/devflow-code-review/agents/git.md +272 -0
  33. package/plugins/devflow-code-review/agents/reviewer.md +119 -0
  34. package/plugins/devflow-code-review/agents/synthesizer.md +204 -0
  35. package/plugins/devflow-code-review/commands/code-review-teams.md +262 -0
  36. package/plugins/devflow-code-review/commands/code-review.md +141 -0
  37. package/plugins/devflow-code-review/skills/accessibility/SKILL.md +229 -0
  38. package/plugins/devflow-code-review/skills/accessibility/references/detection.md +171 -0
  39. package/plugins/devflow-code-review/skills/accessibility/references/patterns.md +670 -0
  40. package/plugins/devflow-code-review/skills/accessibility/references/violations.md +419 -0
  41. package/plugins/devflow-code-review/skills/agent-teams/SKILL.md +124 -0
  42. package/plugins/devflow-code-review/skills/agent-teams/references/cleanup.md +104 -0
  43. package/plugins/devflow-code-review/skills/agent-teams/references/communication.md +122 -0
  44. package/plugins/devflow-code-review/skills/agent-teams/references/team-patterns.md +217 -0
  45. package/plugins/devflow-code-review/skills/architecture-patterns/SKILL.md +153 -0
  46. package/plugins/devflow-code-review/skills/architecture-patterns/references/detection.md +337 -0
  47. package/plugins/devflow-code-review/skills/architecture-patterns/references/patterns.md +873 -0
  48. package/plugins/devflow-code-review/skills/architecture-patterns/references/violations.md +575 -0
  49. package/plugins/devflow-code-review/skills/complexity-patterns/SKILL.md +143 -0
  50. package/plugins/devflow-code-review/skills/complexity-patterns/references/detection.md +264 -0
  51. package/plugins/devflow-code-review/skills/complexity-patterns/references/patterns.md +487 -0
  52. package/plugins/devflow-code-review/skills/complexity-patterns/references/violations.md +361 -0
  53. package/plugins/devflow-code-review/skills/consistency-patterns/SKILL.md +140 -0
  54. package/plugins/devflow-code-review/skills/consistency-patterns/references/detection.md +207 -0
  55. package/plugins/devflow-code-review/skills/consistency-patterns/references/patterns.md +202 -0
  56. package/plugins/devflow-code-review/skills/consistency-patterns/references/violations.md +213 -0
  57. package/plugins/devflow-code-review/skills/database-patterns/SKILL.md +134 -0
  58. package/plugins/devflow-code-review/skills/database-patterns/references/detection.md +208 -0
  59. package/plugins/devflow-code-review/skills/database-patterns/references/patterns.md +394 -0
  60. package/plugins/devflow-code-review/skills/database-patterns/references/violations.md +332 -0
  61. package/plugins/devflow-code-review/skills/dependencies-patterns/SKILL.md +141 -0
  62. package/plugins/devflow-code-review/skills/dependencies-patterns/references/detection.md +181 -0
  63. package/plugins/devflow-code-review/skills/dependencies-patterns/references/patterns.md +225 -0
  64. package/plugins/devflow-code-review/skills/dependencies-patterns/references/violations.md +247 -0
  65. package/plugins/devflow-code-review/skills/documentation-patterns/SKILL.md +125 -0
  66. package/plugins/devflow-code-review/skills/documentation-patterns/references/detection.md +190 -0
  67. package/plugins/devflow-code-review/skills/documentation-patterns/references/patterns.md +189 -0
  68. package/plugins/devflow-code-review/skills/documentation-patterns/references/violations.md +163 -0
  69. package/plugins/devflow-code-review/skills/frontend-design/SKILL.md +254 -0
  70. package/plugins/devflow-code-review/skills/frontend-design/references/detection.md +184 -0
  71. package/plugins/devflow-code-review/skills/frontend-design/references/patterns.md +511 -0
  72. package/plugins/devflow-code-review/skills/frontend-design/references/violations.md +453 -0
  73. package/plugins/devflow-code-review/skills/performance-patterns/SKILL.md +154 -0
  74. package/plugins/devflow-code-review/skills/performance-patterns/references/detection.md +351 -0
  75. package/plugins/devflow-code-review/skills/performance-patterns/references/patterns.md +503 -0
  76. package/plugins/devflow-code-review/skills/performance-patterns/references/violations.md +354 -0
  77. package/plugins/devflow-code-review/skills/react/SKILL.md +276 -0
  78. package/plugins/devflow-code-review/skills/react/references/patterns.md +1331 -0
  79. package/plugins/devflow-code-review/skills/react/references/violations.md +565 -0
  80. package/plugins/devflow-code-review/skills/regression-patterns/SKILL.md +146 -0
  81. package/plugins/devflow-code-review/skills/regression-patterns/references/detection.md +237 -0
  82. package/plugins/devflow-code-review/skills/regression-patterns/references/patterns.md +226 -0
  83. package/plugins/devflow-code-review/skills/regression-patterns/references/violations.md +225 -0
  84. package/plugins/devflow-code-review/skills/review-methodology/SKILL.md +119 -0
  85. package/plugins/devflow-code-review/skills/review-methodology/references/patterns.md +186 -0
  86. package/plugins/devflow-code-review/skills/review-methodology/references/report-template.md +142 -0
  87. package/plugins/devflow-code-review/skills/review-methodology/references/violations.md +125 -0
  88. package/plugins/devflow-code-review/skills/security-patterns/SKILL.md +156 -0
  89. package/plugins/devflow-code-review/skills/security-patterns/references/detection.md +287 -0
  90. package/plugins/devflow-code-review/skills/security-patterns/references/patterns.md +507 -0
  91. package/plugins/devflow-code-review/skills/security-patterns/references/violations.md +237 -0
  92. package/plugins/devflow-code-review/skills/test-patterns/SKILL.md +183 -0
  93. package/plugins/devflow-code-review/skills/test-patterns/references/detection.md +149 -0
  94. package/plugins/devflow-code-review/skills/test-patterns/references/patterns.md +220 -0
  95. package/plugins/devflow-code-review/skills/test-patterns/references/report-template.md +108 -0
  96. package/plugins/devflow-code-review/skills/test-patterns/references/violations.md +221 -0
  97. package/plugins/devflow-core-skills/.claude-plugin/plugin.json +27 -0
  98. package/plugins/devflow-core-skills/README.md +50 -0
  99. package/plugins/devflow-core-skills/skills/accessibility/SKILL.md +229 -0
  100. package/plugins/devflow-core-skills/skills/accessibility/references/detection.md +171 -0
  101. package/plugins/devflow-core-skills/skills/accessibility/references/patterns.md +670 -0
  102. package/plugins/devflow-core-skills/skills/accessibility/references/violations.md +419 -0
  103. package/plugins/devflow-core-skills/skills/core-patterns/SKILL.md +162 -0
  104. package/plugins/devflow-core-skills/skills/core-patterns/references/checklist.md +276 -0
  105. package/plugins/devflow-core-skills/skills/core-patterns/references/code-smell-violations.md +144 -0
  106. package/plugins/devflow-core-skills/skills/core-patterns/references/detection.md +303 -0
  107. package/plugins/devflow-core-skills/skills/core-patterns/references/patterns.md +576 -0
  108. package/plugins/devflow-core-skills/skills/core-patterns/references/violations.md +369 -0
  109. package/plugins/devflow-core-skills/skills/docs-framework/SKILL.md +134 -0
  110. package/plugins/devflow-core-skills/skills/docs-framework/references/patterns.md +346 -0
  111. package/plugins/devflow-core-skills/skills/docs-framework/references/violations.md +221 -0
  112. package/plugins/devflow-core-skills/skills/frontend-design/SKILL.md +254 -0
  113. package/plugins/devflow-core-skills/skills/frontend-design/references/detection.md +184 -0
  114. package/plugins/devflow-core-skills/skills/frontend-design/references/patterns.md +511 -0
  115. package/plugins/devflow-core-skills/skills/frontend-design/references/violations.md +453 -0
  116. package/plugins/devflow-core-skills/skills/git-safety/SKILL.md +122 -0
  117. package/plugins/devflow-core-skills/skills/git-safety/references/detection.md +290 -0
  118. package/plugins/devflow-core-skills/skills/git-safety/references/patterns.md +289 -0
  119. package/plugins/devflow-core-skills/skills/git-safety/references/violations.md +18 -0
  120. package/plugins/devflow-core-skills/skills/git-workflow/SKILL.md +158 -0
  121. package/plugins/devflow-core-skills/skills/git-workflow/references/commit-patterns.md +115 -0
  122. package/plugins/devflow-core-skills/skills/git-workflow/references/commit-violations.md +77 -0
  123. package/plugins/devflow-core-skills/skills/git-workflow/references/pr-patterns.md +127 -0
  124. package/plugins/devflow-core-skills/skills/git-workflow/references/pr-violations.md +96 -0
  125. package/plugins/devflow-core-skills/skills/github-patterns/SKILL.md +153 -0
  126. package/plugins/devflow-core-skills/skills/github-patterns/references/patterns.md +572 -0
  127. package/plugins/devflow-core-skills/skills/github-patterns/references/violations.md +298 -0
  128. package/plugins/devflow-core-skills/skills/input-validation/SKILL.md +148 -0
  129. package/plugins/devflow-core-skills/skills/input-validation/references/detection.md +283 -0
  130. package/plugins/devflow-core-skills/skills/input-validation/references/patterns.md +361 -0
  131. package/plugins/devflow-core-skills/skills/input-validation/references/violations.md +224 -0
  132. package/plugins/devflow-core-skills/skills/react/SKILL.md +276 -0
  133. package/plugins/devflow-core-skills/skills/react/references/patterns.md +1331 -0
  134. package/plugins/devflow-core-skills/skills/react/references/violations.md +565 -0
  135. package/plugins/devflow-core-skills/skills/test-patterns/SKILL.md +183 -0
  136. package/plugins/devflow-core-skills/skills/test-patterns/references/detection.md +149 -0
  137. package/plugins/devflow-core-skills/skills/test-patterns/references/patterns.md +220 -0
  138. package/plugins/devflow-core-skills/skills/test-patterns/references/report-template.md +108 -0
  139. package/plugins/devflow-core-skills/skills/test-patterns/references/violations.md +221 -0
  140. package/plugins/devflow-core-skills/skills/typescript/SKILL.md +176 -0
  141. package/plugins/devflow-core-skills/skills/typescript/references/patterns.md +1105 -0
  142. package/plugins/devflow-core-skills/skills/typescript/references/violations.md +433 -0
  143. package/plugins/devflow-debug/.claude-plugin/plugin.json +18 -0
  144. package/plugins/devflow-debug/README.md +65 -0
  145. package/plugins/devflow-debug/agents/git.md +272 -0
  146. package/plugins/devflow-debug/commands/debug-teams.md +231 -0
  147. package/plugins/devflow-debug/commands/debug.md +160 -0
  148. package/plugins/devflow-debug/skills/agent-teams/SKILL.md +124 -0
  149. package/plugins/devflow-debug/skills/agent-teams/references/cleanup.md +104 -0
  150. package/plugins/devflow-debug/skills/agent-teams/references/communication.md +122 -0
  151. package/plugins/devflow-debug/skills/agent-teams/references/team-patterns.md +217 -0
  152. package/plugins/devflow-debug/skills/git-safety/SKILL.md +122 -0
  153. package/plugins/devflow-debug/skills/git-safety/references/detection.md +290 -0
  154. package/plugins/devflow-debug/skills/git-safety/references/patterns.md +289 -0
  155. package/plugins/devflow-debug/skills/git-safety/references/violations.md +18 -0
  156. package/plugins/devflow-implement/.claude-plugin/plugin.json +21 -0
  157. package/plugins/devflow-implement/README.md +71 -0
  158. package/plugins/devflow-implement/agents/coder.md +122 -0
  159. package/plugins/devflow-implement/agents/git.md +272 -0
  160. package/plugins/devflow-implement/agents/scrutinizer.md +80 -0
  161. package/plugins/devflow-implement/agents/shepherd.md +94 -0
  162. package/plugins/devflow-implement/agents/simplifier.md +62 -0
  163. package/plugins/devflow-implement/agents/skimmer.md +88 -0
  164. package/plugins/devflow-implement/agents/synthesizer.md +204 -0
  165. package/plugins/devflow-implement/agents/validator.md +86 -0
  166. package/plugins/devflow-implement/commands/implement-teams.md +608 -0
  167. package/plugins/devflow-implement/commands/implement.md +426 -0
  168. package/plugins/devflow-implement/skills/accessibility/SKILL.md +229 -0
  169. package/plugins/devflow-implement/skills/accessibility/references/detection.md +171 -0
  170. package/plugins/devflow-implement/skills/accessibility/references/patterns.md +670 -0
  171. package/plugins/devflow-implement/skills/accessibility/references/violations.md +419 -0
  172. package/plugins/devflow-implement/skills/agent-teams/SKILL.md +124 -0
  173. package/plugins/devflow-implement/skills/agent-teams/references/cleanup.md +104 -0
  174. package/plugins/devflow-implement/skills/agent-teams/references/communication.md +122 -0
  175. package/plugins/devflow-implement/skills/agent-teams/references/team-patterns.md +217 -0
  176. package/plugins/devflow-implement/skills/frontend-design/SKILL.md +254 -0
  177. package/plugins/devflow-implement/skills/frontend-design/references/detection.md +184 -0
  178. package/plugins/devflow-implement/skills/frontend-design/references/patterns.md +511 -0
  179. package/plugins/devflow-implement/skills/frontend-design/references/violations.md +453 -0
  180. package/plugins/devflow-implement/skills/implementation-patterns/SKILL.md +162 -0
  181. package/plugins/devflow-implement/skills/implementation-patterns/references/patterns.md +1063 -0
  182. package/plugins/devflow-implement/skills/implementation-patterns/references/violations.md +483 -0
  183. package/plugins/devflow-implement/skills/self-review/SKILL.md +149 -0
  184. package/plugins/devflow-implement/skills/self-review/references/patterns.md +405 -0
  185. package/plugins/devflow-implement/skills/self-review/references/report-template.md +253 -0
  186. package/plugins/devflow-implement/skills/self-review/references/violations.md +308 -0
  187. package/plugins/devflow-resolve/.claude-plugin/plugin.json +19 -0
  188. package/plugins/devflow-resolve/README.md +65 -0
  189. package/plugins/devflow-resolve/agents/git.md +272 -0
  190. package/plugins/devflow-resolve/agents/resolver.md +131 -0
  191. package/plugins/devflow-resolve/agents/simplifier.md +62 -0
  192. package/plugins/devflow-resolve/commands/resolve-teams.md +298 -0
  193. package/plugins/devflow-resolve/commands/resolve.md +237 -0
  194. package/plugins/devflow-resolve/skills/agent-teams/SKILL.md +124 -0
  195. package/plugins/devflow-resolve/skills/agent-teams/references/cleanup.md +104 -0
  196. package/plugins/devflow-resolve/skills/agent-teams/references/communication.md +122 -0
  197. package/plugins/devflow-resolve/skills/agent-teams/references/team-patterns.md +217 -0
  198. package/plugins/devflow-resolve/skills/implementation-patterns/SKILL.md +162 -0
  199. package/plugins/devflow-resolve/skills/implementation-patterns/references/patterns.md +1063 -0
  200. package/plugins/devflow-resolve/skills/implementation-patterns/references/violations.md +483 -0
  201. package/plugins/devflow-resolve/skills/security-patterns/SKILL.md +156 -0
  202. package/plugins/devflow-resolve/skills/security-patterns/references/detection.md +287 -0
  203. package/plugins/devflow-resolve/skills/security-patterns/references/patterns.md +507 -0
  204. package/plugins/devflow-resolve/skills/security-patterns/references/violations.md +237 -0
  205. package/plugins/devflow-self-review/.claude-plugin/plugin.json +7 -0
  206. package/plugins/devflow-self-review/README.md +38 -0
  207. package/plugins/devflow-self-review/agents/scrutinizer.md +80 -0
  208. package/plugins/devflow-self-review/agents/simplifier.md +62 -0
  209. package/plugins/devflow-self-review/agents/validator.md +86 -0
  210. package/plugins/devflow-self-review/commands/self-review.md +126 -0
  211. package/plugins/devflow-self-review/skills/core-patterns/SKILL.md +162 -0
  212. package/plugins/devflow-self-review/skills/core-patterns/references/checklist.md +276 -0
  213. package/plugins/devflow-self-review/skills/core-patterns/references/code-smell-violations.md +144 -0
  214. package/plugins/devflow-self-review/skills/core-patterns/references/detection.md +303 -0
  215. package/plugins/devflow-self-review/skills/core-patterns/references/patterns.md +576 -0
  216. package/plugins/devflow-self-review/skills/core-patterns/references/violations.md +369 -0
  217. package/plugins/devflow-self-review/skills/self-review/SKILL.md +149 -0
  218. package/plugins/devflow-self-review/skills/self-review/references/patterns.md +405 -0
  219. package/plugins/devflow-self-review/skills/self-review/references/report-template.md +253 -0
  220. package/plugins/devflow-self-review/skills/self-review/references/violations.md +308 -0
  221. package/plugins/devflow-specify/.claude-plugin/plugin.json +15 -0
  222. package/plugins/devflow-specify/README.md +46 -0
  223. package/plugins/devflow-specify/agents/skimmer.md +88 -0
  224. package/plugins/devflow-specify/agents/synthesizer.md +204 -0
  225. package/plugins/devflow-specify/commands/specify-teams.md +314 -0
  226. package/plugins/devflow-specify/commands/specify.md +179 -0
  227. package/plugins/devflow-specify/skills/agent-teams/SKILL.md +124 -0
  228. package/plugins/devflow-specify/skills/agent-teams/references/cleanup.md +104 -0
  229. package/plugins/devflow-specify/skills/agent-teams/references/communication.md +122 -0
  230. package/plugins/devflow-specify/skills/agent-teams/references/team-patterns.md +217 -0
  231. package/scripts/hooks/background-memory-update.sh +167 -0
  232. package/scripts/hooks/pre-compact-memory.sh +81 -0
  233. package/scripts/hooks/session-start-memory.sh +84 -0
  234. package/scripts/hooks/stop-update-memory.sh +81 -0
  235. package/shared/agents/coder.md +122 -0
  236. package/shared/agents/git.md +272 -0
  237. package/shared/agents/resolver.md +131 -0
  238. package/shared/agents/reviewer.md +119 -0
  239. package/shared/agents/scrutinizer.md +80 -0
  240. package/shared/agents/shepherd.md +94 -0
  241. package/shared/agents/simplifier.md +62 -0
  242. package/shared/agents/skimmer.md +88 -0
  243. package/shared/agents/synthesizer.md +204 -0
  244. package/shared/agents/validator.md +86 -0
  245. package/shared/skills/accessibility/SKILL.md +229 -0
  246. package/shared/skills/accessibility/references/detection.md +171 -0
  247. package/shared/skills/accessibility/references/patterns.md +670 -0
  248. package/shared/skills/accessibility/references/violations.md +419 -0
  249. package/shared/skills/agent-teams/SKILL.md +124 -0
  250. package/shared/skills/agent-teams/references/cleanup.md +104 -0
  251. package/shared/skills/agent-teams/references/communication.md +122 -0
  252. package/shared/skills/agent-teams/references/team-patterns.md +217 -0
  253. package/shared/skills/architecture-patterns/SKILL.md +153 -0
  254. package/shared/skills/architecture-patterns/references/detection.md +337 -0
  255. package/shared/skills/architecture-patterns/references/patterns.md +873 -0
  256. package/shared/skills/architecture-patterns/references/violations.md +575 -0
  257. package/shared/skills/complexity-patterns/SKILL.md +143 -0
  258. package/shared/skills/complexity-patterns/references/detection.md +264 -0
  259. package/shared/skills/complexity-patterns/references/patterns.md +487 -0
  260. package/shared/skills/complexity-patterns/references/violations.md +361 -0
  261. package/shared/skills/consistency-patterns/SKILL.md +140 -0
  262. package/shared/skills/consistency-patterns/references/detection.md +207 -0
  263. package/shared/skills/consistency-patterns/references/patterns.md +202 -0
  264. package/shared/skills/consistency-patterns/references/violations.md +213 -0
  265. package/shared/skills/core-patterns/SKILL.md +162 -0
  266. package/shared/skills/core-patterns/references/checklist.md +276 -0
  267. package/shared/skills/core-patterns/references/code-smell-violations.md +144 -0
  268. package/shared/skills/core-patterns/references/detection.md +303 -0
  269. package/shared/skills/core-patterns/references/patterns.md +576 -0
  270. package/shared/skills/core-patterns/references/violations.md +369 -0
  271. package/shared/skills/database-patterns/SKILL.md +134 -0
  272. package/shared/skills/database-patterns/references/detection.md +208 -0
  273. package/shared/skills/database-patterns/references/patterns.md +394 -0
  274. package/shared/skills/database-patterns/references/violations.md +332 -0
  275. package/shared/skills/dependencies-patterns/SKILL.md +141 -0
  276. package/shared/skills/dependencies-patterns/references/detection.md +181 -0
  277. package/shared/skills/dependencies-patterns/references/patterns.md +225 -0
  278. package/shared/skills/dependencies-patterns/references/violations.md +247 -0
  279. package/shared/skills/docs-framework/SKILL.md +134 -0
  280. package/shared/skills/docs-framework/references/patterns.md +346 -0
  281. package/shared/skills/docs-framework/references/violations.md +221 -0
  282. package/shared/skills/documentation-patterns/SKILL.md +125 -0
  283. package/shared/skills/documentation-patterns/references/detection.md +190 -0
  284. package/shared/skills/documentation-patterns/references/patterns.md +189 -0
  285. package/shared/skills/documentation-patterns/references/violations.md +163 -0
  286. package/shared/skills/frontend-design/SKILL.md +254 -0
  287. package/shared/skills/frontend-design/references/detection.md +184 -0
  288. package/shared/skills/frontend-design/references/patterns.md +511 -0
  289. package/shared/skills/frontend-design/references/violations.md +453 -0
  290. package/shared/skills/git-safety/SKILL.md +122 -0
  291. package/shared/skills/git-safety/references/detection.md +290 -0
  292. package/shared/skills/git-safety/references/patterns.md +289 -0
  293. package/shared/skills/git-safety/references/violations.md +18 -0
  294. package/shared/skills/git-workflow/SKILL.md +158 -0
  295. package/shared/skills/git-workflow/references/commit-patterns.md +115 -0
  296. package/shared/skills/git-workflow/references/commit-violations.md +77 -0
  297. package/shared/skills/git-workflow/references/pr-patterns.md +127 -0
  298. package/shared/skills/git-workflow/references/pr-violations.md +96 -0
  299. package/shared/skills/github-patterns/SKILL.md +153 -0
  300. package/shared/skills/github-patterns/references/patterns.md +572 -0
  301. package/shared/skills/github-patterns/references/violations.md +298 -0
  302. package/shared/skills/implementation-patterns/SKILL.md +162 -0
  303. package/shared/skills/implementation-patterns/references/patterns.md +1063 -0
  304. package/shared/skills/implementation-patterns/references/violations.md +483 -0
  305. package/shared/skills/input-validation/SKILL.md +148 -0
  306. package/shared/skills/input-validation/references/detection.md +283 -0
  307. package/shared/skills/input-validation/references/patterns.md +361 -0
  308. package/shared/skills/input-validation/references/violations.md +224 -0
  309. package/shared/skills/performance-patterns/SKILL.md +154 -0
  310. package/shared/skills/performance-patterns/references/detection.md +351 -0
  311. package/shared/skills/performance-patterns/references/patterns.md +503 -0
  312. package/shared/skills/performance-patterns/references/violations.md +354 -0
  313. package/shared/skills/react/SKILL.md +276 -0
  314. package/shared/skills/react/references/patterns.md +1331 -0
  315. package/shared/skills/react/references/violations.md +565 -0
  316. package/shared/skills/regression-patterns/SKILL.md +146 -0
  317. package/shared/skills/regression-patterns/references/detection.md +237 -0
  318. package/shared/skills/regression-patterns/references/patterns.md +226 -0
  319. package/shared/skills/regression-patterns/references/violations.md +225 -0
  320. package/shared/skills/review-methodology/SKILL.md +119 -0
  321. package/shared/skills/review-methodology/references/patterns.md +186 -0
  322. package/shared/skills/review-methodology/references/report-template.md +142 -0
  323. package/shared/skills/review-methodology/references/violations.md +125 -0
  324. package/shared/skills/security-patterns/SKILL.md +156 -0
  325. package/shared/skills/security-patterns/references/detection.md +287 -0
  326. package/shared/skills/security-patterns/references/patterns.md +507 -0
  327. package/shared/skills/security-patterns/references/violations.md +237 -0
  328. package/shared/skills/self-review/SKILL.md +149 -0
  329. package/shared/skills/self-review/references/patterns.md +405 -0
  330. package/shared/skills/self-review/references/report-template.md +253 -0
  331. package/shared/skills/self-review/references/violations.md +308 -0
  332. package/shared/skills/test-patterns/SKILL.md +183 -0
  333. package/shared/skills/test-patterns/references/detection.md +149 -0
  334. package/shared/skills/test-patterns/references/patterns.md +220 -0
  335. package/shared/skills/test-patterns/references/report-template.md +108 -0
  336. package/shared/skills/test-patterns/references/violations.md +221 -0
  337. package/shared/skills/typescript/SKILL.md +176 -0
  338. package/shared/skills/typescript/references/patterns.md +1105 -0
  339. package/shared/skills/typescript/references/violations.md +433 -0
  340. package/src/templates/claudeignore.template +188 -0
  341. package/src/templates/managed-settings.json +146 -0
  342. package/src/templates/settings.json +59 -0
  343. package/dist/cli.d.ts.map +0 -1
  344. package/dist/cli.js.map +0 -1
  345. package/dist/commands/init.d.ts.map +0 -1
  346. package/dist/commands/init.js.map +0 -1
  347. package/dist/commands/uninstall.d.ts.map +0 -1
  348. package/dist/commands/uninstall.js.map +0 -1
  349. package/dist/utils/git.d.ts.map +0 -1
  350. package/dist/utils/git.js.map +0 -1
  351. package/dist/utils/paths.d.ts.map +0 -1
  352. package/dist/utils/paths.js.map +0 -1
  353. package/src/claude/CLAUDE.md +0 -400
  354. package/src/claude/agents/devflow/audit-architecture.md +0 -132
  355. package/src/claude/agents/devflow/audit-complexity.md +0 -132
  356. package/src/claude/agents/devflow/audit-database.md +0 -132
  357. package/src/claude/agents/devflow/audit-dependencies.md +0 -132
  358. package/src/claude/agents/devflow/audit-documentation.md +0 -132
  359. package/src/claude/agents/devflow/audit-performance.md +0 -256
  360. package/src/claude/agents/devflow/audit-security.md +0 -259
  361. package/src/claude/agents/devflow/audit-tests.md +0 -132
  362. package/src/claude/agents/devflow/audit-typescript.md +0 -132
  363. package/src/claude/agents/devflow/brainstorm.md +0 -279
  364. package/src/claude/agents/devflow/catch-up.md +0 -345
  365. package/src/claude/agents/devflow/code-review.md +0 -307
  366. package/src/claude/agents/devflow/commit.md +0 -380
  367. package/src/claude/agents/devflow/debug.md +0 -476
  368. package/src/claude/agents/devflow/design.md +0 -491
  369. package/src/claude/agents/devflow/get-issue.md +0 -286
  370. package/src/claude/agents/devflow/pr-comments.md +0 -285
  371. package/src/claude/agents/devflow/project-state.md +0 -419
  372. package/src/claude/agents/devflow/pull-request.md +0 -493
  373. package/src/claude/agents/devflow/release.md +0 -1137
  374. package/src/claude/agents/devflow/tech-debt.md +0 -338
  375. package/src/claude/commands/devflow/brainstorm.md +0 -68
  376. package/src/claude/commands/devflow/breakdown.md +0 -125
  377. package/src/claude/commands/devflow/catch-up.md +0 -29
  378. package/src/claude/commands/devflow/code-review.md +0 -237
  379. package/src/claude/commands/devflow/commit.md +0 -17
  380. package/src/claude/commands/devflow/debug.md +0 -56
  381. package/src/claude/commands/devflow/design.md +0 -82
  382. package/src/claude/commands/devflow/devlog.md +0 -408
  383. package/src/claude/commands/devflow/get-issue.md +0 -16
  384. package/src/claude/commands/devflow/implement.md +0 -100
  385. package/src/claude/commands/devflow/plan.md +0 -223
  386. package/src/claude/commands/devflow/pull-request.md +0 -20
  387. package/src/claude/commands/devflow/release.md +0 -251
  388. package/src/claude/commands/devflow/resolve-comments.md +0 -583
  389. package/src/claude/scripts/statusline.sh +0 -47
  390. package/src/claude/settings.json +0 -6
  391. package/src/claude/skills/devflow/code-smell/SKILL.md +0 -428
  392. package/src/claude/skills/devflow/debug/SKILL.md +0 -119
  393. package/src/claude/skills/devflow/error-handling/SKILL.md +0 -597
  394. package/src/claude/skills/devflow/input-validation/SKILL.md +0 -514
  395. package/src/claude/skills/devflow/pattern-check/SKILL.md +0 -238
  396. package/src/claude/skills/devflow/research/SKILL.md +0 -138
  397. package/src/claude/skills/devflow/test-design/SKILL.md +0 -384
@@ -3,126 +3,60 @@ import { promises as fs } from 'fs';
3
3
  import * as path from 'path';
4
4
  import { fileURLToPath } from 'url';
5
5
  import { dirname } from 'path';
6
- import * as readline from 'readline';
6
+ import * as p from '@clack/prompts';
7
+ import color from 'picocolors';
7
8
  import { getInstallationPaths } from '../utils/paths.js';
8
9
  import { getGitRoot } from '../utils/git.js';
10
+ import { isClaudeCliAvailable } from '../utils/cli.js';
11
+ import { installViaCli, installViaFileCopy } from '../utils/installer.js';
12
+ import { installSettings, installManagedSettings, installClaudeignore, updateGitignore, createDocsStructure, } from '../utils/post-install.js';
13
+ import { DEVFLOW_PLUGINS, LEGACY_SKILL_NAMES, LEGACY_COMMAND_NAMES, buildAssetMaps } from '../plugins.js';
14
+ import { detectPlatform, detectShell, getProfilePath, getSafeDeleteInfo, hasSafeDelete } from '../utils/safe-delete.js';
15
+ import { generateSafeDeleteBlock, isAlreadyInstalled, installToProfile } from '../utils/safe-delete-install.js';
16
+ // Re-export pure functions for tests (canonical source is post-install.ts)
17
+ export { substituteSettingsTemplate, computeGitignoreAppend, applyTeamsConfig, stripTeamsConfig, mergeDenyList } from '../utils/post-install.js';
9
18
  const __filename = fileURLToPath(import.meta.url);
10
19
  const __dirname = dirname(__filename);
11
- function isNodeSystemError(error) {
12
- return (error instanceof Error &&
13
- 'code' in error &&
14
- typeof error.code === 'string');
15
- }
16
20
  /**
17
- * Prompt user for confirmation (async)
21
+ * Parse a comma-separated plugin selection string into normalized plugin names.
22
+ * Validates against known plugins; returns invalid names as errors.
18
23
  */
19
- async function promptUser(question) {
20
- const rl = readline.createInterface({
21
- input: process.stdin,
22
- output: process.stdout
23
- });
24
- return new Promise((resolve) => {
25
- rl.question(question, (answer) => {
26
- rl.close();
27
- resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
28
- });
24
+ export function parsePluginSelection(input, validPlugins) {
25
+ const selected = input.split(',').map(p => {
26
+ const trimmed = p.trim();
27
+ return trimmed.startsWith('devflow-') ? trimmed : `devflow-${trimmed}`;
29
28
  });
29
+ const validNames = validPlugins.map(p => p.name);
30
+ const invalid = selected.filter(p => !validNames.includes(p));
31
+ return { selected, invalid };
30
32
  }
31
33
  /**
32
- * DevFlow commands with user-friendly descriptions.
33
- * Used for displaying available commands in init output.
34
- */
35
- const DEVFLOW_COMMANDS = [
36
- { name: '/catch-up', description: 'Get up to speed on project state' },
37
- { name: '/brainstorm', description: 'Explore design decisions' },
38
- { name: '/design', description: 'Create implementation plan' },
39
- { name: '/plan', description: 'Triage issues from discussion' },
40
- { name: '/breakdown', description: 'Break down tasks quickly' },
41
- { name: '/get-issue', description: 'Fetch issue and create branch' },
42
- { name: '/implement', description: 'Interactive implementation' },
43
- { name: '/code-review', description: 'Comprehensive code review' },
44
- { name: '/commit', description: 'Smart atomic commits' },
45
- { name: '/pull-request', description: 'Create PR with description' },
46
- { name: '/release', description: 'Automated releases' },
47
- { name: '/devlog', description: 'Document session progress' },
48
- { name: '/debug', description: 'Systematic debugging' },
49
- { name: '/resolve-comments', description: 'Address PR feedback' },
50
- ];
51
- /**
52
- * DevFlow skills with descriptions.
53
- * Displayed only in verbose mode to show auto-activating capabilities.
54
- */
55
- const DEVFLOW_SKILLS = [
56
- { name: 'pattern-check', description: 'Architectural pattern validation' },
57
- { name: 'test-design', description: 'Test quality enforcement' },
58
- { name: 'code-smell', description: 'Anti-pattern detection' },
59
- { name: 'research', description: 'Pre-implementation planning (auto)' },
60
- { name: 'debug', description: 'Systematic debugging (auto)' },
61
- { name: 'input-validation', description: 'Boundary validation' },
62
- { name: 'error-handling', description: 'Result type consistency' },
63
- ];
64
- /**
65
- * Render clean, minimal output for default (non-verbose) mode.
66
- * Shows only essential information: version, available commands, and docs link.
67
- *
68
- * @param version - The DevFlow version string to display
34
+ * Build the list of configuration extras available for the given scope/git context.
35
+ * Pure function no I/O, no side effects.
69
36
  */
70
- function renderCleanOutput(version) {
71
- console.log(`\n✓ DevFlow v${version} installed\n`);
72
- console.log('Commands available:');
73
- // Calculate max command name length for alignment
74
- const maxLen = Math.max(...DEVFLOW_COMMANDS.map(c => c.name.length));
75
- for (const cmd of DEVFLOW_COMMANDS) {
76
- const padding = ' '.repeat(maxLen - cmd.name.length + 2);
77
- console.log(` ${cmd.name}${padding}${cmd.description}`);
78
- }
79
- console.log('\nRun any command in Claude Code to get started.');
80
- console.log('\nDocs: https://github.com/dean0x/devflow');
81
- }
82
- /**
83
- * Render detailed output for verbose mode.
84
- * Shows full installation details including paths, merge instructions, and skills.
85
- *
86
- * @param version - The DevFlow version string to display
87
- * @param scope - Installation scope ('user' for user-wide, 'local' for project-only)
88
- * @param claudeDir - Path to the Claude Code directory
89
- * @param devflowDir - Path to the DevFlow directory
90
- * @param settingsExists - Whether existing settings.json was preserved
91
- * @param claudeMdExists - Whether existing CLAUDE.md was preserved
92
- */
93
- function renderVerboseOutput(version, scope, claudeDir, devflowDir, settingsExists, claudeMdExists) {
94
- console.log(`\n✅ DevFlow v${version} installed!\n`);
95
- console.log(`📍 Installation scope: ${scope}`);
96
- console.log(` Claude dir: ${claudeDir}`);
97
- console.log(` DevFlow dir: ${devflowDir}\n`);
98
- // Show manual merge instructions if needed
99
- if (settingsExists || claudeMdExists) {
100
- console.log('📝 Manual merge recommended:\n');
101
- if (settingsExists) {
102
- console.log(' Settings: Review settings.devflow.json and merge desired config into settings.json');
103
- console.log(' Key setting: statusLine configuration for DevFlow statusline\n');
104
- }
105
- if (claudeMdExists) {
106
- console.log(' Instructions: Review CLAUDE.devflow.md and adopt desired practices');
107
- console.log(" This contains DevFlow's recommended development patterns\n");
108
- }
37
+ export function buildExtrasOptions(scope, gitRoot) {
38
+ const options = [
39
+ { value: 'settings', label: 'Settings & Working Memory', hint: 'Model defaults, session memory hooks, status line' },
40
+ ];
41
+ if (gitRoot) {
42
+ options.push({ value: 'claudeignore', label: '.claudeignore', hint: 'Exclude secrets, deps, build artifacts from Claude context' });
109
43
  }
110
- console.log('Available commands:');
111
- for (const cmd of DEVFLOW_COMMANDS) {
112
- console.log(` ${cmd.name.padEnd(18)}${cmd.description}`);
44
+ if (scope === 'local' && gitRoot) {
45
+ options.push({ value: 'gitignore', label: '.gitignore entries', hint: 'Add .claude/ and .devflow/ to .gitignore' });
113
46
  }
114
- console.log('\nInstalled skills (auto-activate):');
115
- for (const skill of DEVFLOW_SKILLS) {
116
- console.log(` ${skill.name.padEnd(18)}${skill.description}`);
47
+ if (scope === 'local') {
48
+ options.push({ value: 'docs', label: '.docs/ directory', hint: 'Review reports, dev logs, status tracking for this project' });
117
49
  }
118
- console.log('\nNote: debug exists as both command (manual) and skill (auto)');
119
- console.log('Docs: https://github.com/dean0x/devflow');
50
+ options.push({ value: 'safe-delete', label: 'Safe-delete (rm trash)', hint: 'Override rm to use trash CLI — prevents accidental deletion' });
51
+ return options;
120
52
  }
121
53
  export const initCommand = new Command('init')
122
54
  .description('Initialize DevFlow for Claude Code')
123
- .option('--skip-docs', 'Skip creating .docs/ structure')
124
- .option('--scope <type>', 'Installation scope: user (user-wide) or local (project-only)', /^(user|local)$/i)
55
+ .option('--scope <type>', 'Installation scope: user or local (project-only)', /^(user|local)$/i)
125
56
  .option('--verbose', 'Show detailed installation output')
57
+ .option('--plugin <names>', 'Install specific plugin(s), comma-separated (e.g., implement,code-review)')
58
+ .option('--teams', 'Enable Agent Teams (peer debate, adversarial review)')
59
+ .option('--no-teams', 'Disable Agent Teams (use parallel subagents instead)')
126
60
  .action(async (options) => {
127
61
  // Get package version
128
62
  const packageJsonPath = path.resolve(__dirname, '../../package.json');
@@ -135,68 +69,109 @@ export const initCommand = new Command('init')
135
69
  version = 'unknown';
136
70
  }
137
71
  const verbose = options.verbose ?? false;
138
- if (verbose) {
139
- console.log(`🚀 DevFlow v${version}\n`);
140
- }
72
+ // Start the CLI flow
73
+ p.intro(color.bgCyan(color.black(` DevFlow v${version} `)));
141
74
  // Determine installation scope
142
- let scope = 'user'; // Default to user for backwards compatibility
75
+ let scope = 'user';
143
76
  if (options.scope) {
144
77
  const normalizedScope = options.scope.toLowerCase();
145
- // Runtime validation (Commander regex already validates, but be defensive)
146
78
  if (normalizedScope !== 'user' && normalizedScope !== 'local') {
147
- console.error('Invalid scope. Use "user" or "local"\n');
79
+ p.log.error('Invalid scope. Use "user" or "local"');
148
80
  process.exit(1);
149
81
  }
150
82
  scope = normalizedScope;
151
83
  }
84
+ else if (!process.stdin.isTTY) {
85
+ p.log.info('Non-interactive mode detected, using scope: user');
86
+ scope = 'user';
87
+ }
152
88
  else {
153
- // Check if running in interactive terminal (TTY)
154
- if (!process.stdin.isTTY) {
155
- // Non-interactive environment (CI/CD, scripts) - use default
156
- if (verbose) {
157
- console.log('📦 Non-interactive environment detected, using default scope: user');
158
- console.log(' To specify scope in CI/CD, use: devflow init --scope <user|local>\n');
159
- }
160
- scope = 'user';
89
+ const selected = await p.select({
90
+ message: 'Installation scope',
91
+ options: [
92
+ { value: 'user', label: 'User', hint: 'all projects (~/.claude/)' },
93
+ { value: 'local', label: 'Local', hint: 'this project only (./.claude/)' },
94
+ ],
95
+ });
96
+ if (p.isCancel(selected)) {
97
+ p.cancel('Installation cancelled.');
98
+ process.exit(0);
161
99
  }
162
- else {
163
- // Interactive prompt for scope
164
- if (verbose) {
165
- console.log('📦 Installation Scope:\n');
166
- console.log(' user - Install for all projects (user-wide)');
167
- console.log(' └─ ~/.claude/ and ~/.devflow/');
168
- console.log(' local - Install for current project only');
169
- console.log(' └─ <git-root>/.claude/ and <git-root>/.devflow/\n');
170
- }
171
- const rl = readline.createInterface({
172
- input: process.stdin,
173
- output: process.stdout
174
- });
175
- const prompt = verbose
176
- ? 'Choose scope (user/local) [user]: '
177
- : 'Install scope - user (all projects) or local (this project only) [user]: ';
178
- const answer = await new Promise((resolve) => {
179
- rl.question(prompt, (input) => {
180
- rl.close();
181
- resolve(input.trim().toLowerCase() || 'user');
182
- });
183
- });
184
- if (answer === 'local' || answer === 'l') {
185
- scope = 'local';
186
- }
187
- else if (answer === 'user' || answer === 'u' || answer === '') {
188
- scope = 'user';
189
- }
190
- else {
191
- console.error('❌ Invalid scope. Use "user" or "local"\n');
192
- process.exit(1);
193
- }
194
- if (verbose) {
195
- console.log();
196
- }
100
+ scope = selected;
101
+ }
102
+ // Select plugins to install
103
+ let selectedPlugins = [];
104
+ if (options.plugin) {
105
+ const { selected, invalid } = parsePluginSelection(options.plugin, DEVFLOW_PLUGINS);
106
+ selectedPlugins = selected;
107
+ if (invalid.length > 0) {
108
+ p.log.error(`Unknown plugin(s): ${invalid.join(', ')}`);
109
+ p.log.info(`Valid plugins: ${DEVFLOW_PLUGINS.map(pl => pl.name).join(', ')}`);
110
+ process.exit(1);
111
+ }
112
+ }
113
+ else if (process.stdin.isTTY) {
114
+ const choices = DEVFLOW_PLUGINS
115
+ .filter(pl => pl.name !== 'devflow-core-skills')
116
+ .map(pl => ({
117
+ value: pl.name,
118
+ label: pl.name.replace('devflow-', ''),
119
+ hint: pl.description + (pl.optional ? ' (optional)' : ''),
120
+ }));
121
+ const preSelected = DEVFLOW_PLUGINS
122
+ .filter(pl => !pl.optional && pl.name !== 'devflow-core-skills')
123
+ .map(pl => pl.name);
124
+ const pluginSelection = await p.multiselect({
125
+ message: 'Select plugins to install',
126
+ options: choices,
127
+ initialValues: preSelected,
128
+ required: true,
129
+ });
130
+ if (p.isCancel(pluginSelection)) {
131
+ p.cancel('Installation cancelled.');
132
+ process.exit(0);
197
133
  }
134
+ selectedPlugins = pluginSelection;
198
135
  }
199
- // Get installation paths with proper validation
136
+ // Agent Teams variant selection
137
+ let teamsEnabled;
138
+ if (options.teams !== undefined) {
139
+ teamsEnabled = options.teams;
140
+ }
141
+ else if (!process.stdin.isTTY) {
142
+ teamsEnabled = false;
143
+ }
144
+ else {
145
+ const teamsChoice = await p.confirm({
146
+ message: 'Enable Agent Teams? (peer debate in review, exploration, debugging)',
147
+ initialValue: false,
148
+ });
149
+ if (p.isCancel(teamsChoice)) {
150
+ p.cancel('Installation cancelled.');
151
+ process.exit(0);
152
+ }
153
+ teamsEnabled = teamsChoice;
154
+ }
155
+ // Security deny list placement (user scope + TTY only)
156
+ let securityMode = 'user';
157
+ if (scope === 'user' && process.stdin.isTTY) {
158
+ const securityChoice = await p.select({
159
+ message: 'How should DevFlow install the security deny list?',
160
+ options: [
161
+ { value: 'managed', label: 'Managed settings (Recommended)', hint: 'Cannot be overridden, requires admin' },
162
+ { value: 'user', label: 'User settings', hint: 'Included in settings.json, editable' },
163
+ ],
164
+ });
165
+ if (p.isCancel(securityChoice)) {
166
+ p.cancel('Installation cancelled.');
167
+ process.exit(0);
168
+ }
169
+ securityMode = securityChoice;
170
+ }
171
+ // Start spinner immediately after prompts — covers path resolution + git detection
172
+ const s = p.spinner();
173
+ s.start('Resolving paths');
174
+ // Get installation paths
200
175
  let claudeDir;
201
176
  let devflowDir;
202
177
  let gitRoot = null;
@@ -204,468 +179,228 @@ export const initCommand = new Command('init')
204
179
  const paths = await getInstallationPaths(scope);
205
180
  claudeDir = paths.claudeDir;
206
181
  devflowDir = paths.devflowDir;
207
- // Cache git root for later use (already computed in getInstallationPaths for local scope)
208
- gitRoot = await getGitRoot();
209
- if (verbose) {
210
- console.log(`📍 Installation scope: ${scope}`);
211
- console.log(` Claude dir: ${claudeDir}`);
212
- console.log(` DevFlow dir: ${devflowDir}\n`);
213
- }
182
+ gitRoot = paths.gitRoot ?? await getGitRoot();
214
183
  }
215
184
  catch (error) {
216
- console.error('Path configuration error:', error instanceof Error ? error.message : error);
185
+ s.stop('Path resolution failed');
186
+ p.log.error(`Path configuration error: ${error instanceof Error ? error.message : error}`);
217
187
  process.exit(1);
218
188
  }
219
- // Check for Claude Code (only for user scope)
220
- if (scope === 'user') {
189
+ // Validate target directory
190
+ s.message('Validating target directory');
191
+ if (scope === 'local') {
221
192
  try {
222
- await fs.access(claudeDir);
193
+ await fs.mkdir(claudeDir, { recursive: true });
223
194
  }
224
- catch {
225
- console.error(`❌ Claude Code not detected at ${claudeDir}`);
226
- console.error(' Install from: https://claude.com/claude-code');
227
- console.error(' Or set CLAUDE_CODE_DIR if installed elsewhere\n');
195
+ catch (error) {
196
+ s.stop('Installation failed');
197
+ p.log.error(`Failed to create ${claudeDir}: ${error}`);
228
198
  process.exit(1);
229
199
  }
230
- if (verbose) {
231
- console.log('✓ Claude Code detected');
232
- }
233
200
  }
234
201
  else {
235
- // Local scope - create .claude directory if it doesn't exist
236
202
  try {
237
- await fs.mkdir(claudeDir, { recursive: true });
238
- if (verbose) {
239
- console.log('✓ Local .claude directory ready');
240
- }
203
+ await fs.access(claudeDir);
241
204
  }
242
- catch (error) {
243
- console.error(`❌ Failed to create ${claudeDir}:`, error);
205
+ catch {
206
+ s.stop('Installation failed');
207
+ p.log.error(`Claude Code not detected at ${claudeDir}`);
208
+ p.log.info('Install from: https://claude.ai/download');
244
209
  process.exit(1);
245
210
  }
246
211
  }
247
- // Get the root directory of the devflow package
212
+ // Resolve plugins and deduplication maps
213
+ s.message('Installing components');
248
214
  const rootDir = path.resolve(__dirname, '../..');
249
- const claudeSourceDir = path.join(rootDir, 'src', 'claude');
250
- try {
251
- // DevFlow namespace directories (single source of truth)
252
- const devflowDirectories = [
253
- {
254
- target: path.join(claudeDir, 'commands', 'devflow'),
255
- source: path.join(claudeSourceDir, 'commands', 'devflow'),
256
- name: 'commands'
257
- },
258
- {
259
- target: path.join(claudeDir, 'agents', 'devflow'),
260
- source: path.join(claudeSourceDir, 'agents', 'devflow'),
261
- name: 'agents'
262
- },
263
- {
264
- target: path.join(claudeDir, 'skills'),
265
- source: path.join(claudeSourceDir, 'skills', 'devflow'),
266
- name: 'skills'
267
- },
268
- {
269
- target: path.join(devflowDir, 'scripts'),
270
- source: path.join(claudeSourceDir, 'scripts'),
271
- name: 'scripts'
272
- }
273
- ];
274
- // Clean old DevFlow files before installing
275
- for (const dir of devflowDirectories) {
276
- if (dir.name === 'skills') {
277
- // Special handling for skills: clean old nested structure and individual skills
278
- // Remove old devflow/ subdirectory if it exists (migration from old structure)
279
- const oldSkillsDir = path.join(claudeDir, 'skills', 'devflow');
280
- try {
281
- await fs.rm(oldSkillsDir, { recursive: true, force: true });
282
- }
283
- catch (e) {
284
- // Directory might not exist
285
- }
286
- // Remove individual skill directories that we're about to reinstall
287
- try {
288
- const skillEntries = await fs.readdir(dir.source, { withFileTypes: true });
289
- for (const entry of skillEntries) {
290
- if (entry.isDirectory()) {
291
- const skillTarget = path.join(dir.target, entry.name);
292
- try {
293
- await fs.rm(skillTarget, { recursive: true, force: true });
294
- }
295
- catch (e) {
296
- // Skill might not exist
297
- }
298
- }
299
- }
300
- }
301
- catch (e) {
302
- // Source directory might not exist
303
- }
304
- }
305
- else {
306
- // For other components (commands, agents, scripts), clean the entire directory
307
- try {
308
- await fs.rm(dir.target, { recursive: true, force: true });
309
- }
310
- catch (e) {
311
- // Directory might not exist on first install
312
- }
313
- }
314
- }
315
- // Install all DevFlow components
316
- for (const dir of devflowDirectories) {
317
- await fs.mkdir(dir.target, { recursive: true });
318
- await copyDirectory(dir.source, dir.target);
319
- }
320
- // Make scripts executable
321
- const scriptsDir = devflowDirectories.find(d => d.name === 'scripts').target;
322
- const scripts = await fs.readdir(scriptsDir);
323
- for (const script of scripts) {
324
- await fs.chmod(path.join(scriptsDir, script), 0o755);
325
- }
326
- if (verbose) {
327
- console.log('✓ Installing components... (commands, agents, skills, scripts)');
215
+ const pluginsDir = path.join(rootDir, 'plugins');
216
+ let pluginsToInstall = selectedPlugins.length > 0
217
+ ? DEVFLOW_PLUGINS.filter(p => selectedPlugins.includes(p.name))
218
+ : DEVFLOW_PLUGINS.filter(p => !p.optional);
219
+ const coreSkillsPlugin = DEVFLOW_PLUGINS.find(p => p.name === 'devflow-core-skills');
220
+ if (pluginsToInstall.length > 0 && coreSkillsPlugin && !pluginsToInstall.includes(coreSkillsPlugin)) {
221
+ pluginsToInstall = [coreSkillsPlugin, ...pluginsToInstall];
222
+ }
223
+ const { skillsMap, agentsMap } = buildAssetMaps(pluginsToInstall);
224
+ // Install: try native CLI first, fall back to file copy
225
+ const cliAvailable = isClaudeCliAvailable();
226
+ const usedNativeCli = cliAvailable && installViaCli(pluginsToInstall, scope, s);
227
+ if (!usedNativeCli) {
228
+ if (cliAvailable && verbose) {
229
+ p.log.warn('Claude CLI installation failed, falling back to manual copy');
328
230
  }
329
- // Install settings.json - never override existing files (atomic operation)
330
- const settingsPath = path.join(claudeDir, 'settings.json');
331
- const devflowSettingsPath = path.join(claudeDir, 'settings.devflow.json');
332
- const sourceSettingsPath = path.join(claudeSourceDir, 'settings.json');
333
- // Read template and replace ~ with actual home directory
334
- const settingsTemplate = await fs.readFile(sourceSettingsPath, 'utf-8');
335
- const settingsContent = settingsTemplate.replace(/~\/\.devflow\/scripts\/statusline\.sh/g, path.join(devflowDir, 'scripts', 'statusline.sh'));
336
- let settingsExists = false;
337
231
  try {
338
- // Atomic exclusive create - fails if file already exists
339
- await fs.writeFile(settingsPath, settingsContent, { encoding: 'utf-8', flag: 'wx' });
340
- if (verbose) {
341
- console.log('✓ Settings configured');
342
- }
232
+ await installViaFileCopy({
233
+ plugins: pluginsToInstall,
234
+ claudeDir,
235
+ pluginsDir,
236
+ rootDir,
237
+ devflowDir,
238
+ skillsMap,
239
+ agentsMap,
240
+ isPartialInstall: !!options.plugin,
241
+ teamsEnabled,
242
+ spinner: s,
243
+ });
343
244
  }
344
245
  catch (error) {
345
- if (isNodeSystemError(error) && error.code === 'EEXIST') {
346
- // Existing settings.json found - install as settings.devflow.json
347
- settingsExists = true;
348
- await fs.writeFile(devflowSettingsPath, settingsContent, 'utf-8');
349
- if (verbose) {
350
- console.log('⚠️ Existing settings.json preserved → DevFlow config: settings.devflow.json');
351
- }
352
- }
353
- else {
354
- throw error;
355
- }
246
+ s.stop('Installation failed');
247
+ p.log.error(`${error}`);
248
+ process.exit(1);
356
249
  }
357
- // Install CLAUDE.md - never override existing files (atomic operation)
358
- const claudeMdPath = path.join(claudeDir, 'CLAUDE.md');
359
- const devflowClaudeMdPath = path.join(claudeDir, 'CLAUDE.devflow.md');
360
- const sourceClaudeMdPath = path.join(claudeSourceDir, 'CLAUDE.md');
361
- let claudeMdExists = false;
250
+ }
251
+ s.stop('Plugins installed');
252
+ // Clean up stale skills from previous installations
253
+ const skillsDir = path.join(claudeDir, 'skills');
254
+ let staleRemoved = 0;
255
+ for (const legacy of LEGACY_SKILL_NAMES) {
256
+ const legacyPath = path.join(skillsDir, legacy);
362
257
  try {
363
- // Atomic exclusive create - fails if file already exists
364
- const content = await fs.readFile(sourceClaudeMdPath, 'utf-8');
365
- await fs.writeFile(claudeMdPath, content, { encoding: 'utf-8', flag: 'wx' });
366
- if (verbose) {
367
- console.log('✓ CLAUDE.md configured');
368
- }
258
+ await fs.rm(legacyPath, { recursive: true });
259
+ staleRemoved++;
369
260
  }
370
- catch (error) {
371
- if (isNodeSystemError(error) && error.code === 'EEXIST') {
372
- // Existing CLAUDE.md found - install as CLAUDE.devflow.md
373
- claudeMdExists = true;
374
- await fs.copyFile(sourceClaudeMdPath, devflowClaudeMdPath);
375
- if (verbose) {
376
- console.log('⚠️ Existing CLAUDE.md preserved → DevFlow guide: CLAUDE.devflow.md');
377
- }
261
+ catch {
262
+ // Doesn't exist expected for most entries
263
+ }
264
+ }
265
+ if (staleRemoved > 0 && verbose) {
266
+ p.log.info(`Cleaned up ${staleRemoved} legacy skill(s)`);
267
+ }
268
+ // Clean up stale commands from previous installations (e.g., /review → /code-review)
269
+ const commandsDir = path.join(claudeDir, 'commands', 'devflow');
270
+ let staleCommandsRemoved = 0;
271
+ for (const legacy of LEGACY_COMMAND_NAMES) {
272
+ for (const suffix of ['.md', '-teams.md']) {
273
+ const legacyPath = path.join(commandsDir, `${legacy}${suffix}`);
274
+ try {
275
+ await fs.rm(legacyPath);
276
+ staleCommandsRemoved++;
378
277
  }
379
- else {
380
- throw error;
278
+ catch {
279
+ // Doesn't exist — expected for most entries
381
280
  }
382
281
  }
383
- // Create .claudeignore in git repository root
384
- let claudeignoreCreated = false;
385
- try {
386
- // Use cached git root (already computed and validated earlier)
387
- if (!gitRoot) {
388
- throw new Error('Not in a git repository');
282
+ }
283
+ if (staleCommandsRemoved > 0 && verbose) {
284
+ p.log.info(`Cleaned up ${staleCommandsRemoved} legacy command(s)`);
285
+ }
286
+ // === Configuration extras ===
287
+ const extrasOptions = buildExtrasOptions(scope, gitRoot);
288
+ let selectedExtras;
289
+ if (process.stdin.isTTY) {
290
+ const extrasSelection = await p.multiselect({
291
+ message: 'Configure extras',
292
+ options: extrasOptions,
293
+ initialValues: extrasOptions.map(o => o.value),
294
+ required: false,
295
+ });
296
+ if (p.isCancel(extrasSelection)) {
297
+ p.cancel('Installation cancelled.');
298
+ process.exit(0);
299
+ }
300
+ selectedExtras = extrasSelection;
301
+ }
302
+ else {
303
+ selectedExtras = extrasOptions.map(o => o.value);
304
+ }
305
+ // Settings may trigger its own TTY sub-prompt — run outside spinner
306
+ if (selectedExtras.includes('settings')) {
307
+ // Attempt managed settings write if user chose managed mode
308
+ let effectiveSecurityMode = securityMode;
309
+ if (securityMode === 'managed') {
310
+ const managed = await installManagedSettings(rootDir, verbose);
311
+ if (!managed) {
312
+ p.log.warn('Managed settings write failed — falling back to user settings');
313
+ effectiveSecurityMode = 'user';
389
314
  }
390
- const claudeignorePath = path.join(gitRoot, '.claudeignore');
391
- // Atomic exclusive create - only create if doesn't exist
392
- const claudeignoreContent = `# DevFlow .claudeignore - Protects against sensitive files and context pollution
393
- # Generated by DevFlow - Edit as needed for your project
394
-
395
- # === SECURITY: Sensitive Files ===
396
- # Environment and secrets
397
- .env
398
- .env.*
399
- .env.local
400
- .env.*.local
401
- *.env
402
- .envrc
403
-
404
- # Credentials and keys
405
- *.key
406
- *.pem
407
- *.p12
408
- *.pfx
409
- *.cer
410
- *.crt
411
- *.der
412
- id_rsa
413
- id_dsa
414
- id_ecdsa
415
- id_ed25519
416
- *.ppk
417
- *_rsa
418
- *_dsa
419
- *secret*
420
- *password*
421
- *credential*
422
- credentials.json
423
- secrets.json
424
- secrets.yaml
425
- secrets.yml
426
-
427
- # Cloud provider credentials
428
- .aws/credentials
429
- .aws/config
430
- .gcp/credentials.json
431
- .azure/credentials
432
-
433
- # Package manager credentials
434
- .npmrc
435
- .pypirc
436
- .gem/credentials
437
- pip.conf
438
-
439
- # Database
440
- *.sql
441
- *.db
442
- *.sqlite
443
- *.sqlite3
444
-
445
- # === DEPENDENCIES & BUILD ===
446
- # Node.js
447
- node_modules/
448
- npm-debug.log*
449
- yarn-debug.log*
450
- yarn-error.log*
451
- pnpm-debug.log*
452
- .pnpm-store/
453
-
454
- # Python
455
- __pycache__/
456
- *.py[cod]
457
- *$py.class
458
- .Python
459
- env/
460
- venv/
461
- ENV/
462
- .venv/
463
- pip-log.txt
464
- pip-delete-this-directory.txt
465
- .eggs/
466
- *.egg-info/
467
- dist/
468
- build/
469
- *.whl
470
-
471
- # Ruby
472
- vendor/bundle/
473
- .bundle/
474
-
475
- # Go
476
- vendor/
477
- go.sum
478
-
479
- # Rust
480
- target/
481
- Cargo.lock
482
-
483
- # Java
484
- target/
485
- *.class
486
- *.jar
487
- *.war
488
-
489
- # PHP
490
- vendor/
491
- composer.lock
492
-
493
- # === BUILD ARTIFACTS ===
494
- dist/
495
- build/
496
- out/
497
- .next/
498
- .nuxt/
499
- .output/
500
- .vite/
501
- .cache/
502
- .parcel-cache/
503
- .turbo/
504
- *.tsbuildinfo
505
-
506
- # === LOGS & TEMP FILES ===
507
- logs/
508
- *.log
509
- *.tmp
510
- *.temp
511
- *.swp
512
- *.swo
513
- *~
514
- .DS_Store
515
- Thumbs.db
516
- *.bak
517
- *.orig
518
- *.rej
519
- .cache
520
-
521
- # === VERSION CONTROL ===
522
- .git/
523
- .svn/
524
- .hg/
525
- .gitignore
526
-
527
- # === IDE & EDITORS ===
528
- .vscode/
529
- .idea/
530
- *.sublime-*
531
- *.code-workspace
532
- .project
533
- .classpath
534
- .settings/
535
-
536
- # === TEST COVERAGE ===
537
- coverage/
538
- .nyc_output/
539
- htmlcov/
540
- .coverage
541
- .pytest_cache/
542
- .tox/
543
-
544
- # === OS-SPECIFIC ===
545
- .DS_Store
546
- .AppleDouble
547
- .LSOverride
548
- Thumbs.db
549
- ehthumbs.db
550
- Desktop.ini
551
-
552
- # === MEDIA & LARGE FILES ===
553
- *.mp4
554
- *.avi
555
- *.mov
556
- *.wmv
557
- *.flv
558
- *.mp3
559
- *.wav
560
- *.zip
561
- *.tar.gz
562
- *.rar
563
- *.7z
564
- *.dmg
565
- *.iso
566
-
567
- # === DOCUMENTATION BUILD ===
568
- site/
569
- _site/
570
- .docusaurus/
571
- .vuepress/dist/
572
-
573
- # === LOCK FILES (usually not needed for AI context) ===
574
- package-lock.json
575
- yarn.lock
576
- pnpm-lock.yaml
577
- Gemfile.lock
578
- poetry.lock
579
- Pipfile.lock
580
- `;
581
- // Atomic exclusive create - fails if file already exists
582
- await fs.writeFile(claudeignorePath, claudeignoreContent, { encoding: 'utf-8', flag: 'wx' });
583
- claudeignoreCreated = true;
584
315
  }
585
- catch (error) {
586
- // Not a git repository or other error - skip .claudeignore creation
316
+ await installSettings(claudeDir, rootDir, devflowDir, verbose, teamsEnabled, effectiveSecurityMode);
317
+ }
318
+ const fileExtras = selectedExtras.filter(e => e !== 'settings' && e !== 'safe-delete');
319
+ if (fileExtras.length > 0) {
320
+ const sExtras = p.spinner();
321
+ sExtras.start('Configuring extras');
322
+ if (selectedExtras.includes('claudeignore') && gitRoot) {
323
+ await installClaudeignore(gitRoot, rootDir, verbose);
587
324
  }
588
- if (claudeignoreCreated && verbose) {
589
- console.log('✓ .claudeignore created');
325
+ if (selectedExtras.includes('gitignore') && gitRoot) {
326
+ await updateGitignore(gitRoot, verbose);
590
327
  }
591
- // For local scope, update .gitignore to exclude .claude/ and .devflow/
592
- if (scope === 'local' && gitRoot) {
593
- try {
594
- const gitignorePath = path.join(gitRoot, '.gitignore');
595
- const entriesToAdd = ['.claude/', '.devflow/'];
596
- let gitignoreContent = '';
597
- try {
598
- gitignoreContent = await fs.readFile(gitignorePath, 'utf-8');
599
- }
600
- catch {
601
- // .gitignore doesn't exist, will create it
602
- }
603
- const linesToAdd = [];
604
- for (const entry of entriesToAdd) {
605
- // Check if entry already exists (exact match or pattern)
606
- if (!gitignoreContent.split('\n').some(line => line.trim() === entry)) {
607
- linesToAdd.push(entry);
608
- }
328
+ if (selectedExtras.includes('docs')) {
329
+ await createDocsStructure(verbose);
330
+ }
331
+ sExtras.stop('Extras configured');
332
+ }
333
+ // Summary output
334
+ if (usedNativeCli) {
335
+ p.log.success('Installed via Claude plugin system');
336
+ }
337
+ else if (!cliAvailable) {
338
+ p.log.info('Installed via file copy (Claude CLI not available)');
339
+ }
340
+ const installedCommands = pluginsToInstall.flatMap(p => p.commands).filter(c => c.length > 0);
341
+ if (installedCommands.length > 0) {
342
+ const commandsNote = installedCommands
343
+ .map(cmd => color.cyan(cmd))
344
+ .join(' ');
345
+ p.note(commandsNote, 'Available commands');
346
+ }
347
+ // Safe-delete auto-install (gated by extras selection)
348
+ if (selectedExtras.includes('safe-delete')) {
349
+ const platform = detectPlatform();
350
+ const shell = detectShell();
351
+ const safeDeleteInfo = getSafeDeleteInfo(platform);
352
+ const safeDeleteAvailable = hasSafeDelete(platform);
353
+ const profilePath = getProfilePath(shell);
354
+ if (process.stdin.isTTY && profilePath) {
355
+ if (!safeDeleteAvailable && safeDeleteInfo.installHint) {
356
+ p.log.info(`Install ${color.cyan(safeDeleteInfo.command ?? 'trash')} first: ${color.dim(safeDeleteInfo.installHint)}`);
357
+ p.log.info(`Then re-run ${color.cyan('devflow init')} to auto-configure safe-delete.`);
358
+ }
359
+ else if (safeDeleteAvailable) {
360
+ const alreadyInstalled = await isAlreadyInstalled(profilePath);
361
+ if (alreadyInstalled) {
362
+ p.log.info(`Safe-delete already configured in ${color.dim(profilePath)}`);
609
363
  }
610
- if (linesToAdd.length > 0) {
611
- const newContent = gitignoreContent
612
- ? `${gitignoreContent.trimEnd()}\n\n# DevFlow local scope installation\n${linesToAdd.join('\n')}\n`
613
- : `# DevFlow local scope installation\n${linesToAdd.join('\n')}\n`;
614
- await fs.writeFile(gitignorePath, newContent, 'utf-8');
615
- if (verbose) {
616
- console.log('✓ .gitignore updated (excluded .claude/ and .devflow/)');
364
+ else {
365
+ const trashCmd = safeDeleteInfo.command;
366
+ const block = generateSafeDeleteBlock(shell, process.platform, trashCmd);
367
+ if (block) {
368
+ const confirm = await p.confirm({
369
+ message: `Install safe-delete to ${profilePath}? (overrides rm to use ${trashCmd ?? 'recycle bin'})`,
370
+ initialValue: true,
371
+ });
372
+ if (!p.isCancel(confirm) && confirm) {
373
+ await installToProfile(profilePath, block);
374
+ p.log.success(`Safe-delete installed to ${color.dim(profilePath)}`);
375
+ p.log.info('Restart your shell or run: ' + color.cyan(`source ${profilePath}`));
376
+ }
617
377
  }
618
378
  }
619
379
  }
620
- catch (error) {
621
- if (verbose) {
622
- console.warn('⚠️ Could not update .gitignore:', error instanceof Error ? error.message : error);
623
- }
624
- }
625
380
  }
626
- // Offer to install project documentation structure
627
- let docsCreated = false;
628
- if (!options.skipDocs) {
629
- const docsDir = path.join(process.cwd(), '.docs');
630
- try {
631
- await fs.mkdir(path.join(docsDir, 'status', 'compact'), { recursive: true });
632
- await fs.mkdir(path.join(docsDir, 'reviews'), { recursive: true });
633
- await fs.mkdir(path.join(docsDir, 'audits', 'standalone'), { recursive: true });
634
- await fs.mkdir(path.join(docsDir, 'releases'), { recursive: true });
635
- docsCreated = true;
381
+ else if (!process.stdin.isTTY) {
382
+ if (safeDeleteAvailable && safeDeleteInfo.command) {
383
+ p.log.info(`Safe-delete available (${safeDeleteInfo.command}). Run interactively to auto-install.`);
636
384
  }
637
- catch (error) {
638
- // .docs/ structure may already exist
385
+ else if (safeDeleteInfo.installHint) {
386
+ p.log.info(`Protect against accidental ${color.red('rm -rf')}: ${color.cyan(safeDeleteInfo.installHint)}`);
639
387
  }
640
388
  }
641
- if (docsCreated && verbose) {
642
- console.log('✓ .docs/ structure ready');
643
- }
644
- // Render output based on verbose flag
645
- if (verbose) {
646
- renderVerboseOutput(version, scope, claudeDir, devflowDir, settingsExists, claudeMdExists);
647
- }
648
- else {
649
- renderCleanOutput(version);
650
- }
651
389
  }
652
- catch (error) {
653
- console.error('❌ Installation failed:', error);
654
- process.exit(1);
390
+ // Verbose mode: show details
391
+ if (verbose) {
392
+ const pluginsList = pluginsToInstall
393
+ .map(plugin => `${color.yellow(plugin.name.padEnd(24))}${color.dim(plugin.description)}`)
394
+ .join('\n');
395
+ p.note(pluginsList, 'Installed plugins');
396
+ p.log.info(`Scope: ${scope}`);
397
+ p.log.info(`Claude dir: ${claudeDir}`);
398
+ p.log.info(`DevFlow dir: ${devflowDir}`);
399
+ const totalSkillDeclarations = pluginsToInstall.reduce((sum, p) => sum + p.skills.length, 0);
400
+ const totalAgentDeclarations = pluginsToInstall.reduce((sum, p) => sum + p.agents.length, 0);
401
+ p.log.info(`Deduplication: ${skillsMap.size} unique skills (from ${totalSkillDeclarations} declarations)`);
402
+ p.log.info(`Deduplication: ${agentsMap.size} unique agents (from ${totalAgentDeclarations} declarations)`);
655
403
  }
404
+ p.outro(color.green('Ready! Run any command in Claude Code to get started.'));
656
405
  });
657
- async function copyDirectory(src, dest) {
658
- await fs.mkdir(dest, { recursive: true });
659
- const entries = await fs.readdir(src, { withFileTypes: true });
660
- for (const entry of entries) {
661
- const srcPath = path.join(src, entry.name);
662
- const destPath = path.join(dest, entry.name);
663
- if (entry.isDirectory()) {
664
- await copyDirectory(srcPath, destPath);
665
- }
666
- else {
667
- await fs.copyFile(srcPath, destPath);
668
- }
669
- }
670
- }
671
406
  //# sourceMappingURL=init.js.map