devflow-kit 1.8.3 → 2.0.1

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 (867) hide show
  1. package/CHANGELOG.md +182 -7
  2. package/LICENSE +1 -1
  3. package/README.md +139 -219
  4. package/dist/cli/agents-view/index.js +9 -0
  5. package/dist/cli/agents-view/render.js +310 -0
  6. package/dist/cli/agents-view/state.js +423 -0
  7. package/dist/cli/agents-view/terminal.js +179 -0
  8. package/dist/cli/commands/agents.js +585 -0
  9. package/dist/cli/commands/ambient.js +231 -0
  10. package/dist/cli/commands/capture.js +133 -0
  11. package/dist/cli/commands/compliance-prompts.js +174 -0
  12. package/dist/cli/commands/compliance.js +337 -0
  13. package/dist/cli/commands/context.js +66 -0
  14. package/dist/cli/commands/debug.js +122 -0
  15. package/dist/cli/commands/flags.js +119 -0
  16. package/dist/cli/commands/hud.js +229 -0
  17. package/dist/cli/commands/init-seed.js +226 -0
  18. package/dist/cli/commands/init.js +1786 -0
  19. package/dist/cli/commands/knowledge/index.js +25 -0
  20. package/dist/cli/commands/knowledge/list.js +115 -0
  21. package/dist/cli/commands/knowledge/toggle.js +84 -0
  22. package/dist/cli/commands/learning.js +311 -0
  23. package/dist/cli/commands/legacy-hooks.js +40 -0
  24. package/dist/cli/commands/memory.js +349 -0
  25. package/dist/cli/commands/proxy.js +1435 -0
  26. package/dist/cli/commands/rules.js +334 -0
  27. package/dist/cli/commands/safe-delete.js +140 -0
  28. package/dist/cli/commands/security.js +179 -0
  29. package/dist/cli/commands/skills.js +140 -0
  30. package/dist/cli/commands/uninstall.js +1214 -0
  31. package/dist/cli.js +35 -10
  32. package/dist/commands/bug-analysis.md +400 -0
  33. package/dist/commands/code-review.md +403 -0
  34. package/dist/commands/debug.md +282 -0
  35. package/dist/commands/dynamic-build.md +972 -0
  36. package/dist/commands/dynamic-plan.md +383 -0
  37. package/dist/commands/dynamic-profile.md +206 -0
  38. package/dist/commands/dynamic-tickets.md +583 -0
  39. package/dist/commands/explore.md +208 -0
  40. package/dist/commands/implement.md +590 -0
  41. package/dist/commands/plan.md +570 -0
  42. package/dist/commands/release.md +206 -0
  43. package/dist/commands/research.md +212 -0
  44. package/dist/commands/resolve.md +731 -0
  45. package/dist/commands/self-review.md +251 -0
  46. package/dist/core/agent-frontmatter.js +209 -0
  47. package/dist/core/agent-models.js +556 -0
  48. package/dist/core/agent-state.js +44 -0
  49. package/dist/core/assets.js +39 -0
  50. package/dist/core/cache.js +205 -0
  51. package/dist/core/codex-auth-inspect.js +128 -0
  52. package/dist/core/compliance-compose.js +458 -0
  53. package/dist/core/compliance.js +165 -0
  54. package/dist/core/external-models.js +76 -0
  55. package/dist/core/feature-config.js +125 -0
  56. package/dist/core/flags.js +309 -0
  57. package/dist/core/fs-atomic.js +74 -0
  58. package/dist/core/git.js +61 -0
  59. package/dist/core/learning-queue-cleanup.js +92 -0
  60. package/dist/core/learning-tuning-config.js +78 -0
  61. package/dist/core/manifest.js +171 -0
  62. package/dist/core/migrations.js +330 -0
  63. package/dist/core/model-discovery.js +655 -0
  64. package/dist/core/observation-io.js +50 -0
  65. package/dist/core/observations.js +109 -0
  66. package/dist/core/orphan-sweep.js +92 -0
  67. package/dist/core/paths.js +48 -0
  68. package/dist/core/plugins.js +525 -0
  69. package/dist/core/project-paths.js +159 -0
  70. package/dist/core/proxy-log.js +165 -0
  71. package/dist/core/proxy-state.js +305 -0
  72. package/dist/core/safe-delete-install.js +191 -0
  73. package/dist/core/teammate-mode-cleanup.js +33 -0
  74. package/dist/hud/colors.js +13 -2
  75. package/dist/hud/components/config-counts.js +2 -2
  76. package/dist/hud/components/context-usage.js +2 -2
  77. package/dist/hud/components/learning-counts.js +92 -0
  78. package/dist/hud/components/session-cost.js +10 -2
  79. package/dist/hud/components/usage-quota.js +43 -8
  80. package/dist/hud/components/version-badge.js +14 -4
  81. package/dist/hud/config.js +4 -2
  82. package/dist/hud/cost-history.js +281 -0
  83. package/dist/hud/git.js +112 -71
  84. package/dist/hud/index.js +47 -4
  85. package/dist/hud/render.js +8 -20
  86. package/dist/hud/transcript.js +5 -6
  87. package/dist/targets/claude-code/claude-paths.js +106 -0
  88. package/dist/targets/claude-code/compliance-install.js +305 -0
  89. package/dist/targets/claude-code/hooks.js +9 -0
  90. package/dist/targets/claude-code/installer.js +458 -0
  91. package/dist/targets/claude-code/legacy.js +239 -0
  92. package/dist/targets/claude-code/post-install.js +971 -0
  93. package/package.json +23 -17
  94. package/src/assets/agents/code.md +244 -0
  95. package/src/assets/agents/design.md +113 -0
  96. package/src/assets/agents/diagnose.md +210 -0
  97. package/src/assets/agents/evaluate.md +117 -0
  98. package/src/assets/agents/git.md +938 -0
  99. package/src/assets/agents/knowledge.md +89 -0
  100. package/src/assets/agents/learning.md +203 -0
  101. package/src/assets/agents/research.md +134 -0
  102. package/src/assets/agents/review.md +220 -0
  103. package/src/assets/agents/scrutinize.md +95 -0
  104. package/src/assets/agents/simplify.md +108 -0
  105. package/src/assets/agents/skim.md +136 -0
  106. package/src/assets/agents/synthesize.md +402 -0
  107. package/src/assets/agents/test.md +155 -0
  108. package/src/assets/agents/triage.md +141 -0
  109. package/src/assets/agents/validate.md +103 -0
  110. package/src/assets/commands/_partials/_compliance.mds +5 -0
  111. package/src/assets/commands/_partials/_decisions.mds +20 -0
  112. package/src/assets/commands/_partials/_engine.mds +244 -0
  113. package/src/assets/commands/_partials/_factory.mds +216 -0
  114. package/src/assets/commands/_partials/_knowledge.mds +95 -0
  115. package/src/assets/commands/_partials/_plan_contract.mds +51 -0
  116. package/src/assets/commands/_partials/_preamble.mds +82 -0
  117. package/src/assets/commands/_partials/_publication.mds +7 -0
  118. package/src/assets/commands/_partials/_roster.mds +31 -0
  119. package/src/assets/commands/_partials/_ticket_template.mds +59 -0
  120. package/src/assets/commands/_partials/_wave.mds +123 -0
  121. package/src/assets/commands/bug-analysis.mds +353 -0
  122. package/src/assets/commands/code-review.mds +355 -0
  123. package/src/assets/commands/debug.mds +224 -0
  124. package/src/assets/commands/dynamic-build.mds +534 -0
  125. package/src/assets/commands/dynamic-plan.mds +244 -0
  126. package/src/assets/commands/dynamic-profile.mds +132 -0
  127. package/src/assets/commands/dynamic-tickets.mds +226 -0
  128. package/src/assets/commands/explore.mds +150 -0
  129. package/src/assets/commands/implement.mds +496 -0
  130. package/src/assets/commands/plan.mds +523 -0
  131. package/src/assets/commands/release.md +206 -0
  132. package/src/assets/commands/research.mds +164 -0
  133. package/src/assets/commands/resolve.mds +636 -0
  134. package/src/assets/commands/self-review.mds +156 -0
  135. package/src/assets/rules/accessibility.md +11 -0
  136. package/src/assets/rules/compliance.md +15 -0
  137. package/src/assets/rules/engineering.md +13 -0
  138. package/src/assets/rules/go.md +12 -0
  139. package/src/assets/rules/java.md +12 -0
  140. package/src/assets/rules/python.md +12 -0
  141. package/src/assets/rules/quality.md +14 -0
  142. package/src/assets/rules/react.md +11 -0
  143. package/src/assets/rules/reliability.md +12 -0
  144. package/src/assets/rules/rust.md +12 -0
  145. package/src/assets/rules/security.md +12 -0
  146. package/src/assets/rules/typescript.md +12 -0
  147. package/src/assets/rules/ui-design.md +11 -0
  148. package/src/assets/scripts/hooks/assets/orchestrator-charter.md +21 -0
  149. package/src/assets/scripts/hooks/background-memory-update +460 -0
  150. package/src/assets/scripts/hooks/capture-prompt +87 -0
  151. package/src/assets/scripts/hooks/capture-question +153 -0
  152. package/src/assets/scripts/hooks/capture-turn +105 -0
  153. package/src/assets/scripts/hooks/debug-trace +75 -0
  154. package/src/assets/scripts/hooks/decisions-usage-scan.cjs +131 -0
  155. package/src/assets/scripts/hooks/ensure-devflow-init +39 -0
  156. package/src/assets/scripts/hooks/ensure-proxy +294 -0
  157. package/src/assets/scripts/hooks/ensure-root-gitignore +116 -0
  158. package/src/assets/scripts/hooks/get-mtime +23 -0
  159. package/src/assets/scripts/hooks/git-marker +16 -0
  160. package/src/assets/scripts/hooks/hook-bootstrap +25 -0
  161. package/src/assets/scripts/hooks/hook-log-init +41 -0
  162. package/src/assets/scripts/hooks/json-helper.cjs +725 -0
  163. package/src/assets/scripts/hooks/json-parse +243 -0
  164. package/src/assets/scripts/hooks/learning-lock +44 -0
  165. package/src/assets/scripts/hooks/lib/decisions-format.cjs +301 -0
  166. package/src/assets/scripts/hooks/lib/mkdir-lock.cjs +106 -0
  167. package/src/assets/scripts/hooks/lib/project-paths.cjs +230 -0
  168. package/src/assets/scripts/hooks/lib/render-decisions.cjs +398 -0
  169. package/src/assets/scripts/hooks/lib/safe-path.cjs +29 -0
  170. package/src/assets/scripts/hooks/log-paths +24 -0
  171. package/src/assets/scripts/hooks/memory-worker +101 -0
  172. package/src/assets/scripts/hooks/pre-compact-memory +126 -0
  173. package/src/assets/scripts/hooks/preamble +77 -0
  174. package/src/assets/scripts/hooks/queue-append +120 -0
  175. package/src/assets/scripts/hooks/resolve-project-root +37 -0
  176. package/src/assets/scripts/hooks/run-hook +31 -0
  177. package/src/assets/scripts/hooks/session-start-context +180 -0
  178. package/src/assets/scripts/hooks/session-start-memory +318 -0
  179. package/src/assets/scripts/hooks/session-start-orchestrator +54 -0
  180. package/src/assets/scripts/hud.sh +5 -0
  181. package/src/assets/scripts/redact-secrets.cjs +410 -0
  182. package/src/assets/skills/accessibility/SKILL.md +145 -0
  183. package/src/assets/skills/accessibility/references/patterns.md +398 -0
  184. package/src/assets/skills/accessibility/references/sources.md +26 -0
  185. package/src/assets/skills/accessibility/references/violations.md +358 -0
  186. package/src/assets/skills/apply-decisions/SKILL.md +100 -0
  187. package/src/assets/skills/apply-feature-knowledge/SKILL.md +69 -0
  188. package/src/assets/skills/architecture/SKILL.md +138 -0
  189. package/src/assets/skills/architecture/references/patterns.md +378 -0
  190. package/src/assets/skills/architecture/references/sources.md +41 -0
  191. package/src/assets/skills/architecture/references/violations.md +314 -0
  192. package/src/assets/skills/boundary-validation/SKILL.md +119 -0
  193. package/src/assets/skills/boundary-validation/references/detection.md +283 -0
  194. package/src/assets/skills/boundary-validation/references/patterns.md +283 -0
  195. package/src/assets/skills/boundary-validation/references/sources.md +41 -0
  196. package/src/assets/skills/boundary-validation/references/violations.md +211 -0
  197. package/src/assets/skills/complexity/SKILL.md +150 -0
  198. package/src/assets/skills/compliance/SKILL.md +121 -0
  199. package/src/assets/skills/compliance/frameworks/gdpr/fragment.md +11 -0
  200. package/src/assets/skills/compliance/frameworks/gdpr/reference.md +50 -0
  201. package/src/assets/skills/compliance/frameworks/hipaa/fragment.md +11 -0
  202. package/src/assets/skills/compliance/frameworks/hipaa/reference.md +44 -0
  203. package/src/assets/skills/compliance/frameworks/iso-27001/fragment.md +10 -0
  204. package/src/assets/skills/compliance/frameworks/iso-27001/reference.md +45 -0
  205. package/src/assets/skills/compliance/frameworks/pci-dss/fragment.md +11 -0
  206. package/src/assets/skills/compliance/frameworks/pci-dss/reference.md +55 -0
  207. package/src/assets/skills/compliance/frameworks/soc2/fragment.md +10 -0
  208. package/src/assets/skills/compliance/frameworks/soc2/reference.md +53 -0
  209. package/src/assets/skills/compliance/frameworks/sox/fragment.md +10 -0
  210. package/src/assets/skills/compliance/frameworks/sox/reference.md +67 -0
  211. package/src/assets/skills/compliance/references/detection.md +108 -0
  212. package/src/assets/skills/compliance/references/sources.md +28 -0
  213. package/src/assets/skills/consistency/SKILL.md +140 -0
  214. package/src/assets/skills/database/SKILL.md +134 -0
  215. package/src/assets/skills/dependencies/SKILL.md +141 -0
  216. package/src/assets/skills/dependency-research/SKILL.md +133 -0
  217. package/src/assets/skills/dependency-research/references/evaluation-criteria.md +101 -0
  218. package/src/assets/skills/design-review/SKILL.md +155 -0
  219. package/src/assets/skills/design-review/references/anti-patterns.md +207 -0
  220. package/src/assets/skills/docs-framework/SKILL.md +190 -0
  221. package/src/assets/skills/docs-framework/references/patterns.md +381 -0
  222. package/src/assets/skills/docs-framework/references/violations.md +221 -0
  223. package/src/assets/skills/documentation/SKILL.md +126 -0
  224. package/src/assets/skills/feature-knowledge/SKILL.md +341 -0
  225. package/src/assets/skills/gap-analysis/SKILL.md +151 -0
  226. package/src/assets/skills/gap-analysis/references/check-layers.md +125 -0
  227. package/src/assets/skills/git/SKILL.md +287 -0
  228. package/src/assets/skills/git/references/github-api.md +666 -0
  229. package/src/assets/skills/git/references/patterns.md +324 -0
  230. package/src/assets/skills/git/references/sources.md +16 -0
  231. package/src/assets/skills/git/references/violations.md +128 -0
  232. package/src/assets/skills/go/SKILL.md +147 -0
  233. package/src/assets/skills/go/references/concurrency.md +335 -0
  234. package/src/assets/skills/go/references/patterns.md +278 -0
  235. package/src/assets/skills/go/references/sources.md +41 -0
  236. package/src/assets/skills/go/references/violations.md +262 -0
  237. package/src/assets/skills/java/SKILL.md +148 -0
  238. package/src/assets/skills/java/references/modern-java.md +335 -0
  239. package/src/assets/skills/java/references/patterns.md +311 -0
  240. package/src/assets/skills/java/references/sources.md +44 -0
  241. package/src/assets/skills/java/references/violations.md +257 -0
  242. package/src/assets/skills/patterns/SKILL.md +162 -0
  243. package/src/assets/skills/performance/SKILL.md +135 -0
  244. package/src/assets/skills/performance/references/patterns.md +516 -0
  245. package/src/assets/skills/performance/references/sources.md +41 -0
  246. package/src/assets/skills/performance/references/violations.md +417 -0
  247. package/src/assets/skills/python/SKILL.md +156 -0
  248. package/src/assets/skills/python/references/async.md +255 -0
  249. package/src/assets/skills/python/references/patterns.md +280 -0
  250. package/src/assets/skills/python/references/sources.md +41 -0
  251. package/src/assets/skills/python/references/violations.md +272 -0
  252. package/src/assets/skills/qa/SKILL.md +136 -0
  253. package/src/assets/skills/qa/references/browser-testing.md +97 -0
  254. package/src/assets/skills/qa/references/patterns.md +118 -0
  255. package/src/assets/skills/qa/references/scenario-templates.md +102 -0
  256. package/src/assets/skills/qa/references/sources.md +30 -0
  257. package/src/assets/skills/qa/references/violations.md +98 -0
  258. package/src/assets/skills/quality-gates/SKILL.md +152 -0
  259. package/src/assets/skills/quality-gates/references/stub-detection.md +135 -0
  260. package/src/assets/skills/react/SKILL.md +143 -0
  261. package/src/assets/skills/react/references/error-handling.md +179 -0
  262. package/src/assets/skills/react/references/forms.md +214 -0
  263. package/src/assets/skills/react/references/hooks.md +193 -0
  264. package/src/assets/skills/react/references/patterns.md +1336 -0
  265. package/src/assets/skills/react/references/sources.md +35 -0
  266. package/src/assets/skills/react/references/violations.md +570 -0
  267. package/src/assets/skills/regression/SKILL.md +146 -0
  268. package/src/assets/skills/reliability/SKILL.md +153 -0
  269. package/src/assets/skills/reliability/references/detection.md +66 -0
  270. package/src/assets/skills/reliability/references/patterns.md +151 -0
  271. package/src/assets/skills/reliability/references/sources.md +27 -0
  272. package/src/assets/skills/reliability/references/violations.md +125 -0
  273. package/src/assets/skills/research-codebase/SKILL.md +135 -0
  274. package/src/assets/skills/research-competitor/SKILL.md +145 -0
  275. package/src/assets/skills/research-external/SKILL.md +141 -0
  276. package/src/assets/skills/research-market/SKILL.md +145 -0
  277. package/src/assets/skills/research-technology/SKILL.md +180 -0
  278. package/src/assets/skills/review-methodology/SKILL.md +121 -0
  279. package/src/assets/skills/review-methodology/references/patterns.md +186 -0
  280. package/src/assets/skills/review-methodology/references/report-template.md +142 -0
  281. package/src/assets/skills/review-methodology/references/violations.md +125 -0
  282. package/src/assets/skills/rust/SKILL.md +148 -0
  283. package/src/assets/skills/rust/references/ownership.md +278 -0
  284. package/src/assets/skills/rust/references/patterns.md +247 -0
  285. package/src/assets/skills/rust/references/sources.md +46 -0
  286. package/src/assets/skills/rust/references/violations.md +252 -0
  287. package/src/assets/skills/security/SKILL.md +121 -0
  288. package/src/assets/skills/security/references/patterns.md +271 -0
  289. package/src/assets/skills/security/references/sources.md +41 -0
  290. package/src/assets/skills/security/references/violations.md +241 -0
  291. package/src/assets/skills/software-design/SKILL.md +143 -0
  292. package/src/assets/skills/software-design/references/checklist.md +259 -0
  293. package/src/assets/skills/software-design/references/code-smell-violations.md +189 -0
  294. package/src/assets/skills/software-design/references/patterns.md +359 -0
  295. package/src/assets/skills/software-design/references/sources.md +41 -0
  296. package/src/assets/skills/software-design/references/violations.md +341 -0
  297. package/src/assets/skills/test-driven-development/SKILL.md +197 -0
  298. package/src/assets/skills/testing/SKILL.md +139 -0
  299. package/src/assets/skills/testing/references/patterns.md +346 -0
  300. package/src/assets/skills/testing/references/sources.md +53 -0
  301. package/src/assets/skills/testing/references/violations.md +322 -0
  302. package/src/assets/skills/typescript/SKILL.md +150 -0
  303. package/src/assets/skills/typescript/references/async.md +333 -0
  304. package/src/assets/skills/typescript/references/patterns.md +440 -0
  305. package/src/assets/skills/typescript/references/sources.md +41 -0
  306. package/src/assets/skills/typescript/references/type-guards.md +333 -0
  307. package/src/assets/skills/typescript/references/utility-types.md +255 -0
  308. package/src/assets/skills/typescript/references/violations.md +285 -0
  309. package/src/assets/skills/ui-design/SKILL.md +144 -0
  310. package/src/assets/skills/ui-design/references/patterns.md +341 -0
  311. package/src/assets/skills/ui-design/references/sources.md +41 -0
  312. package/src/assets/skills/ui-design/references/violations.md +312 -0
  313. package/src/assets/skills/worktree-support/SKILL.md +92 -0
  314. package/src/targets/claude-code/templates/claudeignore.template +188 -0
  315. package/src/targets/claude-code/templates/settings.json +86 -0
  316. package/dist/cli.d.ts +0 -3
  317. package/dist/commands/ambient.d.ts +0 -18
  318. package/dist/commands/ambient.js +0 -137
  319. package/dist/commands/hud.d.ts +0 -22
  320. package/dist/commands/hud.js +0 -180
  321. package/dist/commands/init.d.ts +0 -16
  322. package/dist/commands/init.js +0 -738
  323. package/dist/commands/list.d.ts +0 -24
  324. package/dist/commands/list.js +0 -89
  325. package/dist/commands/memory.d.ts +0 -22
  326. package/dist/commands/memory.js +0 -175
  327. package/dist/commands/skills.d.ts +0 -11
  328. package/dist/commands/skills.js +0 -116
  329. package/dist/commands/uninstall.d.ts +0 -22
  330. package/dist/commands/uninstall.js +0 -558
  331. package/dist/hud/cache.d.ts +0 -14
  332. package/dist/hud/cache.js +0 -54
  333. package/dist/hud/colors.d.ts +0 -23
  334. package/dist/hud/components/config-counts.d.ts +0 -8
  335. package/dist/hud/components/context-usage.d.ts +0 -8
  336. package/dist/hud/components/diff-stats.d.ts +0 -3
  337. package/dist/hud/components/directory.d.ts +0 -3
  338. package/dist/hud/components/git-ahead-behind.d.ts +0 -3
  339. package/dist/hud/components/git-branch.d.ts +0 -3
  340. package/dist/hud/components/model.d.ts +0 -3
  341. package/dist/hud/components/release-info.d.ts +0 -3
  342. package/dist/hud/components/session-cost.d.ts +0 -3
  343. package/dist/hud/components/session-duration.d.ts +0 -3
  344. package/dist/hud/components/todo-progress.d.ts +0 -3
  345. package/dist/hud/components/usage-quota.d.ts +0 -3
  346. package/dist/hud/components/version-badge.d.ts +0 -3
  347. package/dist/hud/components/worktree-count.d.ts +0 -3
  348. package/dist/hud/config.d.ts +0 -10
  349. package/dist/hud/credentials.d.ts +0 -17
  350. package/dist/hud/credentials.js +0 -99
  351. package/dist/hud/git.d.ts +0 -7
  352. package/dist/hud/index.d.ts +0 -2
  353. package/dist/hud/render.d.ts +0 -7
  354. package/dist/hud/stdin.d.ts +0 -6
  355. package/dist/hud/transcript.d.ts +0 -7
  356. package/dist/hud/types.d.ts +0 -116
  357. package/dist/hud/usage-api.d.ts +0 -7
  358. package/dist/hud/usage-api.js +0 -84
  359. package/dist/plugins.d.ts +0 -46
  360. package/dist/plugins.js +0 -233
  361. package/dist/utils/cli.d.ts +0 -5
  362. package/dist/utils/cli.js +0 -14
  363. package/dist/utils/git.d.ts +0 -11
  364. package/dist/utils/git.js +0 -36
  365. package/dist/utils/installer.d.ts +0 -41
  366. package/dist/utils/installer.js +0 -195
  367. package/dist/utils/manifest.d.ts +0 -46
  368. package/dist/utils/manifest.js +0 -100
  369. package/dist/utils/paths.d.ts +0 -42
  370. package/dist/utils/paths.js +0 -106
  371. package/dist/utils/post-install.d.ts +0 -87
  372. package/dist/utils/post-install.js +0 -546
  373. package/dist/utils/safe-delete-install.d.ts +0 -29
  374. package/dist/utils/safe-delete-install.js +0 -191
  375. package/dist/utils/safe-delete.d.ts +0 -12
  376. package/plugins/devflow-accessibility/.claude-plugin/plugin.json +0 -21
  377. package/plugins/devflow-accessibility/skills/accessibility/SKILL.md +0 -229
  378. package/plugins/devflow-accessibility/skills/accessibility/references/patterns.md +0 -670
  379. package/plugins/devflow-accessibility/skills/accessibility/references/violations.md +0 -419
  380. package/plugins/devflow-ambient/.claude-plugin/plugin.json +0 -33
  381. package/plugins/devflow-ambient/README.md +0 -68
  382. package/plugins/devflow-ambient/agents/coder.md +0 -135
  383. package/plugins/devflow-ambient/agents/reviewer.md +0 -165
  384. package/plugins/devflow-ambient/agents/scrutinizer.md +0 -82
  385. package/plugins/devflow-ambient/agents/shepherd.md +0 -108
  386. package/plugins/devflow-ambient/agents/simplifier.md +0 -102
  387. package/plugins/devflow-ambient/agents/skimmer.md +0 -143
  388. package/plugins/devflow-ambient/agents/validator.md +0 -86
  389. package/plugins/devflow-ambient/skills/ambient-router/SKILL.md +0 -145
  390. package/plugins/devflow-ambient/skills/ambient-router/references/skill-catalog.md +0 -74
  391. package/plugins/devflow-ambient/skills/debug-orchestration/SKILL.md +0 -69
  392. package/plugins/devflow-ambient/skills/implementation-orchestration/SKILL.md +0 -92
  393. package/plugins/devflow-ambient/skills/plan-orchestration/SKILL.md +0 -71
  394. package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +0 -19
  395. package/plugins/devflow-audit-claude/README.md +0 -46
  396. package/plugins/devflow-audit-claude/agents/claude-md-auditor.md +0 -134
  397. package/plugins/devflow-audit-claude/commands/audit-claude.md +0 -89
  398. package/plugins/devflow-code-review/.claude-plugin/plugin.json +0 -38
  399. package/plugins/devflow-code-review/README.md +0 -73
  400. package/plugins/devflow-code-review/agents/git.md +0 -277
  401. package/plugins/devflow-code-review/agents/reviewer.md +0 -165
  402. package/plugins/devflow-code-review/agents/synthesizer.md +0 -211
  403. package/plugins/devflow-code-review/commands/code-review-teams.md +0 -285
  404. package/plugins/devflow-code-review/commands/code-review.md +0 -163
  405. package/plugins/devflow-code-review/skills/agent-teams/SKILL.md +0 -124
  406. package/plugins/devflow-code-review/skills/agent-teams/references/cleanup.md +0 -104
  407. package/plugins/devflow-code-review/skills/agent-teams/references/communication.md +0 -122
  408. package/plugins/devflow-code-review/skills/agent-teams/references/team-patterns.md +0 -217
  409. package/plugins/devflow-code-review/skills/architecture-patterns/SKILL.md +0 -153
  410. package/plugins/devflow-code-review/skills/architecture-patterns/references/patterns.md +0 -873
  411. package/plugins/devflow-code-review/skills/architecture-patterns/references/violations.md +0 -575
  412. package/plugins/devflow-code-review/skills/complexity-patterns/SKILL.md +0 -143
  413. package/plugins/devflow-code-review/skills/consistency-patterns/SKILL.md +0 -140
  414. package/plugins/devflow-code-review/skills/database-patterns/SKILL.md +0 -134
  415. package/plugins/devflow-code-review/skills/dependencies-patterns/SKILL.md +0 -141
  416. package/plugins/devflow-code-review/skills/documentation-patterns/SKILL.md +0 -125
  417. package/plugins/devflow-code-review/skills/knowledge-persistence/SKILL.md +0 -128
  418. package/plugins/devflow-code-review/skills/knowledge-persistence/references/examples.md +0 -44
  419. package/plugins/devflow-code-review/skills/performance-patterns/SKILL.md +0 -154
  420. package/plugins/devflow-code-review/skills/performance-patterns/references/patterns.md +0 -503
  421. package/plugins/devflow-code-review/skills/performance-patterns/references/violations.md +0 -354
  422. package/plugins/devflow-code-review/skills/regression-patterns/SKILL.md +0 -146
  423. package/plugins/devflow-code-review/skills/review-methodology/SKILL.md +0 -119
  424. package/plugins/devflow-code-review/skills/review-methodology/references/patterns.md +0 -186
  425. package/plugins/devflow-code-review/skills/review-methodology/references/report-template.md +0 -142
  426. package/plugins/devflow-code-review/skills/review-methodology/references/violations.md +0 -125
  427. package/plugins/devflow-code-review/skills/security-patterns/SKILL.md +0 -156
  428. package/plugins/devflow-code-review/skills/security-patterns/references/patterns.md +0 -507
  429. package/plugins/devflow-code-review/skills/security-patterns/references/violations.md +0 -237
  430. package/plugins/devflow-code-review/skills/test-patterns/SKILL.md +0 -183
  431. package/plugins/devflow-code-review/skills/test-patterns/references/patterns.md +0 -220
  432. package/plugins/devflow-code-review/skills/test-patterns/references/violations.md +0 -221
  433. package/plugins/devflow-core-skills/.claude-plugin/plugin.json +0 -31
  434. package/plugins/devflow-core-skills/README.md +0 -50
  435. package/plugins/devflow-core-skills/skills/core-patterns/SKILL.md +0 -162
  436. package/plugins/devflow-core-skills/skills/core-patterns/references/checklist.md +0 -276
  437. package/plugins/devflow-core-skills/skills/core-patterns/references/code-smell-violations.md +0 -144
  438. package/plugins/devflow-core-skills/skills/core-patterns/references/patterns.md +0 -576
  439. package/plugins/devflow-core-skills/skills/core-patterns/references/violations.md +0 -369
  440. package/plugins/devflow-core-skills/skills/docs-framework/SKILL.md +0 -143
  441. package/plugins/devflow-core-skills/skills/docs-framework/references/patterns.md +0 -346
  442. package/plugins/devflow-core-skills/skills/docs-framework/references/violations.md +0 -221
  443. package/plugins/devflow-core-skills/skills/git-safety/SKILL.md +0 -122
  444. package/plugins/devflow-core-skills/skills/git-safety/references/patterns.md +0 -289
  445. package/plugins/devflow-core-skills/skills/git-safety/references/violations.md +0 -18
  446. package/plugins/devflow-core-skills/skills/git-workflow/SKILL.md +0 -158
  447. package/plugins/devflow-core-skills/skills/git-workflow/references/commit-patterns.md +0 -115
  448. package/plugins/devflow-core-skills/skills/git-workflow/references/commit-violations.md +0 -77
  449. package/plugins/devflow-core-skills/skills/git-workflow/references/pr-patterns.md +0 -127
  450. package/plugins/devflow-core-skills/skills/git-workflow/references/pr-violations.md +0 -96
  451. package/plugins/devflow-core-skills/skills/github-patterns/SKILL.md +0 -153
  452. package/plugins/devflow-core-skills/skills/github-patterns/references/patterns.md +0 -572
  453. package/plugins/devflow-core-skills/skills/github-patterns/references/violations.md +0 -298
  454. package/plugins/devflow-core-skills/skills/input-validation/SKILL.md +0 -148
  455. package/plugins/devflow-core-skills/skills/input-validation/references/detection.md +0 -283
  456. package/plugins/devflow-core-skills/skills/input-validation/references/patterns.md +0 -361
  457. package/plugins/devflow-core-skills/skills/input-validation/references/violations.md +0 -224
  458. package/plugins/devflow-core-skills/skills/search-first/SKILL.md +0 -133
  459. package/plugins/devflow-core-skills/skills/search-first/references/evaluation-criteria.md +0 -101
  460. package/plugins/devflow-core-skills/skills/test-driven-development/SKILL.md +0 -137
  461. package/plugins/devflow-core-skills/skills/test-patterns/SKILL.md +0 -183
  462. package/plugins/devflow-core-skills/skills/test-patterns/references/detection.md +0 -149
  463. package/plugins/devflow-core-skills/skills/test-patterns/references/patterns.md +0 -220
  464. package/plugins/devflow-core-skills/skills/test-patterns/references/report-template.md +0 -108
  465. package/plugins/devflow-core-skills/skills/test-patterns/references/violations.md +0 -221
  466. package/plugins/devflow-debug/.claude-plugin/plugin.json +0 -26
  467. package/plugins/devflow-debug/README.md +0 -65
  468. package/plugins/devflow-debug/agents/git.md +0 -277
  469. package/plugins/devflow-debug/agents/synthesizer.md +0 -211
  470. package/plugins/devflow-debug/commands/debug-teams.md +0 -245
  471. package/plugins/devflow-debug/commands/debug.md +0 -174
  472. package/plugins/devflow-debug/skills/agent-teams/SKILL.md +0 -124
  473. package/plugins/devflow-debug/skills/agent-teams/references/cleanup.md +0 -104
  474. package/plugins/devflow-debug/skills/agent-teams/references/communication.md +0 -122
  475. package/plugins/devflow-debug/skills/agent-teams/references/team-patterns.md +0 -217
  476. package/plugins/devflow-debug/skills/git-safety/SKILL.md +0 -122
  477. package/plugins/devflow-debug/skills/git-safety/references/detection.md +0 -290
  478. package/plugins/devflow-debug/skills/git-safety/references/patterns.md +0 -289
  479. package/plugins/devflow-debug/skills/git-safety/references/violations.md +0 -18
  480. package/plugins/devflow-debug/skills/knowledge-persistence/SKILL.md +0 -128
  481. package/plugins/devflow-debug/skills/knowledge-persistence/references/examples.md +0 -44
  482. package/plugins/devflow-frontend-design/.claude-plugin/plugin.json +0 -21
  483. package/plugins/devflow-frontend-design/skills/frontend-design/SKILL.md +0 -254
  484. package/plugins/devflow-frontend-design/skills/frontend-design/references/patterns.md +0 -511
  485. package/plugins/devflow-frontend-design/skills/frontend-design/references/violations.md +0 -453
  486. package/plugins/devflow-go/.claude-plugin/plugin.json +0 -21
  487. package/plugins/devflow-go/skills/go/SKILL.md +0 -187
  488. package/plugins/devflow-go/skills/go/references/concurrency.md +0 -312
  489. package/plugins/devflow-go/skills/go/references/patterns.md +0 -232
  490. package/plugins/devflow-go/skills/go/references/violations.md +0 -205
  491. package/plugins/devflow-implement/.claude-plugin/plugin.json +0 -35
  492. package/plugins/devflow-implement/README.md +0 -71
  493. package/plugins/devflow-implement/agents/coder.md +0 -135
  494. package/plugins/devflow-implement/agents/git.md +0 -277
  495. package/plugins/devflow-implement/agents/scrutinizer.md +0 -82
  496. package/plugins/devflow-implement/agents/shepherd.md +0 -108
  497. package/plugins/devflow-implement/agents/simplifier.md +0 -102
  498. package/plugins/devflow-implement/agents/skimmer.md +0 -143
  499. package/plugins/devflow-implement/agents/synthesizer.md +0 -211
  500. package/plugins/devflow-implement/agents/validator.md +0 -86
  501. package/plugins/devflow-implement/commands/implement-teams.md +0 -620
  502. package/plugins/devflow-implement/commands/implement.md +0 -430
  503. package/plugins/devflow-implement/skills/agent-teams/SKILL.md +0 -124
  504. package/plugins/devflow-implement/skills/agent-teams/references/cleanup.md +0 -104
  505. package/plugins/devflow-implement/skills/agent-teams/references/communication.md +0 -122
  506. package/plugins/devflow-implement/skills/agent-teams/references/team-patterns.md +0 -217
  507. package/plugins/devflow-implement/skills/implementation-patterns/SKILL.md +0 -162
  508. package/plugins/devflow-implement/skills/knowledge-persistence/SKILL.md +0 -128
  509. package/plugins/devflow-implement/skills/knowledge-persistence/references/examples.md +0 -44
  510. package/plugins/devflow-implement/skills/self-review/SKILL.md +0 -149
  511. package/plugins/devflow-implement/skills/self-review/references/stub-detection.md +0 -135
  512. package/plugins/devflow-java/.claude-plugin/plugin.json +0 -21
  513. package/plugins/devflow-java/skills/java/SKILL.md +0 -183
  514. package/plugins/devflow-java/skills/java/references/modern-java.md +0 -270
  515. package/plugins/devflow-java/skills/java/references/patterns.md +0 -235
  516. package/plugins/devflow-java/skills/java/references/violations.md +0 -213
  517. package/plugins/devflow-python/.claude-plugin/plugin.json +0 -21
  518. package/plugins/devflow-python/skills/python/SKILL.md +0 -188
  519. package/plugins/devflow-python/skills/python/references/async.md +0 -220
  520. package/plugins/devflow-python/skills/python/references/patterns.md +0 -226
  521. package/plugins/devflow-python/skills/python/references/violations.md +0 -204
  522. package/plugins/devflow-react/.claude-plugin/plugin.json +0 -21
  523. package/plugins/devflow-react/skills/react/SKILL.md +0 -276
  524. package/plugins/devflow-react/skills/react/references/patterns.md +0 -1331
  525. package/plugins/devflow-react/skills/react/references/violations.md +0 -565
  526. package/plugins/devflow-resolve/.claude-plugin/plugin.json +0 -29
  527. package/plugins/devflow-resolve/README.md +0 -65
  528. package/plugins/devflow-resolve/agents/git.md +0 -277
  529. package/plugins/devflow-resolve/agents/resolver.md +0 -131
  530. package/plugins/devflow-resolve/agents/simplifier.md +0 -102
  531. package/plugins/devflow-resolve/commands/resolve-teams.md +0 -307
  532. package/plugins/devflow-resolve/commands/resolve.md +0 -246
  533. package/plugins/devflow-resolve/skills/agent-teams/SKILL.md +0 -124
  534. package/plugins/devflow-resolve/skills/agent-teams/references/cleanup.md +0 -104
  535. package/plugins/devflow-resolve/skills/agent-teams/references/communication.md +0 -122
  536. package/plugins/devflow-resolve/skills/agent-teams/references/team-patterns.md +0 -217
  537. package/plugins/devflow-resolve/skills/implementation-patterns/SKILL.md +0 -162
  538. package/plugins/devflow-resolve/skills/implementation-patterns/references/patterns.md +0 -1063
  539. package/plugins/devflow-resolve/skills/implementation-patterns/references/violations.md +0 -483
  540. package/plugins/devflow-resolve/skills/knowledge-persistence/SKILL.md +0 -128
  541. package/plugins/devflow-resolve/skills/knowledge-persistence/references/examples.md +0 -44
  542. package/plugins/devflow-resolve/skills/security-patterns/SKILL.md +0 -156
  543. package/plugins/devflow-resolve/skills/security-patterns/references/detection.md +0 -287
  544. package/plugins/devflow-resolve/skills/security-patterns/references/patterns.md +0 -507
  545. package/plugins/devflow-resolve/skills/security-patterns/references/violations.md +0 -237
  546. package/plugins/devflow-rust/.claude-plugin/plugin.json +0 -21
  547. package/plugins/devflow-rust/skills/rust/SKILL.md +0 -193
  548. package/plugins/devflow-rust/skills/rust/references/ownership.md +0 -242
  549. package/plugins/devflow-rust/skills/rust/references/patterns.md +0 -210
  550. package/plugins/devflow-rust/skills/rust/references/violations.md +0 -191
  551. package/plugins/devflow-self-review/.claude-plugin/plugin.json +0 -26
  552. package/plugins/devflow-self-review/README.md +0 -38
  553. package/plugins/devflow-self-review/agents/scrutinizer.md +0 -82
  554. package/plugins/devflow-self-review/agents/simplifier.md +0 -102
  555. package/plugins/devflow-self-review/agents/validator.md +0 -86
  556. package/plugins/devflow-self-review/commands/self-review.md +0 -132
  557. package/plugins/devflow-self-review/skills/core-patterns/SKILL.md +0 -162
  558. package/plugins/devflow-self-review/skills/core-patterns/references/checklist.md +0 -276
  559. package/plugins/devflow-self-review/skills/core-patterns/references/code-smell-violations.md +0 -144
  560. package/plugins/devflow-self-review/skills/core-patterns/references/detection.md +0 -303
  561. package/plugins/devflow-self-review/skills/core-patterns/references/patterns.md +0 -576
  562. package/plugins/devflow-self-review/skills/core-patterns/references/violations.md +0 -369
  563. package/plugins/devflow-self-review/skills/self-review/SKILL.md +0 -149
  564. package/plugins/devflow-self-review/skills/self-review/references/patterns.md +0 -405
  565. package/plugins/devflow-self-review/skills/self-review/references/report-template.md +0 -253
  566. package/plugins/devflow-self-review/skills/self-review/references/stub-detection.md +0 -135
  567. package/plugins/devflow-self-review/skills/self-review/references/violations.md +0 -308
  568. package/plugins/devflow-specify/.claude-plugin/plugin.json +0 -25
  569. package/plugins/devflow-specify/README.md +0 -46
  570. package/plugins/devflow-specify/agents/skimmer.md +0 -143
  571. package/plugins/devflow-specify/agents/synthesizer.md +0 -211
  572. package/plugins/devflow-specify/commands/specify-teams.md +0 -321
  573. package/plugins/devflow-specify/commands/specify.md +0 -186
  574. package/plugins/devflow-specify/skills/agent-teams/SKILL.md +0 -124
  575. package/plugins/devflow-specify/skills/agent-teams/references/cleanup.md +0 -104
  576. package/plugins/devflow-specify/skills/agent-teams/references/communication.md +0 -122
  577. package/plugins/devflow-specify/skills/agent-teams/references/team-patterns.md +0 -217
  578. package/plugins/devflow-typescript/.claude-plugin/plugin.json +0 -21
  579. package/plugins/devflow-typescript/skills/typescript/SKILL.md +0 -176
  580. package/plugins/devflow-typescript/skills/typescript/references/patterns.md +0 -1105
  581. package/plugins/devflow-typescript/skills/typescript/references/violations.md +0 -433
  582. package/scripts/hooks/ambient-prompt +0 -50
  583. package/scripts/hooks/background-memory-update +0 -257
  584. package/scripts/hooks/ensure-memory-gitignore +0 -17
  585. package/scripts/hooks/pre-compact-memory +0 -87
  586. package/scripts/hooks/run-hook +0 -23
  587. package/scripts/hooks/session-start-memory +0 -165
  588. package/scripts/hooks/stop-update-memory +0 -85
  589. package/scripts/hud/cache.d.ts +0 -14
  590. package/scripts/hud/cache.d.ts.map +0 -1
  591. package/scripts/hud/cache.js +0 -54
  592. package/scripts/hud/cache.js.map +0 -1
  593. package/scripts/hud/colors.d.ts +0 -23
  594. package/scripts/hud/colors.d.ts.map +0 -1
  595. package/scripts/hud/colors.js +0 -62
  596. package/scripts/hud/colors.js.map +0 -1
  597. package/scripts/hud/components/config-counts.d.ts +0 -8
  598. package/scripts/hud/components/config-counts.d.ts.map +0 -1
  599. package/scripts/hud/components/config-counts.js +0 -91
  600. package/scripts/hud/components/config-counts.js.map +0 -1
  601. package/scripts/hud/components/context-usage.d.ts +0 -8
  602. package/scripts/hud/components/context-usage.d.ts.map +0 -1
  603. package/scripts/hud/components/context-usage.js +0 -49
  604. package/scripts/hud/components/context-usage.js.map +0 -1
  605. package/scripts/hud/components/diff-stats.d.ts +0 -3
  606. package/scripts/hud/components/diff-stats.d.ts.map +0 -1
  607. package/scripts/hud/components/diff-stats.js +0 -36
  608. package/scripts/hud/components/diff-stats.js.map +0 -1
  609. package/scripts/hud/components/directory.d.ts +0 -3
  610. package/scripts/hud/components/directory.d.ts.map +0 -1
  611. package/scripts/hud/components/directory.js +0 -10
  612. package/scripts/hud/components/directory.js.map +0 -1
  613. package/scripts/hud/components/git-ahead-behind.d.ts +0 -3
  614. package/scripts/hud/components/git-ahead-behind.d.ts.map +0 -1
  615. package/scripts/hud/components/git-ahead-behind.js +0 -16
  616. package/scripts/hud/components/git-ahead-behind.js.map +0 -1
  617. package/scripts/hud/components/git-branch.d.ts +0 -3
  618. package/scripts/hud/components/git-branch.d.ts.map +0 -1
  619. package/scripts/hud/components/git-branch.js +0 -14
  620. package/scripts/hud/components/git-branch.js.map +0 -1
  621. package/scripts/hud/components/model.d.ts +0 -3
  622. package/scripts/hud/components/model.d.ts.map +0 -1
  623. package/scripts/hud/components/model.js +0 -21
  624. package/scripts/hud/components/model.js.map +0 -1
  625. package/scripts/hud/components/release-info.d.ts +0 -3
  626. package/scripts/hud/components/release-info.d.ts.map +0 -1
  627. package/scripts/hud/components/release-info.js +0 -9
  628. package/scripts/hud/components/release-info.js.map +0 -1
  629. package/scripts/hud/components/session-cost.d.ts +0 -3
  630. package/scripts/hud/components/session-cost.d.ts.map +0 -1
  631. package/scripts/hud/components/session-cost.js +0 -9
  632. package/scripts/hud/components/session-cost.js.map +0 -1
  633. package/scripts/hud/components/session-duration.d.ts +0 -3
  634. package/scripts/hud/components/session-duration.d.ts.map +0 -1
  635. package/scripts/hud/components/session-duration.js +0 -18
  636. package/scripts/hud/components/session-duration.js.map +0 -1
  637. package/scripts/hud/components/todo-progress.d.ts +0 -3
  638. package/scripts/hud/components/todo-progress.d.ts.map +0 -1
  639. package/scripts/hud/components/todo-progress.js +0 -11
  640. package/scripts/hud/components/todo-progress.js.map +0 -1
  641. package/scripts/hud/components/usage-quota.d.ts +0 -3
  642. package/scripts/hud/components/usage-quota.d.ts.map +0 -1
  643. package/scripts/hud/components/usage-quota.js +0 -45
  644. package/scripts/hud/components/usage-quota.js.map +0 -1
  645. package/scripts/hud/components/version-badge.d.ts +0 -3
  646. package/scripts/hud/components/version-badge.d.ts.map +0 -1
  647. package/scripts/hud/components/version-badge.js +0 -80
  648. package/scripts/hud/components/version-badge.js.map +0 -1
  649. package/scripts/hud/components/worktree-count.d.ts +0 -3
  650. package/scripts/hud/components/worktree-count.d.ts.map +0 -1
  651. package/scripts/hud/components/worktree-count.js +0 -8
  652. package/scripts/hud/components/worktree-count.js.map +0 -1
  653. package/scripts/hud/config.d.ts +0 -10
  654. package/scripts/hud/config.d.ts.map +0 -1
  655. package/scripts/hud/config.js +0 -55
  656. package/scripts/hud/config.js.map +0 -1
  657. package/scripts/hud/credentials.d.ts +0 -17
  658. package/scripts/hud/credentials.d.ts.map +0 -1
  659. package/scripts/hud/credentials.js +0 -99
  660. package/scripts/hud/credentials.js.map +0 -1
  661. package/scripts/hud/git.d.ts +0 -7
  662. package/scripts/hud/git.d.ts.map +0 -1
  663. package/scripts/hud/git.js +0 -153
  664. package/scripts/hud/git.js.map +0 -1
  665. package/scripts/hud/index.d.ts +0 -2
  666. package/scripts/hud/index.d.ts.map +0 -1
  667. package/scripts/hud/index.js +0 -81
  668. package/scripts/hud/index.js.map +0 -1
  669. package/scripts/hud/render.d.ts +0 -7
  670. package/scripts/hud/render.d.ts.map +0 -1
  671. package/scripts/hud/render.js +0 -111
  672. package/scripts/hud/render.js.map +0 -1
  673. package/scripts/hud/stdin.d.ts +0 -6
  674. package/scripts/hud/stdin.d.ts.map +0 -1
  675. package/scripts/hud/stdin.js +0 -25
  676. package/scripts/hud/stdin.js.map +0 -1
  677. package/scripts/hud/transcript.d.ts +0 -7
  678. package/scripts/hud/transcript.d.ts.map +0 -1
  679. package/scripts/hud/transcript.js +0 -130
  680. package/scripts/hud/transcript.js.map +0 -1
  681. package/scripts/hud/types.d.ts +0 -116
  682. package/scripts/hud/types.d.ts.map +0 -1
  683. package/scripts/hud/types.js +0 -2
  684. package/scripts/hud/types.js.map +0 -1
  685. package/scripts/hud/usage-api.d.ts +0 -7
  686. package/scripts/hud/usage-api.d.ts.map +0 -1
  687. package/scripts/hud/usage-api.js +0 -84
  688. package/scripts/hud/usage-api.js.map +0 -1
  689. package/scripts/hud.sh +0 -5
  690. package/shared/agents/coder.md +0 -135
  691. package/shared/agents/git.md +0 -277
  692. package/shared/agents/resolver.md +0 -131
  693. package/shared/agents/reviewer.md +0 -165
  694. package/shared/agents/scrutinizer.md +0 -82
  695. package/shared/agents/shepherd.md +0 -108
  696. package/shared/agents/simplifier.md +0 -102
  697. package/shared/agents/skimmer.md +0 -143
  698. package/shared/agents/synthesizer.md +0 -211
  699. package/shared/agents/validator.md +0 -86
  700. package/shared/skills/accessibility/SKILL.md +0 -229
  701. package/shared/skills/accessibility/references/detection.md +0 -171
  702. package/shared/skills/accessibility/references/patterns.md +0 -670
  703. package/shared/skills/accessibility/references/violations.md +0 -419
  704. package/shared/skills/agent-teams/SKILL.md +0 -124
  705. package/shared/skills/agent-teams/references/cleanup.md +0 -104
  706. package/shared/skills/agent-teams/references/communication.md +0 -122
  707. package/shared/skills/agent-teams/references/team-patterns.md +0 -217
  708. package/shared/skills/ambient-router/SKILL.md +0 -145
  709. package/shared/skills/ambient-router/references/skill-catalog.md +0 -74
  710. package/shared/skills/architecture-patterns/SKILL.md +0 -153
  711. package/shared/skills/architecture-patterns/references/detection.md +0 -337
  712. package/shared/skills/architecture-patterns/references/patterns.md +0 -873
  713. package/shared/skills/architecture-patterns/references/violations.md +0 -575
  714. package/shared/skills/complexity-patterns/SKILL.md +0 -143
  715. package/shared/skills/complexity-patterns/references/detection.md +0 -264
  716. package/shared/skills/complexity-patterns/references/patterns.md +0 -487
  717. package/shared/skills/complexity-patterns/references/violations.md +0 -361
  718. package/shared/skills/consistency-patterns/SKILL.md +0 -140
  719. package/shared/skills/consistency-patterns/references/detection.md +0 -207
  720. package/shared/skills/consistency-patterns/references/patterns.md +0 -202
  721. package/shared/skills/consistency-patterns/references/violations.md +0 -213
  722. package/shared/skills/core-patterns/SKILL.md +0 -162
  723. package/shared/skills/core-patterns/references/checklist.md +0 -276
  724. package/shared/skills/core-patterns/references/code-smell-violations.md +0 -144
  725. package/shared/skills/core-patterns/references/detection.md +0 -303
  726. package/shared/skills/core-patterns/references/patterns.md +0 -576
  727. package/shared/skills/core-patterns/references/violations.md +0 -369
  728. package/shared/skills/database-patterns/SKILL.md +0 -134
  729. package/shared/skills/database-patterns/references/detection.md +0 -208
  730. package/shared/skills/database-patterns/references/patterns.md +0 -394
  731. package/shared/skills/database-patterns/references/violations.md +0 -332
  732. package/shared/skills/debug-orchestration/SKILL.md +0 -69
  733. package/shared/skills/dependencies-patterns/SKILL.md +0 -141
  734. package/shared/skills/dependencies-patterns/references/detection.md +0 -181
  735. package/shared/skills/dependencies-patterns/references/patterns.md +0 -225
  736. package/shared/skills/dependencies-patterns/references/violations.md +0 -247
  737. package/shared/skills/docs-framework/SKILL.md +0 -143
  738. package/shared/skills/docs-framework/references/patterns.md +0 -346
  739. package/shared/skills/docs-framework/references/violations.md +0 -221
  740. package/shared/skills/documentation-patterns/SKILL.md +0 -125
  741. package/shared/skills/documentation-patterns/references/detection.md +0 -190
  742. package/shared/skills/documentation-patterns/references/patterns.md +0 -189
  743. package/shared/skills/documentation-patterns/references/violations.md +0 -163
  744. package/shared/skills/frontend-design/SKILL.md +0 -254
  745. package/shared/skills/frontend-design/references/detection.md +0 -184
  746. package/shared/skills/frontend-design/references/patterns.md +0 -511
  747. package/shared/skills/frontend-design/references/violations.md +0 -453
  748. package/shared/skills/git-safety/SKILL.md +0 -122
  749. package/shared/skills/git-safety/references/detection.md +0 -290
  750. package/shared/skills/git-safety/references/patterns.md +0 -289
  751. package/shared/skills/git-safety/references/violations.md +0 -18
  752. package/shared/skills/git-workflow/SKILL.md +0 -158
  753. package/shared/skills/git-workflow/references/commit-patterns.md +0 -115
  754. package/shared/skills/git-workflow/references/commit-violations.md +0 -77
  755. package/shared/skills/git-workflow/references/pr-patterns.md +0 -127
  756. package/shared/skills/git-workflow/references/pr-violations.md +0 -96
  757. package/shared/skills/github-patterns/SKILL.md +0 -153
  758. package/shared/skills/github-patterns/references/patterns.md +0 -572
  759. package/shared/skills/github-patterns/references/violations.md +0 -298
  760. package/shared/skills/go/SKILL.md +0 -187
  761. package/shared/skills/go/references/concurrency.md +0 -312
  762. package/shared/skills/go/references/detection.md +0 -129
  763. package/shared/skills/go/references/patterns.md +0 -232
  764. package/shared/skills/go/references/violations.md +0 -205
  765. package/shared/skills/implementation-orchestration/SKILL.md +0 -92
  766. package/shared/skills/implementation-patterns/SKILL.md +0 -162
  767. package/shared/skills/implementation-patterns/references/patterns.md +0 -1063
  768. package/shared/skills/implementation-patterns/references/violations.md +0 -483
  769. package/shared/skills/input-validation/SKILL.md +0 -148
  770. package/shared/skills/input-validation/references/detection.md +0 -283
  771. package/shared/skills/input-validation/references/patterns.md +0 -361
  772. package/shared/skills/input-validation/references/violations.md +0 -224
  773. package/shared/skills/java/SKILL.md +0 -183
  774. package/shared/skills/java/references/detection.md +0 -120
  775. package/shared/skills/java/references/modern-java.md +0 -270
  776. package/shared/skills/java/references/patterns.md +0 -235
  777. package/shared/skills/java/references/violations.md +0 -213
  778. package/shared/skills/knowledge-persistence/SKILL.md +0 -128
  779. package/shared/skills/knowledge-persistence/references/examples.md +0 -44
  780. package/shared/skills/performance-patterns/SKILL.md +0 -154
  781. package/shared/skills/performance-patterns/references/detection.md +0 -351
  782. package/shared/skills/performance-patterns/references/patterns.md +0 -503
  783. package/shared/skills/performance-patterns/references/violations.md +0 -354
  784. package/shared/skills/plan-orchestration/SKILL.md +0 -71
  785. package/shared/skills/python/SKILL.md +0 -188
  786. package/shared/skills/python/references/async.md +0 -220
  787. package/shared/skills/python/references/detection.md +0 -128
  788. package/shared/skills/python/references/patterns.md +0 -226
  789. package/shared/skills/python/references/violations.md +0 -204
  790. package/shared/skills/react/SKILL.md +0 -276
  791. package/shared/skills/react/references/patterns.md +0 -1331
  792. package/shared/skills/react/references/violations.md +0 -565
  793. package/shared/skills/regression-patterns/SKILL.md +0 -146
  794. package/shared/skills/regression-patterns/references/detection.md +0 -237
  795. package/shared/skills/regression-patterns/references/patterns.md +0 -226
  796. package/shared/skills/regression-patterns/references/violations.md +0 -225
  797. package/shared/skills/review-methodology/SKILL.md +0 -119
  798. package/shared/skills/review-methodology/references/patterns.md +0 -186
  799. package/shared/skills/review-methodology/references/report-template.md +0 -142
  800. package/shared/skills/review-methodology/references/violations.md +0 -125
  801. package/shared/skills/rust/SKILL.md +0 -193
  802. package/shared/skills/rust/references/detection.md +0 -131
  803. package/shared/skills/rust/references/ownership.md +0 -242
  804. package/shared/skills/rust/references/patterns.md +0 -210
  805. package/shared/skills/rust/references/violations.md +0 -191
  806. package/shared/skills/search-first/SKILL.md +0 -133
  807. package/shared/skills/search-first/references/evaluation-criteria.md +0 -101
  808. package/shared/skills/security-patterns/SKILL.md +0 -156
  809. package/shared/skills/security-patterns/references/detection.md +0 -287
  810. package/shared/skills/security-patterns/references/patterns.md +0 -507
  811. package/shared/skills/security-patterns/references/violations.md +0 -237
  812. package/shared/skills/self-review/SKILL.md +0 -149
  813. package/shared/skills/self-review/references/patterns.md +0 -405
  814. package/shared/skills/self-review/references/report-template.md +0 -253
  815. package/shared/skills/self-review/references/stub-detection.md +0 -135
  816. package/shared/skills/self-review/references/violations.md +0 -308
  817. package/shared/skills/test-driven-development/SKILL.md +0 -137
  818. package/shared/skills/test-driven-development/references/rationalization-prevention.md +0 -111
  819. package/shared/skills/test-patterns/SKILL.md +0 -183
  820. package/shared/skills/test-patterns/references/detection.md +0 -149
  821. package/shared/skills/test-patterns/references/patterns.md +0 -220
  822. package/shared/skills/test-patterns/references/report-template.md +0 -108
  823. package/shared/skills/test-patterns/references/violations.md +0 -221
  824. package/shared/skills/typescript/SKILL.md +0 -176
  825. package/shared/skills/typescript/references/patterns.md +0 -1105
  826. package/shared/skills/typescript/references/violations.md +0 -433
  827. package/src/templates/claudeignore.template +0 -188
  828. package/src/templates/settings.json +0 -59
  829. /package/dist/{utils → core}/safe-delete.js +0 -0
  830. /package/{plugins/devflow-accessibility → src/assets}/skills/accessibility/references/detection.md +0 -0
  831. /package/{plugins/devflow-code-review/skills/architecture-patterns → src/assets/skills/architecture}/references/detection.md +0 -0
  832. /package/{plugins/devflow-code-review/skills/complexity-patterns → src/assets/skills/complexity}/references/detection.md +0 -0
  833. /package/{plugins/devflow-code-review/skills/complexity-patterns → src/assets/skills/complexity}/references/patterns.md +0 -0
  834. /package/{plugins/devflow-code-review/skills/complexity-patterns → src/assets/skills/complexity}/references/violations.md +0 -0
  835. /package/{plugins/devflow-code-review/skills/consistency-patterns → src/assets/skills/consistency}/references/detection.md +0 -0
  836. /package/{plugins/devflow-code-review/skills/consistency-patterns → src/assets/skills/consistency}/references/patterns.md +0 -0
  837. /package/{plugins/devflow-code-review/skills/consistency-patterns → src/assets/skills/consistency}/references/violations.md +0 -0
  838. /package/{plugins/devflow-code-review/skills/database-patterns → src/assets/skills/database}/references/detection.md +0 -0
  839. /package/{plugins/devflow-code-review/skills/database-patterns → src/assets/skills/database}/references/patterns.md +0 -0
  840. /package/{plugins/devflow-code-review/skills/database-patterns → src/assets/skills/database}/references/violations.md +0 -0
  841. /package/{plugins/devflow-code-review/skills/dependencies-patterns → src/assets/skills/dependencies}/references/detection.md +0 -0
  842. /package/{plugins/devflow-code-review/skills/dependencies-patterns → src/assets/skills/dependencies}/references/patterns.md +0 -0
  843. /package/{plugins/devflow-code-review/skills/dependencies-patterns → src/assets/skills/dependencies}/references/violations.md +0 -0
  844. /package/{plugins/devflow-code-review/skills/documentation-patterns → src/assets/skills/documentation}/references/detection.md +0 -0
  845. /package/{plugins/devflow-code-review/skills/documentation-patterns → src/assets/skills/documentation}/references/patterns.md +0 -0
  846. /package/{plugins/devflow-code-review/skills/documentation-patterns → src/assets/skills/documentation}/references/violations.md +0 -0
  847. /package/{plugins/devflow-core-skills/skills/git-safety → src/assets/skills/git}/references/detection.md +0 -0
  848. /package/{plugins/devflow-go → src/assets}/skills/go/references/detection.md +0 -0
  849. /package/{plugins/devflow-java → src/assets}/skills/java/references/detection.md +0 -0
  850. /package/{plugins/devflow-implement/skills/implementation-patterns → src/assets/skills/patterns}/references/patterns.md +0 -0
  851. /package/{plugins/devflow-implement/skills/implementation-patterns → src/assets/skills/patterns}/references/violations.md +0 -0
  852. /package/{plugins/devflow-code-review/skills/performance-patterns → src/assets/skills/performance}/references/detection.md +0 -0
  853. /package/{plugins/devflow-python → src/assets}/skills/python/references/detection.md +0 -0
  854. /package/{plugins/devflow-implement/skills/self-review → src/assets/skills/quality-gates}/references/patterns.md +0 -0
  855. /package/{plugins/devflow-implement/skills/self-review → src/assets/skills/quality-gates}/references/report-template.md +0 -0
  856. /package/{plugins/devflow-implement/skills/self-review → src/assets/skills/quality-gates}/references/violations.md +0 -0
  857. /package/{plugins/devflow-code-review/skills/regression-patterns → src/assets/skills/regression}/references/detection.md +0 -0
  858. /package/{plugins/devflow-code-review/skills/regression-patterns → src/assets/skills/regression}/references/patterns.md +0 -0
  859. /package/{plugins/devflow-code-review/skills/regression-patterns → src/assets/skills/regression}/references/violations.md +0 -0
  860. /package/{plugins/devflow-rust → src/assets}/skills/rust/references/detection.md +0 -0
  861. /package/{plugins/devflow-code-review/skills/security-patterns → src/assets/skills/security}/references/detection.md +0 -0
  862. /package/{plugins/devflow-core-skills/skills/core-patterns → src/assets/skills/software-design}/references/detection.md +0 -0
  863. /package/{plugins/devflow-core-skills → src/assets}/skills/test-driven-development/references/rationalization-prevention.md +0 -0
  864. /package/{plugins/devflow-code-review/skills/test-patterns → src/assets/skills/testing}/references/detection.md +0 -0
  865. /package/{plugins/devflow-code-review/skills/test-patterns → src/assets/skills/testing}/references/report-template.md +0 -0
  866. /package/{plugins/devflow-frontend-design/skills/frontend-design → src/assets/skills/ui-design}/references/detection.md +0 -0
  867. /package/src/{templates → targets/claude-code/templates}/managed-settings.json +0 -0
@@ -0,0 +1,1214 @@
1
+ import { Command } from 'commander';
2
+ import { promises as fs } from 'fs';
3
+ import * as os from 'os';
4
+ import * as path from 'path';
5
+ import * as p from '@clack/prompts';
6
+ import color from 'picocolors';
7
+ import { getInstallationPaths, getClaudeDirectory, getManagedSettingsPath } from '../../targets/claude-code/claude-paths.js';
8
+ import { getGitRoot } from '../../core/git.js';
9
+ import { DEVFLOW_PLUGINS, SKILL_NAMESPACE, getAllSkillNames, getAllAgentNames, getAllCommandNames, parsePluginSelection, resolveFeatureRedirect, prefixSkillName, unprefixSkillName, FEATURE_OWNED_SKILLS } from '../../core/plugins.js';
10
+ import { sweepOrphanedAssets, mdFileName, mdEntryName } from '../../core/orphan-sweep.js';
11
+ import { LEGACY_SKILL_NAMES } from '../../targets/claude-code/legacy.js';
12
+ import { removeAmbientHook } from './ambient.js';
13
+ import { removeMemoryHooks } from './memory.js';
14
+ import { removeCaptureHooks } from './capture.js';
15
+ import { removeDreamHook } from './legacy-hooks.js';
16
+ import { removeHudStatusLine } from './hud.js';
17
+ import { removeContextHook } from './context.js';
18
+ import { applyDisableToSettings } from './proxy.js';
19
+ import { readProxyState, DEFAULT_PROXY_PORT } from '../../core/proxy-state.js';
20
+ import { hudCacheDir } from '../../core/cache.js';
21
+ import { revertExternalAgents } from '../../core/agent-models.js';
22
+ import { detectShell, getProfilePath } from '../../core/safe-delete.js';
23
+ import { isAlreadyInstalled, removeFromProfile } from '../../core/safe-delete-install.js';
24
+ import { removeManagedSettings, stripUserDenyList, detectDenyState, DEVFLOW_HISTORICAL_DENY } from '../../targets/claude-code/post-install.js';
25
+ import { writeFileAtomicExclusive } from '../../core/fs-atomic.js';
26
+ import { stripFlags, stripViewMode } from '../../core/flags.js';
27
+ import { stripDevflowTeammateModeFromJson } from '../../core/teammate-mode-cleanup.js';
28
+ import { getPackageRoot, isContainedIn } from '../../core/paths.js';
29
+ /**
30
+ * Compute which assets should be removed during selective plugin uninstall.
31
+ * Skills and agents shared by remaining plugins are retained.
32
+ * Rules shared by remaining plugins are also retained.
33
+ */
34
+ export function computeAssetsToRemove(selectedPlugins, allPlugins) {
35
+ const selectedNames = new Set(selectedPlugins.map(p => p.name));
36
+ const remainingPlugins = allPlugins.filter(p => !selectedNames.has(p.name));
37
+ const retainedSkills = new Set();
38
+ const retainedAgents = new Set();
39
+ const retainedRules = new Set();
40
+ for (const rp of remainingPlugins) {
41
+ for (const s of rp.skills)
42
+ retainedSkills.add(s);
43
+ for (const a of rp.agents)
44
+ retainedAgents.add(a);
45
+ for (const r of rp.rules)
46
+ retainedRules.add(r);
47
+ }
48
+ const skills = [];
49
+ const agents = [];
50
+ const commands = [];
51
+ const rules = [];
52
+ for (const plugin of selectedPlugins) {
53
+ for (const skill of plugin.skills) {
54
+ if (!retainedSkills.has(skill))
55
+ skills.push(skill);
56
+ }
57
+ for (const agent of plugin.agents) {
58
+ if (!retainedAgents.has(agent))
59
+ agents.push(agent);
60
+ }
61
+ for (const rule of plugin.rules) {
62
+ if (!retainedRules.has(rule))
63
+ rules.push(rule);
64
+ }
65
+ commands.push(...plugin.commands);
66
+ }
67
+ return { skills, agents, commands, rules };
68
+ }
69
+ /**
70
+ * Format a dry-run plan showing what would be removed.
71
+ * Pure function — no I/O, fully testable.
72
+ */
73
+ export function formatDryRunPlan(assets) {
74
+ const skills = [...new Set(assets.skills)];
75
+ const agents = [...new Set(assets.agents)];
76
+ const commands = [...new Set(assets.commands)];
77
+ const rules = [...new Set(assets.rules ?? [])];
78
+ const hasAssets = skills.length > 0 || agents.length > 0 || commands.length > 0 || rules.length > 0;
79
+ if (!hasAssets) {
80
+ return 'Nothing to remove.';
81
+ }
82
+ const lines = [];
83
+ if (skills.length > 0)
84
+ lines.push(`Skills (${skills.length}): ${skills.join(', ')}`);
85
+ if (agents.length > 0)
86
+ lines.push(`Agents (${agents.length}): ${agents.join(', ')}`);
87
+ if (commands.length > 0)
88
+ lines.push(`Commands (${commands.length}): ${commands.join(', ')}`);
89
+ if (rules.length > 0)
90
+ lines.push(`Rules (${rules.length}): ${rules.join(', ')}`);
91
+ return lines.join('\n');
92
+ }
93
+ /**
94
+ * Determine whether the security deny list should prompt for removal in an
95
+ * interactive session, and what the non-interactive default is.
96
+ *
97
+ * PURE — no I/O, fully testable.
98
+ *
99
+ * Safety invariant: non-interactive mode NEVER removes the deny list
100
+ * (protective-by-default). `keepDocs` suppresses the entire section.
101
+ *
102
+ * Returns:
103
+ * - "skip" — nothing present, or keepDocs is set; no action needed
104
+ * - "preserve" — non-interactive (isTTY=false); deny list preserved
105
+ * - "prompt" — interactive (isTTY=true); caller should ask the user
106
+ *
107
+ * @D1 Non-interactive-preserve invariant: when isTTY is false the result is
108
+ * always "preserve", never "prompt" — avoids PF-004 half-applied-state hazard.
109
+ */
110
+ export function resolveSecurityRemovalDecision(opts) {
111
+ if (!opts.anySecurityPresent || opts.keepDocs)
112
+ return 'skip';
113
+ if (!opts.isTTY)
114
+ return 'preserve';
115
+ return 'prompt';
116
+ }
117
+ /**
118
+ * Resolve the answer from a Clack confirm prompt for the .devflow/ project data
119
+ * removal question into a boolean removal decision.
120
+ *
121
+ * A cancel (user presses Ctrl-C on this prompt) is treated as decline: the
122
+ * .devflow/ directory is preserved and the uninstall continues with the remaining
123
+ * steps rather than aborting via process.exit() (applies PF-014, applies ADR-003).
124
+ *
125
+ * PURE — no I/O, fully testable.
126
+ *
127
+ * @param answer - The value returned by p.confirm(): boolean or a cancel symbol.
128
+ * @returns true only when the user explicitly confirmed removal.
129
+ */
130
+ export function resolveProjectDataCleanup(answer) {
131
+ return answer === true;
132
+ }
133
+ /**
134
+ * Determine the appropriate cleanup action for the user-scope devflow directory on
135
+ * full uninstall. Mirrors the resolveSecurityRemovalDecision pattern.
136
+ *
137
+ * PURE — no I/O, no side effects, fully testable. All decision logic lives here;
138
+ * the .action() caller performs I/O and prompt rendering only.
139
+ *
140
+ * Safety invariants checked as preconditions (guard fires → 'artifacts-only'):
141
+ * 1. basename(devflowDir) must be '.devflow'
142
+ * 2. devflowDir must not equal homeDir
143
+ * 3. devflowDir must not be the filesystem root '/'
144
+ * 4. devflowDir must reside inside $HOME (guards DEVFLOW_DIR env overrides)
145
+ *
146
+ * Returns:
147
+ * - 'artifacts-only' — remove only manifest.json; leave the directory intact
148
+ * - 'prompt' — interactive session with user-authored content; caller should ask
149
+ *
150
+ * @D5 Precondition guard: any anomalous devflowDir falls back to 'artifacts-only' rather
151
+ * than throwing — business logic must not throw (engineering rule). The explicit guard
152
+ * makes the invariant present in production code, not only in tests (reliability rule).
153
+ * @D6 avoids PF-014: the caller must NOT process.exit() after a cancel/decline response;
154
+ * removeAllDevFlow has already run by the time the prompt fires, so removeDevFlowInstallArtifacts
155
+ * must execute on every non-confirm path to leave a clean end-state (applies ADR-003).
156
+ * @D7 keepDocs gate: when the caller passes --keep-docs, the entire ~/.devflow dir cleanup
157
+ * prompt is suppressed — artifacts-only regardless of isTTY or userContent. This prevents
158
+ * --keep-docs from triggering prompts about skill shadows or preference-profile.md.
159
+ */
160
+ export function resolveDevflowDirCleanup(opts) {
161
+ // Local scope never removes project data — only install artifacts.
162
+ if (opts.scope !== 'user')
163
+ return 'artifacts-only';
164
+ // --keep-docs: suppress the full cleanup prompt entirely; artifacts-only.
165
+ if (opts.keepDocs)
166
+ return 'artifacts-only';
167
+ // Precondition guard: devflowDir must be a well-known, safe-to-rm path.
168
+ // Any anomalous value (DEVFLOW_DIR override, bare homedir, filesystem root)
169
+ // resolves to artifacts-only — never throw in business logic (engineering rule).
170
+ const isBasenameValid = path.basename(opts.devflowDir) === '.devflow';
171
+ const isNotHomeDir = opts.devflowDir !== opts.homeDir;
172
+ const isNotRoot = opts.devflowDir !== '/';
173
+ const isInsideHome = opts.devflowDir.startsWith(opts.homeDir + path.sep);
174
+ if (!isBasenameValid || !isNotHomeDir || !isNotRoot || !isInsideHome) {
175
+ return 'artifacts-only';
176
+ }
177
+ // Non-interactive: never prompt for or perform full-dir removal.
178
+ if (!opts.isTTY)
179
+ return 'artifacts-only';
180
+ // No user-authored content: nothing to warn about; artifacts-only without prompting.
181
+ if (opts.userContent.length === 0)
182
+ return 'artifacts-only';
183
+ return 'prompt';
184
+ }
185
+ /**
186
+ * Enumerate user-authored content in devflowDir that would be deleted by a
187
+ * full cleanup of the directory.
188
+ *
189
+ * Checks for items that exist on disk and are worth backing up:
190
+ * devflowDir/skills/ — skill shadow overrides (user-maintained)
191
+ * devflowDir/rules/ — rule shadow overrides (user-maintained)
192
+ * devflowDir/preference-profile.md — dynamic-plan preference profile
193
+ * devflowDir/learning.json — global learning agent tuning config
194
+ * devflowDir/hud.json — HUD enable/disable preference and display config
195
+ *
196
+ * NOT listed here: agent-models.json — reclassified as an INSTALL ARTIFACT (AC-P1-F4).
197
+ * Stale per-agent model overrides silently re-apply to renamed/deleted agents on reinstall,
198
+ * so it must be cleaned up by removeDevFlowInstallArtifacts, not preserved behind a confirm gate.
199
+ *
200
+ * Returns labels for each item that actually exists. Empty array means nothing
201
+ * user-authored is present in the directory.
202
+ *
203
+ * Pure I/O — no side effects, no output, fully testable.
204
+ *
205
+ * @D4 Called BEFORE any removal so shadow state is captured from real disk.
206
+ * Avoids the anti-pattern of checking existence after files are removed.
207
+ */
208
+ export async function enumerateUserDevFlowContent(devflowDir) {
209
+ const items = [];
210
+ // Skill shadow overrides (~/.devflow/skills/{name}/)
211
+ try {
212
+ const entries = await fs.readdir(path.join(devflowDir, 'skills'));
213
+ if (entries.length > 0) {
214
+ items.push(`skill shadows (${path.join(devflowDir, 'skills')})`);
215
+ }
216
+ }
217
+ catch { /* dir absent or unreadable */ }
218
+ // Rule shadow overrides (~/.devflow/rules/{name}.md)
219
+ try {
220
+ const entries = await fs.readdir(path.join(devflowDir, 'rules'));
221
+ if (entries.length > 0) {
222
+ items.push(`rule shadows (${path.join(devflowDir, 'rules')})`);
223
+ }
224
+ }
225
+ catch { /* dir absent or unreadable */ }
226
+ // preference-profile.md — user-curated decision-preference profile
227
+ try {
228
+ await fs.access(path.join(devflowDir, 'preference-profile.md'));
229
+ items.push('preference-profile.md');
230
+ }
231
+ catch { /* absent */ }
232
+ // learning.json — global learning agent tuning config
233
+ try {
234
+ await fs.access(path.join(devflowDir, 'learning.json'));
235
+ items.push('learning.json');
236
+ }
237
+ catch { /* absent */ }
238
+ // hud.json — user HUD enable/disable preference and display config
239
+ try {
240
+ await fs.access(path.join(devflowDir, 'hud.json'));
241
+ items.push('hud.json (HUD configuration)');
242
+ }
243
+ catch { /* absent */ }
244
+ return items;
245
+ }
246
+ /**
247
+ * Single source of truth for Devflow-owned install artifacts under `devflowDir`.
248
+ *
249
+ * Returns the paths that the artifact-removal loop inside `removeDevFlowInstallArtifacts`
250
+ * removes. Note: manifest.json is removed by a separate step at the top of that
251
+ * function and is NOT in this list. Having this as a standalone pure function
252
+ * lets callers (dry-run display, tests) enumerate the artifact set without
253
+ * duplicating the list.
254
+ *
255
+ * @D8 Nothing returned here may overlap with the items enumerated by
256
+ * `enumerateUserDevFlowContent` — the disjointness invariant is tested by test 9f
257
+ * and enforced by keeping both lists in one place.
258
+ *
259
+ * @param devflowDir - Absolute path to ~/.devflow (used to resolve cache dir).
260
+ */
261
+ export function installArtifactPaths(devflowDir) {
262
+ return [
263
+ // migration run-state — removed so migrations re-run cleanly on reinstall
264
+ { relPath: 'migrations.json' },
265
+ // per-agent model overrides — removed so stale keys (keyed to renamed/deleted agents
266
+ // from the wave-4 agent roster rename) cannot silently re-apply on reinstall (AC-P1-F4)
267
+ { relPath: 'agent-models.json' },
268
+ // cost history — auto-generated session telemetry, not user-authored.
269
+ // The whole costs/ tree is removed so sessions/ and archive.jsonl cannot
270
+ // drift from their write sites in src/hud/cost-history.ts (avoids PF-013).
271
+ { relPath: 'costs', isDir: true },
272
+ // proxy artifacts
273
+ { relPath: 'proxy.json' },
274
+ { relPath: 'proxy-routing.json' },
275
+ { relPath: 'proxy.pid' },
276
+ { relPath: '.proxy-spawn.lock', isDir: true },
277
+ // per-project hook logs (logs/{project-slug}/) AND global logs — remove the
278
+ // whole logs/ tree; covers proxy.log, debug logs, and any project-slug dirs.
279
+ { relPath: 'logs', isDir: true },
280
+ // Model-discovery + HUD component caches. hudCacheDir() is the authoritative
281
+ // accessor for the cache/ parent (modelCacheDir() resolves beneath it), so the
282
+ // removal site stays byte-locked to the write sites (avoids PF-013).
283
+ { relPath: path.relative(devflowDir, hudCacheDir(devflowDir)), isDir: true },
284
+ ];
285
+ }
286
+ /**
287
+ * Remove Devflow install artifacts from devflowDir: manifest.json, migrations.json,
288
+ * proxy artifacts, logs/, costs/, and cache/.
289
+ * The scripts/ directory is already removed by removeAllDevFlow.
290
+ *
291
+ * Used for:
292
+ * - Local scope (always — never removes project data under .devflow/)
293
+ * - User scope when full-dir confirm is declined or session is non-interactive
294
+ *
295
+ * @D8 Nothing enumerated by enumerateUserDevFlowContent may appear in this list.
296
+ * This function runs on the decline, cancel, non-interactive AND --keep-docs paths,
297
+ * so an entry here is deleted even when the user answers "no" to the full wipe.
298
+ * User-authored state (skill/rule shadows, preference-profile.md, learning.json,
299
+ * hud.json) is removed only by the confirmed full-dir rm.
300
+ * agent-models.json is an INSTALL ARTIFACT (stale per-agent overrides silently
301
+ * re-apply to renamed/deleted agents on reinstall — AC-P1-F4) and therefore
302
+ * belongs in this list, not in enumerateUserDevFlowContent.
303
+ */
304
+ export async function removeDevFlowInstallArtifacts(devflowDir, verbose) {
305
+ const manifestPath = path.join(devflowDir, 'manifest.json');
306
+ try {
307
+ await fs.rm(manifestPath, { force: true });
308
+ if (verbose) {
309
+ p.log.success('Removed manifest.json');
310
+ }
311
+ }
312
+ catch (error) {
313
+ p.log.warn(`Could not remove manifest.json: ${error}`);
314
+ }
315
+ // Proxy install artifacts — remove non-fatally (per-item failure isolation, avoids PF-009)
316
+ // Inform the user if a proxy relay process is still running (never kill — informational only).
317
+ try {
318
+ const pidContent = await fs.readFile(path.join(devflowDir, 'proxy.pid'), 'utf-8');
319
+ const pid = parseInt(pidContent.trim(), 10);
320
+ if (!isNaN(pid) && pid > 0) {
321
+ try {
322
+ process.kill(pid, 0); // existence check — throws if process is gone
323
+ p.log.warn(`Proxy relay process (PID ${pid}) is still running — it will exit when ` +
324
+ `Claude Code closes, or stop it manually: kill ${pid}`);
325
+ }
326
+ catch { /* process is gone — nothing to report */ }
327
+ }
328
+ }
329
+ catch { /* proxy.pid absent or unreadable — non-fatal */ }
330
+ // All install artifacts removed non-fatally (avoids PF-009).
331
+ for (const artifact of installArtifactPaths(devflowDir)) {
332
+ const fullPath = path.join(devflowDir, artifact.relPath);
333
+ // Containment invariant: every artifact must resolve to a path STRICTLY inside
334
+ // devflowDir. A derived relPath that ever collapsed to '' or '..' would turn the
335
+ // recursive rm below into a wipe of devflowDir itself (or an ancestor). Asserting
336
+ // it in production code — not only in tests — keeps the invariant load-bearing
337
+ // (reliability rule) and never throws (engineering rule).
338
+ if (!isContainedIn(devflowDir, artifact.relPath)) {
339
+ continue;
340
+ }
341
+ try {
342
+ await fs.rm(fullPath, { force: true, recursive: artifact.isDir === true });
343
+ if (verbose)
344
+ p.log.success(`Removed ${artifact.relPath}`);
345
+ }
346
+ catch { /* absent or unreadable — non-fatal */ }
347
+ }
348
+ }
349
+ /**
350
+ * Check if Devflow is installed at the given claudeDir by detecting any
351
+ * owned namespace: commands/devflow/, agents/devflow/, or any skill dir
352
+ * whose name starts with the devflow: namespace prefix.
353
+ *
354
+ * Keying off commands/devflow/ alone misses installs where the user selected
355
+ * a commandless plugin set — agents and skills may still be present.
356
+ */
357
+ export async function isDevFlowInstalled(claudeDir) {
358
+ // Check commands namespace
359
+ try {
360
+ await fs.access(path.join(claudeDir, 'commands', 'devflow'));
361
+ return true;
362
+ }
363
+ catch { /* not present */ }
364
+ // Check agents namespace
365
+ try {
366
+ await fs.access(path.join(claudeDir, 'agents', 'devflow'));
367
+ return true;
368
+ }
369
+ catch { /* not present */ }
370
+ // Check for any installed skill under the devflow: namespace
371
+ try {
372
+ const entries = await fs.readdir(path.join(claudeDir, 'skills'));
373
+ if (entries.some(e => e.startsWith(SKILL_NAMESPACE)))
374
+ return true;
375
+ }
376
+ catch { /* skills dir absent or unreadable */ }
377
+ return false;
378
+ }
379
+ // ---------------------------------------------------------------------------
380
+ // Phase runners — extracted from the action function for readability and
381
+ // independent testability. Each covers one logical stage of the uninstall.
382
+ // ---------------------------------------------------------------------------
383
+ /**
384
+ * Enumerate paths that would be removed by a full uninstall for the given
385
+ * scope directories, intersected with what actually exists on disk.
386
+ *
387
+ * Extracted from the dry-run loop body so the enumeration logic is
388
+ * independently testable (avoids PF-018: tests must exercise the production
389
+ * path, not only the pure helper functions).
390
+ *
391
+ * Coverage matches removeAllDevFlow exactly:
392
+ * 1. Whole Claude directories (commands/devflow, agents/devflow, rules/devflow)
393
+ * and the scripts directory inside devflowDir.
394
+ * 2. ALL skill removal candidates (existence-filtered):
395
+ * - Prefixed (devflow:name): live registry ∪ LEGACY_SKILL_NAMES.
396
+ * - Bare (name or devflow-name legacy): LEGACY_SKILL_NAMES ONLY.
397
+ * ~/.claude/skills/ is shared; bare dirs for live-registry skill names
398
+ * are by construction foreign to Devflow (avoids PF-012).
399
+ * 3. manifest.json (removed separately in removeDevFlowInstallArtifacts).
400
+ * 4. Every artifact path from installArtifactPaths(devflowDir) — the single
401
+ * source of truth shared with the real removal loop.
402
+ *
403
+ * @param claudeDir - Target Claude Code directory (e.g. ~/.claude)
404
+ * @param devflowDir - Devflow data directory (e.g. ~/.devflow)
405
+ */
406
+ export async function enumerateDryRunExtras(claudeDir, devflowDir) {
407
+ const extras = [];
408
+ // 1. Whole directories removed by removeAllDevFlow
409
+ for (const dir of [
410
+ path.join(claudeDir, 'commands', 'devflow'),
411
+ path.join(claudeDir, 'agents', 'devflow'),
412
+ path.join(claudeDir, 'rules', 'devflow'),
413
+ path.join(devflowDir, 'scripts'),
414
+ ]) {
415
+ try {
416
+ await fs.access(dir);
417
+ extras.push(dir);
418
+ }
419
+ catch { /* absent */ }
420
+ }
421
+ // 2. Skills: enumerate ALL removal candidates that exist on disk.
422
+ // Mirrors removeAllDevFlow's split-pass approach (avoids PF-012 + PF-018):
423
+ // Prefixed: live registry ∪ LEGACY_SKILL_NAMES ∪ FEATURE_OWNED_SKILLS
424
+ // Bare: LEGACY_SKILL_NAMES only — shared skills/ dir; live-registry bare
425
+ // dirs are by construction foreign to Devflow.
426
+ // FEATURE_OWNED_SKILLS (compliance) is included so full uninstall removes
427
+ // devflow:compliance even though it left the plugin registry (step 1.5).
428
+ const prefixedSkillNames = new Set([...getAllSkillNames(), ...LEGACY_SKILL_NAMES, ...FEATURE_OWNED_SKILLS]);
429
+ const skillsDir = path.join(claudeDir, 'skills');
430
+ for (const skillName of prefixedSkillNames) {
431
+ const prefixedPath = path.join(skillsDir, prefixSkillName(skillName));
432
+ try {
433
+ await fs.access(prefixedPath);
434
+ extras.push(prefixedPath);
435
+ }
436
+ catch { /* absent */ }
437
+ }
438
+ for (const skillName of LEGACY_SKILL_NAMES) {
439
+ const barePath = path.join(skillsDir, skillName);
440
+ try {
441
+ await fs.access(barePath);
442
+ extras.push(barePath);
443
+ }
444
+ catch { /* absent */ }
445
+ }
446
+ // 3. manifest.json — removed separately by removeDevFlowInstallArtifacts
447
+ // (NOT in installArtifactPaths). List it here so the preview is complete.
448
+ const manifestPath = path.join(devflowDir, 'manifest.json');
449
+ try {
450
+ await fs.access(manifestPath);
451
+ extras.push(manifestPath);
452
+ }
453
+ catch { /* absent */ }
454
+ // 4. All install artifacts — derived from the single source of truth shared
455
+ // with the real removal loop (removeDevFlowInstallArtifacts).
456
+ // Guard with fs.access so files that never existed don't pollute the preview.
457
+ // (F7: previously pushed unconditionally, inflating the dry-run list with
458
+ // paths that were never on disk.)
459
+ for (const artifact of installArtifactPaths(devflowDir)) {
460
+ const fullPath = path.join(devflowDir, artifact.relPath);
461
+ try {
462
+ await fs.access(fullPath);
463
+ extras.push(fullPath);
464
+ }
465
+ catch { /* absent — omit from dry-run preview */ }
466
+ }
467
+ return extras;
468
+ }
469
+ /**
470
+ * DRY-RUN PHASE: display what would be removed without making any changes.
471
+ *
472
+ * Selective: uses the pure registry-diff plan from formatDryRunPlan.
473
+ * Full: enumerates what is actually on disk for each detected scope so the
474
+ * output reflects legacy/orphaned assets that the registry cannot see.
475
+ *
476
+ * @param opts.scopesToUninstall - Scopes detected in the setup phase.
477
+ * @param opts.isSelectiveUninstall - true when --plugin was given.
478
+ * @param opts.selectedPlugins - The plugin subset for selective mode.
479
+ */
480
+ export async function runDryRunPhase(opts) {
481
+ const { scopesToUninstall, isSelectiveUninstall, selectedPlugins } = opts;
482
+ p.log.info(`Scope(s): ${[...scopesToUninstall].join(', ')} (dry-run shows all detected scopes)`);
483
+ if (isSelectiveUninstall) {
484
+ // Selective: compute from registry — this accurately reflects what would be removed.
485
+ const assets = computeAssetsToRemove(selectedPlugins, DEVFLOW_PLUGINS);
486
+ const plan = formatDryRunPlan(assets);
487
+ for (const line of plan.split('\n')) {
488
+ p.log.info(line);
489
+ }
490
+ }
491
+ else {
492
+ // Full uninstall: the real path does rm -rf on entire directories plus a
493
+ // skills sweep. Enumerate what is actually on disk for each detected scope
494
+ // rather than computing from the registry (which misses legacy/orphaned assets).
495
+ const extras = [];
496
+ for (const scope of [...scopesToUninstall]) {
497
+ try {
498
+ const paths = await getInstallationPaths(scope);
499
+ const { claudeDir: cd, devflowDir: dd } = paths;
500
+ const moreExtras = await enumerateDryRunExtras(cd, dd);
501
+ extras.push(...moreExtras);
502
+ }
503
+ catch { /* scope path resolution failed */ }
504
+ }
505
+ // Project .devflow/ data dir
506
+ const devflowDataDir = path.join(process.cwd(), '.devflow');
507
+ try {
508
+ await fs.access(devflowDataDir);
509
+ extras.push(`${devflowDataDir} (if confirmed)`);
510
+ }
511
+ catch { /* noop */ }
512
+ extras.push('hooks removed from settings.json');
513
+ for (const line of extras) {
514
+ p.log.info(` ${line}`);
515
+ }
516
+ }
517
+ }
518
+ /**
519
+ * SELECTIVE PHASE (per scope): revert agent model overrides, remove the
520
+ * selected plugins' assets, and clean up the ambient hook if the ambient
521
+ * plugin is being removed.
522
+ *
523
+ * @param opts.claudeDir - Target Claude Code directory for this scope.
524
+ * @param opts.devflowDir - Devflow data directory for this scope.
525
+ * @param opts.selectedPlugins - Plugin subset to remove.
526
+ * @param opts.verbose - Whether to emit verbose log lines.
527
+ */
528
+ export async function runSelectivePhaseForScope(opts) {
529
+ const { claudeDir, devflowDir, selectedPlugins, verbose } = opts;
530
+ // Revert GPT agent frontmatter BEFORE removing agent files — strips GPT model
531
+ // lines from installed agent frontmatter while the files are still present.
532
+ // Non-fatal: tolerate missing agents dir or revert errors.
533
+ {
534
+ const agentsInstallDir = path.join(claudeDir, 'agents', 'devflow');
535
+ try {
536
+ await fs.access(agentsInstallDir);
537
+ await revertExternalAgents({
538
+ installDir: agentsInstallDir,
539
+ devflowDir,
540
+ onWarning: (msg) => { if (verbose)
541
+ p.log.warn(msg); },
542
+ });
543
+ }
544
+ catch { /* agents dir absent or revert failed — non-fatal */ }
545
+ }
546
+ await removeSelectedPlugins(claudeDir, selectedPlugins, verbose);
547
+ // Clean up ambient hook if ambient plugin is being removed
548
+ if (selectedPlugins.some(sp => sp.name === 'devflow-ambient')) {
549
+ const settingsPath = path.join(claudeDir, 'settings.json');
550
+ try {
551
+ const settings = await fs.readFile(settingsPath, 'utf-8');
552
+ const updated = await removeAmbientHook(settings);
553
+ if (updated !== settings) {
554
+ await fs.writeFile(settingsPath, updated, 'utf-8');
555
+ if (verbose) {
556
+ p.log.success('Ambient mode hooks removed from settings.json');
557
+ }
558
+ }
559
+ }
560
+ catch { /* settings.json may not exist */ }
561
+ }
562
+ }
563
+ /**
564
+ * FULL PHASE (per scope): revert agent model overrides, remove all Devflow
565
+ * assets from the scope, then perform scope-appropriate devflowDir cleanup.
566
+ *
567
+ * Local scope: remove only install artifacts — project data (memory, learning,
568
+ * docs, features) is always preserved under the git root.
569
+ * User scope: interactive TTY with user-authored content → confirm before wiping
570
+ * ~/.devflow/; non-interactive or no user content → artifacts-only.
571
+ *
572
+ * @param opts.scope - 'user' or 'local'.
573
+ * @param opts.claudeDir - Target Claude Code directory for this scope.
574
+ * @param opts.devflowDir - Devflow data directory for this scope.
575
+ * @param opts.devflowScriptsDir - scripts/ sub-directory removed by removeAllDevFlow.
576
+ * @param opts.verbose - Whether to emit verbose log lines.
577
+ * @param opts.keepDocs - When true, suppresses the full-dir prompt (artifacts-only).
578
+ * @param opts.isTTY - Whether the session is interactive. Injected rather than
579
+ * read from process.stdin so the prompt gate is an explicit input (matching
580
+ * resolveDevflowDirCleanup) instead of an ambient global a test cannot control.
581
+ */
582
+ export async function runFullPhaseForScope(opts) {
583
+ const { scope, claudeDir, devflowDir, devflowScriptsDir, verbose, keepDocs, isTTY } = opts;
584
+ // Revert GPT agent frontmatter before removing agents — ensures no orphaned
585
+ // GPT model lines remain if agents dir is preserved by a later partial flow.
586
+ // Non-fatal: tolerate missing agents dir or revert errors.
587
+ {
588
+ const agentsInstallDir = path.join(claudeDir, 'agents', 'devflow');
589
+ try {
590
+ await fs.access(agentsInstallDir);
591
+ await revertExternalAgents({
592
+ installDir: agentsInstallDir,
593
+ devflowDir,
594
+ onWarning: (msg) => { if (verbose)
595
+ p.log.warn(msg); },
596
+ });
597
+ }
598
+ catch { /* agents dir absent or revert failed — non-fatal */ }
599
+ }
600
+ // removeAllDevFlow removes Claude Code assets (commands, agents, rules, skills)
601
+ // and devflowDir/scripts/. Scope-aware cleanup handles the rest of devflowDir.
602
+ await removeAllDevFlow(claudeDir, devflowScriptsDir, verbose);
603
+ if (scope === 'local') {
604
+ // Local scope: devflowDir is gitRoot/.devflow/ which holds project data
605
+ // (memory, learning, features, docs, config.json). Never remove those —
606
+ // only remove install artifacts: scripts/ (done above) + manifest.json and
607
+ // the other Devflow-generated artifacts (see removeDevFlowInstallArtifacts).
608
+ await removeDevFlowInstallArtifacts(devflowDir, verbose);
609
+ p.log.info('Local project data (memory, learning, features, docs) preserved');
610
+ }
611
+ else {
612
+ // User scope (devflowDir = ~/.devflow/): offer full cleanup behind a confirm gate
613
+ // that enumerates user-authored content worth backing up before wiping the dir.
614
+ // Non-interactive, no user content, or precondition guard failure → artifacts-only.
615
+ const userContent = await enumerateUserDevFlowContent(devflowDir);
616
+ const cleanupDecision = resolveDevflowDirCleanup({
617
+ scope: 'user',
618
+ isTTY,
619
+ userContent,
620
+ devflowDir,
621
+ homeDir: os.homedir(),
622
+ keepDocs,
623
+ });
624
+ if (cleanupDecision === 'artifacts-only') {
625
+ await removeDevFlowInstallArtifacts(devflowDir, verbose);
626
+ if (!isTTY && userContent.length > 0) {
627
+ p.log.info(`${devflowDir} preserved (non-interactive mode — removing scripts and install artifacts only)`);
628
+ }
629
+ }
630
+ else {
631
+ // cleanupDecision === 'prompt': interactive session with user-authored content present.
632
+ p.log.info(`User-authored content in ${devflowDir}:`);
633
+ for (const item of userContent) {
634
+ p.log.info(` ${item}`);
635
+ }
636
+ const confirmFullCleanup = await p.confirm({
637
+ message: `Remove entire ${devflowDir}? (includes the items listed above, plus logs and install metadata)`,
638
+ initialValue: false,
639
+ });
640
+ if (p.isCancel(confirmFullCleanup)) {
641
+ // removeAllDevFlow already ran — clean up the manifest to leave a consistent
642
+ // state. avoids PF-014: process.exit() here would skip removeDevFlowInstallArtifacts,
643
+ // leaving a stale manifest.json that points to assets no longer on disk.
644
+ await removeDevFlowInstallArtifacts(devflowDir, verbose);
645
+ p.log.info(`${devflowDir} preserved (full removal cancelled; removing scripts and install artifacts only)`);
646
+ }
647
+ else if (confirmFullCleanup) {
648
+ await fs.rm(devflowDir, { recursive: true, force: true });
649
+ p.log.success(`${devflowDir} removed`);
650
+ }
651
+ else {
652
+ await removeDevFlowInstallArtifacts(devflowDir, verbose);
653
+ p.log.info(`${devflowDir} preserved (removing scripts and install artifacts only)`);
654
+ }
655
+ }
656
+ }
657
+ }
658
+ /**
659
+ * CLEANUP PHASE: post-loop extras run only on full uninstall.
660
+ *
661
+ * Steps (all non-fatal, every interactive path gated on opts.isTTY):
662
+ * 1. .devflow/ project data directory
663
+ * 2. .claudeignore
664
+ * 3. settings.json — remove all Devflow hooks and flags
665
+ * 4. Security deny list
666
+ * 5. Safe-delete shell function
667
+ *
668
+ * This phase touches machine-wide state outside `cwd` — the user's settings.json
669
+ * and shell profile — so both of its ambient inputs are injected: `cwd` (which now
670
+ * also seeds the git-root lookup) and `isTTY`. Reading process.stdin.isTTY directly
671
+ * would leave every destructive prompt gated on a global the caller cannot set,
672
+ * which under a TTY test runner points the prompts at the developer's real files.
673
+ *
674
+ * @param opts.scopesToUninstall - Scopes processed by the scope loop.
675
+ * @param opts.keepDocs - When true, .devflow/ and security prompts are suppressed.
676
+ * @param opts.verbose - Whether to emit verbose log lines.
677
+ * @param opts.cwd - Working directory for project-local path resolution
678
+ * (.devflow/, git root, .claudeignore fallback).
679
+ * @param opts.isTTY - Whether the session is interactive. Every confirm
680
+ * prompt in this phase is gated on it.
681
+ */
682
+ export async function runCleanupPhase(opts) {
683
+ const { scopesToUninstall, keepDocs, verbose, cwd, isTTY } = opts;
684
+ // Resolve the git root from the injected cwd, not process.cwd(): otherwise
685
+ // .devflow/ resolves under `cwd` while .claudeignore resolves under the process
686
+ // directory, and the two halves of this phase act on different repositories.
687
+ const gitRoot = await getGitRoot(cwd);
688
+ // 1. .devflow/ project data directory (contains docs/, memory/, learning/, features/, etc.)
689
+ const devflowDataDir = path.join(cwd, '.devflow');
690
+ let devflowDataExists = false;
691
+ try {
692
+ await fs.access(devflowDataDir);
693
+ devflowDataExists = true;
694
+ }
695
+ catch { /* .devflow doesn't exist */ }
696
+ if (devflowDataExists) {
697
+ let shouldRemoveDevflow = false;
698
+ // Tracks whether a specific "preserved" log was already emitted (e.g. the
699
+ // cancel-path message below) to avoid printing the generic one twice. (F10)
700
+ let preservedLogged = false;
701
+ if (keepDocs) {
702
+ shouldRemoveDevflow = false;
703
+ }
704
+ else if (isTTY) {
705
+ const removeDevflow = await p.confirm({
706
+ message: '.devflow/ directory found. Remove project data (docs, memory, learning)?',
707
+ initialValue: false,
708
+ });
709
+ if (p.isCancel(removeDevflow)) {
710
+ // Treat cancel as decline: preserve .devflow/ and continue cleanup.
711
+ // avoids PF-014: process.exit() here would skip claudeignore, hooks,
712
+ // and safe-delete removal — removeAllDevFlow has already run.
713
+ // applies ADR-003: clean end-state on every path.
714
+ p.log.info('.devflow/ preserved (prompt cancelled — continuing cleanup)');
715
+ preservedLogged = true;
716
+ }
717
+ shouldRemoveDevflow = resolveProjectDataCleanup(removeDevflow);
718
+ }
719
+ if (shouldRemoveDevflow) {
720
+ await fs.rm(devflowDataDir, { recursive: true, force: true });
721
+ p.log.success('.devflow/ removed');
722
+ }
723
+ else if (!preservedLogged) {
724
+ p.log.info('.devflow/ preserved');
725
+ }
726
+ }
727
+ // 2. .claudeignore
728
+ const claudeignorePath = gitRoot
729
+ ? path.join(gitRoot, '.claudeignore')
730
+ : path.join(cwd, '.claudeignore');
731
+ let claudeignoreExists = false;
732
+ try {
733
+ await fs.access(claudeignorePath);
734
+ claudeignoreExists = true;
735
+ }
736
+ catch { /* doesn't exist */ }
737
+ if (claudeignoreExists) {
738
+ if (isTTY) {
739
+ const removeClaudeignore = await p.confirm({
740
+ message: '.claudeignore found. Remove it? (may contain custom rules)',
741
+ initialValue: false,
742
+ });
743
+ if (!p.isCancel(removeClaudeignore) && removeClaudeignore) {
744
+ await fs.rm(claudeignorePath, { force: true });
745
+ p.log.success('.claudeignore removed');
746
+ }
747
+ else {
748
+ p.log.info('.claudeignore preserved');
749
+ }
750
+ }
751
+ else {
752
+ p.log.info('.claudeignore preserved (non-interactive mode)');
753
+ }
754
+ }
755
+ // 3. settings.json (Devflow hooks)
756
+ for (const scope of [...scopesToUninstall]) {
757
+ try {
758
+ const paths = await getInstallationPaths(scope);
759
+ const settingsPath = path.join(paths.claudeDir, 'settings.json');
760
+ const originalContent = await fs.readFile(settingsPath, 'utf-8');
761
+ // Remove all Devflow hooks and flags in one pass (idempotent)
762
+ let settingsContent = await removeAmbientHook(originalContent);
763
+ settingsContent = removeMemoryHooks(settingsContent);
764
+ settingsContent = removeCaptureHooks(settingsContent);
765
+ settingsContent = removeDreamHook(settingsContent);
766
+ settingsContent = removeHudStatusLine(settingsContent);
767
+ settingsContent = removeContextHook(settingsContent);
768
+ settingsContent = stripFlags(settingsContent);
769
+ settingsContent = stripViewMode(settingsContent);
770
+ settingsContent = stripDevflowTeammateModeFromJson(settingsContent);
771
+ // Remove proxy hooks and ANTHROPIC_BASE_URL env in a single parse-mutate-serialize pass.
772
+ // REG-1: scope the URL strip to the port Devflow manages — use the pre-captured port
773
+ // (from opts.managedProxyPorts) because proxy.json is already deleted by
774
+ // removeDevFlowInstallArtifacts before this phase runs. A user's own localhost
775
+ // gateway on any other port is left in settings untouched.
776
+ {
777
+ const managedPort = opts.managedProxyPorts?.get(scope) ?? DEFAULT_PROXY_PORT;
778
+ const parsedSettings = JSON.parse(settingsContent);
779
+ applyDisableToSettings(parsedSettings, managedPort);
780
+ settingsContent = JSON.stringify(parsedSettings, null, 2) + '\n';
781
+ }
782
+ if (settingsContent !== originalContent) {
783
+ await fs.writeFile(settingsPath, settingsContent, 'utf-8');
784
+ if (verbose) {
785
+ p.log.success(`Devflow hooks removed from settings.json (${scope})`);
786
+ }
787
+ }
788
+ // The Devflow strippers above (removeAmbientHook, removeMemoryHooks, etc.) surgically
789
+ // remove every Devflow-owned hook entry. When they complete, any remaining
790
+ // settings.hooks entries belong to THIRD-PARTY tools and must be preserved.
791
+ // (F5: a prior bulk-removal block here was incorrectly scoped — it only fired when
792
+ // foreign hooks were present, and would have removed them. It is gone now.)
793
+ }
794
+ catch {
795
+ // settings.json doesn't exist or can't be parsed — skip
796
+ }
797
+ }
798
+ // 4. Security deny list
799
+ // Detect what's installed
800
+ let userSettingsJsonForSecurity = null;
801
+ const userSettingsPathForSecurity = path.join(getClaudeDirectory(), 'settings.json');
802
+ try {
803
+ userSettingsJsonForSecurity = await fs.readFile(userSettingsPathForSecurity, 'utf-8');
804
+ }
805
+ catch { /* absent */ }
806
+ let managedExistsForSecurity = false;
807
+ let managedContentForSecurity = null;
808
+ try {
809
+ const managedPath = getManagedSettingsPath();
810
+ managedContentForSecurity = await fs.readFile(managedPath, 'utf-8');
811
+ managedExistsForSecurity = true;
812
+ }
813
+ catch { /* absent or unsupported platform */ }
814
+ const detectedSecurity = detectDenyState(userSettingsJsonForSecurity, managedExistsForSecurity, managedContentForSecurity);
815
+ const anySecurityPresent = detectedSecurity.user || detectedSecurity.managed;
816
+ if (anySecurityPresent) {
817
+ const bothLocations = detectedSecurity.user && detectedSecurity.managed;
818
+ const locationLabel = bothLocations ? 'user settings + managed settings'
819
+ : detectedSecurity.user ? 'user settings' : 'managed settings';
820
+ const securityDecision = resolveSecurityRemovalDecision({
821
+ anySecurityPresent,
822
+ keepDocs,
823
+ isTTY: isTTY,
824
+ });
825
+ let shouldRemoveSecurity = false;
826
+ if (securityDecision === 'prompt') {
827
+ const removeDenyConfirm = await p.confirm({
828
+ message: `Remove Devflow security deny list from ${locationLabel}?`,
829
+ initialValue: false,
830
+ });
831
+ if (!p.isCancel(removeDenyConfirm) && removeDenyConfirm) {
832
+ shouldRemoveSecurity = true;
833
+ }
834
+ else {
835
+ p.log.info(`Security deny list preserved (${locationLabel})`);
836
+ }
837
+ }
838
+ else if (securityDecision === 'preserve') {
839
+ p.log.info(`Security deny list preserved (${locationLabel}, non-interactive mode)`);
840
+ }
841
+ // securityDecision === 'skip' when keepDocs is set — no message, no action
842
+ if (shouldRemoveSecurity) {
843
+ // Strip from user settings (ENOENT-tolerant; atomic write via temp+rename).
844
+ // NOTE: unparseable user settings are detected as user=false by detectDenyState
845
+ // (JSON.parse failure sets unknown=true but not user=true), so this branch is
846
+ // only reached when the JSON is valid — stripUserDenyList will not throw.
847
+ // Unlike `devflow security --disable`, uninstall does NOT hard-fail on corrupt
848
+ // JSON; it silently skips the strip instead (user=false → guard below is false).
849
+ if (detectedSecurity.user && userSettingsJsonForSecurity !== null) {
850
+ const { json: stripped, removed } = stripUserDenyList(userSettingsJsonForSecurity, DEVFLOW_HISTORICAL_DENY);
851
+ if (removed.length > 0) {
852
+ await writeFileAtomicExclusive(userSettingsPathForSecurity, stripped);
853
+ p.log.success(`Security deny list removed from user settings (${removed.length} entries)`);
854
+ }
855
+ }
856
+ // Strip from managed settings (ENOENT-tolerant via removeManagedSettings)
857
+ if (managedExistsForSecurity) {
858
+ await removeManagedSettings(getPackageRoot(), verbose);
859
+ }
860
+ }
861
+ }
862
+ // 5. Safe-delete shell function
863
+ const shell = detectShell();
864
+ const profilePath = getProfilePath(shell);
865
+ if (profilePath && await isAlreadyInstalled(profilePath)) {
866
+ if (isTTY) {
867
+ const removeSafeDelete = await p.confirm({
868
+ message: `Remove safe-delete function from ${profilePath}?`,
869
+ initialValue: false,
870
+ });
871
+ if (!p.isCancel(removeSafeDelete) && removeSafeDelete) {
872
+ const removed = await removeFromProfile(profilePath);
873
+ if (removed) {
874
+ p.log.success(`Safe-delete removed from ${profilePath}`);
875
+ }
876
+ else {
877
+ p.log.warn(`Could not remove safe-delete from ${profilePath}`);
878
+ }
879
+ }
880
+ else {
881
+ p.log.info('Safe-delete preserved in shell profile');
882
+ }
883
+ }
884
+ else {
885
+ p.log.info(`Safe-delete function preserved in ${profilePath} (non-interactive mode)`);
886
+ }
887
+ }
888
+ }
889
+ export const uninstallCommand = new Command('uninstall')
890
+ .description('Uninstall Devflow from Claude Code')
891
+ .option('--keep-docs', 'Keep .devflow/ directory and project data')
892
+ .option('--scope <type>', 'Uninstall from specific scope only (default: auto-detect all)', /^(user|local)$/i)
893
+ .option('--plugin <names>', 'Uninstall specific plugin(s), comma-separated (e.g., implement,code-review)')
894
+ .option('--verbose', 'Show detailed uninstall output')
895
+ .option('--dry-run', 'Show what would be removed without actually removing anything')
896
+ .action(async (options) => {
897
+ const dryRun = options.dryRun ?? false;
898
+ p.intro(color.bgRed(color.white(dryRun ? ' Devflow Uninstall (dry run) ' : ' Uninstalling Devflow ')));
899
+ const verbose = options.verbose ?? false;
900
+ // Parse plugin selection
901
+ let selectedPluginNames = [];
902
+ if (options.plugin) {
903
+ // Friendly redirect for retired feature plugins (e.g. devflow-compliance → `devflow compliance`).
904
+ // Strip retired names, emit the notice, and continue with the remaining plugins so that a
905
+ // mixed list like `devflow-implement,devflow-compliance` still uninstalls devflow-implement.
906
+ // Exit 0 only when nothing non-retired remains (compliance-only invocation).
907
+ const rawNames = options.plugin.split(',').map((s) => s.trim());
908
+ const redirect = resolveFeatureRedirect(rawNames);
909
+ if (redirect.notice) {
910
+ p.log.info(redirect.notice);
911
+ }
912
+ if (redirect.remaining.length === 0) {
913
+ process.exit(0);
914
+ }
915
+ const { selected, invalid } = parsePluginSelection(redirect.remaining.join(','), DEVFLOW_PLUGINS);
916
+ selectedPluginNames = selected;
917
+ if (invalid.length > 0) {
918
+ p.log.error(`Unknown plugin(s): ${invalid.join(', ')}`);
919
+ p.log.info(`Valid plugins: ${DEVFLOW_PLUGINS.map(pl => pl.name).join(', ')}`);
920
+ process.exit(1);
921
+ }
922
+ }
923
+ const isSelectiveUninstall = selectedPluginNames.length > 0;
924
+ const selectedPlugins = isSelectiveUninstall
925
+ ? DEVFLOW_PLUGINS.filter(p => selectedPluginNames.includes(p.name))
926
+ : [];
927
+ // Determine which scopes to uninstall
928
+ let scopesToUninstall = [];
929
+ if (options.scope) {
930
+ scopesToUninstall = [options.scope.toLowerCase()];
931
+ }
932
+ else {
933
+ const userClaudeDir = getClaudeDirectory();
934
+ const gitRoot = await getGitRoot();
935
+ if (await isDevFlowInstalled(userClaudeDir)) {
936
+ scopesToUninstall.push('user');
937
+ }
938
+ if (gitRoot) {
939
+ const localClaudeDir = path.join(gitRoot, '.claude');
940
+ if (await isDevFlowInstalled(localClaudeDir)) {
941
+ scopesToUninstall.push('local');
942
+ }
943
+ }
944
+ if (scopesToUninstall.length === 0) {
945
+ p.log.error('No Devflow installation found');
946
+ p.log.info('Checked user scope (~/.claude/) and local scope (git-root/.claude/)');
947
+ process.exit(1);
948
+ }
949
+ if (scopesToUninstall.length > 1 && !dryRun) {
950
+ if (process.stdin.isTTY) {
951
+ const scopeChoice = await p.select({
952
+ message: 'Found Devflow in multiple scopes. Uninstall from:',
953
+ options: [
954
+ { value: 'both', label: 'Both', hint: 'user + local' },
955
+ { value: 'user', label: 'User scope', hint: '~/.claude/' },
956
+ { value: 'local', label: 'Local scope', hint: 'git-root/.claude/' },
957
+ ],
958
+ });
959
+ if (p.isCancel(scopeChoice)) {
960
+ p.cancel('Uninstall cancelled.');
961
+ process.exit(0);
962
+ }
963
+ if (scopeChoice !== 'both') {
964
+ scopesToUninstall = [scopeChoice];
965
+ }
966
+ }
967
+ else {
968
+ p.log.info('Multiple scopes detected, uninstalling from both...');
969
+ }
970
+ }
971
+ }
972
+ // === DRY RUN: show plan and exit ===
973
+ if (dryRun) {
974
+ await runDryRunPhase({ scopesToUninstall, isSelectiveUninstall, selectedPlugins });
975
+ p.outro(color.dim('No changes made (dry run)'));
976
+ return;
977
+ }
978
+ // Pre-capture managed proxy ports for each scope BEFORE artifact removal.
979
+ // proxy.json is deleted by removeDevFlowInstallArtifacts (inside runFullPhaseForScope),
980
+ // so reading it after the full phase would always yield DEFAULT_PROXY_PORT. (F6)
981
+ const managedProxyPorts = new Map();
982
+ if (!isSelectiveUninstall) {
983
+ for (const scope of scopesToUninstall) {
984
+ try {
985
+ const paths = await getInstallationPaths(scope);
986
+ const proxyState = await readProxyState(paths.devflowDir);
987
+ if (proxyState.ok)
988
+ managedProxyPorts.set(scope, proxyState.value.port);
989
+ }
990
+ catch { /* non-fatal: if we can't read, we fall back to DEFAULT_PROXY_PORT */ }
991
+ }
992
+ }
993
+ // Uninstall from each scope
994
+ for (const scope of scopesToUninstall) {
995
+ let claudeDir;
996
+ let devflowScriptsDir;
997
+ let devflowDir;
998
+ try {
999
+ const paths = await getInstallationPaths(scope);
1000
+ claudeDir = paths.claudeDir;
1001
+ devflowDir = paths.devflowDir;
1002
+ devflowScriptsDir = path.join(paths.devflowDir, 'scripts');
1003
+ if (scope === 'user') {
1004
+ p.log.step('Uninstalling user scope (~/.claude/)');
1005
+ }
1006
+ else {
1007
+ p.log.step('Uninstalling local scope (git-root/.claude/)');
1008
+ }
1009
+ }
1010
+ catch (error) {
1011
+ p.log.warn(`Cannot uninstall ${scope} scope: ${error instanceof Error ? error.message : error}`);
1012
+ continue;
1013
+ }
1014
+ if (isSelectiveUninstall) {
1015
+ await runSelectivePhaseForScope({ claudeDir, devflowDir, selectedPlugins, verbose });
1016
+ }
1017
+ else {
1018
+ await runFullPhaseForScope({ scope, claudeDir, devflowDir, devflowScriptsDir, verbose, keepDocs: !!options.keepDocs, isTTY: !!process.stdin.isTTY });
1019
+ }
1020
+ const pluginLabel = isSelectiveUninstall
1021
+ ? ` (${selectedPluginNames.join(', ')})`
1022
+ : '';
1023
+ p.log.success(`Plugin removed${pluginLabel}`);
1024
+ }
1025
+ // === CLEANUP EXTRAS (only for full uninstall) ===
1026
+ if (!isSelectiveUninstall) {
1027
+ await runCleanupPhase({ scopesToUninstall, keepDocs: !!options.keepDocs, verbose, cwd: process.cwd(), isTTY: !!process.stdin.isTTY, managedProxyPorts });
1028
+ }
1029
+ const status = color.green('Devflow uninstalled successfully');
1030
+ p.outro(`${status}${color.dim(' Reinstall: npx devflow-kit init')}`);
1031
+ });
1032
+ /**
1033
+ * Remove all Devflow assets (full uninstall).
1034
+ */
1035
+ export async function removeAllDevFlow(claudeDir, devflowScriptsDir, verbose) {
1036
+ const devflowDirectories = [
1037
+ { path: path.join(claudeDir, 'commands', 'devflow'), name: 'commands' },
1038
+ { path: path.join(claudeDir, 'agents', 'devflow'), name: 'agents' },
1039
+ { path: path.join(claudeDir, 'rules', 'devflow'), name: 'rules' },
1040
+ { path: devflowScriptsDir, name: 'scripts' }
1041
+ ];
1042
+ for (const dir of devflowDirectories) {
1043
+ try {
1044
+ await fs.rm(dir.path, { recursive: true, force: true });
1045
+ if (verbose) {
1046
+ p.log.success(`Removed Devflow ${dir.name}`);
1047
+ }
1048
+ }
1049
+ catch (error) {
1050
+ p.log.warn(`Could not remove ${dir.name}: ${error}`);
1051
+ }
1052
+ }
1053
+ // Remove Devflow skill directories.
1054
+ // ~/.claude/skills/ is shared with other tools; the two passes use different
1055
+ // name sets to avoid deleting foreign dirs (avoids PF-012):
1056
+ //
1057
+ // Prefixed pass (devflow:name): live registry ∪ LEGACY_SKILL_NAMES ∪ FEATURE_OWNED_SKILLS.
1058
+ // prefixSkillName() is idempotent for already-prefixed legacy entries.
1059
+ // FEATURE_OWNED_SKILLS (compliance) is included so full uninstall removes
1060
+ // devflow:compliance even though it left the plugin registry (step 1.5).
1061
+ // Bare pass (name or devflow-name legacy): LEGACY_SKILL_NAMES ONLY.
1062
+ // A bare dir whose name matches a live-registry skill is by construction
1063
+ // foreign to Devflow (the devflow: namespace shipped in dcecda3, 2026-03-30).
1064
+ // A bare 'compliance/' dir is also foreign (not in LEGACY_SKILL_NAMES) — PF-012.
1065
+ const prefixedSkillNames = new Set([...getAllSkillNames(), ...LEGACY_SKILL_NAMES, ...FEATURE_OWNED_SKILLS]);
1066
+ const skillsDir = path.join(claudeDir, 'skills');
1067
+ let skillsRemoved = 0;
1068
+ for (const skillName of prefixedSkillNames) {
1069
+ // Remove prefixed variant (devflow:name) — current naming
1070
+ const prefixedPath = path.join(skillsDir, prefixSkillName(skillName));
1071
+ try {
1072
+ await fs.stat(prefixedPath);
1073
+ await fs.rm(prefixedPath, { recursive: true, force: true });
1074
+ skillsRemoved++;
1075
+ }
1076
+ catch { /* Skill doesn't exist */ }
1077
+ }
1078
+ for (const skillName of LEGACY_SKILL_NAMES) {
1079
+ // Remove bare variant — frozen legacy list only, never the live registry
1080
+ const barePath = path.join(skillsDir, skillName);
1081
+ try {
1082
+ await fs.stat(barePath);
1083
+ await fs.rm(barePath, { recursive: true, force: true });
1084
+ skillsRemoved++;
1085
+ }
1086
+ catch { /* Skill doesn't exist */ }
1087
+ }
1088
+ if (skillsRemoved > 0 && verbose) {
1089
+ p.log.success(`Removed ${skillsRemoved} Devflow skill directories`);
1090
+ }
1091
+ // Also remove old nested skills structure if it exists
1092
+ try {
1093
+ await fs.rm(path.join(claudeDir, 'skills', 'devflow'), { recursive: true, force: true });
1094
+ }
1095
+ catch {
1096
+ // Old structure doesn't exist
1097
+ }
1098
+ // Registry-diff sweep: catch any devflow:* skill dirs whose names left the
1099
+ // registry (retired, renamed, or deleted). The loop above walks the static
1100
+ // registry + LEGACY list; this sweep walks the actual directory, so orphaned
1101
+ // dirs from older versions are also cleaned up. (F9)
1102
+ await sweepDevflowNamespaces(claudeDir, verbose);
1103
+ }
1104
+ /**
1105
+ * Registry-diff sweep of all Devflow-owned namespaces in `claudeDir`:
1106
+ * - agents/devflow/ — entries absent from getAllAgentNames()
1107
+ * - commands/devflow/ — entries absent from getAllCommandNames()
1108
+ * - skills/ — devflow:* entries absent from getAllSkillNames()
1109
+ *
1110
+ * Called by removeSelectedPlugins after per-plugin removals so that retired
1111
+ * asset names (agents/commands renamed or deleted from the registry) are
1112
+ * cleaned up promptly rather than accumulating on disk.
1113
+ *
1114
+ * knownNames spans ALL plugins for each asset type so assets belonging to
1115
+ * plugins NOT being uninstalled are never swept (avoids PF-012).
1116
+ *
1117
+ * Removals are announced only under `verbose`, but removal FAILURES always warn:
1118
+ * a swept-but-not-actually-removed agent or command keeps loading in Claude Code,
1119
+ * and the user has no other signal that it is still there.
1120
+ */
1121
+ export async function sweepDevflowNamespaces(claudeDir, verbose) {
1122
+ const agentsDir = path.join(claudeDir, 'agents', 'devflow');
1123
+ const commandsDir = path.join(claudeDir, 'commands', 'devflow');
1124
+ const skillsDir = path.join(claudeDir, 'skills');
1125
+ const agentsSweep = await sweepOrphanedAssets(agentsDir, new Set(getAllAgentNames()), mdEntryName);
1126
+ const commandsSweep = await sweepOrphanedAssets(commandsDir, new Set(getAllCommandNames()), mdEntryName);
1127
+ // FEATURE_OWNED_SKILLS (compliance) unioned into knownNames so a selective
1128
+ // uninstall of another plugin does not sweep devflow:compliance — nothing
1129
+ // converges after selective uninstall (only installViaFileCopy + convergeComplianceArtifacts
1130
+ // on full/partial init re-materialize it). D-FO-1 applies.
1131
+ const skillsSweep = await sweepOrphanedAssets(skillsDir, new Set([...getAllSkillNames(), ...FEATURE_OWNED_SKILLS]), (entry) => entry.startsWith(SKILL_NAMESPACE) ? unprefixSkillName(entry) : null);
1132
+ const byKind = [
1133
+ { kind: 'agent', sweep: agentsSweep },
1134
+ { kind: 'command', sweep: commandsSweep },
1135
+ { kind: 'skill', sweep: skillsSweep },
1136
+ ];
1137
+ for (const { kind, sweep } of byKind) {
1138
+ if (verbose) {
1139
+ for (const name of sweep.removed)
1140
+ p.log.success(`Swept orphaned ${kind} ${name}`);
1141
+ }
1142
+ for (const failure of sweep.failed) {
1143
+ const reason = failure.error instanceof Error ? failure.error.message : String(failure.error);
1144
+ p.log.warn(`Could not remove orphaned ${kind} "${failure.name}" (${reason}) — remove it manually`);
1145
+ }
1146
+ }
1147
+ }
1148
+ /**
1149
+ * Remove only specific plugin assets (selective uninstall).
1150
+ * For commands and agents: remove files belonging to selected plugins, then
1151
+ * sweep the install directory for any orphaned assets whose names left the
1152
+ * registry (retired agents/commands survive indefinitely without the sweep).
1153
+ * For skills: only remove skills that are NOT used by any remaining plugin.
1154
+ */
1155
+ export async function removeSelectedPlugins(claudeDir, plugins, verbose) {
1156
+ const { skills, agents, commands, rules } = computeAssetsToRemove(plugins, DEVFLOW_PLUGINS);
1157
+ const commandsDir = path.join(claudeDir, 'commands', 'devflow');
1158
+ for (const cmd of commands) {
1159
+ const cmdFileName = mdFileName(cmd.replace(/^\//, ''));
1160
+ try {
1161
+ await fs.rm(path.join(commandsDir, cmdFileName), { force: true });
1162
+ if (verbose) {
1163
+ p.log.success(`Removed command ${cmd}`);
1164
+ }
1165
+ }
1166
+ catch {
1167
+ // Command file might not exist
1168
+ }
1169
+ }
1170
+ const agentsDir = path.join(claudeDir, 'agents', 'devflow');
1171
+ for (const agent of agents) {
1172
+ try {
1173
+ await fs.rm(path.join(agentsDir, mdFileName(agent)), { force: true });
1174
+ if (verbose) {
1175
+ p.log.success(`Removed agent ${agent}`);
1176
+ }
1177
+ }
1178
+ catch {
1179
+ // Agent file might not exist
1180
+ }
1181
+ }
1182
+ const skillsDir = path.join(claudeDir, 'skills');
1183
+ for (const skill of skills) {
1184
+ // Remove only the prefixed variant (devflow:name) — current naming.
1185
+ // Bare dirs (~/.claude/skills/{name}) and legacy devflow-* dirs are owned
1186
+ // exclusively by the frozen LEGACY_SKILL_NAMES pass in removeAllDevFlow and
1187
+ // in init.ts; live-registry skills never had bare installs (the devflow:
1188
+ // namespace shipped in dcecda3, 2026-03-30), so a bare dir for a current
1189
+ // registry name is by construction foreign (avoids PF-012).
1190
+ try {
1191
+ await fs.rm(path.join(skillsDir, prefixSkillName(skill)), { recursive: true, force: true });
1192
+ }
1193
+ catch { /* Skill might not exist */ }
1194
+ if (verbose) {
1195
+ p.log.success(`Removed skill ${skill}`);
1196
+ }
1197
+ }
1198
+ const rulesDir = path.join(claudeDir, 'rules', 'devflow');
1199
+ for (const rule of rules) {
1200
+ try {
1201
+ await fs.rm(path.join(rulesDir, mdFileName(rule)), { force: true });
1202
+ if (verbose) {
1203
+ p.log.success(`Removed rule ${rule}`);
1204
+ }
1205
+ }
1206
+ catch { /* Rule file might not exist */ }
1207
+ }
1208
+ // Registry-diff sweep: agents, commands, AND skills — named step (A6).
1209
+ // Removes any orphaned files whose names left the registry (retired, renamed,
1210
+ // or deleted from all plugins). Spans ALL plugins so assets belonging to
1211
+ // non-selected plugins are never swept (avoids PF-012).
1212
+ await sweepDevflowNamespaces(claudeDir, verbose);
1213
+ }
1214
+ //# sourceMappingURL=uninstall.js.map