agileflow 4.0.0-alpha.2 → 4.0.0-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/content/plugins/accessibility/plugin.yaml +14 -0
  3. package/content/plugins/accessibility/skills/agileflow-accessibility/SKILL.md +392 -0
  4. package/content/plugins/accessibility/skills/agileflow-accessibility/references/aria-patterns.md +528 -0
  5. package/content/plugins/accessibility/skills/agileflow-accessibility/references/testing-checklist.md +457 -0
  6. package/content/plugins/accessibility/skills/agileflow-accessibility/references/wcag-guide.md +683 -0
  7. package/content/plugins/accessibility/skills/agileflow-accessibility/workflows/audit-page.md +310 -0
  8. package/content/plugins/accessibility/skills/agileflow-accessibility/workflows/implement-accessible-component.md +479 -0
  9. package/content/plugins/ads/agents/ads-audit-budget.md +185 -0
  10. package/content/plugins/ads/agents/ads-audit-compliance.md +171 -0
  11. package/content/plugins/ads/agents/ads-audit-creative.md +168 -0
  12. package/content/plugins/ads/agents/ads-audit-google.md +227 -0
  13. package/content/plugins/ads/agents/ads-audit-meta.md +184 -0
  14. package/content/plugins/ads/agents/ads-audit-tracking.md +205 -0
  15. package/content/plugins/ads/agents/ads-consensus.md +410 -0
  16. package/content/plugins/ads/agents/ads-generate.md +152 -0
  17. package/content/plugins/ads/agents/ads-performance-tracker.md +212 -0
  18. package/content/plugins/ads/plugin.yaml +23 -4
  19. package/content/plugins/ads/skills/agileflow-ads/SKILL.md +218 -0
  20. package/content/plugins/ads/skills/agileflow-ads/references/ad-copy-formula-guide.md +131 -0
  21. package/content/plugins/ads/skills/agileflow-ads/references/audience-targeting-guide.md +137 -0
  22. package/content/plugins/ads/skills/agileflow-ads/references/bid-strategy-guide.md +115 -0
  23. package/content/plugins/ads/skills/agileflow-ads/references/platform-benchmarks.md +100 -0
  24. package/content/plugins/ads/skills/agileflow-ads/workflows/audit.md +118 -0
  25. package/content/plugins/ads/skills/agileflow-ads/workflows/generate.md +84 -0
  26. package/content/plugins/audit/agents/a11y-analyzer-aria.md +173 -0
  27. package/content/plugins/audit/agents/a11y-analyzer-forms.md +173 -0
  28. package/content/plugins/audit/agents/a11y-analyzer-keyboard.md +183 -0
  29. package/content/plugins/audit/agents/a11y-analyzer-semantic.md +169 -0
  30. package/content/plugins/audit/agents/a11y-analyzer-visual.md +172 -0
  31. package/content/plugins/audit/agents/a11y-consensus.md +249 -0
  32. package/content/plugins/audit/agents/accessibility.md +558 -0
  33. package/content/plugins/audit/agents/api-quality-analyzer-conventions.md +156 -0
  34. package/content/plugins/audit/agents/api-quality-analyzer-docs.md +184 -0
  35. package/content/plugins/audit/agents/api-quality-analyzer-errors.md +191 -0
  36. package/content/plugins/audit/agents/api-quality-analyzer-pagination.md +179 -0
  37. package/content/plugins/audit/agents/api-quality-analyzer-versioning.md +150 -0
  38. package/content/plugins/audit/agents/api-quality-consensus.md +217 -0
  39. package/content/plugins/audit/agents/api-validator.md +191 -0
  40. package/content/plugins/audit/agents/arch-analyzer-circular.md +156 -0
  41. package/content/plugins/audit/agents/arch-analyzer-complexity.md +193 -0
  42. package/content/plugins/audit/agents/arch-analyzer-coupling.md +152 -0
  43. package/content/plugins/audit/agents/arch-analyzer-layering.md +160 -0
  44. package/content/plugins/audit/agents/arch-analyzer-patterns.md +210 -0
  45. package/content/plugins/audit/agents/arch-consensus.md +228 -0
  46. package/content/plugins/audit/agents/browser-qa.md +342 -0
  47. package/content/plugins/audit/agents/code-reviewer.md +298 -0
  48. package/content/plugins/audit/agents/completeness-analyzer-api.md +199 -0
  49. package/content/plugins/audit/agents/completeness-analyzer-conditional.md +211 -0
  50. package/content/plugins/audit/agents/completeness-analyzer-handlers.md +166 -0
  51. package/content/plugins/audit/agents/completeness-analyzer-imports.md +165 -0
  52. package/content/plugins/audit/agents/completeness-analyzer-routes.md +190 -0
  53. package/content/plugins/audit/agents/completeness-analyzer-state.md +196 -0
  54. package/content/plugins/audit/agents/completeness-analyzer-stubs.md +206 -0
  55. package/content/plugins/audit/agents/completeness-consensus.md +295 -0
  56. package/content/plugins/audit/agents/error-analyzer.md +213 -0
  57. package/content/plugins/audit/agents/flow-analyzer-authorization.md +182 -0
  58. package/content/plugins/audit/agents/flow-analyzer-discovery.md +174 -0
  59. package/content/plugins/audit/agents/flow-analyzer-errors.md +186 -0
  60. package/content/plugins/audit/agents/flow-analyzer-feedback.md +185 -0
  61. package/content/plugins/audit/agents/flow-analyzer-navigation.md +177 -0
  62. package/content/plugins/audit/agents/flow-analyzer-persistence.md +193 -0
  63. package/content/plugins/audit/agents/flow-analyzer-wiring.md +169 -0
  64. package/content/plugins/audit/agents/flow-consensus.md +237 -0
  65. package/content/plugins/audit/agents/legal-analyzer-a11y.md +114 -0
  66. package/content/plugins/audit/agents/legal-analyzer-ai.md +121 -0
  67. package/content/plugins/audit/agents/legal-analyzer-consumer.md +114 -0
  68. package/content/plugins/audit/agents/legal-analyzer-content.md +117 -0
  69. package/content/plugins/audit/agents/legal-analyzer-international.md +119 -0
  70. package/content/plugins/audit/agents/legal-analyzer-licensing.md +119 -0
  71. package/content/plugins/audit/agents/legal-analyzer-privacy.md +112 -0
  72. package/content/plugins/audit/agents/legal-analyzer-security.md +116 -0
  73. package/content/plugins/audit/agents/legal-analyzer-terms.md +115 -0
  74. package/content/plugins/audit/agents/legal-consensus.md +250 -0
  75. package/content/plugins/audit/agents/logic-analyzer-edge.md +179 -0
  76. package/content/plugins/audit/agents/logic-analyzer-flow.md +264 -0
  77. package/content/plugins/audit/agents/logic-analyzer-invariant.md +215 -0
  78. package/content/plugins/audit/agents/logic-analyzer-race.md +280 -0
  79. package/content/plugins/audit/agents/logic-analyzer-type.md +227 -0
  80. package/content/plugins/audit/agents/logic-consensus.md +259 -0
  81. package/content/plugins/audit/agents/perf-analyzer-assets.md +182 -0
  82. package/content/plugins/audit/agents/perf-analyzer-bundle.md +173 -0
  83. package/content/plugins/audit/agents/perf-analyzer-caching.md +170 -0
  84. package/content/plugins/audit/agents/perf-analyzer-compute.md +173 -0
  85. package/content/plugins/audit/agents/perf-analyzer-memory.md +193 -0
  86. package/content/plugins/audit/agents/perf-analyzer-network.md +165 -0
  87. package/content/plugins/audit/agents/perf-analyzer-queries.md +162 -0
  88. package/content/plugins/audit/agents/perf-analyzer-rendering.md +168 -0
  89. package/content/plugins/audit/agents/perf-consensus.md +287 -0
  90. package/content/plugins/audit/agents/qa.md +820 -0
  91. package/content/plugins/audit/agents/quality-analyzer-comments.md +159 -0
  92. package/content/plugins/audit/agents/quality-analyzer-duplication.md +184 -0
  93. package/content/plugins/audit/agents/quality-analyzer-naming.md +160 -0
  94. package/content/plugins/audit/agents/quality-consensus.md +241 -0
  95. package/content/plugins/audit/agents/schema-validator.md +473 -0
  96. package/content/plugins/audit/agents/security-analyzer-api.md +210 -0
  97. package/content/plugins/audit/agents/security-analyzer-auth.md +169 -0
  98. package/content/plugins/audit/agents/security-analyzer-authz.md +180 -0
  99. package/content/plugins/audit/agents/security-analyzer-deps.md +153 -0
  100. package/content/plugins/audit/agents/security-analyzer-infra.md +184 -0
  101. package/content/plugins/audit/agents/security-analyzer-injection.md +155 -0
  102. package/content/plugins/audit/agents/security-analyzer-input.md +201 -0
  103. package/content/plugins/audit/agents/security-analyzer-secrets.md +183 -0
  104. package/content/plugins/audit/agents/security-consensus.md +283 -0
  105. package/content/plugins/audit/agents/test-analyzer-assertions.md +188 -0
  106. package/content/plugins/audit/agents/test-analyzer-coverage.md +189 -0
  107. package/content/plugins/audit/agents/test-analyzer-fragility.md +193 -0
  108. package/content/plugins/audit/agents/test-analyzer-integration.md +161 -0
  109. package/content/plugins/audit/agents/test-analyzer-maintenance.md +180 -0
  110. package/content/plugins/audit/agents/test-analyzer-mocking.md +188 -0
  111. package/content/plugins/audit/agents/test-analyzer-patterns.md +196 -0
  112. package/content/plugins/audit/agents/test-analyzer-structure.md +184 -0
  113. package/content/plugins/audit/agents/test-consensus.md +301 -0
  114. package/content/plugins/audit/agents/testing.md +561 -0
  115. package/content/plugins/audit/agents/ui-validator.md +344 -0
  116. package/content/plugins/audit/plugin.yaml +186 -5
  117. package/content/plugins/audit/skills/agileflow-audit/SKILL.md +113 -0
  118. package/content/plugins/audit/skills/agileflow-audit/references/audit-depth-guide.md +151 -0
  119. package/content/plugins/audit/skills/agileflow-audit/references/dependency-risk-guide.md +139 -0
  120. package/content/plugins/audit/skills/agileflow-audit/references/owasp-top10.md +120 -0
  121. package/content/plugins/audit/skills/agileflow-audit/references/performance-budget-guide.md +143 -0
  122. package/content/plugins/audit/skills/agileflow-audit/references/wcag-criteria.md +117 -0
  123. package/content/plugins/audit/skills/agileflow-audit/workflows/run-audit.md +52 -0
  124. package/content/plugins/audit/skills/agileflow-audit/workflows/tdd.md +66 -0
  125. package/content/plugins/core/agents/adr-writer.md +521 -0
  126. package/content/plugins/core/agents/epic-planner.md +520 -0
  127. package/content/plugins/core/agents/mentor.md +709 -0
  128. package/content/plugins/core/agents/orchestrator.md +776 -0
  129. package/content/plugins/core/agents/team-coordinator.md +334 -0
  130. package/content/plugins/core/agents/team-lead.md +181 -0
  131. package/content/plugins/core/agents/workspace-orchestrator.md +146 -0
  132. package/content/plugins/core/hooks/context-loader.js +31 -4
  133. package/content/plugins/core/hooks/damage-control-bash.js +10 -2
  134. package/content/plugins/core/hooks/damage-control-edit.js +4 -1
  135. package/content/plugins/core/hooks/damage-control-patterns.yaml +1 -1
  136. package/content/plugins/core/hooks/damage-control-write.js +4 -1
  137. package/content/plugins/core/hooks/{pre-compact-state.js → post-compact-state.js} +25 -8
  138. package/content/plugins/core/hooks/preferences-injector.js +352 -0
  139. package/content/plugins/core/plugin.yaml +24 -28
  140. package/content/plugins/core/skills/agileflow-adr/SKILL.md +34 -8
  141. package/content/plugins/core/skills/agileflow-adr/references/madr-format-guide.md +86 -0
  142. package/content/plugins/core/skills/agileflow-adr/workflows/write-adr.md +57 -0
  143. package/content/plugins/core/skills/agileflow-babysit-mentor/SKILL.md +94 -27
  144. package/content/plugins/core/skills/agileflow-babysit-mentor/references/mentor-decision-guide.md +81 -0
  145. package/content/plugins/core/skills/agileflow-babysit-mentor/workflows/mentor-session.md +79 -0
  146. package/content/plugins/core/skills/agileflow-epic-planner/SKILL.md +37 -7
  147. package/content/plugins/core/skills/agileflow-epic-planner/references/epic-sizing-guide.md +81 -0
  148. package/content/plugins/core/skills/agileflow-epic-planner/workflows/plan-epic.md +55 -0
  149. package/content/plugins/core/skills/agileflow-status-updater/SKILL.md +36 -20
  150. package/content/plugins/core/skills/agileflow-status-updater/references/status-transitions.md +89 -0
  151. package/content/plugins/core/skills/agileflow-status-updater/workflows/update-status.md +56 -0
  152. package/content/plugins/core/skills/agileflow-story-writer/SKILL.md +39 -114
  153. package/content/plugins/core/skills/agileflow-story-writer/references/estimation-reference.md +36 -0
  154. package/content/plugins/core/skills/agileflow-story-writer/references/story-template.md +92 -0
  155. package/content/plugins/core/skills/agileflow-story-writer/workflows/write-story.md +138 -0
  156. package/content/plugins/council/agents/council-advocate.md +223 -0
  157. package/content/plugins/council/agents/council-analyst.md +278 -0
  158. package/content/plugins/council/agents/council-compounder.md +204 -0
  159. package/content/plugins/council/agents/council-contrarian.md +217 -0
  160. package/content/plugins/council/agents/council-moonshot.md +217 -0
  161. package/content/plugins/council/agents/council-optimist.md +185 -0
  162. package/content/plugins/council/agents/council-revenue.md +200 -0
  163. package/content/plugins/council/agents/council-technical.md +218 -0
  164. package/content/plugins/council/agents/multi-expert.md +334 -0
  165. package/content/plugins/council/plugin.yaml +23 -4
  166. package/content/plugins/council/skills/agileflow-council/SKILL.md +102 -0
  167. package/content/plugins/council/skills/agileflow-council/references/decision-log-template.md +109 -0
  168. package/content/plugins/council/skills/agileflow-council/references/perspective-guide.md +104 -0
  169. package/content/plugins/council/skills/agileflow-council/references/when-to-convene-guide.md +112 -0
  170. package/content/plugins/council/skills/agileflow-council/workflows/convene.md +73 -0
  171. package/content/plugins/council/skills/agileflow-council/workflows/multi-expert.md +75 -0
  172. package/content/plugins/database/plugin.yaml +14 -0
  173. package/content/plugins/database/skills/agileflow-database/SKILL.md +284 -0
  174. package/content/plugins/database/skills/agileflow-database/references/indexing-guide.md +313 -0
  175. package/content/plugins/database/skills/agileflow-database/references/migration-guide.md +328 -0
  176. package/content/plugins/database/skills/agileflow-database/references/schema-design-guide.md +467 -0
  177. package/content/plugins/database/skills/agileflow-database/workflows/design-schema.md +213 -0
  178. package/content/plugins/database/skills/agileflow-database/workflows/optimize-query.md +253 -0
  179. package/content/plugins/debugging/plugin.yaml +14 -0
  180. package/content/plugins/debugging/skills/agileflow-debug/SKILL.md +236 -0
  181. package/content/plugins/debugging/skills/agileflow-debug/references/common-patterns.md +350 -0
  182. package/content/plugins/debugging/skills/agileflow-debug/references/debugging-strategies.md +328 -0
  183. package/content/plugins/debugging/skills/agileflow-debug/workflows/debug-issue.md +187 -0
  184. package/content/plugins/debugging/skills/agileflow-debug/workflows/reproduce-bug.md +194 -0
  185. package/content/plugins/delivery/agents/ci.md +547 -0
  186. package/content/plugins/delivery/agents/devops.md +789 -0
  187. package/content/plugins/delivery/plugin.yaml +19 -0
  188. package/content/plugins/delivery/skills/agileflow-delivery/SKILL.md +111 -0
  189. package/content/plugins/delivery/skills/agileflow-delivery/references/changelog-format-guide.md +133 -0
  190. package/content/plugins/delivery/skills/agileflow-delivery/references/ci-pipeline-guide.md +158 -0
  191. package/content/plugins/delivery/skills/agileflow-delivery/references/pr-checklist-guide.md +133 -0
  192. package/content/plugins/delivery/skills/agileflow-delivery/references/release-checklist.md +142 -0
  193. package/content/plugins/delivery/skills/agileflow-delivery/workflows/changelog.md +72 -0
  194. package/content/plugins/delivery/skills/agileflow-delivery/workflows/deploy.md +74 -0
  195. package/content/plugins/delivery/skills/agileflow-delivery/workflows/pr.md +75 -0
  196. package/content/plugins/docs/agents/documentation.md +544 -0
  197. package/content/plugins/docs/agents/readme-updater.md +640 -0
  198. package/content/plugins/docs/plugin.yaml +19 -0
  199. package/content/plugins/docs/skills/agileflow-docs/SKILL.md +106 -0
  200. package/content/plugins/docs/skills/agileflow-docs/references/api-doc-template.md +167 -0
  201. package/content/plugins/docs/skills/agileflow-docs/references/doc-types-guide.md +141 -0
  202. package/content/plugins/docs/skills/agileflow-docs/references/readme-template.md +156 -0
  203. package/content/plugins/docs/skills/agileflow-docs/workflows/readme-sync.md +57 -0
  204. package/content/plugins/docs/skills/agileflow-docs/workflows/sync.md +64 -0
  205. package/content/plugins/engineering/agents/api.md +718 -0
  206. package/content/plugins/engineering/agents/codebase-query.md +285 -0
  207. package/content/plugins/engineering/agents/compliance.md +559 -0
  208. package/content/plugins/engineering/agents/database.md +644 -0
  209. package/content/plugins/engineering/agents/integrations.md +644 -0
  210. package/content/plugins/engineering/agents/mobile.md +552 -0
  211. package/content/plugins/engineering/agents/monitoring.md +585 -0
  212. package/content/plugins/engineering/agents/performance.md +529 -0
  213. package/content/plugins/engineering/agents/refactor.md +592 -0
  214. package/content/plugins/engineering/agents/security.md +524 -0
  215. package/content/plugins/engineering/agents/ui.md +1336 -0
  216. package/content/plugins/engineering/plugin.yaml +37 -0
  217. package/content/plugins/engineering/skills/agileflow-engineering/SKILL.md +127 -0
  218. package/content/plugins/engineering/skills/agileflow-engineering/references/code-review-guide.md +126 -0
  219. package/content/plugins/engineering/skills/agileflow-engineering/references/domain-routing-guide.md +89 -0
  220. package/content/plugins/engineering/skills/agileflow-engineering/references/refactoring-guide.md +136 -0
  221. package/content/plugins/engineering/skills/agileflow-engineering/workflows/diagnose.md +63 -0
  222. package/content/plugins/engineering/skills/agileflow-engineering/workflows/impact.md +60 -0
  223. package/content/plugins/ideation/agents/brainstorm-analyzer-features.md +179 -0
  224. package/content/plugins/ideation/agents/brainstorm-analyzer-growth.md +169 -0
  225. package/content/plugins/ideation/agents/brainstorm-analyzer-integration.md +181 -0
  226. package/content/plugins/ideation/agents/brainstorm-analyzer-market.md +150 -0
  227. package/content/plugins/ideation/agents/brainstorm-analyzer-ux.md +180 -0
  228. package/content/plugins/ideation/agents/brainstorm-consensus.md +245 -0
  229. package/content/plugins/ideation/agents/design.md +568 -0
  230. package/content/plugins/ideation/agents/product.md +582 -0
  231. package/content/plugins/ideation/plugin.yaml +31 -0
  232. package/content/plugins/ideation/skills/agileflow-ideation/SKILL.md +109 -0
  233. package/content/plugins/ideation/skills/agileflow-ideation/references/brainstorm-techniques.md +138 -0
  234. package/content/plugins/ideation/skills/agileflow-ideation/references/competitive-analysis-template.md +148 -0
  235. package/content/plugins/ideation/skills/agileflow-ideation/references/feature-prioritization-guide.md +147 -0
  236. package/content/plugins/ideation/skills/agileflow-ideation/references/user-story-patterns.md +152 -0
  237. package/content/plugins/ideation/skills/agileflow-ideation/workflows/features.md +65 -0
  238. package/content/plugins/ideation/skills/agileflow-ideation/workflows/ideate.md +54 -0
  239. package/content/plugins/migration/agents/datamigration.md +757 -0
  240. package/content/plugins/migration/plugin.yaml +17 -0
  241. package/content/plugins/migration/skills/agileflow-migration/SKILL.md +106 -0
  242. package/content/plugins/migration/skills/agileflow-migration/references/data-validation-checklist.md +154 -0
  243. package/content/plugins/migration/skills/agileflow-migration/references/migration-patterns.md +209 -0
  244. package/content/plugins/migration/skills/agileflow-migration/references/rollback-playbook.md +171 -0
  245. package/content/plugins/migration/skills/agileflow-migration/references/version-compatibility-matrix.md +155 -0
  246. package/content/plugins/migration/skills/agileflow-migration/workflows/plan.md +73 -0
  247. package/content/plugins/migration/skills/agileflow-migration/workflows/validate.md +71 -0
  248. package/content/plugins/performance/plugin.yaml +14 -0
  249. package/content/plugins/performance/skills/agileflow-performance/SKILL.md +224 -0
  250. package/content/plugins/performance/skills/agileflow-performance/references/optimization-patterns.md +554 -0
  251. package/content/plugins/performance/skills/agileflow-performance/references/profiling-guide.md +383 -0
  252. package/content/plugins/performance/skills/agileflow-performance/references/web-vitals-guide.md +360 -0
  253. package/content/plugins/performance/skills/agileflow-performance/workflows/improve-web-vitals.md +344 -0
  254. package/content/plugins/performance/skills/agileflow-performance/workflows/profile-and-fix.md +254 -0
  255. package/content/plugins/planning/agents/analytics.md +670 -0
  256. package/content/plugins/planning/agents/rlm-subcore.md +215 -0
  257. package/content/plugins/planning/plugin.yaml +19 -0
  258. package/content/plugins/planning/skills/agileflow-planning/SKILL.md +111 -0
  259. package/content/plugins/planning/skills/agileflow-planning/references/estimation-guide.md +114 -0
  260. package/content/plugins/planning/skills/agileflow-planning/references/rpi-workflow.md +119 -0
  261. package/content/plugins/planning/skills/agileflow-planning/references/sprint-planning-guide.md +145 -0
  262. package/content/plugins/planning/skills/agileflow-planning/workflows/impact.md +63 -0
  263. package/content/plugins/planning/skills/agileflow-planning/workflows/rpi.md +104 -0
  264. package/content/plugins/psychology/plugin.yaml +14 -0
  265. package/content/plugins/psychology/skills/agileflow-retention/SKILL.md +252 -0
  266. package/content/plugins/psychology/skills/agileflow-retention/references/competitor-analysis.md +240 -0
  267. package/content/plugins/psychology/skills/agileflow-retention/references/psychology-models.md +349 -0
  268. package/content/plugins/psychology/skills/agileflow-retention/references/retention-patterns.md +279 -0
  269. package/content/plugins/psychology/skills/agileflow-retention/workflows/design-retention-feature.md +287 -0
  270. package/content/plugins/psychology/skills/agileflow-retention/workflows/retention-audit.md +259 -0
  271. package/content/plugins/refactoring/plugin.yaml +14 -0
  272. package/content/plugins/refactoring/skills/agileflow-refactor/SKILL.md +235 -0
  273. package/content/plugins/refactoring/skills/agileflow-refactor/references/refactoring-patterns.md +405 -0
  274. package/content/plugins/refactoring/skills/agileflow-refactor/references/safety-checks.md +177 -0
  275. package/content/plugins/refactoring/skills/agileflow-refactor/workflows/extract-module.md +226 -0
  276. package/content/plugins/refactoring/skills/agileflow-refactor/workflows/safe-refactor.md +169 -0
  277. package/content/plugins/research/agents/research.md +503 -0
  278. package/content/plugins/research/plugin.yaml +17 -0
  279. package/content/plugins/research/skills/agileflow-research/SKILL.md +110 -0
  280. package/content/plugins/research/skills/agileflow-research/references/knowledge-decay-guide.md +121 -0
  281. package/content/plugins/research/skills/agileflow-research/references/research-prompt-guide.md +141 -0
  282. package/content/plugins/research/skills/agileflow-research/references/synthesis-template.md +154 -0
  283. package/content/plugins/research/skills/agileflow-research/workflows/analyze.md +60 -0
  284. package/content/plugins/research/skills/agileflow-research/workflows/ask.md +64 -0
  285. package/content/plugins/research/skills/agileflow-research/workflows/import.md +66 -0
  286. package/content/plugins/research/skills/agileflow-research/workflows/synthesize.md +66 -0
  287. package/content/plugins/reviews/plugin.yaml +14 -0
  288. package/content/plugins/reviews/skills/agileflow-pr-reviewer/SKILL.md +241 -0
  289. package/content/plugins/reviews/skills/agileflow-pr-reviewer/references/review-checklist.md +200 -0
  290. package/content/plugins/reviews/skills/agileflow-pr-reviewer/references/security-patterns.md +328 -0
  291. package/content/plugins/reviews/skills/agileflow-pr-reviewer/workflows/review-pr.md +153 -0
  292. package/content/plugins/reviews/skills/agileflow-pr-reviewer/workflows/security-review.md +177 -0
  293. package/content/plugins/seo/agents/seo-analyzer-content.md +169 -0
  294. package/content/plugins/seo/agents/seo-analyzer-images.md +198 -0
  295. package/content/plugins/seo/agents/seo-analyzer-performance.md +217 -0
  296. package/content/plugins/seo/agents/seo-analyzer-schema.md +184 -0
  297. package/content/plugins/seo/agents/seo-analyzer-sitemap.md +177 -0
  298. package/content/plugins/seo/agents/seo-analyzer-technical.md +151 -0
  299. package/content/plugins/seo/agents/seo-consensus.md +304 -0
  300. package/content/plugins/seo/plugin.yaml +19 -4
  301. package/content/plugins/seo/skills/agileflow-seo/SKILL.md +188 -0
  302. package/content/plugins/seo/skills/agileflow-seo/references/cwv-thresholds.md +110 -0
  303. package/content/plugins/seo/skills/agileflow-seo/references/eeat-framework.md +144 -0
  304. package/content/plugins/seo/skills/agileflow-seo/references/keyword-research-guide.md +125 -0
  305. package/content/plugins/seo/skills/agileflow-seo/references/schema-types.md +139 -0
  306. package/content/plugins/seo/skills/agileflow-seo/references/technical-seo-checklist.md +139 -0
  307. package/content/plugins/seo/skills/agileflow-seo/workflows/audit.md +98 -0
  308. package/content/plugins/seo/skills/agileflow-seo/workflows/page.md +118 -0
  309. package/content/plugins/testing/plugin.yaml +16 -0
  310. package/content/plugins/testing/skills/agileflow-test-writer/SKILL.md +260 -0
  311. package/content/plugins/testing/skills/agileflow-test-writer/references/coverage-targets.md +239 -0
  312. package/content/plugins/testing/skills/agileflow-test-writer/references/test-patterns.md +420 -0
  313. package/content/plugins/testing/skills/agileflow-test-writer/workflows/add-coverage.md +154 -0
  314. package/content/plugins/testing/skills/agileflow-test-writer/workflows/write-tests-from-ac.md +225 -0
  315. package/package.json +2 -2
  316. package/src/cli/commands/doctor.js +818 -30
  317. package/src/cli/commands/hook.js +17 -14
  318. package/src/cli/commands/launch.js +1454 -0
  319. package/src/cli/commands/learn.js +149 -0
  320. package/src/cli/commands/plugins.js +113 -0
  321. package/src/cli/commands/setup.js +455 -110
  322. package/src/cli/commands/skills.js +324 -0
  323. package/src/cli/commands/status.js +8 -10
  324. package/src/cli/commands/update.js +76 -15
  325. package/src/cli/index.js +90 -26
  326. package/src/cli/wizard/babysit-mode-picker.js +192 -0
  327. package/src/cli/wizard/behaviors-picker.js +208 -54
  328. package/src/cli/wizard/ide-picker.js +40 -28
  329. package/src/cli/wizard/install-scope-picker.js +57 -0
  330. package/src/cli/wizard/launch-alias-picker.js +50 -0
  331. package/src/cli/wizard/launch-cli-picker.js +129 -0
  332. package/src/cli/wizard/launch-tmux-picker.js +133 -0
  333. package/src/cli/wizard/learnings-picker.js +40 -0
  334. package/src/cli/wizard/plugin-picker.js +47 -16
  335. package/src/lib/brand.js +116 -0
  336. package/src/lib/errors.js +120 -0
  337. package/src/lib/path-check.js +39 -0
  338. package/src/runtime/config/defaults.js +22 -17
  339. package/src/runtime/config/loader.js +77 -8
  340. package/src/runtime/config/schema.json +43 -16
  341. package/src/runtime/config/writer.js +3 -1
  342. package/src/runtime/ide/babysit-skill.js +202 -0
  343. package/src/runtime/ide/capabilities.js +84 -29
  344. package/src/runtime/ide/claude-code-content.js +177 -0
  345. package/src/runtime/ide/claude-code-settings.js +67 -29
  346. package/src/runtime/ide/claude-code-skills.js +47 -32
  347. package/src/runtime/ide/codex-config.js +295 -0
  348. package/src/runtime/installer/install.js +252 -24
  349. package/src/runtime/launch/alias-installer.js +191 -0
  350. package/src/runtime/launch/cli-resume.js +244 -0
  351. package/src/runtime/launch/closed-windows.js +338 -0
  352. package/src/runtime/launch/defaults.js +66 -0
  353. package/src/runtime/launch/detect-clis.js +69 -0
  354. package/src/runtime/launch/doctor.js +464 -0
  355. package/src/runtime/launch/exec-wrapper.js +114 -0
  356. package/src/runtime/launch/parallel-session.js +247 -0
  357. package/src/runtime/launch/prefs.js +211 -0
  358. package/src/runtime/launch/project-prefs.js +234 -0
  359. package/src/runtime/launch/resolve-cli.js +56 -0
  360. package/src/runtime/launch/restore.js +152 -0
  361. package/src/runtime/launch/schema.json +75 -0
  362. package/src/runtime/launch/session-lifecycle.js +313 -0
  363. package/src/runtime/launch/session-registry.js +401 -0
  364. package/src/runtime/launch/spawn.js +103 -0
  365. package/src/runtime/launch/tabs.js +350 -0
  366. package/src/runtime/launch/tmux.js +764 -0
  367. package/src/runtime/launch/worktree.js +260 -0
  368. package/src/runtime/plugins/registry.js +16 -11
  369. package/src/runtime/plugins/validator.js +57 -43
  370. package/src/runtime/skills/learnings.js +308 -0
  371. package/content/plugins/core/hooks/babysit-mentor-injector.js +0 -55
  372. package/src/cli/wizard/personalization.js +0 -64
@@ -35,15 +35,28 @@ const {
35
35
  buildHookManifest,
36
36
  } = require("../hooks/aggregator.js");
37
37
  const { normalizeManifest } = require("../hooks/manifest-loader.js");
38
- const { capabilitiesFor } = require("../ide/capabilities.js");
38
+ const { capabilitiesFor, SUPPORTED_IDES } = require("../ide/capabilities.js");
39
39
  const {
40
40
  writeClaudeCodeSettings,
41
41
  removeClaudeCodeSettings,
42
42
  } = require("../ide/claude-code-settings.js");
43
+ const {
44
+ writeCodexConfig,
45
+ removeCodexConfig,
46
+ } = require("../ide/codex-config.js");
43
47
  const {
44
48
  mirrorClaudeCodeSkills,
45
49
  unmirrorClaudeCodeSkills,
46
50
  } = require("../ide/claude-code-skills.js");
51
+ const {
52
+ mirrorClaudeCodeAgents,
53
+ unmirrorClaudeCodeAgents,
54
+ } = require("../ide/claude-code-content.js");
55
+ const { loadSkill } = require("../skills/validator.js");
56
+ const {
57
+ resolveSkillsDir,
58
+ resolveLearnFile,
59
+ } = require("../skills/learnings.js");
47
60
 
48
61
  /**
49
62
  * @typedef {import('../plugins/registry.js').PluginManifest} PluginManifest
@@ -53,9 +66,12 @@ const {
53
66
  * @property {Iterable<string>} userSelected
54
67
  * @property {string} agileflowDir - target install root (typically `<cwd>/.agileflow`)
55
68
  * @property {string} cliVersion - written into the file index header
56
- * @property {string} [ide='claude-code'] - target IDE for capability gating
69
+ * @property {string} [ide='claude-code'] - DEPRECATED single-target shorthand (use `ides`)
70
+ * @property {string[]} [ides] - target IDEs for capability gating; takes precedence over `ide`
57
71
  * @property {Record<string, boolean>} [behaviors] - behavior preset toggles
72
+ * @property {boolean} [learningsEnabled=true] - global learnings on/off
58
73
  * @property {boolean} [force=false] - overwrite user modifications
74
+ * @property {import('../config/defaults.js').AgileflowConfig} [config] - merged config used for skill rendering
59
75
  *
60
76
  * @typedef {Object} InstallResult
61
77
  * @property {string[]} ordered - plugin ids in install order
@@ -67,10 +83,15 @@ const {
67
83
  * @property {string} timestamp
68
84
  * @property {string|null} hookManifestPath - path of the written hook manifest, or null
69
85
  * @property {string|null} settingsPath - path of the written .claude/settings.json, or null
70
- * @property {string[]} skillsMirrored - skill ids copied into .claude/skills/
71
- * @property {string[]} skillsPruned - skill ids removed from .claude/skills/
86
+ * @property {string|null} codexConfigPath - path of the written .codex/config.toml, or null
87
+ * @property {string[]} skillsMirrored - skill ids copied across all skill-supporting IDEs
88
+ * @property {string[]} skillsPruned - skill ids removed from skill dirs
72
89
  * @property {Array<{skillId:string, error:string}>} [skillsSkipped] - skills with missing source
73
- * @property {string} ide - the target IDE for this install
90
+ * @property {string[]} agentsMirrored - Claude Code subagents mirrored from enabled plugins
91
+ * @property {Array<{id:string, error:string}>} [agentsSkipped] - agents with missing source
92
+ * @property {string[]} docsScaffolded - doc dirs created on first install
93
+ * @property {string[]} learningsScaffolded - skill ids whose learnings file was newly created
94
+ * @property {string[]} ides - the target IDEs for this install
74
95
  */
75
96
 
76
97
  /**
@@ -191,6 +212,124 @@ async function removeDisabledPlugins(
191
212
  return removed;
192
213
  }
193
214
 
215
+ /**
216
+ * Scaffold `_learnings/<file>.yaml` files for every skill in the ordered
217
+ * plugin set whose frontmatter declares `learns.enabled: true`. Idempotent:
218
+ * existing files are left untouched.
219
+ *
220
+ * @param {PluginManifest[]} ordered
221
+ * @param {string} projectRoot
222
+ * @returns {Promise<string[]>} skill ids whose learnings file was newly created
223
+ */
224
+ async function scaffoldSkillLearnings(ordered, projectRoot) {
225
+ /** @type {string[]} */
226
+ const created = [];
227
+ const skillsDir = resolveSkillsDir(projectRoot);
228
+ for (const plugin of ordered) {
229
+ const skills = (plugin.provides && plugin.provides.skills) || [];
230
+ for (const s of skills) {
231
+ const skillDir = s && s.dir ? path.join(plugin.dir, s.dir) : null;
232
+ if (!skillDir) continue;
233
+ const skillPath = path.join(skillDir, "SKILL.md");
234
+ let manifest;
235
+ try {
236
+ manifest = await loadSkill(skillPath);
237
+ } catch {
238
+ continue; // validator will surface the load failure separately
239
+ }
240
+ const fm = manifest.frontmatter;
241
+ if (!fm || !fm.learns || fm.learns.enabled !== true) continue;
242
+ const learnFile =
243
+ typeof fm.learns.file === "string" && fm.learns.file
244
+ ? fm.learns.file
245
+ : undefined;
246
+ const p = resolveLearnFile(skillsDir, manifest.skillId, learnFile);
247
+ await fs.promises.mkdir(path.dirname(p), { recursive: true });
248
+ try {
249
+ await fs.promises.access(p);
250
+ } catch (err) {
251
+ if (err.code !== "ENOENT") throw err;
252
+ const header = `# AgileFlow skill learnings — ${manifest.skillId}\n# Append-only signals; oldest trimmed when count exceeds maxEntries.\nentries: []\n`;
253
+ await fs.promises.writeFile(p, header, "utf8");
254
+ created.push(manifest.skillId);
255
+ }
256
+ }
257
+ }
258
+ return created;
259
+ }
260
+
261
+ /**
262
+ * Standard docs folder layout that AgileFlow expects at the project root.
263
+ * Only created on first install (dirs that already exist are skipped).
264
+ */
265
+ const DOCS_DIRS = [
266
+ "docs/00-meta",
267
+ "docs/01-brainstorming",
268
+ "docs/02-practices",
269
+ "docs/03-decisions",
270
+ "docs/04-architecture",
271
+ "docs/05-epics",
272
+ "docs/06-stories",
273
+ "docs/07-testing",
274
+ "docs/08-project",
275
+ "docs/09-agents",
276
+ "docs/10-research",
277
+ ];
278
+
279
+ /**
280
+ * Scaffold the project docs folder on first install.
281
+ * Returns the list of dirs that were newly created.
282
+ * @param {string} projectRoot
283
+ * @returns {Promise<string[]>}
284
+ */
285
+ async function scaffoldDocs(projectRoot) {
286
+ const created = [];
287
+ for (const rel of DOCS_DIRS) {
288
+ const dir = path.join(projectRoot, rel);
289
+ try {
290
+ await fs.promises.access(dir);
291
+ } catch (err) {
292
+ if (err.code !== "ENOENT") throw err;
293
+ await fs.promises.mkdir(dir, { recursive: true });
294
+ created.push(rel);
295
+ }
296
+ }
297
+
298
+ // Seed docs/09-agents/status.json only when newly created.
299
+ if (created.includes("docs/09-agents")) {
300
+ const statusPath = path.join(projectRoot, "docs/09-agents/status.json");
301
+ const seed = JSON.stringify(
302
+ { updated: new Date().toISOString(), epics: {}, stories: {} },
303
+ null,
304
+ 2,
305
+ );
306
+ await fs.promises.writeFile(statusPath, seed + "\n", "utf8");
307
+ }
308
+
309
+ // Seed docs/00-meta/agileflow-metadata.json only when newly created.
310
+ if (created.includes("docs/00-meta")) {
311
+ const metaPath = path.join(
312
+ projectRoot,
313
+ "docs/00-meta/agileflow-metadata.json",
314
+ );
315
+ const seed = JSON.stringify(
316
+ {
317
+ version: "4.0.0",
318
+ created: new Date().toISOString(),
319
+ updated: new Date().toISOString(),
320
+ docsFolder: "docs",
321
+ archival: { threshold_days: 30, enabled: true },
322
+ features: {},
323
+ },
324
+ null,
325
+ 2,
326
+ );
327
+ await fs.promises.writeFile(metaPath, seed + "\n", "utf8");
328
+ }
329
+
330
+ return created;
331
+ }
332
+
194
333
  /**
195
334
  * @param {InstallOptions} options
196
335
  * @returns {Promise<InstallResult>}
@@ -201,11 +340,27 @@ async function installPlugins(options) {
201
340
  userSelected,
202
341
  agileflowDir,
203
342
  cliVersion,
204
- ide = "claude-code",
343
+ ide,
344
+ ides,
205
345
  behaviors,
346
+ learningsEnabled = true,
206
347
  force = false,
348
+ config,
207
349
  } = options;
208
350
 
351
+ // Resolve the multi-target list. Prefer `ides` (new); fall back to
352
+ // `ide` (legacy single-target callers — including current tests).
353
+ /** @type {string[]} */
354
+ const targetIdes =
355
+ Array.isArray(ides) && ides.length
356
+ ? ides
357
+ : typeof ide === "string" && ide
358
+ ? [ide]
359
+ : ["claude-code"];
360
+ // Per-target capabilities; first target is the "primary" used to
361
+ // decide hook-manifest / settings.json writes.
362
+ const primaryIde = targetIdes[0];
363
+
209
364
  // 1. Strict-validate. Errors abort; warnings are surfaced elsewhere.
210
365
  const issues = validatePluginSet(discovered);
211
366
  if (hasErrors(issues)) {
@@ -266,9 +421,18 @@ async function installPlugins(options) {
266
421
  // contribution NOW prevents step 8 from registering hook
267
422
  // dispatchers in settings.json that point at an unparseable
268
423
  // manifest.
269
- const caps = capabilitiesFor(ide);
424
+ //
425
+ // Hook manifest is a global artifact (only one .agileflow/
426
+ // hook-manifest.yaml exists per project). We write it whenever ANY
427
+ // selected target supports hooks; otherwise we remove any stale
428
+ // manifest from a prior hook-capable install.
429
+ const targetCaps = targetIdes.map((id) => ({
430
+ id,
431
+ caps: capabilitiesFor(id),
432
+ }));
433
+ const anyHooks = targetCaps.some(({ caps }) => caps.hooks);
270
434
  let hookManifestPath = null;
271
- if (caps.hooks) {
435
+ if (anyHooks) {
272
436
  const manifestObj = buildHookManifest(ordered, behaviors);
273
437
  try {
274
438
  normalizeManifest(manifestObj);
@@ -284,31 +448,87 @@ async function installPlugins(options) {
284
448
  await removeAggregatedManifest(agileflowDir);
285
449
  }
286
450
 
287
- // 8. Register or unregister our hook dispatchers in
288
- // `.claude/settings.json`. Only when ide=claude-code.
451
+ // 8. Register hook dispatchers in `.claude/settings.json` iff
452
+ // claude-code is in the target set; otherwise remove any prior
453
+ // registration we may have written.
289
454
  const projectRoot = path.dirname(agileflowDir);
290
455
  let settingsPath = null;
291
- if (ide === "claude-code") {
456
+ let agentsMirrored = [];
457
+ let agentsSkipped = [];
458
+ if (targetIdes.includes("claude-code")) {
292
459
  settingsPath = await writeClaudeCodeSettings(projectRoot);
460
+ const agentMirror = await mirrorClaudeCodeAgents(ordered, projectRoot);
461
+ agentsMirrored = agentMirror.mirrored;
462
+ agentsSkipped = agentMirror.skipped;
293
463
  } else {
294
464
  await removeClaudeCodeSettings(projectRoot);
465
+ await unmirrorClaudeCodeAgents(projectRoot);
295
466
  }
296
467
 
297
- // 9. Mirror skills into `.claude/skills/<id>/`. Copy (not symlink)
298
- // for Windows portability. Missing skill sources are skipped
299
- // gracefully; non-ENOENT errors propagate.
300
- let skillsMirrored = [];
301
- let skillsPruned = [];
302
- let skillsSkipped = [];
303
- if (caps.skills) {
304
- const r = await mirrorClaudeCodeSkills(ordered, projectRoot);
305
- skillsMirrored = r.mirrored;
306
- skillsPruned = r.pruned;
307
- skillsSkipped = r.skipped || [];
468
+ let codexConfigPath = null;
469
+ if (targetIdes.includes("codex")) {
470
+ codexConfigPath = await writeCodexConfig(projectRoot);
308
471
  } else {
309
- skillsPruned = await unmirrorClaudeCodeSkills(projectRoot);
472
+ await removeCodexConfig(projectRoot);
310
473
  }
311
474
 
475
+ // 9. Mirror skills into EACH selected IDE's skills dir. For IDEs that
476
+ // don't support skills, unmirror so a previous install doesn't
477
+ // leave stale files behind.
478
+ /** @type {Set<string>} */
479
+ const mirroredSet = new Set();
480
+ /** @type {Set<string>} */
481
+ const prunedSet = new Set();
482
+ /** @type {Array<{skillId:string, error:string}>} */
483
+ let skillsSkipped = [];
484
+ for (const target of targetCaps) {
485
+ const { caps } = target;
486
+ if (caps.skills) {
487
+ const r = await mirrorClaudeCodeSkills(
488
+ ordered,
489
+ projectRoot,
490
+ caps.skillsDir,
491
+ {
492
+ targetIde: target.id,
493
+ config,
494
+ },
495
+ );
496
+ r.mirrored.forEach((s) => mirroredSet.add(s));
497
+ r.pruned.forEach((s) => prunedSet.add(s));
498
+ if (r.skipped) skillsSkipped = skillsSkipped.concat(r.skipped);
499
+ } else {
500
+ const removed = await unmirrorClaudeCodeSkills(
501
+ projectRoot,
502
+ caps.skillsDir,
503
+ );
504
+ removed.forEach((s) => prunedSet.add(s));
505
+ }
506
+ }
507
+ // Also unmirror from any *unselected* IDE's skills dir so a
508
+ // re-install with a narrower target set actually removes the old
509
+ // mirrors. Cheap belt-and-suspenders — unmirror is a no-op when the
510
+ // dir doesn't exist.
511
+ for (const id of SUPPORTED_IDES) {
512
+ if (targetIdes.includes(id)) continue;
513
+ const caps = capabilitiesFor(id);
514
+ const removed = await unmirrorClaudeCodeSkills(projectRoot, caps.skillsDir);
515
+ removed.forEach((s) => prunedSet.add(s));
516
+ }
517
+ const skillsMirrored = [...mirroredSet];
518
+ const skillsPruned = [...prunedSet];
519
+ const anySkills = targetCaps.some(({ caps }) => caps.skills);
520
+
521
+ // 10. Scaffold the project docs folder on first install.
522
+ const docsScaffolded = await scaffoldDocs(projectRoot);
523
+
524
+ // 11. Scaffold persistent learnings files for skills that opt in.
525
+ // Lives in .agileflow/skills/_learnings/ — outside the mirror wipe
526
+ // zone so re-installs never destroy accumulated signals.
527
+ const learningsScaffolded =
528
+ anySkills && learningsEnabled
529
+ ? await scaffoldSkillLearnings(ordered, projectRoot)
530
+ : [];
531
+
312
532
  return {
313
533
  ordered: ordered.map((p) => p.id),
314
534
  autoEnabled,
@@ -319,10 +539,18 @@ async function installPlugins(options) {
319
539
  timestamp,
320
540
  hookManifestPath,
321
541
  settingsPath,
542
+ codexConfigPath,
322
543
  skillsMirrored,
323
544
  skillsPruned,
324
545
  skillsSkipped,
325
- ide,
546
+ agentsMirrored,
547
+ agentsSkipped,
548
+ docsScaffolded,
549
+ learningsScaffolded,
550
+ ides: targetIdes,
551
+ // Back-compat: keep `ide` as the primary so existing callers /
552
+ // test assertions keep working without a sweep.
553
+ ide: primaryIde,
326
554
  };
327
555
  }
328
556
 
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Install / uninstall the `af` short alias for `agileflow launch`.
3
+ *
4
+ * Strategy: symlink `~/.local/bin/af` → the active `agileflow` binary.
5
+ * `~/.local/bin` is the XDG-standard user-scoped bin directory — no
6
+ * sudo required, no global mutation. Most modern Linux/macOS setups
7
+ * include it on PATH (via `~/.profile` / `~/.zprofile`); if not, we
8
+ * surface a clear warning telling the user how to add it.
9
+ *
10
+ * On Windows the symlink approach is fragile (requires Developer Mode
11
+ * or admin); slice 1 reports `unsupported` and the user can copy the
12
+ * suggested PowerShell function from the warning. Slice 4 can add a
13
+ * proper Windows shim.
14
+ */
15
+ const fs = require("fs");
16
+ const os = require("os");
17
+ const path = require("path");
18
+
19
+ /**
20
+ * Resolve where the `af` symlink should live.
21
+ *
22
+ * @param {string} [home]
23
+ * @returns {string}
24
+ */
25
+ function aliasPath(home) {
26
+ return path.join(home || os.homedir(), ".local", "bin", "af");
27
+ }
28
+
29
+ /**
30
+ * Best-effort: locate the `agileflow` binary that should be the symlink
31
+ * target. Prefers `process.argv[1]` (the script Node was invoked with)
32
+ * which is what the user actually ran — falls back to "agileflow" so
33
+ * the symlink resolves via PATH if the absolute path can't be inferred.
34
+ *
35
+ * @param {NodeJS.Process} [proc]
36
+ * @returns {string}
37
+ */
38
+ function resolveAgileflowBin(proc = process) {
39
+ const argv1 = proc && proc.argv && proc.argv[1];
40
+ if (argv1) {
41
+ try {
42
+ const resolved = fs.realpathSync(argv1);
43
+ return resolved;
44
+ } catch {
45
+ /* fall through */
46
+ }
47
+ }
48
+ return "agileflow";
49
+ }
50
+
51
+ /**
52
+ * Check whether `~/.local/bin` is on the user's PATH.
53
+ *
54
+ * @param {string} [home]
55
+ * @param {string} [pathEnv]
56
+ * @returns {boolean}
57
+ */
58
+ function localBinOnPath(home, pathEnv) {
59
+ const target = path.join(home || os.homedir(), ".local", "bin");
60
+ const env = typeof pathEnv === "string" ? pathEnv : process.env.PATH || "";
61
+ const sep = process.platform === "win32" ? ";" : ":";
62
+ return env
63
+ .split(sep)
64
+ .map((p) => p.replace(/[/\\]+$/, ""))
65
+ .includes(target.replace(/[/\\]+$/, ""));
66
+ }
67
+
68
+ /**
69
+ * @typedef {Object} AliasInstallResult
70
+ * @property {'installed' | 'updated' | 'unchanged' | 'unsupported' | 'failed'} status
71
+ * @property {string} path - where the symlink was written (or attempted)
72
+ * @property {string} [target] - what it points at, when installed
73
+ * @property {string} [message] - human-readable detail (for failures / warnings)
74
+ * @property {boolean} [onPath] - whether the alias directory is on PATH
75
+ */
76
+
77
+ /**
78
+ * Create or refresh the `af` symlink.
79
+ *
80
+ * @param {{ home?: string, proc?: NodeJS.Process }} [opts]
81
+ * @returns {Promise<AliasInstallResult>}
82
+ */
83
+ async function installAfAlias(opts = {}) {
84
+ if (process.platform === "win32") {
85
+ return {
86
+ status: "unsupported",
87
+ path: aliasPath(opts.home),
88
+ message:
89
+ "Windows symlinks require Developer Mode or admin. Slice 4 will add a proper shim. " +
90
+ "For now: add `function af { agileflow launch @args }` to your PowerShell profile.",
91
+ };
92
+ }
93
+
94
+ const link = aliasPath(opts.home);
95
+ const target = resolveAgileflowBin(opts.proc);
96
+ const onPath = localBinOnPath(opts.home);
97
+
98
+ try {
99
+ await fs.promises.mkdir(path.dirname(link), { recursive: true });
100
+
101
+ // If a symlink already exists, check whether it points at the same target.
102
+ let existing = null;
103
+ try {
104
+ existing = await fs.promises.readlink(link);
105
+ } catch {
106
+ /* not a symlink or absent */
107
+ }
108
+
109
+ if (existing === target) {
110
+ return { status: "unchanged", path: link, target, onPath };
111
+ }
112
+
113
+ // Remove anything in the way (broken symlink, old file). Don't blow
114
+ // away a non-symlink regular file — the user may have put it there.
115
+ let removed = false;
116
+ try {
117
+ const stat = await fs.promises.lstat(link);
118
+ if (stat.isSymbolicLink()) {
119
+ await fs.promises.unlink(link);
120
+ removed = true;
121
+ } else {
122
+ return {
123
+ status: "failed",
124
+ path: link,
125
+ message: `${link} exists and is not a symlink — leaving it alone. Remove it manually if you want the alias.`,
126
+ onPath,
127
+ };
128
+ }
129
+ } catch {
130
+ /* doesn't exist — fine */
131
+ }
132
+
133
+ await fs.promises.symlink(target, link);
134
+ return {
135
+ status: removed ? "updated" : "installed",
136
+ path: link,
137
+ target,
138
+ onPath,
139
+ };
140
+ } catch (err) {
141
+ return {
142
+ status: "failed",
143
+ path: link,
144
+ message: `could not create symlink: ${err.message}`,
145
+ onPath,
146
+ };
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Remove the `af` symlink if it points at agileflow. Safe no-op otherwise.
152
+ *
153
+ * @param {{ home?: string }} [opts]
154
+ * @returns {Promise<{ status: 'removed' | 'absent' | 'skipped' | 'failed', path: string, message?: string }>}
155
+ */
156
+ async function uninstallAfAlias(opts = {}) {
157
+ const link = aliasPath(opts.home);
158
+ try {
159
+ const stat = await fs.promises.lstat(link);
160
+ if (!stat.isSymbolicLink()) {
161
+ return {
162
+ status: "skipped",
163
+ path: link,
164
+ message: `${link} is not a symlink — leaving it alone.`,
165
+ };
166
+ }
167
+ const target = await fs.promises.readlink(link);
168
+ if (!/agileflow/i.test(target)) {
169
+ return {
170
+ status: "skipped",
171
+ path: link,
172
+ message: `${link} points at ${target}; not removing.`,
173
+ };
174
+ }
175
+ await fs.promises.unlink(link);
176
+ return { status: "removed", path: link };
177
+ } catch (err) {
178
+ if (err && err.code === "ENOENT") {
179
+ return { status: "absent", path: link };
180
+ }
181
+ return { status: "failed", path: link, message: err.message };
182
+ }
183
+ }
184
+
185
+ module.exports = {
186
+ aliasPath,
187
+ resolveAgileflowBin,
188
+ localBinOnPath,
189
+ installAfAlias,
190
+ uninstallAfAlias,
191
+ };