agileflow 3.4.3 → 4.0.0-alpha.10

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 (1093) hide show
  1. package/CHANGELOG.md +294 -478
  2. package/README.md +22 -114
  3. package/bin/agileflow.js +15 -0
  4. package/bin/hooks/pre-bash.js +35 -0
  5. package/bin/hooks/pre-compact.js +34 -0
  6. package/bin/hooks/pre-edit.js +32 -0
  7. package/bin/hooks/pre-write.js +32 -0
  8. package/bin/hooks/session-start.js +42 -0
  9. package/bin/hooks/stop.js +34 -0
  10. package/content/plugins/accessibility/plugin.yaml +14 -0
  11. package/content/plugins/accessibility/skills/agileflow-accessibility/SKILL.md +392 -0
  12. package/content/plugins/accessibility/skills/agileflow-accessibility/references/aria-patterns.md +528 -0
  13. package/content/plugins/accessibility/skills/agileflow-accessibility/references/testing-checklist.md +457 -0
  14. package/content/plugins/accessibility/skills/agileflow-accessibility/references/wcag-guide.md +683 -0
  15. package/content/plugins/accessibility/skills/agileflow-accessibility/workflows/audit-page.md +310 -0
  16. package/content/plugins/accessibility/skills/agileflow-accessibility/workflows/implement-accessible-component.md +479 -0
  17. package/content/plugins/ads/agents/ads-audit-budget.md +185 -0
  18. package/content/plugins/ads/agents/ads-audit-compliance.md +171 -0
  19. package/content/plugins/ads/agents/ads-audit-creative.md +168 -0
  20. package/content/plugins/ads/agents/ads-audit-google.md +227 -0
  21. package/content/plugins/ads/agents/ads-audit-meta.md +184 -0
  22. package/content/plugins/ads/agents/ads-audit-tracking.md +205 -0
  23. package/content/plugins/ads/agents/ads-consensus.md +410 -0
  24. package/content/plugins/ads/agents/ads-generate.md +152 -0
  25. package/content/plugins/ads/agents/ads-performance-tracker.md +212 -0
  26. package/content/plugins/ads/plugin.yaml +33 -0
  27. package/content/plugins/ads/skills/agileflow-ads/SKILL.md +218 -0
  28. package/content/plugins/ads/skills/agileflow-ads/references/ad-copy-formula-guide.md +131 -0
  29. package/content/plugins/ads/skills/agileflow-ads/references/audience-targeting-guide.md +137 -0
  30. package/content/plugins/ads/skills/agileflow-ads/references/bid-strategy-guide.md +115 -0
  31. package/content/plugins/ads/skills/agileflow-ads/references/platform-benchmarks.md +100 -0
  32. package/content/plugins/ads/skills/agileflow-ads/workflows/audit.md +118 -0
  33. package/content/plugins/ads/skills/agileflow-ads/workflows/generate.md +84 -0
  34. package/content/plugins/audit/agents/a11y-analyzer-aria.md +173 -0
  35. package/content/plugins/audit/agents/a11y-analyzer-forms.md +173 -0
  36. package/content/plugins/audit/agents/a11y-analyzer-keyboard.md +183 -0
  37. package/content/plugins/audit/agents/a11y-analyzer-semantic.md +169 -0
  38. package/content/plugins/audit/agents/a11y-analyzer-visual.md +172 -0
  39. package/content/plugins/audit/agents/a11y-consensus.md +249 -0
  40. package/content/plugins/audit/agents/accessibility.md +558 -0
  41. package/content/plugins/audit/agents/api-quality-analyzer-conventions.md +156 -0
  42. package/content/plugins/audit/agents/api-quality-analyzer-docs.md +184 -0
  43. package/content/plugins/audit/agents/api-quality-analyzer-errors.md +191 -0
  44. package/content/plugins/audit/agents/api-quality-analyzer-pagination.md +179 -0
  45. package/content/plugins/audit/agents/api-quality-analyzer-versioning.md +150 -0
  46. package/content/plugins/audit/agents/api-quality-consensus.md +217 -0
  47. package/content/plugins/audit/agents/api-validator.md +191 -0
  48. package/content/plugins/audit/agents/arch-analyzer-circular.md +156 -0
  49. package/content/plugins/audit/agents/arch-analyzer-complexity.md +193 -0
  50. package/content/plugins/audit/agents/arch-analyzer-coupling.md +152 -0
  51. package/content/plugins/audit/agents/arch-analyzer-layering.md +160 -0
  52. package/content/plugins/audit/agents/arch-analyzer-patterns.md +210 -0
  53. package/content/plugins/audit/agents/arch-consensus.md +228 -0
  54. package/content/plugins/audit/agents/browser-qa.md +342 -0
  55. package/content/plugins/audit/agents/code-reviewer.md +298 -0
  56. package/content/plugins/audit/agents/completeness-analyzer-api.md +199 -0
  57. package/content/plugins/audit/agents/completeness-analyzer-conditional.md +211 -0
  58. package/content/plugins/audit/agents/completeness-analyzer-handlers.md +166 -0
  59. package/content/plugins/audit/agents/completeness-analyzer-imports.md +165 -0
  60. package/content/plugins/audit/agents/completeness-analyzer-routes.md +190 -0
  61. package/content/plugins/audit/agents/completeness-analyzer-state.md +196 -0
  62. package/content/plugins/audit/agents/completeness-analyzer-stubs.md +206 -0
  63. package/content/plugins/audit/agents/completeness-consensus.md +295 -0
  64. package/content/plugins/audit/agents/error-analyzer.md +213 -0
  65. package/content/plugins/audit/agents/flow-analyzer-authorization.md +182 -0
  66. package/content/plugins/audit/agents/flow-analyzer-discovery.md +174 -0
  67. package/content/plugins/audit/agents/flow-analyzer-errors.md +186 -0
  68. package/content/plugins/audit/agents/flow-analyzer-feedback.md +185 -0
  69. package/content/plugins/audit/agents/flow-analyzer-navigation.md +177 -0
  70. package/content/plugins/audit/agents/flow-analyzer-persistence.md +193 -0
  71. package/content/plugins/audit/agents/flow-analyzer-wiring.md +169 -0
  72. package/content/plugins/audit/agents/flow-consensus.md +237 -0
  73. package/content/plugins/audit/agents/legal-analyzer-a11y.md +114 -0
  74. package/content/plugins/audit/agents/legal-analyzer-ai.md +121 -0
  75. package/content/plugins/audit/agents/legal-analyzer-consumer.md +114 -0
  76. package/content/plugins/audit/agents/legal-analyzer-content.md +117 -0
  77. package/content/plugins/audit/agents/legal-analyzer-international.md +119 -0
  78. package/content/plugins/audit/agents/legal-analyzer-licensing.md +119 -0
  79. package/content/plugins/audit/agents/legal-analyzer-privacy.md +112 -0
  80. package/content/plugins/audit/agents/legal-analyzer-security.md +116 -0
  81. package/content/plugins/audit/agents/legal-analyzer-terms.md +115 -0
  82. package/content/plugins/audit/agents/legal-consensus.md +250 -0
  83. package/content/plugins/audit/agents/logic-analyzer-edge.md +179 -0
  84. package/content/plugins/audit/agents/logic-analyzer-flow.md +264 -0
  85. package/content/plugins/audit/agents/logic-analyzer-invariant.md +215 -0
  86. package/content/plugins/audit/agents/logic-analyzer-race.md +280 -0
  87. package/content/plugins/audit/agents/logic-analyzer-type.md +227 -0
  88. package/content/plugins/audit/agents/logic-consensus.md +259 -0
  89. package/content/plugins/audit/agents/perf-analyzer-assets.md +182 -0
  90. package/content/plugins/audit/agents/perf-analyzer-bundle.md +173 -0
  91. package/content/plugins/audit/agents/perf-analyzer-caching.md +170 -0
  92. package/content/plugins/audit/agents/perf-analyzer-compute.md +173 -0
  93. package/content/plugins/audit/agents/perf-analyzer-memory.md +193 -0
  94. package/content/plugins/audit/agents/perf-analyzer-network.md +165 -0
  95. package/content/plugins/audit/agents/perf-analyzer-queries.md +162 -0
  96. package/content/plugins/audit/agents/perf-analyzer-rendering.md +168 -0
  97. package/content/plugins/audit/agents/perf-consensus.md +287 -0
  98. package/content/plugins/audit/agents/qa.md +820 -0
  99. package/content/plugins/audit/agents/quality-analyzer-comments.md +159 -0
  100. package/content/plugins/audit/agents/quality-analyzer-duplication.md +184 -0
  101. package/content/plugins/audit/agents/quality-analyzer-naming.md +160 -0
  102. package/content/plugins/audit/agents/quality-consensus.md +241 -0
  103. package/content/plugins/audit/agents/schema-validator.md +473 -0
  104. package/content/plugins/audit/agents/security-analyzer-api.md +210 -0
  105. package/content/plugins/audit/agents/security-analyzer-auth.md +169 -0
  106. package/content/plugins/audit/agents/security-analyzer-authz.md +180 -0
  107. package/content/plugins/audit/agents/security-analyzer-deps.md +153 -0
  108. package/content/plugins/audit/agents/security-analyzer-infra.md +184 -0
  109. package/content/plugins/audit/agents/security-analyzer-injection.md +155 -0
  110. package/content/plugins/audit/agents/security-analyzer-input.md +201 -0
  111. package/content/plugins/audit/agents/security-analyzer-secrets.md +183 -0
  112. package/content/plugins/audit/agents/security-consensus.md +283 -0
  113. package/content/plugins/audit/agents/test-analyzer-assertions.md +188 -0
  114. package/content/plugins/audit/agents/test-analyzer-coverage.md +189 -0
  115. package/content/plugins/audit/agents/test-analyzer-fragility.md +193 -0
  116. package/content/plugins/audit/agents/test-analyzer-integration.md +161 -0
  117. package/content/plugins/audit/agents/test-analyzer-maintenance.md +180 -0
  118. package/content/plugins/audit/agents/test-analyzer-mocking.md +188 -0
  119. package/content/plugins/audit/agents/test-analyzer-patterns.md +196 -0
  120. package/content/plugins/audit/agents/test-analyzer-structure.md +184 -0
  121. package/content/plugins/audit/agents/test-consensus.md +301 -0
  122. package/content/plugins/audit/agents/testing.md +561 -0
  123. package/content/plugins/audit/agents/ui-validator.md +344 -0
  124. package/content/plugins/audit/plugin.yaml +195 -0
  125. package/content/plugins/audit/skills/agileflow-audit/SKILL.md +113 -0
  126. package/content/plugins/audit/skills/agileflow-audit/references/audit-depth-guide.md +151 -0
  127. package/content/plugins/audit/skills/agileflow-audit/references/dependency-risk-guide.md +139 -0
  128. package/content/plugins/audit/skills/agileflow-audit/references/owasp-top10.md +120 -0
  129. package/content/plugins/audit/skills/agileflow-audit/references/performance-budget-guide.md +143 -0
  130. package/content/plugins/audit/skills/agileflow-audit/references/wcag-criteria.md +117 -0
  131. package/content/plugins/audit/skills/agileflow-audit/workflows/run-audit.md +52 -0
  132. package/content/plugins/audit/skills/agileflow-audit/workflows/tdd.md +66 -0
  133. package/content/plugins/core/agents/adr-writer.md +521 -0
  134. package/content/plugins/core/agents/epic-planner.md +520 -0
  135. package/content/plugins/core/agents/mentor.md +709 -0
  136. package/content/plugins/core/agents/orchestrator.md +776 -0
  137. package/content/plugins/core/agents/team-coordinator.md +334 -0
  138. package/content/plugins/core/agents/team-lead.md +181 -0
  139. package/content/plugins/core/agents/workspace-orchestrator.md +146 -0
  140. package/content/plugins/core/hooks/context-loader.js +196 -0
  141. package/content/plugins/core/hooks/damage-control-bash.js +86 -0
  142. package/content/plugins/core/hooks/damage-control-edit.js +79 -0
  143. package/content/plugins/core/hooks/damage-control-patterns.yaml +100 -0
  144. package/content/plugins/core/hooks/damage-control-write.js +75 -0
  145. package/content/plugins/core/hooks/post-compact-state.js +107 -0
  146. package/content/plugins/core/hooks/preferences-injector.js +352 -0
  147. package/content/plugins/core/hooks/session-welcome.js +19 -0
  148. package/content/plugins/core/plugin.yaml +78 -0
  149. package/content/plugins/core/skills/agileflow-adr/SKILL.md +205 -0
  150. package/content/plugins/core/skills/agileflow-adr/references/madr-format-guide.md +86 -0
  151. package/content/plugins/core/skills/agileflow-adr/workflows/write-adr.md +57 -0
  152. package/content/plugins/core/skills/agileflow-babysit-mentor/SKILL.md +211 -0
  153. package/content/plugins/core/skills/agileflow-babysit-mentor/references/mentor-decision-guide.md +81 -0
  154. package/content/plugins/core/skills/agileflow-babysit-mentor/workflows/mentor-session.md +79 -0
  155. package/content/plugins/core/skills/agileflow-epic-planner/SKILL.md +209 -0
  156. package/content/plugins/core/skills/agileflow-epic-planner/references/epic-sizing-guide.md +81 -0
  157. package/content/plugins/core/skills/agileflow-epic-planner/workflows/plan-epic.md +55 -0
  158. package/content/plugins/core/skills/agileflow-status-updater/SKILL.md +148 -0
  159. package/content/plugins/core/skills/agileflow-status-updater/references/status-transitions.md +89 -0
  160. package/content/plugins/core/skills/agileflow-status-updater/workflows/update-status.md +56 -0
  161. package/content/plugins/core/skills/agileflow-story-writer/SKILL.md +125 -0
  162. package/content/plugins/core/skills/agileflow-story-writer/references/estimation-reference.md +36 -0
  163. package/content/plugins/core/skills/agileflow-story-writer/references/story-template.md +92 -0
  164. package/content/plugins/core/skills/agileflow-story-writer/workflows/write-story.md +138 -0
  165. package/content/plugins/council/agents/council-advocate.md +223 -0
  166. package/content/plugins/council/agents/council-analyst.md +278 -0
  167. package/content/plugins/council/agents/council-compounder.md +204 -0
  168. package/content/plugins/council/agents/council-contrarian.md +217 -0
  169. package/content/plugins/council/agents/council-moonshot.md +217 -0
  170. package/content/plugins/council/agents/council-optimist.md +185 -0
  171. package/content/plugins/council/agents/council-revenue.md +200 -0
  172. package/content/plugins/council/agents/council-technical.md +218 -0
  173. package/content/plugins/council/agents/multi-expert.md +334 -0
  174. package/content/plugins/council/plugin.yaml +33 -0
  175. package/content/plugins/council/skills/agileflow-council/SKILL.md +102 -0
  176. package/content/plugins/council/skills/agileflow-council/references/decision-log-template.md +109 -0
  177. package/content/plugins/council/skills/agileflow-council/references/perspective-guide.md +104 -0
  178. package/content/plugins/council/skills/agileflow-council/references/when-to-convene-guide.md +112 -0
  179. package/content/plugins/council/skills/agileflow-council/workflows/convene.md +73 -0
  180. package/content/plugins/council/skills/agileflow-council/workflows/multi-expert.md +75 -0
  181. package/content/plugins/database/plugin.yaml +14 -0
  182. package/content/plugins/database/skills/agileflow-database/SKILL.md +284 -0
  183. package/content/plugins/database/skills/agileflow-database/references/indexing-guide.md +313 -0
  184. package/content/plugins/database/skills/agileflow-database/references/migration-guide.md +328 -0
  185. package/content/plugins/database/skills/agileflow-database/references/schema-design-guide.md +467 -0
  186. package/content/plugins/database/skills/agileflow-database/workflows/design-schema.md +213 -0
  187. package/content/plugins/database/skills/agileflow-database/workflows/optimize-query.md +253 -0
  188. package/content/plugins/debugging/plugin.yaml +14 -0
  189. package/content/plugins/debugging/skills/agileflow-debug/SKILL.md +236 -0
  190. package/content/plugins/debugging/skills/agileflow-debug/references/common-patterns.md +350 -0
  191. package/content/plugins/debugging/skills/agileflow-debug/references/debugging-strategies.md +328 -0
  192. package/content/plugins/debugging/skills/agileflow-debug/workflows/debug-issue.md +187 -0
  193. package/content/plugins/debugging/skills/agileflow-debug/workflows/reproduce-bug.md +194 -0
  194. package/content/plugins/delivery/agents/ci.md +547 -0
  195. package/content/plugins/delivery/agents/devops.md +789 -0
  196. package/content/plugins/delivery/plugin.yaml +19 -0
  197. package/content/plugins/delivery/skills/agileflow-delivery/SKILL.md +111 -0
  198. package/content/plugins/delivery/skills/agileflow-delivery/references/changelog-format-guide.md +133 -0
  199. package/content/plugins/delivery/skills/agileflow-delivery/references/ci-pipeline-guide.md +158 -0
  200. package/content/plugins/delivery/skills/agileflow-delivery/references/pr-checklist-guide.md +133 -0
  201. package/content/plugins/delivery/skills/agileflow-delivery/references/release-checklist.md +142 -0
  202. package/content/plugins/delivery/skills/agileflow-delivery/workflows/changelog.md +72 -0
  203. package/content/plugins/delivery/skills/agileflow-delivery/workflows/deploy.md +74 -0
  204. package/content/plugins/delivery/skills/agileflow-delivery/workflows/pr.md +75 -0
  205. package/content/plugins/docs/agents/documentation.md +544 -0
  206. package/content/plugins/docs/agents/readme-updater.md +640 -0
  207. package/content/plugins/docs/plugin.yaml +19 -0
  208. package/content/plugins/docs/skills/agileflow-docs/SKILL.md +106 -0
  209. package/content/plugins/docs/skills/agileflow-docs/references/api-doc-template.md +167 -0
  210. package/content/plugins/docs/skills/agileflow-docs/references/doc-types-guide.md +141 -0
  211. package/content/plugins/docs/skills/agileflow-docs/references/readme-template.md +156 -0
  212. package/content/plugins/docs/skills/agileflow-docs/workflows/readme-sync.md +57 -0
  213. package/content/plugins/docs/skills/agileflow-docs/workflows/sync.md +64 -0
  214. package/content/plugins/engineering/agents/api.md +718 -0
  215. package/content/plugins/engineering/agents/codebase-query.md +285 -0
  216. package/content/plugins/engineering/agents/compliance.md +559 -0
  217. package/content/plugins/engineering/agents/database.md +644 -0
  218. package/content/plugins/engineering/agents/integrations.md +644 -0
  219. package/content/plugins/engineering/agents/mobile.md +552 -0
  220. package/content/plugins/engineering/agents/monitoring.md +585 -0
  221. package/content/plugins/engineering/agents/performance.md +529 -0
  222. package/content/plugins/engineering/agents/refactor.md +592 -0
  223. package/content/plugins/engineering/agents/security.md +524 -0
  224. package/content/plugins/engineering/agents/ui.md +1336 -0
  225. package/content/plugins/engineering/plugin.yaml +37 -0
  226. package/content/plugins/engineering/skills/agileflow-engineering/SKILL.md +127 -0
  227. package/content/plugins/engineering/skills/agileflow-engineering/references/code-review-guide.md +126 -0
  228. package/content/plugins/engineering/skills/agileflow-engineering/references/domain-routing-guide.md +89 -0
  229. package/content/plugins/engineering/skills/agileflow-engineering/references/refactoring-guide.md +136 -0
  230. package/content/plugins/engineering/skills/agileflow-engineering/workflows/diagnose.md +63 -0
  231. package/content/plugins/engineering/skills/agileflow-engineering/workflows/impact.md +60 -0
  232. package/content/plugins/ideation/agents/brainstorm-analyzer-features.md +179 -0
  233. package/content/plugins/ideation/agents/brainstorm-analyzer-growth.md +169 -0
  234. package/content/plugins/ideation/agents/brainstorm-analyzer-integration.md +181 -0
  235. package/content/plugins/ideation/agents/brainstorm-analyzer-market.md +150 -0
  236. package/content/plugins/ideation/agents/brainstorm-analyzer-ux.md +180 -0
  237. package/content/plugins/ideation/agents/brainstorm-consensus.md +245 -0
  238. package/content/plugins/ideation/agents/design.md +568 -0
  239. package/content/plugins/ideation/agents/product.md +582 -0
  240. package/content/plugins/ideation/plugin.yaml +31 -0
  241. package/content/plugins/ideation/skills/agileflow-ideation/SKILL.md +109 -0
  242. package/content/plugins/ideation/skills/agileflow-ideation/references/brainstorm-techniques.md +138 -0
  243. package/content/plugins/ideation/skills/agileflow-ideation/references/competitive-analysis-template.md +148 -0
  244. package/content/plugins/ideation/skills/agileflow-ideation/references/feature-prioritization-guide.md +147 -0
  245. package/content/plugins/ideation/skills/agileflow-ideation/references/user-story-patterns.md +152 -0
  246. package/content/plugins/ideation/skills/agileflow-ideation/workflows/features.md +65 -0
  247. package/content/plugins/ideation/skills/agileflow-ideation/workflows/ideate.md +54 -0
  248. package/content/plugins/migration/agents/datamigration.md +757 -0
  249. package/content/plugins/migration/plugin.yaml +17 -0
  250. package/content/plugins/migration/skills/agileflow-migration/SKILL.md +106 -0
  251. package/content/plugins/migration/skills/agileflow-migration/references/data-validation-checklist.md +154 -0
  252. package/content/plugins/migration/skills/agileflow-migration/references/migration-patterns.md +209 -0
  253. package/content/plugins/migration/skills/agileflow-migration/references/rollback-playbook.md +171 -0
  254. package/content/plugins/migration/skills/agileflow-migration/references/version-compatibility-matrix.md +155 -0
  255. package/content/plugins/migration/skills/agileflow-migration/workflows/plan.md +73 -0
  256. package/content/plugins/migration/skills/agileflow-migration/workflows/validate.md +71 -0
  257. package/content/plugins/performance/plugin.yaml +14 -0
  258. package/content/plugins/performance/skills/agileflow-performance/SKILL.md +224 -0
  259. package/content/plugins/performance/skills/agileflow-performance/references/optimization-patterns.md +554 -0
  260. package/content/plugins/performance/skills/agileflow-performance/references/profiling-guide.md +383 -0
  261. package/content/plugins/performance/skills/agileflow-performance/references/web-vitals-guide.md +360 -0
  262. package/content/plugins/performance/skills/agileflow-performance/workflows/improve-web-vitals.md +344 -0
  263. package/content/plugins/performance/skills/agileflow-performance/workflows/profile-and-fix.md +254 -0
  264. package/content/plugins/planning/agents/analytics.md +670 -0
  265. package/content/plugins/planning/agents/rlm-subcore.md +215 -0
  266. package/content/plugins/planning/plugin.yaml +19 -0
  267. package/content/plugins/planning/skills/agileflow-planning/SKILL.md +111 -0
  268. package/content/plugins/planning/skills/agileflow-planning/references/estimation-guide.md +114 -0
  269. package/content/plugins/planning/skills/agileflow-planning/references/rpi-workflow.md +119 -0
  270. package/content/plugins/planning/skills/agileflow-planning/references/sprint-planning-guide.md +145 -0
  271. package/content/plugins/planning/skills/agileflow-planning/workflows/impact.md +63 -0
  272. package/content/plugins/planning/skills/agileflow-planning/workflows/rpi.md +104 -0
  273. package/content/plugins/psychology/plugin.yaml +14 -0
  274. package/content/plugins/psychology/skills/agileflow-retention/SKILL.md +252 -0
  275. package/content/plugins/psychology/skills/agileflow-retention/references/competitor-analysis.md +240 -0
  276. package/content/plugins/psychology/skills/agileflow-retention/references/psychology-models.md +349 -0
  277. package/content/plugins/psychology/skills/agileflow-retention/references/retention-patterns.md +279 -0
  278. package/content/plugins/psychology/skills/agileflow-retention/workflows/design-retention-feature.md +287 -0
  279. package/content/plugins/psychology/skills/agileflow-retention/workflows/retention-audit.md +259 -0
  280. package/content/plugins/refactoring/plugin.yaml +14 -0
  281. package/content/plugins/refactoring/skills/agileflow-refactor/SKILL.md +235 -0
  282. package/content/plugins/refactoring/skills/agileflow-refactor/references/refactoring-patterns.md +405 -0
  283. package/content/plugins/refactoring/skills/agileflow-refactor/references/safety-checks.md +177 -0
  284. package/content/plugins/refactoring/skills/agileflow-refactor/workflows/extract-module.md +226 -0
  285. package/content/plugins/refactoring/skills/agileflow-refactor/workflows/safe-refactor.md +169 -0
  286. package/content/plugins/research/agents/research.md +503 -0
  287. package/content/plugins/research/plugin.yaml +17 -0
  288. package/content/plugins/research/skills/agileflow-research/SKILL.md +110 -0
  289. package/content/plugins/research/skills/agileflow-research/references/knowledge-decay-guide.md +121 -0
  290. package/content/plugins/research/skills/agileflow-research/references/research-prompt-guide.md +141 -0
  291. package/content/plugins/research/skills/agileflow-research/references/synthesis-template.md +154 -0
  292. package/content/plugins/research/skills/agileflow-research/workflows/analyze.md +60 -0
  293. package/content/plugins/research/skills/agileflow-research/workflows/ask.md +64 -0
  294. package/content/plugins/research/skills/agileflow-research/workflows/import.md +66 -0
  295. package/content/plugins/research/skills/agileflow-research/workflows/synthesize.md +66 -0
  296. package/content/plugins/reviews/plugin.yaml +14 -0
  297. package/content/plugins/reviews/skills/agileflow-pr-reviewer/SKILL.md +241 -0
  298. package/content/plugins/reviews/skills/agileflow-pr-reviewer/references/review-checklist.md +200 -0
  299. package/content/plugins/reviews/skills/agileflow-pr-reviewer/references/security-patterns.md +328 -0
  300. package/content/plugins/reviews/skills/agileflow-pr-reviewer/workflows/review-pr.md +153 -0
  301. package/content/plugins/reviews/skills/agileflow-pr-reviewer/workflows/security-review.md +177 -0
  302. package/content/plugins/seo/agents/seo-analyzer-content.md +169 -0
  303. package/content/plugins/seo/agents/seo-analyzer-images.md +198 -0
  304. package/content/plugins/seo/agents/seo-analyzer-performance.md +217 -0
  305. package/content/plugins/seo/agents/seo-analyzer-schema.md +184 -0
  306. package/content/plugins/seo/agents/seo-analyzer-sitemap.md +177 -0
  307. package/content/plugins/seo/agents/seo-analyzer-technical.md +151 -0
  308. package/content/plugins/seo/agents/seo-consensus.md +304 -0
  309. package/content/plugins/seo/plugin.yaml +29 -0
  310. package/content/plugins/seo/skills/agileflow-seo/SKILL.md +188 -0
  311. package/content/plugins/seo/skills/agileflow-seo/references/cwv-thresholds.md +110 -0
  312. package/content/plugins/seo/skills/agileflow-seo/references/eeat-framework.md +144 -0
  313. package/content/plugins/seo/skills/agileflow-seo/references/keyword-research-guide.md +125 -0
  314. package/content/plugins/seo/skills/agileflow-seo/references/schema-types.md +139 -0
  315. package/content/plugins/seo/skills/agileflow-seo/references/technical-seo-checklist.md +139 -0
  316. package/content/plugins/seo/skills/agileflow-seo/workflows/audit.md +98 -0
  317. package/content/plugins/seo/skills/agileflow-seo/workflows/page.md +118 -0
  318. package/content/plugins/testing/plugin.yaml +16 -0
  319. package/content/plugins/testing/skills/agileflow-test-writer/SKILL.md +260 -0
  320. package/content/plugins/testing/skills/agileflow-test-writer/references/coverage-targets.md +239 -0
  321. package/content/plugins/testing/skills/agileflow-test-writer/references/test-patterns.md +420 -0
  322. package/content/plugins/testing/skills/agileflow-test-writer/workflows/add-coverage.md +154 -0
  323. package/content/plugins/testing/skills/agileflow-test-writer/workflows/write-tests-from-ac.md +225 -0
  324. package/package.json +30 -50
  325. package/src/cli/commands/doctor.js +947 -0
  326. package/src/cli/commands/hook.js +83 -0
  327. package/src/cli/commands/launch.js +1385 -0
  328. package/src/cli/commands/learn.js +149 -0
  329. package/src/cli/commands/plugins.js +113 -0
  330. package/src/cli/commands/setup.js +637 -0
  331. package/src/cli/commands/skills.js +324 -0
  332. package/src/cli/commands/status.js +45 -0
  333. package/src/cli/commands/update.js +144 -0
  334. package/src/cli/index.js +137 -0
  335. package/src/cli/wizard/babysit-mode-picker.js +192 -0
  336. package/src/cli/wizard/behaviors-picker.js +262 -0
  337. package/src/cli/wizard/ide-picker.js +69 -0
  338. package/src/cli/wizard/install-scope-picker.js +57 -0
  339. package/src/cli/wizard/launch-alias-picker.js +50 -0
  340. package/src/cli/wizard/launch-cli-picker.js +129 -0
  341. package/src/cli/wizard/launch-tmux-picker.js +133 -0
  342. package/src/cli/wizard/learnings-picker.js +40 -0
  343. package/src/cli/wizard/plugin-picker.js +137 -0
  344. package/src/lib/brand.js +116 -0
  345. package/src/lib/errors.js +120 -0
  346. package/src/lib/hash.js +41 -0
  347. package/src/lib/path-check.js +39 -0
  348. package/src/runtime/config/defaults.js +66 -0
  349. package/src/runtime/config/loader.js +186 -0
  350. package/src/runtime/config/schema.json +126 -0
  351. package/src/runtime/config/writer.js +57 -0
  352. package/src/runtime/hooks/aggregator.js +157 -0
  353. package/src/runtime/hooks/chain.js +93 -0
  354. package/src/runtime/hooks/logger.js +68 -0
  355. package/src/runtime/hooks/manifest-loader.js +228 -0
  356. package/src/runtime/hooks/orchestrator.js +322 -0
  357. package/src/runtime/ide/babysit-skill.js +202 -0
  358. package/src/runtime/ide/capabilities.js +166 -0
  359. package/src/runtime/ide/claude-code-content.js +177 -0
  360. package/src/runtime/ide/claude-code-settings.js +272 -0
  361. package/src/runtime/ide/claude-code-skills.js +217 -0
  362. package/src/runtime/ide/codex-config.js +295 -0
  363. package/src/runtime/installer/file-index.js +112 -0
  364. package/src/runtime/installer/install.js +557 -0
  365. package/src/runtime/installer/stash.js +61 -0
  366. package/src/runtime/installer/sync-engine.js +205 -0
  367. package/src/runtime/launch/alias-installer.js +191 -0
  368. package/src/runtime/launch/cli-resume.js +244 -0
  369. package/src/runtime/launch/closed-windows.js +338 -0
  370. package/src/runtime/launch/defaults.js +66 -0
  371. package/src/runtime/launch/detect-clis.js +69 -0
  372. package/src/runtime/launch/doctor.js +464 -0
  373. package/src/runtime/launch/exec-wrapper.js +114 -0
  374. package/src/runtime/launch/parallel-session.js +247 -0
  375. package/src/runtime/launch/prefs.js +211 -0
  376. package/src/runtime/launch/project-prefs.js +234 -0
  377. package/src/runtime/launch/resolve-cli.js +56 -0
  378. package/src/runtime/launch/restore.js +142 -0
  379. package/src/runtime/launch/schema.json +75 -0
  380. package/src/runtime/launch/session-lifecycle.js +313 -0
  381. package/src/runtime/launch/session-registry.js +401 -0
  382. package/src/runtime/launch/spawn.js +103 -0
  383. package/src/runtime/launch/tabs.js +315 -0
  384. package/src/runtime/launch/tmux.js +654 -0
  385. package/src/runtime/launch/worktree.js +260 -0
  386. package/src/runtime/plugins/registry.js +137 -0
  387. package/src/runtime/plugins/resolver.js +138 -0
  388. package/src/runtime/plugins/validator.js +210 -0
  389. package/src/runtime/skills/learnings.js +308 -0
  390. package/src/runtime/skills/validator.js +335 -0
  391. package/lib/README.md +0 -178
  392. package/lib/api-routes.js +0 -625
  393. package/lib/api-server.js +0 -278
  394. package/lib/cache-provider.js +0 -155
  395. package/lib/codebase-indexer.js +0 -819
  396. package/lib/colors.generated.js +0 -117
  397. package/lib/colors.js +0 -341
  398. package/lib/consent.js +0 -232
  399. package/lib/content-sanitizer.js +0 -464
  400. package/lib/correlation.js +0 -277
  401. package/lib/drivers/claude-driver.ts +0 -312
  402. package/lib/drivers/codex-driver.ts +0 -464
  403. package/lib/drivers/driver-manager.ts +0 -159
  404. package/lib/drivers/gemini-driver.ts +0 -498
  405. package/lib/drivers/index.ts +0 -17
  406. package/lib/error-codes.js +0 -590
  407. package/lib/errors.js +0 -670
  408. package/lib/feature-flags.js +0 -171
  409. package/lib/feedback.js +0 -595
  410. package/lib/file-cache.js +0 -541
  411. package/lib/flag-detection.js +0 -344
  412. package/lib/format-error.js +0 -156
  413. package/lib/gate-runner.js +0 -282
  414. package/lib/generator-factory.js +0 -333
  415. package/lib/git-operations.js +0 -266
  416. package/lib/lazy-require.js +0 -59
  417. package/lib/lock-file.js +0 -144
  418. package/lib/logger.js +0 -106
  419. package/lib/merge-operations.js +0 -1006
  420. package/lib/path-resolver.js +0 -544
  421. package/lib/path-utils.js +0 -49
  422. package/lib/paths.js +0 -291
  423. package/lib/placeholder-registry.js +0 -822
  424. package/lib/process-executor.js +0 -214
  425. package/lib/progress.js +0 -334
  426. package/lib/protocol/driver.ts +0 -354
  427. package/lib/protocol/index.ts +0 -12
  428. package/lib/protocol/ir.ts +0 -271
  429. package/lib/registry-cache.js +0 -80
  430. package/lib/registry-di.js +0 -358
  431. package/lib/result-schema.js +0 -363
  432. package/lib/result.js +0 -210
  433. package/lib/session-display.js +0 -331
  434. package/lib/session-operations.js +0 -611
  435. package/lib/session-registry.js +0 -484
  436. package/lib/session-state-machine.js +0 -465
  437. package/lib/session-switching.js +0 -191
  438. package/lib/skill-loader.js +0 -213
  439. package/lib/smart-json-file.js +0 -682
  440. package/lib/state-machine.js +0 -286
  441. package/lib/table-formatter.js +0 -519
  442. package/lib/template-loader.js +0 -143
  443. package/lib/transient-status.js +0 -374
  444. package/lib/ui-manager.js +0 -612
  445. package/lib/validate-args.js +0 -213
  446. package/lib/validate-commands.js +0 -308
  447. package/lib/validate-names.js +0 -143
  448. package/lib/validate-paths.js +0 -434
  449. package/lib/validate.js +0 -134
  450. package/lib/worktree-operations.js +0 -201
  451. package/lib/yaml-utils.js +0 -164
  452. package/scripts/README.md +0 -267
  453. package/scripts/af +0 -34
  454. package/scripts/agent-loop.js +0 -879
  455. package/scripts/agileflow-configure.js +0 -368
  456. package/scripts/agileflow-statusline.sh +0 -857
  457. package/scripts/agileflow-welcome.js +0 -2246
  458. package/scripts/api-server-runner.js +0 -177
  459. package/scripts/archive-completed-stories.sh +0 -308
  460. package/scripts/auto-self-improve.js +0 -326
  461. package/scripts/automation-run-due.js +0 -128
  462. package/scripts/babysit-clear-restore.js +0 -154
  463. package/scripts/babysit-context-restore.js +0 -89
  464. package/scripts/backfill-ideation-status.js +0 -128
  465. package/scripts/batch-pmap-loop.js +0 -551
  466. package/scripts/check-sessions.js +0 -116
  467. package/scripts/check-update.js +0 -282
  468. package/scripts/ci-summary.js +0 -294
  469. package/scripts/claude-smart.sh +0 -85
  470. package/scripts/claude-tmux.sh +0 -737
  471. package/scripts/claude-watchdog.sh +0 -225
  472. package/scripts/clear-active-command.js +0 -48
  473. package/scripts/compress-status.sh +0 -116
  474. package/scripts/context-loader.js +0 -310
  475. package/scripts/damage-control/bash-tool-damage-control.js +0 -22
  476. package/scripts/damage-control/edit-tool-damage-control.js +0 -19
  477. package/scripts/damage-control/patterns.yaml +0 -227
  478. package/scripts/damage-control/write-tool-damage-control.js +0 -19
  479. package/scripts/damage-control-bash.js +0 -51
  480. package/scripts/damage-control-edit.js +0 -48
  481. package/scripts/damage-control-multi-agent.js +0 -231
  482. package/scripts/damage-control-write.js +0 -48
  483. package/scripts/dependency-check.js +0 -311
  484. package/scripts/document-repl.js +0 -793
  485. package/scripts/expertise-metrics.sh +0 -264
  486. package/scripts/generate-all.sh +0 -77
  487. package/scripts/generate-colors.js +0 -314
  488. package/scripts/generators/agent-registry.js +0 -183
  489. package/scripts/generators/command-registry.js +0 -166
  490. package/scripts/generators/index.js +0 -85
  491. package/scripts/generators/inject-babysit.js +0 -191
  492. package/scripts/generators/inject-help.js +0 -125
  493. package/scripts/generators/inject-readme.js +0 -166
  494. package/scripts/generators/skill-registry.js +0 -188
  495. package/scripts/get-env.js +0 -225
  496. package/scripts/init.sh +0 -76
  497. package/scripts/lib/README-portable-tasks.md +0 -424
  498. package/scripts/lib/ac-test-matcher.js +0 -452
  499. package/scripts/lib/audit-cleanup.js +0 -250
  500. package/scripts/lib/audit-registry.js +0 -340
  501. package/scripts/lib/automation-registry.js +0 -544
  502. package/scripts/lib/automation-runner.js +0 -476
  503. package/scripts/lib/browser-qa-evidence.js +0 -409
  504. package/scripts/lib/browser-qa-status.js +0 -192
  505. package/scripts/lib/bus-utils.js +0 -473
  506. package/scripts/lib/colors.generated.sh +0 -82
  507. package/scripts/lib/colors.sh +0 -46
  508. package/scripts/lib/command-prereqs.js +0 -280
  509. package/scripts/lib/concurrency-limiter.js +0 -511
  510. package/scripts/lib/configure-detect.js +0 -596
  511. package/scripts/lib/configure-features.js +0 -1927
  512. package/scripts/lib/configure-repair.js +0 -327
  513. package/scripts/lib/configure-utils.js +0 -114
  514. package/scripts/lib/context-formatter.js +0 -1158
  515. package/scripts/lib/context-loader.js +0 -840
  516. package/scripts/lib/counter.js +0 -103
  517. package/scripts/lib/damage-control-utils.js +0 -619
  518. package/scripts/lib/feature-catalog.js +0 -332
  519. package/scripts/lib/file-lock.js +0 -392
  520. package/scripts/lib/file-tracking.js +0 -735
  521. package/scripts/lib/frontmatter-parser.js +0 -133
  522. package/scripts/lib/gate-enforcer.js +0 -295
  523. package/scripts/lib/hook-metrics.js +0 -324
  524. package/scripts/lib/ideation-index.js +0 -1205
  525. package/scripts/lib/json-utils.sh +0 -162
  526. package/scripts/lib/lifecycle-detector.js +0 -125
  527. package/scripts/lib/model-profiles.js +0 -118
  528. package/scripts/lib/portable-tasks-cli.js +0 -274
  529. package/scripts/lib/portable-tasks.js +0 -479
  530. package/scripts/lib/process-cleanup.js +0 -527
  531. package/scripts/lib/quality-gates.js +0 -788
  532. package/scripts/lib/scale-detector.js +0 -396
  533. package/scripts/lib/sessionRegistry.js +0 -678
  534. package/scripts/lib/signal-detectors.js +0 -867
  535. package/scripts/lib/skill-catalog.js +0 -557
  536. package/scripts/lib/skill-recommender.js +0 -311
  537. package/scripts/lib/state-migrator.js +0 -353
  538. package/scripts/lib/status-task-bridge.js +0 -522
  539. package/scripts/lib/status-writer.js +0 -255
  540. package/scripts/lib/story-claiming.js +0 -704
  541. package/scripts/lib/story-state-machine.js +0 -437
  542. package/scripts/lib/sync-ideation-status.js +0 -291
  543. package/scripts/lib/task-registry-cache.js +0 -490
  544. package/scripts/lib/task-registry.js +0 -1191
  545. package/scripts/lib/task-sync.js +0 -230
  546. package/scripts/lib/tdd-phase-manager.js +0 -455
  547. package/scripts/lib/team-events.js +0 -510
  548. package/scripts/lib/tmux-audit-monitor.js +0 -612
  549. package/scripts/lib/tmux-group-colors.js +0 -113
  550. package/scripts/lib/tool-registry.yaml +0 -241
  551. package/scripts/lib/tool-shed.js +0 -441
  552. package/scripts/lib/validation-registry.js +0 -177
  553. package/scripts/messaging-bridge.js +0 -561
  554. package/scripts/migrate-ideation-index.js +0 -553
  555. package/scripts/native-team-observer.js +0 -219
  556. package/scripts/obtain-context.js +0 -272
  557. package/scripts/pre-push-check.sh +0 -46
  558. package/scripts/precompact-context.sh +0 -306
  559. package/scripts/query-codebase.js +0 -543
  560. package/scripts/ralph-loop.js +0 -1278
  561. package/scripts/resume-session.sh +0 -121
  562. package/scripts/screenshot-verifier.js +0 -215
  563. package/scripts/session-boundary.js +0 -138
  564. package/scripts/session-coordinator.sh +0 -232
  565. package/scripts/session-manager.js +0 -546
  566. package/scripts/smart-detect.js +0 -449
  567. package/scripts/spawn-audit-sessions.js +0 -877
  568. package/scripts/spawn-parallel.js +0 -751
  569. package/scripts/strip-ai-attribution.js +0 -63
  570. package/scripts/task-completed-gate.js +0 -237
  571. package/scripts/team-manager.js +0 -596
  572. package/scripts/team-status-display.js +0 -200
  573. package/scripts/teammate-idle-gate.js +0 -237
  574. package/scripts/test-session-boundary.js +0 -80
  575. package/scripts/tmux-close-windows.sh +0 -180
  576. package/scripts/tmux-restore-window.sh +0 -67
  577. package/scripts/tmux-save-closed-window.sh +0 -35
  578. package/scripts/tui/App.js +0 -151
  579. package/scripts/tui/Dashboard.js +0 -277
  580. package/scripts/tui/blessed/data/watcher.js +0 -180
  581. package/scripts/tui/blessed/index.js +0 -244
  582. package/scripts/tui/blessed/panels/output.js +0 -101
  583. package/scripts/tui/blessed/panels/sessions.js +0 -150
  584. package/scripts/tui/blessed/panels/trace.js +0 -97
  585. package/scripts/tui/blessed/ui/help.js +0 -77
  586. package/scripts/tui/blessed/ui/screen.js +0 -52
  587. package/scripts/tui/blessed/ui/statusbar.js +0 -47
  588. package/scripts/tui/blessed/ui/tabbar.js +0 -99
  589. package/scripts/tui/index.js +0 -70
  590. package/scripts/tui/lib/crashRecovery.js +0 -304
  591. package/scripts/tui/lib/eventStream.js +0 -309
  592. package/scripts/tui/lib/keyboard.js +0 -261
  593. package/scripts/tui/lib/loopControl.js +0 -371
  594. package/scripts/tui/panels/OutputPanel.js +0 -240
  595. package/scripts/tui/panels/SessionPanel.js +0 -170
  596. package/scripts/tui/panels/TracePanel.js +0 -298
  597. package/scripts/tui/simple-tui.js +0 -510
  598. package/scripts/validate-expertise.sh +0 -263
  599. package/scripts/validate-tokens.sh +0 -73
  600. package/scripts/validators/README.md +0 -143
  601. package/scripts/validators/component-validator.js +0 -239
  602. package/scripts/validators/json-schema-validator.js +0 -186
  603. package/scripts/validators/markdown-validator.js +0 -152
  604. package/scripts/validators/migration-validator.js +0 -129
  605. package/scripts/validators/security-validator.js +0 -380
  606. package/scripts/validators/story-format-validator.js +0 -197
  607. package/scripts/validators/test-result-validator.js +0 -114
  608. package/scripts/validators/workflow-validator.js +0 -247
  609. package/scripts/welcome-deferred.js +0 -437
  610. package/scripts/worktree-create.sh +0 -111
  611. package/src/core/agents/a11y-analyzer-aria.md +0 -155
  612. package/src/core/agents/a11y-analyzer-forms.md +0 -162
  613. package/src/core/agents/a11y-analyzer-keyboard.md +0 -175
  614. package/src/core/agents/a11y-analyzer-semantic.md +0 -153
  615. package/src/core/agents/a11y-analyzer-visual.md +0 -158
  616. package/src/core/agents/a11y-consensus.md +0 -248
  617. package/src/core/agents/accessibility.md +0 -515
  618. package/src/core/agents/adr-writer.md +0 -463
  619. package/src/core/agents/ads-audit-budget.md +0 -181
  620. package/src/core/agents/ads-audit-compliance.md +0 -169
  621. package/src/core/agents/ads-audit-creative.md +0 -164
  622. package/src/core/agents/ads-audit-google.md +0 -226
  623. package/src/core/agents/ads-audit-meta.md +0 -183
  624. package/src/core/agents/ads-audit-tracking.md +0 -197
  625. package/src/core/agents/ads-consensus.md +0 -396
  626. package/src/core/agents/ads-generate.md +0 -145
  627. package/src/core/agents/ads-performance-tracker.md +0 -197
  628. package/src/core/agents/analytics.md +0 -617
  629. package/src/core/agents/api-quality-analyzer-conventions.md +0 -148
  630. package/src/core/agents/api-quality-analyzer-docs.md +0 -176
  631. package/src/core/agents/api-quality-analyzer-errors.md +0 -183
  632. package/src/core/agents/api-quality-analyzer-pagination.md +0 -171
  633. package/src/core/agents/api-quality-analyzer-versioning.md +0 -143
  634. package/src/core/agents/api-quality-consensus.md +0 -214
  635. package/src/core/agents/api-validator.md +0 -183
  636. package/src/core/agents/api.md +0 -665
  637. package/src/core/agents/arch-analyzer-circular.md +0 -148
  638. package/src/core/agents/arch-analyzer-complexity.md +0 -171
  639. package/src/core/agents/arch-analyzer-coupling.md +0 -146
  640. package/src/core/agents/arch-analyzer-layering.md +0 -151
  641. package/src/core/agents/arch-analyzer-patterns.md +0 -162
  642. package/src/core/agents/arch-consensus.md +0 -227
  643. package/src/core/agents/brainstorm-analyzer-features.md +0 -169
  644. package/src/core/agents/brainstorm-analyzer-growth.md +0 -161
  645. package/src/core/agents/brainstorm-analyzer-integration.md +0 -172
  646. package/src/core/agents/brainstorm-analyzer-market.md +0 -147
  647. package/src/core/agents/brainstorm-analyzer-ux.md +0 -167
  648. package/src/core/agents/brainstorm-consensus.md +0 -237
  649. package/src/core/agents/browser-qa.md +0 -328
  650. package/src/core/agents/ci.md +0 -511
  651. package/src/core/agents/code-reviewer.md +0 -288
  652. package/src/core/agents/codebase-query.md +0 -266
  653. package/src/core/agents/completeness-analyzer-api.md +0 -190
  654. package/src/core/agents/completeness-analyzer-conditional.md +0 -201
  655. package/src/core/agents/completeness-analyzer-handlers.md +0 -159
  656. package/src/core/agents/completeness-analyzer-imports.md +0 -159
  657. package/src/core/agents/completeness-analyzer-routes.md +0 -182
  658. package/src/core/agents/completeness-analyzer-state.md +0 -188
  659. package/src/core/agents/completeness-analyzer-stubs.md +0 -198
  660. package/src/core/agents/completeness-consensus.md +0 -286
  661. package/src/core/agents/compliance.md +0 -509
  662. package/src/core/agents/council-advocate.md +0 -206
  663. package/src/core/agents/council-analyst.md +0 -252
  664. package/src/core/agents/council-optimist.md +0 -170
  665. package/src/core/agents/database.md +0 -601
  666. package/src/core/agents/datamigration.md +0 -699
  667. package/src/core/agents/design.md +0 -525
  668. package/src/core/agents/devops.md +0 -720
  669. package/src/core/agents/documentation.md +0 -504
  670. package/src/core/agents/epic-planner.md +0 -480
  671. package/src/core/agents/error-analyzer.md +0 -201
  672. package/src/core/agents/integrations.md +0 -603
  673. package/src/core/agents/legal-analyzer-a11y.md +0 -110
  674. package/src/core/agents/legal-analyzer-ai.md +0 -117
  675. package/src/core/agents/legal-analyzer-consumer.md +0 -108
  676. package/src/core/agents/legal-analyzer-content.md +0 -113
  677. package/src/core/agents/legal-analyzer-international.md +0 -115
  678. package/src/core/agents/legal-analyzer-licensing.md +0 -115
  679. package/src/core/agents/legal-analyzer-privacy.md +0 -108
  680. package/src/core/agents/legal-analyzer-security.md +0 -112
  681. package/src/core/agents/legal-analyzer-terms.md +0 -111
  682. package/src/core/agents/legal-consensus.md +0 -242
  683. package/src/core/agents/logic-analyzer-edge.md +0 -170
  684. package/src/core/agents/logic-analyzer-flow.md +0 -253
  685. package/src/core/agents/logic-analyzer-invariant.md +0 -206
  686. package/src/core/agents/logic-analyzer-race.md +0 -266
  687. package/src/core/agents/logic-analyzer-type.md +0 -217
  688. package/src/core/agents/logic-consensus.md +0 -253
  689. package/src/core/agents/mentor.md +0 -654
  690. package/src/core/agents/mobile.md +0 -501
  691. package/src/core/agents/monitoring.md +0 -537
  692. package/src/core/agents/multi-expert.md +0 -311
  693. package/src/core/agents/orchestrator.md +0 -749
  694. package/src/core/agents/perf-analyzer-assets.md +0 -174
  695. package/src/core/agents/perf-analyzer-bundle.md +0 -165
  696. package/src/core/agents/perf-analyzer-caching.md +0 -160
  697. package/src/core/agents/perf-analyzer-compute.md +0 -165
  698. package/src/core/agents/perf-analyzer-memory.md +0 -182
  699. package/src/core/agents/perf-analyzer-network.md +0 -157
  700. package/src/core/agents/perf-analyzer-queries.md +0 -155
  701. package/src/core/agents/perf-analyzer-rendering.md +0 -156
  702. package/src/core/agents/perf-consensus.md +0 -280
  703. package/src/core/agents/performance.md +0 -492
  704. package/src/core/agents/product.md +0 -535
  705. package/src/core/agents/qa.md +0 -765
  706. package/src/core/agents/readme-updater.md +0 -579
  707. package/src/core/agents/refactor.md +0 -558
  708. package/src/core/agents/research.md +0 -453
  709. package/src/core/agents/rlm-subcore.md +0 -207
  710. package/src/core/agents/schema-validator.md +0 -454
  711. package/src/core/agents/security-analyzer-api.md +0 -199
  712. package/src/core/agents/security-analyzer-auth.md +0 -160
  713. package/src/core/agents/security-analyzer-authz.md +0 -168
  714. package/src/core/agents/security-analyzer-deps.md +0 -147
  715. package/src/core/agents/security-analyzer-infra.md +0 -176
  716. package/src/core/agents/security-analyzer-injection.md +0 -148
  717. package/src/core/agents/security-analyzer-input.md +0 -191
  718. package/src/core/agents/security-analyzer-secrets.md +0 -175
  719. package/src/core/agents/security-consensus.md +0 -276
  720. package/src/core/agents/security.md +0 -486
  721. package/src/core/agents/seo-analyzer-content.md +0 -167
  722. package/src/core/agents/seo-analyzer-images.md +0 -187
  723. package/src/core/agents/seo-analyzer-performance.md +0 -206
  724. package/src/core/agents/seo-analyzer-schema.md +0 -176
  725. package/src/core/agents/seo-analyzer-sitemap.md +0 -172
  726. package/src/core/agents/seo-analyzer-technical.md +0 -144
  727. package/src/core/agents/seo-consensus.md +0 -289
  728. package/src/core/agents/team-coordinator.md +0 -333
  729. package/src/core/agents/team-lead.md +0 -171
  730. package/src/core/agents/test-analyzer-assertions.md +0 -181
  731. package/src/core/agents/test-analyzer-coverage.md +0 -183
  732. package/src/core/agents/test-analyzer-fragility.md +0 -185
  733. package/src/core/agents/test-analyzer-integration.md +0 -155
  734. package/src/core/agents/test-analyzer-maintenance.md +0 -173
  735. package/src/core/agents/test-analyzer-mocking.md +0 -178
  736. package/src/core/agents/test-analyzer-patterns.md +0 -189
  737. package/src/core/agents/test-analyzer-structure.md +0 -177
  738. package/src/core/agents/test-consensus.md +0 -294
  739. package/src/core/agents/testing.md +0 -527
  740. package/src/core/agents/ui-validator.md +0 -331
  741. package/src/core/agents/ui.md +0 -1227
  742. package/src/core/commands/adr/list.md +0 -191
  743. package/src/core/commands/adr/update.md +0 -258
  744. package/src/core/commands/adr/view.md +0 -274
  745. package/src/core/commands/adr.md +0 -394
  746. package/src/core/commands/ads/audit.md +0 -453
  747. package/src/core/commands/ads/budget.md +0 -97
  748. package/src/core/commands/ads/competitor.md +0 -112
  749. package/src/core/commands/ads/creative.md +0 -85
  750. package/src/core/commands/ads/generate.md +0 -238
  751. package/src/core/commands/ads/google.md +0 -112
  752. package/src/core/commands/ads/health.md +0 -327
  753. package/src/core/commands/ads/landing.md +0 -119
  754. package/src/core/commands/ads/linkedin.md +0 -112
  755. package/src/core/commands/ads/meta.md +0 -91
  756. package/src/core/commands/ads/microsoft.md +0 -115
  757. package/src/core/commands/ads/plan.md +0 -321
  758. package/src/core/commands/ads/test-plan.md +0 -317
  759. package/src/core/commands/ads/tiktok.md +0 -129
  760. package/src/core/commands/ads/track.md +0 -288
  761. package/src/core/commands/ads/youtube.md +0 -124
  762. package/src/core/commands/ads.md +0 -140
  763. package/src/core/commands/agent.md +0 -256
  764. package/src/core/commands/api.md +0 -267
  765. package/src/core/commands/assign.md +0 -369
  766. package/src/core/commands/audit.md +0 -531
  767. package/src/core/commands/auto.md +0 -556
  768. package/src/core/commands/automate.md +0 -415
  769. package/src/core/commands/babysit.md +0 -643
  770. package/src/core/commands/baseline.md +0 -743
  771. package/src/core/commands/batch.md +0 -551
  772. package/src/core/commands/blockers.md +0 -602
  773. package/src/core/commands/board.md +0 -509
  774. package/src/core/commands/browser-qa.md +0 -240
  775. package/src/core/commands/changelog.md +0 -582
  776. package/src/core/commands/choose.md +0 -430
  777. package/src/core/commands/ci.md +0 -330
  778. package/src/core/commands/code/accessibility.md +0 -363
  779. package/src/core/commands/code/api.md +0 -313
  780. package/src/core/commands/code/architecture.md +0 -313
  781. package/src/core/commands/code/completeness.md +0 -519
  782. package/src/core/commands/code/legal.md +0 -509
  783. package/src/core/commands/code/logic.md +0 -432
  784. package/src/core/commands/code/performance.md +0 -506
  785. package/src/core/commands/code/security.md +0 -509
  786. package/src/core/commands/code/test.md +0 -505
  787. package/src/core/commands/compress.md +0 -408
  788. package/src/core/commands/configure.md +0 -1159
  789. package/src/core/commands/context/export.md +0 -296
  790. package/src/core/commands/context/full.md +0 -353
  791. package/src/core/commands/context/note.md +0 -380
  792. package/src/core/commands/council.md +0 -592
  793. package/src/core/commands/debt.md +0 -491
  794. package/src/core/commands/deploy.md +0 -864
  795. package/src/core/commands/deps.md +0 -728
  796. package/src/core/commands/diagnose.md +0 -404
  797. package/src/core/commands/docs.md +0 -469
  798. package/src/core/commands/epic/edit.md +0 -213
  799. package/src/core/commands/epic/list.md +0 -190
  800. package/src/core/commands/epic/view.md +0 -267
  801. package/src/core/commands/epic.md +0 -477
  802. package/src/core/commands/export.md +0 -238
  803. package/src/core/commands/feedback.md +0 -603
  804. package/src/core/commands/handoff.md +0 -386
  805. package/src/core/commands/help.md +0 -194
  806. package/src/core/commands/ideate/brief.md +0 -363
  807. package/src/core/commands/ideate/discover.md +0 -399
  808. package/src/core/commands/ideate/features.md +0 -497
  809. package/src/core/commands/ideate/history.md +0 -403
  810. package/src/core/commands/ideate/new.md +0 -900
  811. package/src/core/commands/impact.md +0 -407
  812. package/src/core/commands/install.md +0 -529
  813. package/src/core/commands/learn/explain.md +0 -118
  814. package/src/core/commands/learn/glossary.md +0 -135
  815. package/src/core/commands/learn/patterns.md +0 -138
  816. package/src/core/commands/learn/tour.md +0 -126
  817. package/src/core/commands/maintain.md +0 -558
  818. package/src/core/commands/metrics.md +0 -844
  819. package/src/core/commands/migrate/codemods.md +0 -151
  820. package/src/core/commands/migrate/plan.md +0 -131
  821. package/src/core/commands/migrate/scan.md +0 -114
  822. package/src/core/commands/migrate/validate.md +0 -119
  823. package/src/core/commands/multi-expert.md +0 -447
  824. package/src/core/commands/packages.md +0 -535
  825. package/src/core/commands/pr.md +0 -337
  826. package/src/core/commands/readme-sync.md +0 -329
  827. package/src/core/commands/research/analyze.md +0 -798
  828. package/src/core/commands/research/ask.md +0 -864
  829. package/src/core/commands/research/import.md +0 -1025
  830. package/src/core/commands/research/list.md +0 -273
  831. package/src/core/commands/research/synthesize.md +0 -928
  832. package/src/core/commands/research/view.md +0 -323
  833. package/src/core/commands/retro.md +0 -795
  834. package/src/core/commands/review.md +0 -694
  835. package/src/core/commands/rlm.md +0 -446
  836. package/src/core/commands/roadmap/analyze.md +0 -400
  837. package/src/core/commands/rpi.md +0 -633
  838. package/src/core/commands/seo/audit.md +0 -444
  839. package/src/core/commands/seo/competitor.md +0 -174
  840. package/src/core/commands/seo/content.md +0 -107
  841. package/src/core/commands/seo/geo.md +0 -229
  842. package/src/core/commands/seo/hreflang.md +0 -140
  843. package/src/core/commands/seo/images.md +0 -96
  844. package/src/core/commands/seo/page.md +0 -198
  845. package/src/core/commands/seo/plan.md +0 -163
  846. package/src/core/commands/seo/programmatic.md +0 -131
  847. package/src/core/commands/seo/references/cwv-thresholds.md +0 -64
  848. package/src/core/commands/seo/references/eeat-framework.md +0 -110
  849. package/src/core/commands/seo/references/quality-gates.md +0 -91
  850. package/src/core/commands/seo/references/schema-types.md +0 -102
  851. package/src/core/commands/seo/schema.md +0 -183
  852. package/src/core/commands/seo/sitemap.md +0 -97
  853. package/src/core/commands/seo/technical.md +0 -100
  854. package/src/core/commands/seo.md +0 -107
  855. package/src/core/commands/session/cleanup.md +0 -452
  856. package/src/core/commands/session/end.md +0 -865
  857. package/src/core/commands/session/history.md +0 -293
  858. package/src/core/commands/session/init.md +0 -210
  859. package/src/core/commands/session/new.md +0 -827
  860. package/src/core/commands/session/resume.md +0 -291
  861. package/src/core/commands/session/spawn.md +0 -205
  862. package/src/core/commands/session/status.md +0 -274
  863. package/src/core/commands/skill/list.md +0 -139
  864. package/src/core/commands/skill/recommend.md +0 -216
  865. package/src/core/commands/sprint.md +0 -714
  866. package/src/core/commands/status/undo.md +0 -191
  867. package/src/core/commands/status.md +0 -423
  868. package/src/core/commands/story/edit.md +0 -204
  869. package/src/core/commands/story/list.md +0 -199
  870. package/src/core/commands/story/view.md +0 -312
  871. package/src/core/commands/story-validate.md +0 -491
  872. package/src/core/commands/story.md +0 -465
  873. package/src/core/commands/tdd-next.md +0 -238
  874. package/src/core/commands/tdd.md +0 -211
  875. package/src/core/commands/team/guide.md +0 -688
  876. package/src/core/commands/team/list.md +0 -59
  877. package/src/core/commands/team/start.md +0 -130
  878. package/src/core/commands/team/status.md +0 -66
  879. package/src/core/commands/team/stop.md +0 -78
  880. package/src/core/commands/template.md +0 -644
  881. package/src/core/commands/tests.md +0 -731
  882. package/src/core/commands/update.md +0 -591
  883. package/src/core/commands/validate-expertise.md +0 -305
  884. package/src/core/commands/velocity.md +0 -630
  885. package/src/core/commands/verify.md +0 -534
  886. package/src/core/commands/whats-new.md +0 -201
  887. package/src/core/commands/workflow.md +0 -449
  888. package/src/core/council/sessions/.gitkeep +0 -0
  889. package/src/core/council/shared_reasoning.template.md +0 -106
  890. package/src/core/experts/README.md +0 -236
  891. package/src/core/experts/_core-expertise.yaml +0 -105
  892. package/src/core/experts/accessibility/expertise.yaml +0 -115
  893. package/src/core/experts/accessibility/question.md +0 -41
  894. package/src/core/experts/accessibility/self-improve.md +0 -45
  895. package/src/core/experts/accessibility/workflow.md +0 -59
  896. package/src/core/experts/adr-writer/expertise.yaml +0 -138
  897. package/src/core/experts/adr-writer/question.md +0 -56
  898. package/src/core/experts/adr-writer/self-improve.md +0 -106
  899. package/src/core/experts/adr-writer/workflow.md +0 -184
  900. package/src/core/experts/analytics/expertise.yaml +0 -119
  901. package/src/core/experts/analytics/question.md +0 -74
  902. package/src/core/experts/analytics/self-improve.md +0 -163
  903. package/src/core/experts/analytics/workflow.md +0 -272
  904. package/src/core/experts/api/expertise.yaml +0 -124
  905. package/src/core/experts/api/question.md +0 -74
  906. package/src/core/experts/api/self-improve.md +0 -122
  907. package/src/core/experts/api/workflow.md +0 -248
  908. package/src/core/experts/ci/expertise.yaml +0 -106
  909. package/src/core/experts/ci/question.md +0 -69
  910. package/src/core/experts/ci/self-improve.md +0 -100
  911. package/src/core/experts/ci/workflow.md +0 -145
  912. package/src/core/experts/codebase-query/expertise.yaml +0 -121
  913. package/src/core/experts/codebase-query/question.md +0 -73
  914. package/src/core/experts/codebase-query/self-improve.md +0 -105
  915. package/src/core/experts/compliance/expertise.yaml +0 -101
  916. package/src/core/experts/compliance/question.md +0 -56
  917. package/src/core/experts/compliance/self-improve.md +0 -106
  918. package/src/core/experts/compliance/workflow.md +0 -184
  919. package/src/core/experts/database/expertise.yaml +0 -109
  920. package/src/core/experts/database/question.md +0 -74
  921. package/src/core/experts/database/self-improve.md +0 -121
  922. package/src/core/experts/database/workflow.md +0 -234
  923. package/src/core/experts/datamigration/expertise.yaml +0 -141
  924. package/src/core/experts/datamigration/question.md +0 -56
  925. package/src/core/experts/datamigration/self-improve.md +0 -106
  926. package/src/core/experts/datamigration/workflow.md +0 -184
  927. package/src/core/experts/design/expertise.yaml +0 -116
  928. package/src/core/experts/design/question.md +0 -56
  929. package/src/core/experts/design/self-improve.md +0 -106
  930. package/src/core/experts/design/workflow.md +0 -184
  931. package/src/core/experts/devops/expertise.yaml +0 -116
  932. package/src/core/experts/devops/question.md +0 -68
  933. package/src/core/experts/devops/self-improve.md +0 -102
  934. package/src/core/experts/devops/workflow.md +0 -142
  935. package/src/core/experts/documentation/expertise.yaml +0 -126
  936. package/src/core/experts/documentation/question.md +0 -41
  937. package/src/core/experts/documentation/self-improve.md +0 -45
  938. package/src/core/experts/documentation/workflow.md +0 -55
  939. package/src/core/experts/epic-planner/expertise.yaml +0 -144
  940. package/src/core/experts/epic-planner/question.md +0 -56
  941. package/src/core/experts/epic-planner/self-improve.md +0 -106
  942. package/src/core/experts/epic-planner/workflow.md +0 -184
  943. package/src/core/experts/integrations/expertise.yaml +0 -113
  944. package/src/core/experts/integrations/question.md +0 -74
  945. package/src/core/experts/integrations/self-improve.md +0 -151
  946. package/src/core/experts/integrations/workflow.md +0 -246
  947. package/src/core/experts/mentor/expertise.yaml +0 -125
  948. package/src/core/experts/mentor/question.md +0 -56
  949. package/src/core/experts/mentor/self-improve.md +0 -106
  950. package/src/core/experts/mentor/workflow.md +0 -184
  951. package/src/core/experts/mobile/expertise.yaml +0 -136
  952. package/src/core/experts/mobile/question.md +0 -72
  953. package/src/core/experts/mobile/self-improve.md +0 -140
  954. package/src/core/experts/mobile/workflow.md +0 -240
  955. package/src/core/experts/monitoring/expertise.yaml +0 -132
  956. package/src/core/experts/monitoring/question.md +0 -76
  957. package/src/core/experts/monitoring/self-improve.md +0 -150
  958. package/src/core/experts/monitoring/workflow.md +0 -264
  959. package/src/core/experts/performance/expertise.yaml +0 -68
  960. package/src/core/experts/performance/question.md +0 -41
  961. package/src/core/experts/performance/self-improve.md +0 -45
  962. package/src/core/experts/performance/workflow.md +0 -61
  963. package/src/core/experts/product/expertise.yaml +0 -143
  964. package/src/core/experts/product/question.md +0 -56
  965. package/src/core/experts/product/self-improve.md +0 -106
  966. package/src/core/experts/product/workflow.md +0 -184
  967. package/src/core/experts/qa/expertise.yaml +0 -110
  968. package/src/core/experts/qa/question.md +0 -56
  969. package/src/core/experts/qa/self-improve.md +0 -106
  970. package/src/core/experts/qa/workflow.md +0 -184
  971. package/src/core/experts/readme-updater/expertise.yaml +0 -141
  972. package/src/core/experts/readme-updater/question.md +0 -56
  973. package/src/core/experts/readme-updater/self-improve.md +0 -106
  974. package/src/core/experts/readme-updater/workflow.md +0 -184
  975. package/src/core/experts/refactor/expertise.yaml +0 -135
  976. package/src/core/experts/refactor/question.md +0 -41
  977. package/src/core/experts/refactor/self-improve.md +0 -45
  978. package/src/core/experts/refactor/workflow.md +0 -57
  979. package/src/core/experts/research/expertise.yaml +0 -143
  980. package/src/core/experts/research/question.md +0 -56
  981. package/src/core/experts/research/self-improve.md +0 -106
  982. package/src/core/experts/research/workflow.md +0 -184
  983. package/src/core/experts/security/expertise.yaml +0 -117
  984. package/src/core/experts/security/question.md +0 -77
  985. package/src/core/experts/security/self-improve.md +0 -102
  986. package/src/core/experts/security/workflow.md +0 -152
  987. package/src/core/experts/templates/expertise-template.yaml +0 -67
  988. package/src/core/experts/templates/question-template.md +0 -56
  989. package/src/core/experts/templates/self-improve-template.md +0 -106
  990. package/src/core/experts/templates/workflow-template.md +0 -184
  991. package/src/core/experts/testing/expertise.yaml +0 -112
  992. package/src/core/experts/testing/question.md +0 -68
  993. package/src/core/experts/testing/self-improve.md +0 -102
  994. package/src/core/experts/testing/workflow.md +0 -143
  995. package/src/core/experts/ui/expertise.yaml +0 -133
  996. package/src/core/experts/ui/question.md +0 -74
  997. package/src/core/experts/ui/self-improve.md +0 -122
  998. package/src/core/experts/ui/workflow.md +0 -262
  999. package/src/core/knowledge/ads/ad-audit-checklist-scoring.md +0 -424
  1000. package/src/core/knowledge/ads/ad-optimization-logic.md +0 -590
  1001. package/src/core/knowledge/ads/ad-technical-specifications.md +0 -385
  1002. package/src/core/knowledge/ads/definitive-advertising-reference-2026.md +0 -506
  1003. package/src/core/knowledge/ads/paid-advertising-research-2026.md +0 -445
  1004. package/src/core/profiles/COMPARISON.md +0 -170
  1005. package/src/core/profiles/README.md +0 -178
  1006. package/src/core/profiles/claude-code.yaml +0 -111
  1007. package/src/core/profiles/codex.yaml +0 -103
  1008. package/src/core/profiles/cursor.yaml +0 -134
  1009. package/src/core/profiles/examples.js +0 -250
  1010. package/src/core/profiles/loader.js +0 -235
  1011. package/src/core/profiles/windsurf.yaml +0 -159
  1012. package/src/core/skills/_learnings/README.md +0 -91
  1013. package/src/core/skills/_learnings/_template.yaml +0 -106
  1014. package/src/core/skills/_learnings/code-review.yaml +0 -118
  1015. package/src/core/skills/_learnings/commit.yaml +0 -69
  1016. package/src/core/skills/_learnings/story-writer.yaml +0 -71
  1017. package/src/core/teams/backend.json +0 -41
  1018. package/src/core/teams/builder-validator.json +0 -51
  1019. package/src/core/teams/code-review.json +0 -41
  1020. package/src/core/teams/frontend.json +0 -41
  1021. package/src/core/teams/fullstack.json +0 -41
  1022. package/src/core/teams/logic-audit.json +0 -53
  1023. package/src/core/teams/perf-audit.json +0 -71
  1024. package/src/core/teams/qa.json +0 -41
  1025. package/src/core/teams/security-audit.json +0 -71
  1026. package/src/core/teams/solo.json +0 -35
  1027. package/src/core/teams/test-audit.json +0 -71
  1028. package/src/core/templates/CONTEXT.md.example +0 -49
  1029. package/src/core/templates/README-template.md +0 -16
  1030. package/src/core/templates/adr-template.md +0 -28
  1031. package/src/core/templates/agent-coordination-pattern.md +0 -38
  1032. package/src/core/templates/agent-profile-template.md +0 -51
  1033. package/src/core/templates/agileflow-metadata.json +0 -150
  1034. package/src/core/templates/browser-qa-spec.yaml +0 -94
  1035. package/src/core/templates/ci-workflow.yml +0 -74
  1036. package/src/core/templates/claude-settings.advanced.example.json +0 -75
  1037. package/src/core/templates/claude-settings.example.json +0 -26
  1038. package/src/core/templates/command-documentation.md +0 -187
  1039. package/src/core/templates/command-prerequisites.yaml +0 -169
  1040. package/src/core/templates/comms-note-template.md +0 -24
  1041. package/src/core/templates/damage-control-patterns.yaml +0 -243
  1042. package/src/core/templates/environment.json +0 -18
  1043. package/src/core/templates/epic-template.md +0 -27
  1044. package/src/core/templates/plan-template.md +0 -125
  1045. package/src/core/templates/preserve-rules-common.md +0 -107
  1046. package/src/core/templates/preserve-rules.json +0 -42
  1047. package/src/core/templates/proactive-action-spec.md +0 -29
  1048. package/src/core/templates/product-brief.md +0 -136
  1049. package/src/core/templates/quality-gate-priorities.md +0 -34
  1050. package/src/core/templates/research-template.md +0 -44
  1051. package/src/core/templates/session-harness-protocol.md +0 -128
  1052. package/src/core/templates/session-state.json +0 -56
  1053. package/src/core/templates/story-lifecycle.md +0 -213
  1054. package/src/core/templates/story-template.md +0 -92
  1055. package/src/core/templates/tdd-test-template.js +0 -241
  1056. package/src/core/templates/worktrees-guide.md +0 -231
  1057. package/tools/agileflow-npx.js +0 -52
  1058. package/tools/cli/agileflow-cli.js +0 -72
  1059. package/tools/cli/commands/config.js +0 -285
  1060. package/tools/cli/commands/doctor.js +0 -496
  1061. package/tools/cli/commands/list.js +0 -385
  1062. package/tools/cli/commands/session.js +0 -1176
  1063. package/tools/cli/commands/setup.js +0 -255
  1064. package/tools/cli/commands/status.js +0 -101
  1065. package/tools/cli/commands/tui.js +0 -56
  1066. package/tools/cli/commands/uninstall.js +0 -155
  1067. package/tools/cli/commands/update.js +0 -299
  1068. package/tools/cli/installers/core/installer.js +0 -892
  1069. package/tools/cli/installers/ide/_base-ide.js +0 -518
  1070. package/tools/cli/installers/ide/_interface.js +0 -238
  1071. package/tools/cli/installers/ide/claude-code.js +0 -432
  1072. package/tools/cli/installers/ide/codex.js +0 -426
  1073. package/tools/cli/installers/ide/cursor.js +0 -217
  1074. package/tools/cli/installers/ide/manager.js +0 -222
  1075. package/tools/cli/installers/ide/windsurf.js +0 -282
  1076. package/tools/cli/lib/command-context.js +0 -382
  1077. package/tools/cli/lib/config-manager.js +0 -446
  1078. package/tools/cli/lib/content-injector.js +0 -969
  1079. package/tools/cli/lib/content-transformer.js +0 -496
  1080. package/tools/cli/lib/docs-setup.js +0 -464
  1081. package/tools/cli/lib/error-handler.js +0 -165
  1082. package/tools/cli/lib/ide-error-factory.js +0 -421
  1083. package/tools/cli/lib/ide-errors.js +0 -367
  1084. package/tools/cli/lib/ide-generator.js +0 -357
  1085. package/tools/cli/lib/ide-health-monitor.js +0 -364
  1086. package/tools/cli/lib/ide-registry.js +0 -297
  1087. package/tools/cli/lib/npm-utils.js +0 -103
  1088. package/tools/cli/lib/self-update.js +0 -148
  1089. package/tools/cli/lib/ui.js +0 -211
  1090. package/tools/cli/lib/utils.js +0 -87
  1091. package/tools/cli/lib/validation-middleware.js +0 -491
  1092. package/tools/cli/lib/version-checker.js +0 -95
  1093. package/tools/postinstall.js +0 -190
@@ -1,2246 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * agileflow-welcome.js - Beautiful SessionStart welcome display
5
- *
6
- * Shows a transparent ASCII table with:
7
- * - Project info (name, version, branch, commit)
8
- * - Story stats (WIP, blocked, completed)
9
- * - Archival status
10
- * - Session cleanup status
11
- * - Last commit
12
- *
13
- * PERFORMANCE OPTIMIZATION (US-0356):
14
- * Phase 1: Table display + instant notifications (~300-350ms)
15
- * Phase 2: Cached update check + instant post-table notifications
16
- * Phase 3: Background deferred work via welcome-deferred.js
17
- * - npm update check (with cache write)
18
- * - Session health warnings
19
- * - Duplicate process detection
20
- * - Story claiming/file tracking cleanup
21
- * - Epic completion, ideation sync, automations
22
- * Deferred warnings saved to session-state.json, displayed next session.
23
- */
24
-
25
- const fs = require('fs');
26
- const path = require('path');
27
- const { executeCommandSync, git, spawnBackground } = require('../lib/process-executor');
28
-
29
- // Shared utilities
30
- const { c, box } = require('../lib/colors');
31
- const {
32
- getProjectRoot,
33
- getStatusPath,
34
- getMetadataPath,
35
- getSessionStatePath,
36
- getAgileflowDir,
37
- getClaudeDir,
38
- } = require('../lib/paths');
39
- const { readJSONCached, readFileCached } = require('../lib/file-cache');
40
- const { tryOptional } = require('../lib/errors');
41
- const { createLogger } = require('../lib/logger');
42
- const log = createLogger('welcome');
43
-
44
- // PERFORMANCE OPTIMIZATION (US-0356): Profiling helper
45
- // Only active when AGILEFLOW_DEBUG=welcome is set
46
- const _profiling = process.env.AGILEFLOW_DEBUG === 'welcome';
47
- const _timings = {};
48
- function _mark(label) {
49
- if (_profiling) _timings[label] = process.hrtime.bigint();
50
- }
51
- function _elapsed(from, to) {
52
- if (!_profiling) return '';
53
- const ns = Number((_timings[to] || process.hrtime.bigint()) - (_timings[from] || 0n));
54
- return `${(ns / 1e6).toFixed(1)}ms`;
55
- }
56
- function _logTimings() {
57
- if (!_profiling) return;
58
- const labels = Object.keys(_timings);
59
- const pairs = [];
60
- for (let i = 1; i < labels.length; i++) {
61
- pairs.push(`${labels[i]}=${_elapsed(labels[i - 1], labels[i])}`);
62
- }
63
- if (labels.length >= 2) {
64
- pairs.push(`TOTAL=${_elapsed(labels[0], labels[labels.length - 1])}`);
65
- }
66
- // Output to stderr so it doesn't mix with the welcome table
67
- console.error(`[welcome:timing] ${pairs.join(' ')}`);
68
- }
69
-
70
- // Hook metrics module (kept at top level - needed early for timer)
71
- let hookMetrics;
72
- try {
73
- hookMetrics = require('./lib/hook-metrics.js');
74
- } catch (e) {
75
- // Hook metrics not available
76
- }
77
-
78
- /**
79
- * PERFORMANCE OPTIMIZATION: Load all project files using LRU cache
80
- * Uses file-cache module for automatic caching with 15s TTL.
81
- * Files are cached across script invocations within TTL window.
82
- * Estimated savings: 60-120ms on cache hits
83
- *
84
- * Additional optimizations in this file (US-0356):
85
- * - Git batching: 3 subprocess calls → 1 (~20-40ms savings)
86
- * - Session-manager inline: subprocess → direct require() (~50-150ms savings)
87
- * - Tmux cache: subprocess → session-state lookup (~10-20ms after first run)
88
- * Total estimated savings: ~130-260ms
89
- */
90
- function loadProjectFiles(rootDir) {
91
- const paths = {
92
- status: getStatusPath(rootDir),
93
- metadata: getMetadataPath(rootDir),
94
- settings: path.join(getClaudeDir(rootDir), 'settings.json'),
95
- sessionState: getSessionStatePath(rootDir),
96
- configYaml: path.join(getAgileflowDir(rootDir), 'config.yaml'),
97
- cliPackage: path.join(rootDir, 'packages', 'cli', 'package.json'),
98
- };
99
-
100
- return {
101
- status: readJSONCached(paths.status),
102
- metadata: readJSONCached(paths.metadata),
103
- settings: readJSONCached(paths.settings),
104
- sessionState: readJSONCached(paths.sessionState),
105
- configYaml: readFileCached(paths.configYaml),
106
- cliPackage: readJSONCached(paths.cliPackage),
107
- };
108
- }
109
-
110
- /**
111
- * Detect the user's platform for install guidance
112
- */
113
- function detectPlatform() {
114
- const platform = process.platform;
115
-
116
- if (platform === 'darwin') {
117
- return { os: 'macOS', installCmd: 'brew install tmux', hasSudo: true };
118
- }
119
-
120
- if (platform === 'linux') {
121
- // Try to detect Linux distribution
122
- try {
123
- const osRelease = fs.readFileSync('/etc/os-release', 'utf8');
124
- if (
125
- osRelease.includes('Ubuntu') ||
126
- osRelease.includes('Debian') ||
127
- osRelease.includes('Pop!_OS') ||
128
- osRelease.includes('Mint')
129
- ) {
130
- return { os: 'Ubuntu/Debian', installCmd: 'sudo apt install tmux', hasSudo: true };
131
- }
132
- if (
133
- osRelease.includes('Fedora') ||
134
- osRelease.includes('Red Hat') ||
135
- osRelease.includes('CentOS') ||
136
- osRelease.includes('Rocky')
137
- ) {
138
- return { os: 'Fedora/RHEL', installCmd: 'sudo dnf install tmux', hasSudo: true };
139
- }
140
- if (osRelease.includes('Arch')) {
141
- return { os: 'Arch', installCmd: 'sudo pacman -S tmux', hasSudo: true };
142
- }
143
- } catch (e) {
144
- // Can't read /etc/os-release
145
- }
146
- return { os: 'Linux', installCmd: 'sudo apt install tmux', hasSudo: true };
147
- }
148
-
149
- // Windows WSL or unknown
150
- return { os: 'Unknown', installCmd: null, hasSudo: false };
151
- }
152
-
153
- /**
154
- * Check if tmux is installed
155
- * PERFORMANCE OPTIMIZATION: Caches result in session-state.json (~10-20ms savings on subsequent runs)
156
- * Returns object with availability info and platform-specific install suggestion
157
- */
158
- function checkTmuxAvailability(cache) {
159
- // Check session state cache first (tmux availability doesn't change within a session)
160
- if (cache?.sessionState?.tmux_available !== undefined) {
161
- if (cache.sessionState.tmux_available) return { available: true };
162
- return {
163
- available: false,
164
- platform: detectPlatform(),
165
- noSudoCmd: 'conda install -c conda-forge tmux',
166
- };
167
- }
168
-
169
- // Actually check (first run or no cache)
170
- const result = executeCommandSync('which', ['tmux'], { fallback: null });
171
- const available = result.data !== null;
172
-
173
- // Cache in session state for next invocation
174
- try {
175
- const rootDir = getProjectRoot();
176
- const sessionStatePath = getSessionStatePath(rootDir);
177
- if (fs.existsSync(sessionStatePath)) {
178
- const state = JSON.parse(fs.readFileSync(sessionStatePath, 'utf8'));
179
- state.tmux_available = available;
180
- fs.writeFileSync(sessionStatePath, JSON.stringify(state, null, 2) + '\n');
181
- }
182
- } catch (e) {
183
- // Cache write failed, non-critical
184
- }
185
-
186
- if (available) return { available: true };
187
- return {
188
- available: false,
189
- platform: detectPlatform(),
190
- noSudoCmd: 'conda install -c conda-forge tmux',
191
- };
192
- }
193
-
194
- /**
195
- * PERFORMANCE OPTIMIZATION: Batch git commands into single call
196
- * Uses `git log -1 --format=%D%n%h%n%s` to get branch, short hash, and subject
197
- * in a single subprocess instead of 3 separate calls.
198
- * Savings: ~20-40ms (eliminates 2 subprocess spawns)
199
- */
200
- function getGitInfo(rootDir) {
201
- const opts = { cwd: rootDir, timeout: 5000, fallback: '' };
202
- const result = git(['log', '-1', '--format=%D%n%h%n%s'], opts);
203
- if (result.data) {
204
- const lines = result.data.split('\n');
205
- // %D gives decorations like "HEAD -> main, origin/main, tag: v3.0.0"
206
- const branchMatch = (lines[0] || '').match(/HEAD -> ([^,\s]+)/);
207
- return {
208
- branch: branchMatch ? branchMatch[1] : 'detached',
209
- commit: (lines[1] || 'unknown').trim(),
210
- lastCommit: lines.slice(2).join('\n').trim(),
211
- };
212
- }
213
- return { branch: 'unknown', commit: 'unknown', lastCommit: '' };
214
- }
215
-
216
- function getProjectInfo(rootDir, cache = null) {
217
- const info = {
218
- name: 'agileflow',
219
- version: 'unknown',
220
- branch: 'unknown',
221
- commit: 'unknown',
222
- lastCommit: '',
223
- wipCount: 0,
224
- blockedCount: 0,
225
- completedCount: 0,
226
- readyCount: 0,
227
- totalStories: 0,
228
- currentStory: null,
229
- };
230
-
231
- // Get AgileFlow version (check multiple sources in priority order)
232
- // 1. .agileflow/config.yaml (installed user projects - primary source)
233
- // 2. AgileFlow metadata (installed user projects - legacy)
234
- // 3. packages/cli/package.json (AgileFlow dev project)
235
- try {
236
- // Primary: .agileflow/config.yaml (use cache if available)
237
- if (cache?.configYaml) {
238
- const versionMatch = cache.configYaml.match(/^version:\s*['"]?([0-9.]+)/m);
239
- if (versionMatch) {
240
- info.version = versionMatch[1];
241
- }
242
- } else if (cache?.metadata?.version) {
243
- // Fallback: metadata from cache
244
- info.version = cache.metadata.version;
245
- } else if (cache?.cliPackage?.version) {
246
- // Dev project: from cache
247
- info.version = cache.cliPackage.version;
248
- } else {
249
- // No cache - fall back to file reads (for backwards compatibility)
250
- const configPath = path.join(getAgileflowDir(rootDir), 'config.yaml');
251
- if (fs.existsSync(configPath)) {
252
- const content = fs.readFileSync(configPath, 'utf8');
253
- const versionMatch = content.match(/^version:\s*['"]?([0-9.]+)/m);
254
- if (versionMatch) {
255
- info.version = versionMatch[1];
256
- }
257
- } else {
258
- const metadataPath = getMetadataPath(rootDir);
259
- if (fs.existsSync(metadataPath)) {
260
- const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
261
- info.version = metadata.version || info.version;
262
- } else {
263
- const pkg = JSON.parse(
264
- fs.readFileSync(path.join(rootDir, 'packages/cli/package.json'), 'utf8')
265
- );
266
- info.version = pkg.version || info.version;
267
- }
268
- }
269
- }
270
- } catch (e) {
271
- // Silently fail - version will remain 'unknown'
272
- }
273
-
274
- // Get git info (batched into single command for performance)
275
- const gitInfo = getGitInfo(rootDir);
276
- info.branch = gitInfo.branch;
277
- info.commit = gitInfo.commit;
278
- info.lastCommit = gitInfo.lastCommit;
279
-
280
- // Get status info (use cache if available)
281
- try {
282
- const status = cache?.status;
283
- if (status?.stories) {
284
- for (const [id, story] of Object.entries(status.stories)) {
285
- info.totalStories++;
286
- if (story.status === 'in_progress') {
287
- info.wipCount++;
288
- if (!info.currentStory) {
289
- info.currentStory = { id, title: story.title };
290
- }
291
- } else if (story.status === 'blocked') {
292
- info.blockedCount++;
293
- } else if (story.status === 'completed') {
294
- info.completedCount++;
295
- } else if (story.status === 'ready') {
296
- info.readyCount++;
297
- }
298
- }
299
- } else if (!cache) {
300
- // No cache - fall back to file read
301
- const statusPath = getStatusPath(rootDir);
302
- if (fs.existsSync(statusPath)) {
303
- const statusData = JSON.parse(fs.readFileSync(statusPath, 'utf8'));
304
- if (statusData.stories) {
305
- for (const [id, story] of Object.entries(statusData.stories)) {
306
- info.totalStories++;
307
- if (story.status === 'in_progress') {
308
- info.wipCount++;
309
- if (!info.currentStory) {
310
- info.currentStory = { id, title: story.title };
311
- }
312
- } else if (story.status === 'blocked') {
313
- info.blockedCount++;
314
- } else if (story.status === 'completed') {
315
- info.completedCount++;
316
- } else if (story.status === 'ready') {
317
- info.readyCount++;
318
- }
319
- }
320
- }
321
- }
322
- }
323
- } catch (e) {
324
- log.debug('getProjectInfo:', e?.message || String(e));
325
- }
326
-
327
- return info;
328
- }
329
-
330
- function runArchival(rootDir, cache = null) {
331
- const result = { ran: false, threshold: 7, archived: 0, remaining: 0 };
332
-
333
- try {
334
- // Use cached metadata if available
335
- const metadata = cache?.metadata;
336
- if (metadata) {
337
- if (metadata.archival?.enabled === false) {
338
- result.disabled = true;
339
- return result;
340
- }
341
- result.threshold = metadata.archival?.threshold_days || 7;
342
- } else {
343
- // No cache - fall back to file read
344
- const metadataPath = getMetadataPath(rootDir);
345
- if (fs.existsSync(metadataPath)) {
346
- const metadataData = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
347
- if (metadataData.archival?.enabled === false) {
348
- result.disabled = true;
349
- return result;
350
- }
351
- result.threshold = metadataData.archival?.threshold_days || 7;
352
- }
353
- }
354
-
355
- // Use cached status if available
356
- const status = cache?.status;
357
- if (!status && !cache) {
358
- const statusPath = getStatusPath(rootDir);
359
- if (!fs.existsSync(statusPath)) return result;
360
- }
361
-
362
- const stories = (status || {}).stories || {};
363
-
364
- const cutoffDate = new Date();
365
- cutoffDate.setDate(cutoffDate.getDate() - result.threshold);
366
-
367
- let toArchiveCount = 0;
368
- for (const [id, story] of Object.entries(stories)) {
369
- if (story.status === 'completed' && story.completed_at) {
370
- if (new Date(story.completed_at) < cutoffDate) {
371
- toArchiveCount++;
372
- }
373
- }
374
- }
375
-
376
- result.ran = true;
377
- result.remaining = Object.keys(stories).length;
378
-
379
- if (toArchiveCount > 0) {
380
- // Run archival
381
- const archiveResult = executeCommandSync('bash', ['scripts/archive-completed-stories.sh'], {
382
- cwd: rootDir,
383
- });
384
- if (archiveResult.ok) {
385
- result.archived = toArchiveCount;
386
- result.remaining -= toArchiveCount;
387
- }
388
- }
389
- } catch (e) {
390
- log.debug('runArchival:', e?.message || String(e));
391
- }
392
-
393
- return result;
394
- }
395
-
396
- function clearActiveCommands(rootDir, cache = null) {
397
- const result = { ran: false, cleared: 0, commandNames: [], preserved: false };
398
-
399
- try {
400
- const sessionStatePath = getSessionStatePath(rootDir);
401
-
402
- // Use cached sessionState if available, but we still need to read fresh for clearing
403
- // because we need to write back. Cache is only useful to check if file exists.
404
- let state;
405
- if (cache?.sessionState) {
406
- state = cache.sessionState;
407
- result.ran = true;
408
- } else {
409
- if (!fs.existsSync(sessionStatePath)) return result;
410
- state = JSON.parse(fs.readFileSync(sessionStatePath, 'utf8'));
411
- result.ran = true;
412
- }
413
-
414
- // Check if PreCompact just ran (within last 30 seconds)
415
- // If so, preserve active_commands instead of clearing them (post-compact session start)
416
- if (state.last_precompact_at) {
417
- const precompactTime = new Date(state.last_precompact_at).getTime();
418
- const now = Date.now();
419
- const secondsSincePrecompact = (now - precompactTime) / 1000;
420
-
421
- if (secondsSincePrecompact < 600) {
422
- // 10 minutes - compacts can take a while with background tasks
423
- // This is a post-compact session start - preserve active commands
424
- result.preserved = true;
425
- // Capture command names for display (but don't clear)
426
- if (state.active_commands && state.active_commands.length > 0) {
427
- for (const cmd of state.active_commands) {
428
- if (cmd.name) result.commandNames.push(cmd.name);
429
- }
430
- }
431
- // Clear the precompact timestamp so next true session start will clear
432
- delete state.last_precompact_at;
433
- fs.writeFileSync(sessionStatePath, JSON.stringify(state, null, 2) + '\n');
434
- return result;
435
- }
436
- // Precompact was too long ago - clear as normal
437
- delete state.last_precompact_at;
438
- }
439
-
440
- // Handle new array format (active_commands)
441
- if (state.active_commands && state.active_commands.length > 0) {
442
- result.cleared = state.active_commands.length;
443
- // Capture command names before clearing
444
- for (const cmd of state.active_commands) {
445
- if (cmd.name) result.commandNames.push(cmd.name);
446
- }
447
- state.active_commands = [];
448
- }
449
-
450
- // Handle legacy singular format (active_command) - only capture if not already in array
451
- if (state.active_command !== undefined) {
452
- const legacyName = state.active_command.name;
453
- // Only add to count/names if not already captured from array (avoid duplicates)
454
- if (legacyName && !result.commandNames.includes(legacyName)) {
455
- result.cleared++;
456
- result.commandNames.push(legacyName);
457
- }
458
- delete state.active_command;
459
- }
460
-
461
- if (result.cleared > 0) {
462
- fs.writeFileSync(sessionStatePath, JSON.stringify(state, null, 2) + '\n');
463
- }
464
- } catch (e) {
465
- log.debug('clearActiveCommands:', e?.message || String(e));
466
- }
467
-
468
- return result;
469
- }
470
-
471
- /**
472
- * PERFORMANCE OPTIMIZATION (US-0356): Lightweight session check
473
- *
474
- * Replaces the full session-manager require chain (~3,600 lines across 8 modules)
475
- * with direct file I/O on the registry.json and lock files (~30 lines).
476
- * Only checks active session count and current session info.
477
- * Full registration, cleanup, and worktree detection deferred to Phase 3 (welcome-deferred.js).
478
- *
479
- * Estimated savings: 100-200ms
480
- */
481
- function checkParallelSessionsFast(rootDir) {
482
- const result = {
483
- available: false,
484
- registered: false,
485
- otherActive: 0,
486
- currentId: null,
487
- cleaned: 0,
488
- cleanedSessions: [],
489
- isMain: true,
490
- nickname: null,
491
- branch: null,
492
- sessionPath: null,
493
- mainPath: rootDir,
494
- };
495
-
496
- try {
497
- const sessionsDir = path.join(getAgileflowDir(rootDir), 'sessions');
498
- const registryPath = path.join(sessionsDir, 'registry.json');
499
-
500
- if (!fs.existsSync(registryPath)) return result;
501
-
502
- const registry = JSON.parse(fs.readFileSync(registryPath, 'utf8'));
503
- if (!registry.sessions) return result;
504
-
505
- result.available = true;
506
- const cwd = process.cwd();
507
- const staleLocks = [];
508
-
509
- for (const [id, session] of Object.entries(registry.sessions)) {
510
- if (session.path === cwd) {
511
- // Found current session
512
- result.registered = true;
513
- result.currentId = id;
514
- result.isMain = session.is_main === true;
515
- result.nickname = session.nickname || null;
516
- result.branch = session.branch || null;
517
- result.sessionPath = session.path;
518
- } else {
519
- // Check if other session is alive via lock file
520
- const lockPath = path.join(sessionsDir, `${id}.lock`);
521
- if (fs.existsSync(lockPath)) {
522
- try {
523
- const content = fs.readFileSync(lockPath, 'utf8');
524
- const pidMatch = content.match(/^pid=(\d+)/m);
525
- if (pidMatch) {
526
- const pid = parseInt(pidMatch[1], 10);
527
- try {
528
- process.kill(pid, 0); // Signal 0 = check alive
529
- result.otherActive++;
530
- } catch (e) {
531
- // Process dead - collect for cleanup
532
- staleLocks.push({ id, lockPath, pid });
533
- }
534
- }
535
- } catch (e) {
536
- // Lock read failed
537
- }
538
- }
539
- }
540
- }
541
-
542
- // Quick cleanup of stale locks (prevents ghost session counts)
543
- for (const stale of staleLocks) {
544
- try {
545
- fs.unlinkSync(stale.lockPath);
546
- result.cleaned++;
547
- result.cleanedSessions.push({
548
- id: stale.id,
549
- pid: stale.pid,
550
- reason: 'pid_dead',
551
- });
552
- } catch (e) {
553
- // Cleanup failed, deferred will retry
554
- }
555
- }
556
- } catch (e) {
557
- log.debug('checkParallelSessionsFast:', e?.message || String(e));
558
- }
559
-
560
- return result;
561
- }
562
-
563
- function checkPreCompact(rootDir, cache = null) {
564
- const result = { configured: false, scriptExists: false, version: null, outdated: false };
565
-
566
- try {
567
- // Check if PreCompact hook is configured in settings (use cache if available)
568
- const settings = cache?.settings;
569
- if (settings) {
570
- if (settings.hooks?.PreCompact?.length > 0) {
571
- result.configured = true;
572
- }
573
- } else {
574
- // No cache - fall back to file read
575
- const settingsPath = path.join(getClaudeDir(rootDir), 'settings.json');
576
- if (fs.existsSync(settingsPath)) {
577
- const settingsData = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
578
- if (settingsData.hooks?.PreCompact?.length > 0) {
579
- result.configured = true;
580
- }
581
- }
582
- }
583
-
584
- // Check if the script exists (must always check filesystem)
585
- const scriptPath = path.join(rootDir, 'scripts', 'precompact-context.sh');
586
- if (fs.existsSync(scriptPath)) {
587
- result.scriptExists = true;
588
- }
589
-
590
- // Check configured version from metadata (use cache if available)
591
- const metadata = cache?.metadata;
592
- if (metadata) {
593
- if (metadata.features?.precompact?.configured_version) {
594
- result.version = metadata.features.precompact.configured_version;
595
- // PreCompact v2.40.0+ has multi-command support
596
- result.outdated = compareVersions(result.version, '2.40.0') < 0;
597
- } else if (result.configured) {
598
- // Hook exists but no version tracked = definitely outdated
599
- result.outdated = true;
600
- result.version = 'unknown';
601
- }
602
- } else if (!cache) {
603
- // No cache - fall back to file read
604
- const metadataPath = getMetadataPath(rootDir);
605
- if (fs.existsSync(metadataPath)) {
606
- const metadataData = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
607
- if (metadataData.features?.precompact?.configured_version) {
608
- result.version = metadataData.features.precompact.configured_version;
609
- result.outdated = compareVersions(result.version, '2.40.0') < 0;
610
- } else if (result.configured) {
611
- result.outdated = true;
612
- result.version = 'unknown';
613
- }
614
- }
615
- }
616
- } catch (e) {
617
- log.debug('checkPreCompact:', e?.message || String(e));
618
- }
619
-
620
- return result;
621
- }
622
-
623
- function checkDamageControl(rootDir, cache = null) {
624
- const result = { configured: false, level: 'standard', patternCount: 0, scriptsOk: true };
625
-
626
- try {
627
- // Check if PreToolUse hooks are configured in settings (use cache if available)
628
- let settings = cache?.settings;
629
- if (!settings && !cache) {
630
- // No cache - fall back to file read
631
- const settingsPath = path.join(getClaudeDir(rootDir), 'settings.json');
632
- if (fs.existsSync(settingsPath)) {
633
- settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
634
- }
635
- }
636
-
637
- if (settings) {
638
- if (settings.hooks?.PreToolUse && Array.isArray(settings.hooks.PreToolUse)) {
639
- // Check for damage-control hooks
640
- const hasDamageControlHooks = settings.hooks.PreToolUse.some(h =>
641
- h.hooks?.some(hk => hk.command?.includes('damage-control'))
642
- );
643
- if (hasDamageControlHooks) {
644
- result.configured = true;
645
-
646
- // Count how many hooks are present (should be 3: Bash, Edit, Write)
647
- const dcHooks = settings.hooks.PreToolUse.filter(h =>
648
- h.hooks?.some(hk => hk.command?.includes('damage-control'))
649
- );
650
- result.hooksCount = dcHooks.length;
651
-
652
- // Check for enhanced mode (has prompt hook)
653
- const hasPromptHook = settings.hooks.PreToolUse.some(h =>
654
- h.hooks?.some(hk => hk.type === 'prompt')
655
- );
656
- if (hasPromptHook) {
657
- result.level = 'enhanced';
658
- }
659
-
660
- // Check if all required scripts exist (in .claude/hooks/damage-control/)
661
- const hooksDir = path.join(getClaudeDir(rootDir), 'hooks', 'damage-control');
662
- const requiredScripts = [
663
- 'bash-tool-damage-control.js',
664
- 'edit-tool-damage-control.js',
665
- 'write-tool-damage-control.js',
666
- ];
667
- for (const script of requiredScripts) {
668
- if (!fs.existsSync(path.join(hooksDir, script))) {
669
- result.scriptsOk = false;
670
- break;
671
- }
672
- }
673
- }
674
- }
675
- }
676
-
677
- // Count patterns in patterns.yaml
678
- const patternsLocations = [
679
- path.join(getClaudeDir(rootDir), 'hooks', 'damage-control', 'patterns.yaml'),
680
- path.join(getAgileflowDir(rootDir), 'scripts', 'damage-control', 'patterns.yaml'),
681
- ];
682
- for (const patternsPath of patternsLocations) {
683
- if (fs.existsSync(patternsPath)) {
684
- const content = fs.readFileSync(patternsPath, 'utf8');
685
- // Count pattern entries (lines starting with " - pattern:")
686
- const patternMatches = content.match(/^\s*-\s*pattern:/gm);
687
- result.patternCount = patternMatches ? patternMatches.length : 0;
688
- break;
689
- }
690
- }
691
- } catch (e) {
692
- log.debug('checkDamageControl:', e?.message || String(e));
693
- }
694
-
695
- return result;
696
- }
697
-
698
- // Compare semantic versions: returns -1 if a < b, 0 if equal, 1 if a > b
699
- function compareVersions(a, b) {
700
- if (!a || !b) return 0;
701
- const partsA = a.split('.').map(Number);
702
- const partsB = b.split('.').map(Number);
703
- for (let i = 0; i < 3; i++) {
704
- const numA = partsA[i] || 0;
705
- const numB = partsB[i] || 0;
706
- if (numA < numB) return -1;
707
- if (numA > numB) return 1;
708
- }
709
- return 0;
710
- }
711
-
712
- /**
713
- * All available config options with their version requirements
714
- * These are the options that can be configured through /agileflow:configure
715
- */
716
- const ALL_CONFIG_OPTIONS = {
717
- claudeMdReinforcement: {
718
- since: '2.92.0',
719
- description: 'Add /babysit rules to CLAUDE.md',
720
- autoApplyable: true,
721
- },
722
- sessionStartHook: {
723
- since: '2.35.0',
724
- description: 'Welcome display on session start',
725
- autoApplyable: false,
726
- },
727
- precompactHook: {
728
- since: '2.40.0',
729
- description: 'Context preservation during /compact',
730
- autoApplyable: false,
731
- },
732
- damageControlHooks: {
733
- since: '2.50.0',
734
- description: 'Block destructive commands',
735
- autoApplyable: false,
736
- },
737
- statusLine: { since: '2.35.0', description: 'Custom status bar display', autoApplyable: false },
738
- autoArchival: {
739
- since: '2.35.0',
740
- description: 'Auto-archive completed stories',
741
- autoApplyable: false,
742
- },
743
- autoUpdate: {
744
- since: '2.70.0',
745
- description: 'Auto-update on session start',
746
- autoApplyable: false,
747
- },
748
- ralphLoop: { since: '2.60.0', description: 'Autonomous story processing', autoApplyable: false },
749
- tmuxAutoSpawn: {
750
- since: '2.92.0',
751
- description: 'Auto-start Claude in tmux session',
752
- autoApplyable: true,
753
- },
754
- };
755
-
756
- /**
757
- * Check for new config options that haven't been presented to the user
758
- * Returns info about outdated config and whether to auto-apply (for "full" profile)
759
- */
760
- function checkConfigStaleness(rootDir, currentVersion, cache = null) {
761
- const result = {
762
- outdated: false,
763
- newOptionsCount: 0,
764
- newOptions: [],
765
- configSchemaVersion: null,
766
- activeProfile: null,
767
- autoApply: false,
768
- };
769
-
770
- try {
771
- const metadata = cache?.metadata;
772
- if (!metadata) return result;
773
-
774
- result.configSchemaVersion = metadata.config_schema_version || null;
775
- result.activeProfile = metadata.active_profile || null;
776
-
777
- const configOptions = metadata.agileflow?.config_options || {};
778
-
779
- // If no config_schema_version, this is an old installation - all options are "new"
780
- if (!result.configSchemaVersion) {
781
- // For old installations, detect which features are actually configured via settings.json
782
- const settings = cache?.settings || {};
783
- const hooks = settings.hooks || {};
784
-
785
- // Check each option against actual configuration
786
- for (const [name, optionInfo] of Object.entries(ALL_CONFIG_OPTIONS)) {
787
- const isConfigured = isOptionActuallyConfigured(name, hooks, settings);
788
- if (!isConfigured) {
789
- result.outdated = true;
790
- result.newOptionsCount++;
791
- result.newOptions.push({
792
- name,
793
- description: optionInfo.description,
794
- autoApplyable: optionInfo.autoApplyable,
795
- });
796
- }
797
- }
798
- } else {
799
- // Check for unconfigured options in metadata
800
- for (const [name, option] of Object.entries(configOptions)) {
801
- if (option.configured === false) {
802
- const optionInfo = ALL_CONFIG_OPTIONS[name] || {
803
- description: name,
804
- autoApplyable: false,
805
- };
806
- result.outdated = true;
807
- result.newOptionsCount++;
808
- result.newOptions.push({
809
- name,
810
- description: optionInfo.description,
811
- autoApplyable: optionInfo.autoApplyable,
812
- });
813
- }
814
- }
815
-
816
- // Check for options that might not be in metadata yet (added after their install)
817
- for (const [name, optionInfo] of Object.entries(ALL_CONFIG_OPTIONS)) {
818
- if (!configOptions[name]) {
819
- // Option doesn't exist in metadata - check if it was added after their config_schema_version
820
- if (compareVersions(result.configSchemaVersion, optionInfo.since) < 0) {
821
- const alreadyAdded = result.newOptions.some(o => o.name === name);
822
- if (!alreadyAdded) {
823
- result.outdated = true;
824
- result.newOptionsCount++;
825
- result.newOptions.push({
826
- name,
827
- description: optionInfo.description,
828
- autoApplyable: optionInfo.autoApplyable,
829
- });
830
- }
831
- }
832
- }
833
- }
834
- }
835
-
836
- // If profile is "full", auto-apply features that support it
837
- if (result.outdated && result.activeProfile === 'full') {
838
- const autoApplyableOptions = result.newOptions.filter(o => o.autoApplyable);
839
- if (autoApplyableOptions.length > 0) {
840
- result.autoApply = true;
841
- // Only auto-apply the auto-applyable ones
842
- result.autoApplyOptions = autoApplyableOptions;
843
- }
844
- }
845
- } catch (e) {
846
- // Silently fail - config check is non-critical
847
- }
848
-
849
- return result;
850
- }
851
-
852
- /**
853
- * Check if a config option is actually configured in settings
854
- */
855
- function isOptionActuallyConfigured(optionName, hooks, settings) {
856
- switch (optionName) {
857
- case 'sessionStartHook':
858
- return hooks.SessionStart && hooks.SessionStart.length > 0;
859
- case 'precompactHook':
860
- return hooks.PreCompact && hooks.PreCompact.length > 0;
861
- case 'damageControlHooks':
862
- return (
863
- hooks.PreToolUse &&
864
- hooks.PreToolUse.some(h => h.hooks?.some(hk => hk.command?.includes('damage-control')))
865
- );
866
- case 'statusLine':
867
- return settings.statusLine && settings.statusLine.command;
868
- case 'autoArchival':
869
- // Archival is tied to SessionStart hook running archive script
870
- return (
871
- hooks.SessionStart &&
872
- hooks.SessionStart.some(h => h.hooks?.some(hk => hk.command?.includes('archive')))
873
- );
874
- case 'autoUpdate':
875
- // Would need to check metadata for autoUpdate setting
876
- return false; // Default to not configured
877
- case 'ralphLoop':
878
- return (
879
- hooks.Stop && hooks.Stop.some(h => h.hooks?.some(hk => hk.command?.includes('ralph-loop')))
880
- );
881
- case 'claudeMdReinforcement':
882
- // Check if CLAUDE.md has the marker - can't easily check from here
883
- return false; // Let welcome script handle this
884
- case 'tmuxAutoSpawn':
885
- // Check metadata for tmuxAutoSpawn setting (default is enabled)
886
- return false; // Let welcome script handle this via metadata
887
- default:
888
- return false;
889
- }
890
- }
891
-
892
- /**
893
- * Auto-apply new config options for "full" profile
894
- * Returns true if any options were applied
895
- */
896
- function autoApplyConfigOptions(rootDir, newOptions) {
897
- let applied = 0;
898
-
899
- for (const option of newOptions) {
900
- try {
901
- if (option.name === 'claudeMdReinforcement') {
902
- // Apply CLAUDE.md reinforcement
903
- const claudeMdPath = path.join(rootDir, 'CLAUDE.md');
904
- const marker = '<!-- AGILEFLOW_BABYSIT_RULES -->';
905
- const content = `
906
-
907
- ${marker}
908
- ## AgileFlow /babysit Context Preservation Rules
909
-
910
- When \`/agileflow:babysit\` is active (check session-state.json), these rules are MANDATORY:
911
-
912
- 1. **ALWAYS end responses with the AskUserQuestion tool** - Not text like "What next?" but the ACTUAL TOOL CALL
913
- 2. **Use Plan Mode for non-trivial tasks** - Call \`EnterPlanMode\` before complex implementations
914
- 3. **Delegate complex work to domain experts** - Use \`Task\` tool with appropriate \`subagent_type\`
915
- 4. **Track progress with TaskCreate/TaskUpdate** - For any task with 3+ steps
916
-
917
- These rules persist across conversation compaction. Check \`docs/09-agents/session-state.json\` for active commands.
918
- ${marker}
919
- `;
920
-
921
- let existingContent = '';
922
- if (fs.existsSync(claudeMdPath)) {
923
- existingContent = fs.readFileSync(claudeMdPath, 'utf8');
924
- }
925
-
926
- if (!existingContent.includes(marker)) {
927
- fs.appendFileSync(claudeMdPath, content);
928
- applied++;
929
- }
930
- } else if (option.name === 'tmuxAutoSpawn') {
931
- // Auto-enable tmux auto-spawn via metadata
932
- const metadataPath = getMetadataPath(rootDir);
933
- if (fs.existsSync(metadataPath)) {
934
- const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
935
- if (!metadata.features) metadata.features = {};
936
- if (
937
- !metadata.features.tmuxAutoSpawn ||
938
- metadata.features.tmuxAutoSpawn.enabled === undefined
939
- ) {
940
- metadata.features.tmuxAutoSpawn = {
941
- enabled: true,
942
- version: metadata.version || '2.92.0',
943
- at: new Date().toISOString(),
944
- };
945
- fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2) + '\n');
946
- applied++;
947
- }
948
- }
949
- }
950
- // Add more option handlers here as new options are added
951
- } catch (e) {
952
- // Silently fail individual options
953
- }
954
- }
955
-
956
- // Update metadata to mark options as configured
957
- if (applied > 0) {
958
- try {
959
- const metadataPath = getMetadataPath(rootDir);
960
- if (fs.existsSync(metadataPath)) {
961
- const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
962
-
963
- // Get current CLI version for updating config_schema_version
964
- let currentVersion = '2.92.0';
965
- try {
966
- const pkgPath = path.join(__dirname, '..', 'package.json');
967
- if (fs.existsSync(pkgPath)) {
968
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
969
- currentVersion = pkg.version;
970
- }
971
- } catch (e) {
972
- log.debug('getPackageVersion:', e?.message || String(e));
973
- }
974
-
975
- // Update config_schema_version
976
- metadata.config_schema_version = currentVersion;
977
-
978
- // Mark applied options as configured
979
- if (!metadata.agileflow) metadata.agileflow = {};
980
- if (!metadata.agileflow.config_options) metadata.agileflow.config_options = {};
981
-
982
- for (const option of newOptions) {
983
- metadata.agileflow.config_options[option.name] = {
984
- ...metadata.agileflow.config_options[option.name],
985
- configured: true,
986
- enabled: true,
987
- configured_at: new Date().toISOString(),
988
- };
989
- }
990
-
991
- fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2) + '\n');
992
- }
993
- } catch (e) {
994
- // Silently fail metadata update
995
- }
996
- }
997
-
998
- return applied;
999
- }
1000
-
1001
- /**
1002
- * PERFORMANCE OPTIMIZATION: Check update cache in session-state.json (1-hour TTL)
1003
- * Avoids ~139ms npm registry network call when cache is fresh.
1004
- * Returns cached update result or null if stale/missing.
1005
- */
1006
- function getUpdateFromCache(cache) {
1007
- try {
1008
- const updateCache = cache?.sessionState?.update_cache;
1009
- if (!updateCache || typeof updateCache !== 'object') return null;
1010
- if (!updateCache.checked_at || !updateCache.result) return null;
1011
-
1012
- const checkedAt = new Date(updateCache.checked_at).getTime();
1013
- if (!Number.isFinite(checkedAt)) return null;
1014
-
1015
- const age = Date.now() - checkedAt;
1016
- const ONE_HOUR = 60 * 60 * 1000;
1017
-
1018
- // Reject negative age (future timestamps from clock skew) or absurdly old
1019
- if (age < 0 || age > 24 * ONE_HOUR) return null;
1020
-
1021
- if (age < ONE_HOUR) {
1022
- return updateCache.result;
1023
- }
1024
- } catch (e) {
1025
- // Cache read failed
1026
- }
1027
- return null;
1028
- }
1029
-
1030
- /**
1031
- * Display deferred warnings from previous session's background work.
1032
- * Warnings are saved by welcome-deferred.js and displayed here on next start.
1033
- * Clears warnings after display.
1034
- */
1035
- function displayDeferredWarnings(rootDir) {
1036
- try {
1037
- const sessionStatePath = getSessionStatePath(rootDir);
1038
- if (!fs.existsSync(sessionStatePath)) return;
1039
-
1040
- const state = JSON.parse(fs.readFileSync(sessionStatePath, 'utf8'));
1041
- const deferredWarnings = state.deferred_warnings;
1042
- if (!deferredWarnings || !Array.isArray(deferredWarnings) || deferredWarnings.length === 0)
1043
- return;
1044
-
1045
- for (const warning of deferredWarnings) {
1046
- if (!warning.lines || warning.lines.length === 0) continue;
1047
-
1048
- console.log('');
1049
- switch (warning.type) {
1050
- case 'update_available':
1051
- console.log(`${c.amber}↑ ${warning.lines[0]}${c.reset}`);
1052
- if (warning.lines[1]) console.log(` ${c.skyBlue}${warning.lines[1]}${c.reset}`);
1053
- break;
1054
- case 'session_health':
1055
- for (const line of warning.lines) {
1056
- if (line.startsWith(' ')) {
1057
- console.log(`${c.dim} └─ ${line.trim()}${c.reset}`);
1058
- } else {
1059
- console.log(`${c.coral}⚠️ ${line}${c.reset}`);
1060
- }
1061
- }
1062
- break;
1063
- case 'process_cleanup':
1064
- console.log(`${c.amber}⚠️ ${warning.lines[0]}${c.reset}`);
1065
- if (warning.lines.length > 1) {
1066
- for (const line of warning.lines.slice(1)) {
1067
- console.log(`${c.slate} ${line}${c.reset}`);
1068
- }
1069
- }
1070
- break;
1071
- case 'epic_completion':
1072
- for (const line of warning.lines) {
1073
- console.log(`${c.mintGreen}✅ ${line}${c.reset}`);
1074
- }
1075
- break;
1076
- case 'ideation_sync':
1077
- console.log(`${c.dim}📊 ${warning.lines[0]}${c.reset}`);
1078
- break;
1079
- case 'automations':
1080
- console.log(`${c.teal}🤖 ${warning.lines[0]}${c.reset}`);
1081
- for (const line of warning.lines.slice(1)) {
1082
- console.log(`${c.dim} └─ ${line}${c.reset}`);
1083
- }
1084
- break;
1085
- case 'story_claiming':
1086
- console.log(`${c.amber}🔒 ${warning.lines[0]}${c.reset}`);
1087
- for (const line of warning.lines.slice(1)) {
1088
- console.log(`${c.dim} └─ ${line.trim()}${c.reset}`);
1089
- }
1090
- break;
1091
- case 'file_tracking':
1092
- console.log(`${c.amber}📁 ${warning.lines[0]}${c.reset}`);
1093
- break;
1094
- default:
1095
- for (const line of warning.lines) {
1096
- console.log(`${c.dim}${line}${c.reset}`);
1097
- }
1098
- }
1099
- }
1100
-
1101
- // Clear deferred warnings after display
1102
- delete state.deferred_warnings;
1103
- fs.writeFileSync(sessionStatePath, JSON.stringify(state, null, 2) + '\n');
1104
- } catch (e) {
1105
- // Display failed, non-critical
1106
- }
1107
- }
1108
-
1109
- // Check for updates (now handled by welcome-deferred.js, kept for backward compatibility)
1110
- async function checkUpdates() {
1111
- const result = {
1112
- available: false,
1113
- installed: null,
1114
- latest: null,
1115
- justUpdated: false,
1116
- previousVersion: null,
1117
- autoUpdate: false,
1118
- changelog: [],
1119
- };
1120
-
1121
- const updateChecker = tryOptional(() => require('./check-update.js'), 'check-update');
1122
- if (!updateChecker) return result;
1123
-
1124
- try {
1125
- const updateInfo = await updateChecker.checkForUpdates();
1126
- result.installed = updateInfo.installed;
1127
- result.latest = updateInfo.latest;
1128
- result.available = updateInfo.updateAvailable;
1129
- result.justUpdated = updateInfo.justUpdated;
1130
- result.previousVersion = updateInfo.previousVersion;
1131
- result.autoUpdate = updateInfo.autoUpdate;
1132
-
1133
- // If just updated, try to get changelog entries
1134
- if (result.justUpdated && result.installed) {
1135
- result.changelog = getChangelogEntries(result.installed);
1136
- }
1137
- } catch (e) {
1138
- // Silently fail - update check is non-critical
1139
- }
1140
-
1141
- return result;
1142
- }
1143
-
1144
- // Parse CHANGELOG.md for entries of a specific version
1145
- function getChangelogEntries(version) {
1146
- const entries = [];
1147
-
1148
- try {
1149
- // Look for CHANGELOG.md in .agileflow or package location
1150
- const possiblePaths = [
1151
- path.join(__dirname, '..', 'CHANGELOG.md'),
1152
- path.join(__dirname, 'CHANGELOG.md'),
1153
- ];
1154
-
1155
- let changelogContent = null;
1156
- for (const p of possiblePaths) {
1157
- if (fs.existsSync(p)) {
1158
- changelogContent = fs.readFileSync(p, 'utf8');
1159
- break;
1160
- }
1161
- }
1162
-
1163
- if (!changelogContent) return entries;
1164
-
1165
- // Find the section for this version
1166
- const versionPattern = new RegExp(`## \\[${version}\\].*?\\n([\\s\\S]*?)(?=## \\[|$)`);
1167
- const match = changelogContent.match(versionPattern);
1168
-
1169
- if (match) {
1170
- // Extract bullet points from Added/Changed/Fixed sections
1171
- const lines = match[1].split('\n');
1172
- for (const line of lines) {
1173
- const bulletMatch = line.match(/^- (.+)$/);
1174
- if (bulletMatch && entries.length < 3) {
1175
- entries.push(bulletMatch[1]);
1176
- }
1177
- }
1178
- }
1179
- } catch (e) {
1180
- // Silently fail
1181
- }
1182
-
1183
- return entries;
1184
- }
1185
-
1186
- // Run auto-update if enabled (quiet mode - minimal output)
1187
- // DEPRECATED: Use spawnAutoUpdateInBackground() instead for non-blocking updates
1188
- async function runAutoUpdate(rootDir, fromVersion, toVersion) {
1189
- const runUpdate = () => {
1190
- return executeCommandSync('npx', ['agileflow@latest', 'update', '--force'], {
1191
- cwd: rootDir,
1192
- timeout: 120000,
1193
- });
1194
- };
1195
-
1196
- console.log(
1197
- `${c.skyBlue}Updating AgileFlow${c.reset} ${c.dim}v${fromVersion} → v${toVersion}${c.reset}`
1198
- );
1199
- const result = runUpdate();
1200
- if (result.ok) {
1201
- console.log(`${c.mintGreen}✓ Update complete${c.reset}`);
1202
- return true;
1203
- }
1204
-
1205
- // Check if this is a stale npm cache issue (ETARGET = version not found)
1206
- if (result.error && (result.error.includes('ETARGET') || result.error.includes('notarget'))) {
1207
- console.log(`${c.dim} Clearing npm cache and retrying...${c.reset}`);
1208
- executeCommandSync('npm', ['cache', 'clean', '--force'], { timeout: 30000 });
1209
- const retryResult = runUpdate();
1210
- if (retryResult.ok) {
1211
- console.log(`${c.mintGreen}✓ Update complete${c.reset}`);
1212
- return true;
1213
- }
1214
- console.log(`${c.peach}Auto-update failed after cache clean${c.reset}`);
1215
- console.log(`${c.dim} Run manually: npx agileflow update${c.reset}`);
1216
- return false;
1217
- }
1218
- console.log(`${c.peach}Auto-update failed${c.reset}`);
1219
- console.log(`${c.dim} Run manually: npx agileflow update${c.reset}`);
1220
- return false;
1221
- }
1222
-
1223
- /**
1224
- * Spawn auto-update in a detached background process
1225
- * This allows the welcome hook to return immediately while the update runs
1226
- *
1227
- * @param {string} rootDir - Project root directory
1228
- * @param {string} fromVersion - Current version
1229
- * @param {string} toVersion - Target version
1230
- */
1231
- function spawnAutoUpdateInBackground(rootDir, fromVersion, toVersion) {
1232
- // Track pending update in session-state.json
1233
- try {
1234
- const sessionStatePath = getSessionStatePath(rootDir);
1235
- let state = {};
1236
- if (fs.existsSync(sessionStatePath)) {
1237
- state = JSON.parse(fs.readFileSync(sessionStatePath, 'utf8'));
1238
- }
1239
- state.pending_update = {
1240
- from: fromVersion,
1241
- to: toVersion,
1242
- started_at: new Date().toISOString(),
1243
- };
1244
- fs.writeFileSync(sessionStatePath, JSON.stringify(state, null, 2) + '\n');
1245
- } catch (e) {
1246
- // Silently continue - tracking is optional
1247
- }
1248
-
1249
- // Create detached subprocess that survives parent exit
1250
- spawnBackground('npx', ['agileflow@latest', 'update', '--force'], { cwd: rootDir });
1251
-
1252
- console.log(`${c.dim} Auto-update starting in background...${c.reset}`);
1253
- }
1254
-
1255
- /**
1256
- * PERFORMANCE OPTIMIZATION: Fast expertise count (directory scan only)
1257
- * Just counts expert directories without reading/validating each expertise.yaml.
1258
- * Saves ~50-150ms by avoiding 29 file reads.
1259
- * Full validation is available via /agileflow:validate-expertise command.
1260
- */
1261
- function getExpertiseCountFast(rootDir) {
1262
- const result = { total: 0, passed: 0, warnings: 0, failed: 0, issues: [], validated: false };
1263
-
1264
- // Find experts directory
1265
- let expertsDir = path.join(getAgileflowDir(rootDir), 'experts');
1266
- if (!fs.existsSync(expertsDir)) {
1267
- expertsDir = path.join(rootDir, 'packages', 'cli', 'src', 'core', 'experts');
1268
- }
1269
- if (!fs.existsSync(expertsDir)) {
1270
- return result;
1271
- }
1272
-
1273
- try {
1274
- const domains = fs
1275
- .readdirSync(expertsDir, { withFileTypes: true })
1276
- .filter(d => d.isDirectory() && d.name !== 'templates');
1277
-
1278
- result.total = domains.length;
1279
-
1280
- // Quick check: just verify expertise.yaml exists in each directory
1281
- // Full validation (staleness, required fields) deferred to separate command
1282
- for (const domain of domains) {
1283
- const filePath = path.join(expertsDir, domain.name, 'expertise.yaml');
1284
- if (!fs.existsSync(filePath)) {
1285
- result.failed++;
1286
- result.issues.push(`${domain.name}: missing file`);
1287
- } else {
1288
- // Spot-check first few files for staleness (sample 3 max for speed)
1289
- if (result.passed < 3) {
1290
- try {
1291
- const content = fs.readFileSync(filePath, 'utf8');
1292
- const lastUpdatedMatch = content.match(/^last_updated:\s*['"]?(\d{4}-\d{2}-\d{2})/m);
1293
- if (lastUpdatedMatch) {
1294
- const lastDate = new Date(lastUpdatedMatch[1]);
1295
- const daysSince = Math.floor(
1296
- (Date.now() - lastDate.getTime()) / (1000 * 60 * 60 * 24)
1297
- );
1298
- if (daysSince > 30) {
1299
- result.warnings++;
1300
- result.issues.push(`${domain.name}: stale (${daysSince}d)`);
1301
- } else {
1302
- result.passed++;
1303
- }
1304
- } else {
1305
- result.passed++;
1306
- }
1307
- } catch (e) {
1308
- result.passed++;
1309
- }
1310
- } else {
1311
- // Assume rest are ok for fast display
1312
- result.passed++;
1313
- }
1314
- }
1315
- }
1316
- } catch (e) {
1317
- // Silently fail
1318
- }
1319
-
1320
- return result;
1321
- }
1322
-
1323
- /**
1324
- * Check if installed commands are in sync with source.
1325
- * Counts .md files in three directories:
1326
- * - .agileflow/commands/ (core install)
1327
- * - .claude/commands/agileflow/ excluding agents/ (IDE install)
1328
- * - packages/cli/src/core/commands/ (dogfooding source, if exists)
1329
- * Returns { sourceCount, coreCount, ideCount, stale, staleCoreInstall } or null on error.
1330
- */
1331
- function checkCommandSync(rootDir) {
1332
- try {
1333
- const countMdFiles = dir => {
1334
- if (!fs.existsSync(dir)) return 0;
1335
- return fs.readdirSync(dir, { recursive: true }).filter(f => String(f).endsWith('.md')).length;
1336
- };
1337
-
1338
- const agileflowDir = getAgileflowDir(rootDir);
1339
- const coreCount = countMdFiles(path.join(agileflowDir, 'commands'));
1340
-
1341
- // IDE install: .claude/commands/agileflow/ excluding agents/ subdir
1342
- const ideDir = path.join(rootDir, '.claude', 'commands', 'agileflow');
1343
- let ideCount = 0;
1344
- if (fs.existsSync(ideDir)) {
1345
- ideCount = fs.readdirSync(ideDir, { recursive: true }).filter(f => {
1346
- const s = String(f);
1347
- return s.endsWith('.md') && !s.startsWith('agents/') && !s.startsWith('agents\\');
1348
- }).length;
1349
- }
1350
-
1351
- // Dogfooding source (only exists in the AgileFlow repo itself)
1352
- const sourceDir = path.join(rootDir, 'packages', 'cli', 'src', 'core', 'commands');
1353
- const sourceCount = countMdFiles(sourceDir);
1354
-
1355
- // Determine staleness
1356
- const referenceCount = sourceCount > 0 ? sourceCount : coreCount;
1357
- const stale = referenceCount > 0 && ideCount < referenceCount;
1358
- const staleCoreInstall = sourceCount > 0 && coreCount < sourceCount;
1359
-
1360
- return { sourceCount, coreCount, ideCount, stale, staleCoreInstall };
1361
- } catch (e) {
1362
- return null;
1363
- }
1364
- }
1365
-
1366
- // Full validation function (kept for /agileflow:validate-expertise command)
1367
- function validateExpertise(rootDir) {
1368
- const result = { total: 0, passed: 0, warnings: 0, failed: 0, issues: [] };
1369
-
1370
- // Find experts directory
1371
- let expertsDir = path.join(getAgileflowDir(rootDir), 'experts');
1372
- if (!fs.existsSync(expertsDir)) {
1373
- expertsDir = path.join(rootDir, 'packages', 'cli', 'src', 'core', 'experts');
1374
- }
1375
- if (!fs.existsSync(expertsDir)) {
1376
- return result; // No experts directory found
1377
- }
1378
-
1379
- const STALE_DAYS = 30;
1380
- const MAX_LINES = 200;
1381
-
1382
- try {
1383
- const domains = fs
1384
- .readdirSync(expertsDir, { withFileTypes: true })
1385
- .filter(d => d.isDirectory() && d.name !== 'templates')
1386
- .map(d => d.name);
1387
-
1388
- for (const domain of domains) {
1389
- const filePath = path.join(expertsDir, domain, 'expertise.yaml');
1390
- if (!fs.existsSync(filePath)) {
1391
- result.total++;
1392
- result.failed++;
1393
- result.issues.push(`${domain}: missing file`);
1394
- continue;
1395
- }
1396
-
1397
- result.total++;
1398
- const content = fs.readFileSync(filePath, 'utf8');
1399
- const lines = content.split('\n');
1400
- let status = 'pass';
1401
- let issue = '';
1402
-
1403
- // Check required fields (use multiline flag)
1404
- const hasVersion = /^version:/m.test(content);
1405
- const hasDomain = /^domain:/m.test(content);
1406
- const hasLastUpdated = /^last_updated:/m.test(content);
1407
-
1408
- if (!hasVersion || !hasDomain || !hasLastUpdated) {
1409
- status = 'fail';
1410
- issue = 'missing required fields';
1411
- }
1412
-
1413
- // Check staleness
1414
- const lastUpdatedMatch = content.match(/^last_updated:\s*['"]?(\d{4}-\d{2}-\d{2})/m);
1415
- if (lastUpdatedMatch && status !== 'fail') {
1416
- const lastDate = new Date(lastUpdatedMatch[1]);
1417
- const daysSince = Math.floor((Date.now() - lastDate.getTime()) / (1000 * 60 * 60 * 24));
1418
- if (daysSince > STALE_DAYS) {
1419
- status = 'warn';
1420
- issue = `stale (${daysSince}d)`;
1421
- }
1422
- }
1423
-
1424
- // Check file size
1425
- if (lines.length > MAX_LINES && status === 'pass') {
1426
- status = 'warn';
1427
- issue = `large (${lines.length} lines)`;
1428
- }
1429
-
1430
- if (status === 'pass') {
1431
- result.passed++;
1432
- } else if (status === 'warn') {
1433
- result.warnings++;
1434
- result.issues.push(`${domain}: ${issue}`);
1435
- } else {
1436
- result.failed++;
1437
- result.issues.push(`${domain}: ${issue}`);
1438
- }
1439
- }
1440
- } catch (e) {
1441
- // Silently fail
1442
- }
1443
-
1444
- return result;
1445
- }
1446
-
1447
- function getFeatureVersions(rootDir) {
1448
- const result = {
1449
- hooks: { version: null, outdated: false },
1450
- archival: { version: null, outdated: false },
1451
- statusline: { version: null, outdated: false },
1452
- precompact: { version: null, outdated: false },
1453
- };
1454
-
1455
- // Minimum compatible versions for each feature
1456
- const minVersions = {
1457
- hooks: '2.35.0',
1458
- archival: '2.35.0',
1459
- statusline: '2.35.0',
1460
- precompact: '2.40.0', // Multi-command support
1461
- };
1462
-
1463
- try {
1464
- const metadataPath = getMetadataPath(rootDir);
1465
- if (fs.existsSync(metadataPath)) {
1466
- const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
1467
-
1468
- for (const feature of Object.keys(result)) {
1469
- if (metadata.features?.[feature]?.configured_version) {
1470
- result[feature].version = metadata.features[feature].configured_version;
1471
- result[feature].outdated =
1472
- compareVersions(result[feature].version, minVersions[feature]) < 0;
1473
- }
1474
- }
1475
- }
1476
- } catch (e) {
1477
- log.debug('getFeatureVersions:', e?.message || String(e));
1478
- }
1479
-
1480
- return result;
1481
- }
1482
-
1483
- function pad(str, len, align = 'left') {
1484
- const stripped = str.replace(/\x1b\[[0-9;]*m/g, '');
1485
- const diff = len - stripped.length;
1486
- if (diff <= 0) return str;
1487
- if (align === 'right') return ' '.repeat(diff) + str;
1488
- if (align === 'center')
1489
- return ' '.repeat(Math.floor(diff / 2)) + str + ' '.repeat(Math.ceil(diff / 2));
1490
- return str + ' '.repeat(diff);
1491
- }
1492
-
1493
- // Truncate string to max length, respecting ANSI codes
1494
- function truncate(str, maxLen, suffix = '..') {
1495
- const stripped = str.replace(/\x1b\[[0-9;]*m/g, '');
1496
- if (stripped.length <= maxLen) return str;
1497
-
1498
- // Find position in original string that corresponds to maxLen - suffix.length visible chars
1499
- const targetLen = maxLen - suffix.length;
1500
- let visibleCount = 0;
1501
- let cutIndex = 0;
1502
- let inEscape = false;
1503
-
1504
- for (let i = 0; i < str.length; i++) {
1505
- if (str[i] === '\x1b') {
1506
- inEscape = true;
1507
- } else if (inEscape && str[i] === 'm') {
1508
- inEscape = false;
1509
- } else if (!inEscape) {
1510
- visibleCount++;
1511
- if (visibleCount >= targetLen) {
1512
- cutIndex = i + 1;
1513
- break;
1514
- }
1515
- }
1516
- }
1517
-
1518
- return str.substring(0, cutIndex) + suffix;
1519
- }
1520
-
1521
- function formatTable(
1522
- info,
1523
- archival,
1524
- session,
1525
- precompact,
1526
- parallelSessions,
1527
- updateInfo = {},
1528
- expertise = {},
1529
- damageControl = {},
1530
- agentTeamsInfo = {},
1531
- scaleDetection = {}
1532
- ) {
1533
- const W = 58; // inner width (total table = W + 2 = 60)
1534
- const R = W - 25; // right column width (33 chars) to match total of 60
1535
- const lines = [];
1536
-
1537
- // Helper to create a row (auto-truncates right content to fit)
1538
- const row = (left, right, leftColor = '', rightColor = '') => {
1539
- const leftStr = `${leftColor}${left}${leftColor ? c.reset : ''}`;
1540
- const rightTrunc = truncate(right, R);
1541
- const rightStr = `${rightColor}${rightTrunc}${rightColor ? c.reset : ''}`;
1542
- return `${c.dim}${box.v}${c.reset} ${pad(leftStr, 20)} ${c.dim}${box.v}${c.reset} ${pad(rightStr, R)} ${c.dim}${box.v}${c.reset}`;
1543
- };
1544
-
1545
- // Helper for full-width row (spans both columns)
1546
- // Content width = W - 2 (for the two spaces after │ and before │)
1547
- const fullRow = (content, color = '') => {
1548
- const contentStr = `${color}${content}${color ? c.reset : ''}`;
1549
- return `${c.dim}${box.v}${c.reset} ${pad(contentStr, W - 2)} ${c.dim}${box.v}${c.reset}`;
1550
- };
1551
-
1552
- // Two-column dividers: ├ + 22 dashes + ┼ + 35 dashes + ┤ = 60 total
1553
- const divider = () =>
1554
- `${c.dim}${box.lT}${box.h.repeat(22)}${box.cross}${box.h.repeat(W - 23)}${box.rT}${c.reset}`;
1555
- // Full-width divider: ├ + 58 dashes + ┤ = 60 total
1556
- const fullDivider = () => `${c.dim}${box.lT}${box.h.repeat(W)}${box.rT}${c.reset}`;
1557
- // Transition: full-width TO two-column
1558
- const splitDivider = () =>
1559
- `${c.dim}${box.lT}${box.h.repeat(22)}${box.tT}${box.h.repeat(W - 23)}${box.rT}${c.reset}`;
1560
- // Transition: two-column TO full-width
1561
- const mergeDivider = () =>
1562
- `${c.dim}${box.lT}${box.h.repeat(22)}${box.bT}${box.h.repeat(W - 23)}${box.rT}${c.reset}`;
1563
- // Borders
1564
- const topBorder = `${c.dim}${box.tl}${box.h.repeat(W)}${box.tr}${c.reset}`;
1565
- const bottomBorder = `${c.dim}${box.bl}${box.h.repeat(22)}${box.bT}${box.h.repeat(W - 23)}${box.br}${c.reset}`;
1566
-
1567
- // Header with version and optional update indicator
1568
- // Use vibrant colors for branch
1569
- const branchColor =
1570
- info.branch === 'main' ? c.mintGreen : info.branch.startsWith('fix') ? c.coral : c.skyBlue;
1571
-
1572
- // Build version string with update status (vibrant colors)
1573
- let versionStr = `v${info.version}`;
1574
- if (updateInfo.justUpdated && updateInfo.previousVersion) {
1575
- versionStr = `v${info.version} ${c.mintGreen}✓${c.reset}${c.slate} (was v${updateInfo.previousVersion})`;
1576
- } else if (updateInfo.available && updateInfo.latest) {
1577
- versionStr = `v${info.version} ${c.amber}↑${updateInfo.latest}${c.reset}`;
1578
- }
1579
-
1580
- // Calculate remaining space for branch
1581
- const versionVisibleLen = updateInfo.justUpdated
1582
- ? info.version.length + 20 + (updateInfo.previousVersion?.length || 0)
1583
- : updateInfo.available
1584
- ? info.version.length + 3 + (updateInfo.latest?.length || 0)
1585
- : info.version.length;
1586
- const maxBranchLen = W - 1 - 15 - versionVisibleLen;
1587
- const branchDisplay =
1588
- info.branch.length > maxBranchLen
1589
- ? info.branch.substring(0, Math.max(5, maxBranchLen - 2)) + '..'
1590
- : info.branch;
1591
-
1592
- const header = `${c.brand}${c.bold}agileflow${c.reset} ${c.dim}${versionStr}${c.reset} ${branchColor}${branchDisplay}${c.reset} ${c.dim}(${info.commit})${c.reset}`;
1593
- const headerLine = `${c.dim}${box.v}${c.reset} ${pad(header, W - 2)} ${c.dim}${box.v}${c.reset}`;
1594
-
1595
- lines.push(topBorder);
1596
- lines.push(headerLine);
1597
-
1598
- // Show update available notification (using vibrant colors)
1599
- if (updateInfo.available && updateInfo.latest && !updateInfo.justUpdated) {
1600
- lines.push(fullDivider());
1601
- lines.push(
1602
- fullRow(
1603
- `${c.amber}↑${c.reset} Update available: ${c.softGold}v${updateInfo.latest}${c.reset}`,
1604
- ''
1605
- )
1606
- );
1607
- lines.push(fullRow(` Run: ${c.skyBlue}npx agileflow update${c.reset}`, ''));
1608
- }
1609
-
1610
- // Always show "What's new" section with current version changelog
1611
- // Get changelog entries for current version (even if not just updated)
1612
- const changelogEntries =
1613
- updateInfo.changelog && updateInfo.changelog.length > 0
1614
- ? updateInfo.changelog
1615
- : getChangelogEntries(info.version);
1616
-
1617
- if (changelogEntries && changelogEntries.length > 0) {
1618
- lines.push(fullDivider());
1619
- const headerText = updateInfo.justUpdated
1620
- ? `${c.mintGreen}✨${c.reset} Just updated to ${c.softGold}v${info.version}${c.reset}:`
1621
- : `${c.teal}📋${c.reset} What's new in ${c.softGold}v${info.version}${c.reset}:`;
1622
- lines.push(fullRow(headerText, ''));
1623
- for (const entry of changelogEntries.slice(0, 2)) {
1624
- lines.push(fullRow(` ${c.teal}•${c.reset} ${truncate(entry, W - 6)}`, ''));
1625
- }
1626
- lines.push(fullRow(` Run ${c.skyBlue}/agileflow:whats-new${c.reset} for full changelog`, ''));
1627
- }
1628
-
1629
- // Transition from full-width sections to two-column stories section
1630
- lines.push(splitDivider());
1631
-
1632
- // Stories section (always colorful labels like obtain-context)
1633
- lines.push(
1634
- row(
1635
- 'In Progress',
1636
- info.wipCount > 0 ? `${info.wipCount}` : '0',
1637
- c.peach,
1638
- info.wipCount > 0 ? c.peach : c.dim
1639
- )
1640
- );
1641
- lines.push(
1642
- row(
1643
- 'Blocked',
1644
- info.blockedCount > 0 ? `${info.blockedCount}` : '0',
1645
- c.coral,
1646
- info.blockedCount > 0 ? c.coral : c.dim
1647
- )
1648
- );
1649
- lines.push(
1650
- row(
1651
- 'Ready',
1652
- info.readyCount > 0 ? `${info.readyCount}` : '0',
1653
- c.skyBlue,
1654
- info.readyCount > 0 ? c.skyBlue : c.dim
1655
- )
1656
- );
1657
- const completedColor = `${c.bold}${c.mintGreen}`;
1658
- lines.push(
1659
- row(
1660
- 'Completed',
1661
- info.completedCount > 0 ? `${info.completedCount}` : '0',
1662
- completedColor,
1663
- info.completedCount > 0 ? completedColor : c.dim
1664
- )
1665
- );
1666
-
1667
- lines.push(divider());
1668
-
1669
- // System section (colorful labels like obtain-context)
1670
- if (archival.disabled) {
1671
- lines.push(row('Auto-archival', 'disabled', c.lavender, c.slate));
1672
- } else if (archival.skippedByScale) {
1673
- lines.push(row('Auto-archival', 'skipped (small project)', c.lavender, c.dim));
1674
- } else {
1675
- const archivalStatus =
1676
- archival.archived > 0 ? `archived ${archival.archived} stories` : `nothing to archive`;
1677
- lines.push(
1678
- row('Auto-archival', archivalStatus, c.lavender, archival.archived > 0 ? c.mintGreen : c.dim)
1679
- );
1680
- }
1681
-
1682
- // Session cleanup
1683
- let sessionStatus, sessionColor;
1684
- if (session.preserved) {
1685
- sessionStatus = `preserved ${session.commandNames.length} command(s)`;
1686
- sessionColor = c.mintGreen;
1687
- } else if (session.cleared > 0) {
1688
- sessionStatus = `cleared ${session.cleared} command(s)`;
1689
- sessionColor = c.mintGreen;
1690
- } else {
1691
- sessionStatus = `clean`;
1692
- sessionColor = c.dim;
1693
- }
1694
- lines.push(row('Session state', sessionStatus, c.lavender, sessionColor));
1695
-
1696
- // PreCompact status with version check
1697
- if (precompact.configured && precompact.scriptExists) {
1698
- if (precompact.outdated) {
1699
- const verStr = precompact.version ? ` (v${precompact.version})` : '';
1700
- lines.push(row('Context preserve', `outdated${verStr}`, c.peach, c.peach));
1701
- } else if (session.commandNames && session.commandNames.length > 0) {
1702
- // Show the preserved command names
1703
- const cmdDisplay = session.commandNames.map(n => `/agileflow:${n}`).join(', ');
1704
- lines.push(row('Context preserve', cmdDisplay, c.lavender, c.mintGreen));
1705
- } else {
1706
- lines.push(row('Context preserve', 'ready', c.lavender, c.dim));
1707
- }
1708
- } else if (precompact.configured) {
1709
- lines.push(row('Context preserve', 'script missing', c.peach, c.peach));
1710
- } else {
1711
- lines.push(row('Context preserve', 'not configured', c.slate, c.slate));
1712
- }
1713
-
1714
- // Parallel sessions status
1715
- if (parallelSessions && parallelSessions.available) {
1716
- if (parallelSessions.otherActive > 0) {
1717
- const sessionStr = `⚠️ ${parallelSessions.otherActive} other active`;
1718
- lines.push(row('Sessions', sessionStr, c.peach, c.peach));
1719
- } else {
1720
- const sessionStr = parallelSessions.currentId
1721
- ? `✓ Session ${parallelSessions.currentId} (only)`
1722
- : '✓ Only session';
1723
- lines.push(row('Sessions', sessionStr, c.lavender, c.mintGreen));
1724
- }
1725
- }
1726
-
1727
- // Agent expertise validation (always show with color)
1728
- if (expertise && expertise.total > 0) {
1729
- if (expertise.failed > 0) {
1730
- const expertStr = `❌ ${expertise.failed} failed, ${expertise.warnings} warnings`;
1731
- lines.push(row('Expertise', expertStr, c.coral, c.coral));
1732
- } else if (expertise.warnings > 0) {
1733
- const expertStr = `⚠️ ${expertise.warnings} warnings (${expertise.passed} ok)`;
1734
- lines.push(row('Expertise', expertStr, c.peach, c.peach));
1735
- } else {
1736
- lines.push(row('Expertise', `✓ ${expertise.total} valid`, c.lavender, c.mintGreen));
1737
- }
1738
- }
1739
-
1740
- // Damage control status (PreToolUse hooks for dangerous command protection)
1741
- if (damageControl && damageControl.configured) {
1742
- if (!damageControl.scriptsOk) {
1743
- lines.push(row('Damage control', '⚠️ scripts missing', c.coral, c.coral));
1744
- } else {
1745
- const levelStr = damageControl.level || 'standard';
1746
- const patternStr =
1747
- damageControl.patternCount > 0 ? `${damageControl.patternCount} patterns` : '';
1748
- const dcStatus = `🛡️ ${levelStr}${patternStr ? ` (${patternStr})` : ''}`;
1749
- lines.push(row('Damage control', dcStatus, c.lavender, c.mintGreen));
1750
- }
1751
- } else {
1752
- lines.push(row('Damage control', 'not configured', c.slate, c.slate));
1753
- }
1754
-
1755
- // Agent Teams status
1756
- if (agentTeamsInfo && agentTeamsInfo.status === 'enabled') {
1757
- lines.push(row('Agent Teams', `${agentTeamsInfo.value}`, c.lavender, c.mintGreen));
1758
- } else if (agentTeamsInfo && agentTeamsInfo.status === 'fallback') {
1759
- lines.push(row('Agent Teams', `${agentTeamsInfo.value}`, c.lavender, c.dim));
1760
- }
1761
-
1762
- // Scale detection (EP-0033)
1763
- if (scaleDetection && scaleDetection.scale) {
1764
- const scaleColors = {
1765
- micro: c.cyan,
1766
- small: c.teal,
1767
- medium: c.mintGreen,
1768
- large: c.peach,
1769
- enterprise: c.coral,
1770
- };
1771
- const scaleIcons = {
1772
- micro: '◦',
1773
- small: '○',
1774
- medium: '◎',
1775
- large: '●',
1776
- enterprise: '◉',
1777
- };
1778
- const scale = scaleDetection.scale;
1779
- const icon = scaleIcons[scale] || '◎';
1780
- const label = scale.charAt(0).toUpperCase() + scale.slice(1);
1781
- const cacheNote = scaleDetection.fromCache ? '' : ` (${scaleDetection.detection_ms}ms)`;
1782
- lines.push(
1783
- row('Scale', `${icon} ${label}${cacheNote}`, c.lavender, scaleColors[scale] || c.dim)
1784
- );
1785
- }
1786
-
1787
- lines.push(divider());
1788
-
1789
- // Current story (colorful like obtain-context)
1790
- if (info.currentStory) {
1791
- lines.push(
1792
- row(
1793
- 'Current',
1794
- `${c.lightYellow}${info.currentStory.id}${c.reset}: ${info.currentStory.title}`,
1795
- c.skyBlue,
1796
- ''
1797
- )
1798
- );
1799
- } else {
1800
- lines.push(row('Current', 'No active story', c.skyBlue, c.dim));
1801
- }
1802
-
1803
- // Last commit (colorful like obtain-context)
1804
- lines.push(
1805
- row('Last commit', `${c.peach}${info.commit}${c.reset} ${info.lastCommit}`, c.lavender, '')
1806
- );
1807
-
1808
- lines.push(bottomBorder);
1809
-
1810
- return lines.join('\n');
1811
- }
1812
-
1813
- // Format session banner for non-main sessions
1814
- function formatSessionBanner(parallelSessions) {
1815
- if (!parallelSessions.available || parallelSessions.isMain) {
1816
- return null;
1817
- }
1818
-
1819
- const W = 62; // banner width
1820
- const lines = [];
1821
-
1822
- // Get display name
1823
- const sessionName = parallelSessions.nickname
1824
- ? `SESSION ${parallelSessions.currentId} "${parallelSessions.nickname}"`
1825
- : `SESSION ${parallelSessions.currentId}`;
1826
-
1827
- lines.push(`${c.dim}${box.tl}${box.h.repeat(W)}${box.tr}${c.reset}`);
1828
- lines.push(
1829
- `${c.dim}${box.v}${c.reset} ${c.teal}${c.bold}${pad(sessionName, W - 2)}${c.reset} ${c.dim}${box.v}${c.reset}`
1830
- );
1831
- lines.push(
1832
- `${c.dim}${box.v}${c.reset} ${c.slate}Branch:${c.reset} ${pad(parallelSessions.branch || 'unknown', W - 13)} ${c.dim}${box.v}${c.reset}`
1833
- );
1834
-
1835
- // Show relative path to main
1836
- if (parallelSessions.sessionPath) {
1837
- const relPath = path.relative(parallelSessions.sessionPath, parallelSessions.mainPath) || '.';
1838
- lines.push(
1839
- `${c.dim}${box.v}${c.reset} ${c.slate}Main at:${c.reset} ${pad(relPath, W - 14)} ${c.dim}${box.v}${c.reset}`
1840
- );
1841
- }
1842
-
1843
- lines.push(`${c.dim}${box.bl}${box.h.repeat(W)}${box.br}${c.reset}`);
1844
-
1845
- return lines.join('\n');
1846
- }
1847
-
1848
- // Main (synchronous - async work deferred to welcome-deferred.js)
1849
- function main() {
1850
- _mark('start');
1851
-
1852
- // Start hook timer for metrics
1853
- const timer = hookMetrics ? hookMetrics.startHookTimer('SessionStart', 'welcome') : null;
1854
-
1855
- const rootDir = getProjectRoot();
1856
-
1857
- // PERFORMANCE: Load all project files once into cache
1858
- // This eliminates 6-8 duplicate file reads across functions
1859
- const cache = loadProjectFiles(rootDir);
1860
- _mark('loadFiles');
1861
-
1862
- // ============================================
1863
- // PHASE 1: INSTANT WELCOME (< 300ms)
1864
- // All fast operations - no network, no auto-update
1865
- // ============================================
1866
- const info = getProjectInfo(rootDir, cache);
1867
- _mark('getInfo');
1868
-
1869
- // PERFORMANCE OPTIMIZATION (US-0356): Read scale from session-state cache
1870
- // Avoids requiring scale-detector module + git subprocess when cache is fresh (< 5 min)
1871
- let earlyScale = null;
1872
- const cachedScale = cache?.sessionState?.scale_detection;
1873
- const scaleFresh =
1874
- cachedScale &&
1875
- cachedScale.detected_at &&
1876
- Date.now() - new Date(cachedScale.detected_at).getTime() < 300000; // 5 min
1877
- if (scaleFresh) {
1878
- earlyScale = { ...cachedScale, fromCache: true };
1879
- } else {
1880
- try {
1881
- const scaleDetector = require('./lib/scale-detector');
1882
- earlyScale = scaleDetector.detectScale({
1883
- rootDir,
1884
- statusJson: cache?.status,
1885
- sessionState: cache?.sessionState,
1886
- });
1887
- } catch (e) {
1888
- // Scale detection not available
1889
- }
1890
- }
1891
-
1892
- const scaleRecommendations = earlyScale
1893
- ? (() => {
1894
- try {
1895
- return require('./lib/scale-detector').getScaleRecommendations(earlyScale.scale);
1896
- } catch {
1897
- return null;
1898
- }
1899
- })()
1900
- : null;
1901
- _mark('scale');
1902
-
1903
- const archival =
1904
- scaleRecommendations && scaleRecommendations.skipArchival
1905
- ? { ran: false, threshold: 0, archived: 0, remaining: 0, skippedByScale: true }
1906
- : runArchival(rootDir, cache);
1907
- _mark('archival');
1908
-
1909
- const session = clearActiveCommands(rootDir, cache);
1910
- _mark('clearCmds');
1911
-
1912
- const precompact = checkPreCompact(rootDir, cache);
1913
- _mark('precompact');
1914
-
1915
- // PERFORMANCE OPTIMIZATION (US-0356): Use lightweight session check
1916
- // Reads registry.json + lock files directly (~30 lines) instead of
1917
- // requiring the full session-manager module chain (~3,600 lines across 8 modules).
1918
- // Full session registration deferred to Phase 3 (welcome-deferred.js).
1919
- const parallelSessions = checkParallelSessionsFast(rootDir);
1920
- _mark('sessions');
1921
-
1922
- // PERFORMANCE OPTIMIZATION (US-0356): Defer expertise count to Phase 3
1923
- // Directory scan with file reads is non-critical for the table.
1924
- // Use cached result from session-state if available, otherwise show placeholder.
1925
- let expertise;
1926
- const cachedExpertise = cache?.sessionState?.expertise_count;
1927
- const validExpertiseCache =
1928
- cachedExpertise &&
1929
- cachedExpertise.total > 0 &&
1930
- typeof cachedExpertise.passed === 'number' &&
1931
- typeof cachedExpertise.warnings === 'number' &&
1932
- typeof cachedExpertise.failed === 'number';
1933
- if (validExpertiseCache) {
1934
- expertise = cachedExpertise;
1935
- } else {
1936
- expertise = getExpertiseCountFast(rootDir);
1937
- }
1938
- _mark('expertise');
1939
-
1940
- const commandSync = checkCommandSync(rootDir);
1941
- _mark('cmdSync');
1942
-
1943
- const damageControl = checkDamageControl(rootDir, cache);
1944
- _mark('damageCtl');
1945
-
1946
- // Use early scale detection result (already computed for hook scheduling)
1947
- const scaleDetection = earlyScale || { scale: 'medium' };
1948
-
1949
- // PERFORMANCE OPTIMIZATION (US-0356): Read Agent Teams mode from metadata cache
1950
- // Avoids requiring feature-flags module when metadata is already loaded.
1951
- // Uses same { label, value, status } format as getAgentTeamsDisplayInfo().
1952
- let agentTeamsInfo = {};
1953
- const envTeams = process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS;
1954
- const envTeamsEnabled = envTeams === '1' || envTeams === 'true' || envTeams === 'yes';
1955
- const metaTeamsEnabled = cache?.metadata?.features?.agentTeams?.enabled === true;
1956
- if (envTeamsEnabled || metaTeamsEnabled) {
1957
- agentTeamsInfo = { label: 'Agent Teams', value: 'ENABLED (native)', status: 'enabled' };
1958
- } else {
1959
- agentTeamsInfo = { label: 'Agent Teams', value: 'subagent mode', status: 'fallback' };
1960
- }
1961
- _mark('agentTeams');
1962
-
1963
- // Check if a previous background update completed successfully
1964
- // This allows us to show "just updated" even for background updates
1965
- let updateInfo = {};
1966
- try {
1967
- // Use already-loaded session state from cache instead of re-reading
1968
- const state = cache?.sessionState;
1969
- if (state?.pending_update) {
1970
- const pendingUpdate = state.pending_update;
1971
- const startedAt = new Date(pendingUpdate.started_at);
1972
- const minutesAgo = (Date.now() - startedAt.getTime()) / (1000 * 60);
1973
-
1974
- if (info.version === pendingUpdate.to) {
1975
- updateInfo.justUpdated = true;
1976
- updateInfo.previousVersion = pendingUpdate.from;
1977
- updateInfo.changelog = getChangelogEntries(info.version);
1978
- // Clear pending update
1979
- const sessionStatePath = getSessionStatePath(rootDir);
1980
- delete state.pending_update;
1981
- fs.writeFileSync(sessionStatePath, JSON.stringify(state, null, 2) + '\n');
1982
- } else if (minutesAgo > 5) {
1983
- const sessionStatePath = getSessionStatePath(rootDir);
1984
- delete state.pending_update;
1985
- fs.writeFileSync(sessionStatePath, JSON.stringify(state, null, 2) + '\n');
1986
- }
1987
- }
1988
- } catch (e) {
1989
- // Silently continue - pending update check is non-critical
1990
- }
1991
- _mark('updateInfo');
1992
-
1993
- // PERFORMANCE OPTIMIZATION (US-0356): Defer config staleness to Phase 3
1994
- // Only produces a notification; not needed for the main table.
1995
- // Read cached result from session-state if available.
1996
- let configStaleness = { outdated: false, autoApply: false };
1997
- let configAutoApplied = 0;
1998
- const cachedConfigStaleness = cache?.sessionState?.config_staleness;
1999
- const configCacheAge = cachedConfigStaleness?.cached_at
2000
- ? Date.now() - new Date(cachedConfigStaleness.cached_at).getTime()
2001
- : Infinity;
2002
- const configCacheFresh = configCacheAge < 300000; // 5 min TTL
2003
- if (cachedConfigStaleness && configCacheFresh) {
2004
- configStaleness = cachedConfigStaleness;
2005
- } else {
2006
- try {
2007
- configStaleness = checkConfigStaleness(rootDir, info.version, cache);
2008
-
2009
- // Auto-apply new options if profile is "full" (only auto-applyable ones)
2010
- if (configStaleness.autoApply && configStaleness.autoApplyOptions?.length > 0) {
2011
- configAutoApplied = autoApplyConfigOptions(rootDir, configStaleness.autoApplyOptions);
2012
- if (configAutoApplied > 0) {
2013
- configStaleness.newOptions = configStaleness.newOptions.filter(o => !o.autoApplyable);
2014
- configStaleness.newOptionsCount = configStaleness.newOptions.length;
2015
- if (configStaleness.newOptionsCount === 0) {
2016
- configStaleness.outdated = false;
2017
- }
2018
- }
2019
- }
2020
- } catch (e) {
2021
- // Config check failed - continue without it
2022
- }
2023
- }
2024
- _mark('configStale');
2025
-
2026
- // Check tmux availability (only if tmuxAutoSpawn is enabled)
2027
- let tmuxCheck = { available: true };
2028
- const tmuxAutoSpawnEnabled = cache?.metadata?.features?.tmuxAutoSpawn?.enabled !== false;
2029
- if (tmuxAutoSpawnEnabled) {
2030
- tmuxCheck = checkTmuxAvailability(cache);
2031
- }
2032
- _mark('tmux');
2033
-
2034
- // Show session banner FIRST if in a non-main session
2035
- const sessionBanner = formatSessionBanner(parallelSessions);
2036
- if (sessionBanner) {
2037
- console.log(sessionBanner);
2038
- }
2039
-
2040
- console.log(
2041
- formatTable(
2042
- info,
2043
- archival,
2044
- session,
2045
- precompact,
2046
- parallelSessions,
2047
- updateInfo,
2048
- expertise,
2049
- damageControl,
2050
- agentTeamsInfo,
2051
- scaleDetection
2052
- )
2053
- );
2054
-
2055
- // ============================================
2056
- // PHASE 2: FAST POST-TABLE NOTIFICATIONS + DEFERRED BACKGROUND WORK
2057
- // Only instant operations here. Expensive work deferred to welcome-deferred.js
2058
- // ============================================
2059
-
2060
- // Display deferred warnings from previous session's background work
2061
- displayDeferredWarnings(rootDir);
2062
-
2063
- // Check update cache (1-hour TTL) - instant if cached, skipped if stale
2064
- let skipUpdateInDeferred = false;
2065
- try {
2066
- const cachedUpdate = getUpdateFromCache(cache);
2067
- if (cachedUpdate) {
2068
- skipUpdateInDeferred = true;
2069
- // Use cached result for notification
2070
- if (cachedUpdate.available && cachedUpdate.latest && !updateInfo.justUpdated) {
2071
- console.log('');
2072
- console.log(
2073
- `${c.amber}↑ Update available:${c.reset} v${info.version} → ${c.softGold}v${cachedUpdate.latest}${c.reset}`
2074
- );
2075
- console.log(` Run: ${c.skyBlue}npx agileflow update${c.reset}`);
2076
- }
2077
- }
2078
- // If no cache or stale, the deferred script will check and cache the result
2079
- } catch (e) {
2080
- // Cache check failed, deferred script will handle it
2081
- }
2082
-
2083
- // Show config auto-apply confirmation (for "full" profile)
2084
- if (configAutoApplied > 0) {
2085
- console.log('');
2086
- console.log(
2087
- `${c.mintGreen}✨ Auto-applied ${configAutoApplied} new config option(s)${c.reset}`
2088
- );
2089
- console.log(` ${c.slate}Profile "full" enables all new features automatically.${c.reset}`);
2090
- }
2091
-
2092
- // Show config staleness notification (for custom profiles)
2093
- if (configStaleness.outdated && configStaleness.newOptionsCount > 0) {
2094
- console.log('');
2095
- console.log(
2096
- `${c.amber}⚙️ ${configStaleness.newOptionsCount} new configuration option(s) available${c.reset}`
2097
- );
2098
- for (const opt of configStaleness.newOptions.slice(0, 3)) {
2099
- console.log(` ${c.dim}• ${opt.description}${c.reset}`);
2100
- }
2101
- console.log(
2102
- ` ${c.slate}Run ${c.skyBlue}/agileflow:configure${c.reset}${c.slate} to enable them.${c.reset}`
2103
- );
2104
- }
2105
-
2106
- // Show command sync staleness notification
2107
- if (commandSync && commandSync.stale) {
2108
- const ref = commandSync.sourceCount > 0 ? commandSync.sourceCount : commandSync.coreCount;
2109
- console.log('');
2110
- console.log(
2111
- `${c.amber}⚠️ ${ref - commandSync.ideCount} command(s) out of sync${c.reset} ${c.dim}(IDE has ${commandSync.ideCount}/${ref})${c.reset}`
2112
- );
2113
- if (commandSync.staleCoreInstall) {
2114
- console.log(
2115
- ` ${c.dim}Core install also stale: ${commandSync.coreCount}/${commandSync.sourceCount}${c.reset}`
2116
- );
2117
- }
2118
- console.log(` ${c.slate}Auto-syncing in background...${c.reset}`);
2119
- }
2120
-
2121
- // Show tmux installation notice if tmux auto-spawn is enabled but tmux not installed
2122
- if (tmuxAutoSpawnEnabled && !tmuxCheck.available) {
2123
- console.log('');
2124
- console.log(
2125
- `${c.amber}📦 tmux not installed${c.reset} ${c.dim}(enables parallel sessions in one terminal)${c.reset}`
2126
- );
2127
-
2128
- // Show platform-specific install command
2129
- if (tmuxCheck.platform?.installCmd) {
2130
- console.log(` ${c.slate}Install for ${tmuxCheck.platform.os}:${c.reset}`);
2131
- console.log(` ${c.cyan}${tmuxCheck.platform.installCmd}${c.reset}`);
2132
- console.log('');
2133
- console.log(` ${c.dim}No sudo? Use: ${c.cyan}${tmuxCheck.noSudoCmd}${c.reset}`);
2134
- } else {
2135
- // Unknown platform - show all options
2136
- console.log(` ${c.slate}Install with one of:${c.reset}`);
2137
- console.log(` ${c.dim}• macOS:${c.reset} ${c.cyan}brew install tmux${c.reset}`);
2138
- console.log(` ${c.dim}• Ubuntu:${c.reset} ${c.cyan}sudo apt install tmux${c.reset}`);
2139
- console.log(` ${c.dim}• No sudo:${c.reset} ${c.cyan}${tmuxCheck.noSudoCmd}${c.reset}`);
2140
- }
2141
- console.log(
2142
- ` ${c.dim}Or disable this notice: ${c.skyBlue}/agileflow:configure --disable=tmuxautospawn${c.reset}`
2143
- );
2144
- }
2145
-
2146
- // Show warning and tip if other sessions are active (vibrant colors)
2147
- if (parallelSessions.otherActive > 0) {
2148
- console.log('');
2149
- console.log(`${c.amber}⚠️ Other Claude session(s) active in this repo.${c.reset}`);
2150
- console.log(
2151
- `${c.slate} Run ${c.skyBlue}/agileflow:session:status${c.reset}${c.slate} to see all sessions.${c.reset}`
2152
- );
2153
- console.log(
2154
- `${c.slate} Run ${c.skyBlue}/agileflow:session:new${c.reset}${c.slate} to create isolated workspace.${c.reset}`
2155
- );
2156
- }
2157
-
2158
- // Show detailed message if sessions were cleaned (VISIBLE - not hidden!)
2159
- if (parallelSessions.cleaned > 0 && parallelSessions.cleanedSessions) {
2160
- console.log('');
2161
- console.log(`${c.amber}📋 Cleaned ${parallelSessions.cleaned} inactive session(s):${c.reset}`);
2162
- parallelSessions.cleanedSessions.forEach(sess => {
2163
- const name = sess.nickname ? `${sess.id} "${sess.nickname}"` : `Session ${sess.id}`;
2164
- const reason = sess.reason === 'pid_dead' ? 'process ended' : sess.reason;
2165
- console.log(` ${c.dim}└─ ${name} (${reason}, PID ${sess.pid})${c.reset}`);
2166
- });
2167
- console.log(
2168
- ` ${c.slate}Sessions are cleaned when their Claude Code process is no longer running.${c.reset}`
2169
- );
2170
- }
2171
-
2172
- _mark('postTable');
2173
-
2174
- // ============================================
2175
- // PHASE 3: SPAWN DEFERRED BACKGROUND WORK
2176
- // Session health, process cleanup, story claiming, file tracking,
2177
- // epic completion, ideation sync, automations, update check (if stale)
2178
- // Also: full session registration, expertise re-scan, config staleness check
2179
- // Results saved to session-state.json for next session display.
2180
- // ============================================
2181
- try {
2182
- const deferredScript = path.join(__dirname, 'welcome-deferred.js');
2183
- if (fs.existsSync(deferredScript)) {
2184
- const deferredArgs = [deferredScript, rootDir, `--version=${info.version}`];
2185
- if (skipUpdateInDeferred) {
2186
- deferredArgs.push('--skip-update');
2187
- }
2188
- if (updateInfo.justUpdated) {
2189
- deferredArgs.push('--just-updated');
2190
- }
2191
- // US-0356: Signal deferred to run full session registration and expertise scan
2192
- deferredArgs.push('--run-session-register');
2193
- deferredArgs.push('--run-expertise-scan');
2194
- if (!cachedConfigStaleness || !configCacheFresh) {
2195
- deferredArgs.push('--run-config-staleness');
2196
- }
2197
- spawnBackground('node', deferredArgs, { cwd: rootDir });
2198
- }
2199
- } catch (e) {
2200
- // Deferred script spawn failed, non-critical
2201
- }
2202
-
2203
- _mark('deferred');
2204
-
2205
- // Spawn background command sync if stale
2206
- if (commandSync && commandSync.stale) {
2207
- try {
2208
- const isDogfooding = commandSync.sourceCount > 0;
2209
- if (isDogfooding) {
2210
- const cliPath = path.join(rootDir, 'packages', 'cli', 'tools', 'cli', 'agileflow-cli.js');
2211
- if (fs.existsSync(cliPath)) {
2212
- spawnBackground('node', [cliPath, 'update', '--force', '-d', rootDir], { cwd: rootDir });
2213
- }
2214
- } else {
2215
- spawnBackground('npx', ['agileflow', 'update', '--force'], { cwd: rootDir });
2216
- }
2217
- } catch (e) {
2218
- // Command sync spawn failed, non-critical
2219
- }
2220
- }
2221
- _mark('cmdSyncSpawn');
2222
-
2223
- // Record hook metrics
2224
- if (timer && hookMetrics) {
2225
- hookMetrics.recordHookMetrics(timer, 'success', null, { rootDir });
2226
- }
2227
-
2228
- // Output profiling data if enabled
2229
- _logTimings();
2230
- }
2231
-
2232
- try {
2233
- main();
2234
- } catch (err) {
2235
- log.error(err.message || String(err));
2236
- // Record error in metrics if possible
2237
- if (hookMetrics) {
2238
- try {
2239
- const rootDir = getProjectRoot();
2240
- const timer = hookMetrics.startHookTimer('SessionStart', 'welcome');
2241
- hookMetrics.recordHookMetrics(timer, 'error', err.message, { rootDir });
2242
- } catch (e) {
2243
- // Silently ignore metrics errors
2244
- }
2245
- }
2246
- }