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
@@ -0,0 +1,1385 @@
1
+ /**
2
+ * `agileflow launch`.
3
+ *
4
+ * Two surfaces:
5
+ * - `agileflow launch setup` — always runs the prefs wizard.
6
+ * - `agileflow launch` — runs setup on first invocation
7
+ * (no prefs file); otherwise loads
8
+ * prefs, resolves the user's preferred
9
+ * AI CLI, and either wraps it in a
10
+ * per-cwd tmux session (if tmux is
11
+ * installed and enabled in prefs) or
12
+ * plain-spawns it as a foreground
13
+ * child.
14
+ *
15
+ * Errors here go through the typed-error / `fail()` plumbing in
16
+ * `src/lib/errors.js` so messages stay consistent with `setup` /
17
+ * `doctor` / etc.
18
+ */
19
+ const fs = require("fs");
20
+ const path = require("path");
21
+ const prompts = require("@clack/prompts");
22
+ const pkg = require("../../../package.json");
23
+ const { logoBanner, questionMessage } = require("../../lib/brand.js");
24
+ const {
25
+ loadPrefs,
26
+ writePrefs,
27
+ prefsExist,
28
+ } = require("../../runtime/launch/prefs.js");
29
+ const { pickCli } = require("../wizard/launch-cli-picker.js");
30
+ const { pickTmux } = require("../wizard/launch-tmux-picker.js");
31
+ const { pickAliases } = require("../wizard/launch-alias-picker.js");
32
+ const { resolveCli } = require("../../runtime/launch/resolve-cli.js");
33
+ const { runCli } = require("../../runtime/launch/spawn.js");
34
+ const {
35
+ isInsideTmux,
36
+ tmuxAvailable,
37
+ launchInTmux,
38
+ listSessionsForCli,
39
+ killSession,
40
+ defaultRunner: defaultTmuxRunner,
41
+ } = require("../../runtime/launch/tmux.js");
42
+ const {
43
+ runParallelSpawn,
44
+ } = require("../../runtime/launch/parallel-session.js");
45
+ const { runExec } = require("../../runtime/launch/exec-wrapper.js");
46
+ const { runRestore } = require("../../runtime/launch/restore.js");
47
+ const {
48
+ loadRegistry,
49
+ pinSession,
50
+ } = require("../../runtime/launch/session-registry.js");
51
+ const {
52
+ listSessions,
53
+ killBySessionName,
54
+ attachByName,
55
+ pruneCandidates,
56
+ applyPrune,
57
+ } = require("../../runtime/launch/session-lifecycle.js");
58
+ const {
59
+ runDoctorChecks,
60
+ anyFailed,
61
+ } = require("../../runtime/launch/doctor.js");
62
+ const {
63
+ installAfAlias,
64
+ uninstallAfAlias,
65
+ resolveAgileflowBin,
66
+ } = require("../../runtime/launch/alias-installer.js");
67
+ const { loadCascadedPrefs } = require("../../runtime/launch/project-prefs.js");
68
+ const closedWindows = require("../../runtime/launch/closed-windows.js");
69
+ const {
70
+ AgileflowError,
71
+ OperationFailedError,
72
+ fail,
73
+ } = require("../../lib/errors.js");
74
+
75
+ /**
76
+ * Pure helper for unit testing: decide which flow to enter given the
77
+ * subcommand name and whether a prefs file exists.
78
+ *
79
+ * @param {{ sub?: string, hasPrefs: boolean }} input
80
+ * @returns {'setup' | 'engine' | 'first-run-setup'}
81
+ */
82
+ function decideFlow({ sub, hasPrefs }) {
83
+ if (sub === "setup") return "setup";
84
+ if (!hasPrefs) return "first-run-setup";
85
+ return "engine";
86
+ }
87
+
88
+ /**
89
+ * Load prefs, or `fail()` with the actionable hint that matches the
90
+ * inner-wizard error path. Without this, the bare-launch / first-run-tail
91
+ * call sites fall through to the catch-all `OperationFailedError` wrapper
92
+ * and the user gets a generic "re-run with DEBUG=1" message for what is
93
+ * really a "fix or delete the prefs file" situation.
94
+ *
95
+ * @returns {Promise<Awaited<ReturnType<typeof loadPrefs>>>}
96
+ */
97
+ async function loadPrefsOrFail() {
98
+ try {
99
+ // Cascade: defaults ← global ~/.agileflow ← project .agileflow.
100
+ // Returns the same shape as loadPrefs() (prefs + source path) plus
101
+ // a `sources` audit trail consumed by `agileflow launch where`.
102
+ const cascaded = await loadCascadedPrefs();
103
+ // Preserve the loadPrefs() shape so existing callers that destructure
104
+ // { prefs } keep working. The extra `sources` field is silently
105
+ // ignored by destructures that don't ask for it.
106
+ return {
107
+ prefs: cascaded.prefs,
108
+ // `source` here reflects the HIGHEST-precedence layer that
109
+ // contributed, since downstream messages like "fix or delete the
110
+ // prefs file" need a single concrete path to point at. If the
111
+ // project file is present, that's the most-recently-edited file.
112
+ source: cascaded.sources.some((s) => s.layer === "project")
113
+ ? "file"
114
+ : cascaded.sources.some((s) => s.layer === "global")
115
+ ? "file"
116
+ : "defaults",
117
+ path:
118
+ (cascaded.sources.find((s) => s.layer === "project") || {}).path ||
119
+ (cascaded.sources.find((s) => s.layer === "global") || {}).path ||
120
+ "",
121
+ sources: cascaded.sources,
122
+ };
123
+ } catch (err) {
124
+ fail(
125
+ new OperationFailedError(err.message, {
126
+ suggestion:
127
+ "fix or delete the prefs file and re-run `agileflow launch setup`",
128
+ cause: err,
129
+ }),
130
+ { command: "launch" },
131
+ );
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Pure helper: decide whether to offer orphan cleanup, given the prior
137
+ * preferred CLI, the new one, and whether tmux is available. Extracted
138
+ * so unit tests can cover the decision matrix without spinning up tmux.
139
+ *
140
+ * @param {{
141
+ * oldPreferred: string | undefined,
142
+ * newPreferred: string,
143
+ * tmuxAvailable: boolean,
144
+ * existingSource: 'file' | 'defaults',
145
+ * }} input
146
+ * @returns {boolean}
147
+ */
148
+ function shouldOfferOrphanCleanup({
149
+ oldPreferred,
150
+ newPreferred,
151
+ tmuxAvailable: tmuxOk,
152
+ existingSource,
153
+ }) {
154
+ if (existingSource !== "file") return false; // first-time setup has no orphans
155
+ if (!tmuxOk) return false;
156
+ if (!oldPreferred || oldPreferred === newPreferred) return false;
157
+ return true;
158
+ }
159
+
160
+ /**
161
+ * Run the interactive setup wizard. Used by both explicit `launch setup`
162
+ * and first-run from bare `launch`.
163
+ *
164
+ * Returns the prefs object that was just persisted so the first-run path
165
+ * can hand it straight to runEngine without re-reading from disk — which
166
+ * avoids surfacing a misleading "fix or delete the prefs file" hint in
167
+ * the rare case where the file becomes unreadable immediately after a
168
+ * successful write.
169
+ *
170
+ * @returns {Promise<import('../../runtime/launch/defaults.js').LaunchPrefs>}
171
+ */
172
+ async function runSetup() {
173
+ // eslint-disable-next-line no-console
174
+ console.log("\n" + logoBanner(pkg.version) + "\n");
175
+ prompts.intro("agileflow launch — setup");
176
+
177
+ /** @type {Awaited<ReturnType<typeof loadPrefs>>} */
178
+ let existing;
179
+ try {
180
+ existing = await loadPrefs();
181
+ } catch (err) {
182
+ prompts.log.error(err.message);
183
+ prompts.cancel("Fix or delete the prefs file and re-run.");
184
+ process.exit(1);
185
+ }
186
+
187
+ if (existing.source === "file") {
188
+ prompts.log.info(
189
+ `Existing prefs at ${existing.path} — re-running wizard to update.`,
190
+ );
191
+ } else {
192
+ prompts.log.info("No prefs found — starting from defaults.");
193
+ }
194
+
195
+ const base = existing.prefs;
196
+
197
+ const cli = await pickCli(base);
198
+ const tmuxAndKeybinds = await pickTmux(base);
199
+ const aliases = await pickAliases(base);
200
+
201
+ const next = {
202
+ version: /** @type {1} */ (1),
203
+ cli,
204
+ tmux: tmuxAndKeybinds.tmux,
205
+ keybinds: tmuxAndKeybinds.keybinds,
206
+ aliases,
207
+ pinned: base.pinned,
208
+ };
209
+
210
+ // Orphan cleanup: when the user switches their preferred CLI, the old
211
+ // `<old-cli>-<dir>` sessions stop being reachable through `launch` but
212
+ // keep occupying the tmux server. Offer to kill them while we have the
213
+ // user's attention — declining is fine, they can clean up manually later.
214
+ if (
215
+ shouldOfferOrphanCleanup({
216
+ oldPreferred: base.cli.preferred,
217
+ newPreferred: cli.preferred,
218
+ tmuxAvailable: tmuxAvailable(),
219
+ existingSource: existing.source,
220
+ })
221
+ ) {
222
+ const runner = defaultTmuxRunner();
223
+ const orphans = listSessionsForCli(base.cli.preferred, runner);
224
+ if (orphans.length > 0) {
225
+ const choice = await prompts.confirm({
226
+ message: questionMessage(
227
+ `Kill ${orphans.length} stale tmux session(s) from your previous CLI (${base.cli.preferred})?`,
228
+ orphans.join(", "),
229
+ ),
230
+ initialValue: true,
231
+ });
232
+ if (prompts.isCancel(choice)) {
233
+ prompts.cancel("Setup cancelled. No changes made.");
234
+ process.exit(1);
235
+ }
236
+ if (choice) {
237
+ let killed = 0;
238
+ let failed = 0;
239
+ for (const name of orphans) {
240
+ if (killSession(name, runner)) killed++;
241
+ else failed++;
242
+ }
243
+ if (killed > 0) {
244
+ prompts.log.info(`Killed ${killed} orphaned session(s).`);
245
+ }
246
+ if (failed > 0) {
247
+ prompts.log.warn(
248
+ `${failed} session(s) could not be killed — check \`tmux ls\`.`,
249
+ );
250
+ }
251
+ }
252
+ }
253
+ }
254
+
255
+ // Apply the alias side-effect BEFORE writing prefs. Writing first
256
+ // risks recording `aliases.af.enabled = true` to disk when the symlink
257
+ // failed to materialize — on next invocation we'd then lie about the
258
+ // alias being installed. Run the install/uninstall, reconcile the
259
+ // `next` object against what actually happened, then persist.
260
+ /** @type {string[]} */
261
+ const aliasSummary = [];
262
+
263
+ if (aliases.af.enabled) {
264
+ const aliasSpinner = prompts.spinner();
265
+ aliasSpinner.start("Installing `af` alias");
266
+ const result = await installAfAlias();
267
+ if (result.status === "installed" || result.status === "updated") {
268
+ aliasSpinner.stop(
269
+ `Alias ${result.status} → ${result.path} → ${result.target}`,
270
+ );
271
+ if (!result.onPath) {
272
+ prompts.log.warn(
273
+ `${path.dirname(result.path)} is not on your PATH. Add this to your shell rc:\n ` +
274
+ `export PATH="$HOME/.local/bin:$PATH"`,
275
+ );
276
+ }
277
+ aliasSummary.push(`af alias: ${result.status} (${result.path})`);
278
+ } else if (result.status === "unchanged") {
279
+ aliasSpinner.stop("Alias already in place");
280
+ aliasSummary.push(`af alias: unchanged (${result.path})`);
281
+ } else if (result.status === "unsupported") {
282
+ aliasSpinner.stop("Alias not auto-installable on this platform");
283
+ prompts.log.warn(result.message || "Unsupported platform");
284
+ aliasSummary.push("af alias: skipped (platform)");
285
+ // Reconcile: no symlink exists, so persist that truth.
286
+ next.aliases.af.enabled = false;
287
+ } else {
288
+ aliasSpinner.stop("Alias install failed");
289
+ prompts.log.warn(
290
+ `${result.message || "unknown failure"}\n ` +
291
+ "Re-run `agileflow launch setup` to retry, or create the symlink manually.",
292
+ );
293
+ aliasSummary.push("af alias: failed");
294
+ // Reconcile: install failed → no symlink exists.
295
+ next.aliases.af.enabled = false;
296
+ }
297
+ } else {
298
+ // User declined — clean up any previous symlink we installed.
299
+ const aliasSpinner = prompts.spinner();
300
+ aliasSpinner.start("Checking `af` alias");
301
+ const removal = await uninstallAfAlias();
302
+ if (removal.status === "removed") {
303
+ aliasSpinner.stop(`Alias removed → ${removal.path}`);
304
+ aliasSummary.push(`af alias: removed (${removal.path})`);
305
+ } else if (removal.status === "absent") {
306
+ aliasSpinner.stop("Alias not present");
307
+ aliasSummary.push("af alias: not present");
308
+ } else if (removal.status === "skipped") {
309
+ aliasSpinner.stop("Alias points elsewhere — left untouched");
310
+ prompts.log.warn(
311
+ removal.message ||
312
+ `${removal.path} points at a different binary; remove it manually to free the name.`,
313
+ );
314
+ aliasSummary.push("af alias: skipped (foreign symlink)");
315
+ } else if (removal.status === "failed") {
316
+ aliasSpinner.stop("Alias removal failed");
317
+ prompts.log.warn(
318
+ `Could not remove existing af alias at ${removal.path}: ${
319
+ removal.message || "unknown error"
320
+ }`,
321
+ );
322
+ aliasSummary.push(`af alias: removal failed (${removal.path})`);
323
+ }
324
+ }
325
+
326
+ const writeSpinner = prompts.spinner();
327
+ writeSpinner.start("Writing launch-prefs.json");
328
+ /** @type {string} */
329
+ let file;
330
+ try {
331
+ file = await writePrefs(next);
332
+ } catch (err) {
333
+ writeSpinner.stop("Prefs write failed");
334
+ prompts.log.error(err.message);
335
+ process.exit(1);
336
+ }
337
+ writeSpinner.stop(`Prefs written → ${file}`);
338
+
339
+ /** @type {string[]} */
340
+ const summary = [
341
+ `preferred CLI: ${cli.preferred}`,
342
+ `fallback order: ${cli.fallbackOrder.join(" → ")}`,
343
+ tmuxAndKeybinds.tmux.enabled
344
+ ? `tmux: on (status ${tmuxAndKeybinds.tmux.statusPosition}, keybinds ${tmuxAndKeybinds.keybinds.preset})`
345
+ : "tmux: off",
346
+ ...aliasSummary,
347
+ ];
348
+
349
+ prompts.outro(summary.join("\n"));
350
+
351
+ return next;
352
+ }
353
+
354
+ /**
355
+ * Resolve the AI CLI from prefs and launch it as a foreground child.
356
+ * Exits the parent with the child's exit code so shell pipelines see
357
+ * the right status.
358
+ *
359
+ * Slice 2b: when `prefs.tmux.enabled === true` AND tmux is on PATH AND
360
+ * we're not already inside a tmux client, wrap the CLI in a per-cwd
361
+ * tmux session via `launchInTmux`. Otherwise — including the
362
+ * "tmux=true but unavailable / nested" fallback paths — plain-spawn the
363
+ * CLI (slice 2a behavior).
364
+ *
365
+ * @param {import('../../runtime/launch/defaults.js').LaunchPrefs} prefs
366
+ * @returns {Promise<never>}
367
+ */
368
+ async function runEngine(prefs) {
369
+ const { resolved, tried } = resolveCli(prefs);
370
+ if (!resolved) {
371
+ fail(
372
+ new OperationFailedError(
373
+ `no configured AI CLI is installed (tried ${tried.join(", ")})`,
374
+ {
375
+ suggestion:
376
+ "install one of the supported CLIs (claude, codex, cursor-agent, aider), " +
377
+ "or run `agileflow launch setup` to update your fallback order",
378
+ },
379
+ ),
380
+ { command: "launch" },
381
+ );
382
+ }
383
+
384
+ if (prefs.tmux.enabled) {
385
+ if (isInsideTmux()) {
386
+ // Nesting tmux sessions is allowed but confusing — and the v3 `af`
387
+ // explicitly avoided it. Plain-spawn in the current pane.
388
+ // eslint-disable-next-line no-console
389
+ console.error(
390
+ `agileflow launch: already inside a tmux session — launching ${resolved.bin} in the current pane.`,
391
+ );
392
+ } else if (!tmuxAvailable()) {
393
+ // eslint-disable-next-line no-console
394
+ console.error(
395
+ `agileflow launch: tmux is not installed — launching ${resolved.bin} directly. Install tmux to enable session management.`,
396
+ );
397
+ } else {
398
+ try {
399
+ const result = await launchInTmux({
400
+ bin: resolved.bin,
401
+ args: [],
402
+ statusPosition: prefs.tmux.statusPosition,
403
+ keybindPreset: prefs.keybinds.preset,
404
+ });
405
+ process.exit(result.exitCode);
406
+ } catch (err) {
407
+ fail(
408
+ new OperationFailedError(
409
+ `tmux launch failed: ${err && err.message ? err.message : String(err)}`,
410
+ {
411
+ suggestion:
412
+ "verify tmux works (`tmux new-session -d -s test && tmux kill-session -t test`), " +
413
+ "or disable tmux via `agileflow launch setup`",
414
+ cause: err,
415
+ },
416
+ ),
417
+ { command: "launch" },
418
+ );
419
+ }
420
+ }
421
+ }
422
+
423
+ const result = await runCli(resolved.bin, []);
424
+ process.exit(result.exitCode);
425
+ }
426
+
427
+ /**
428
+ * `agileflow launch new [name]` — spawn a parallel session (same-dir or
429
+ * worktree-backed) and switch the user's tmux client to it. Bound by
430
+ * default to Alt+s (no name) and Alt+n (prompts for a name) via the
431
+ * default keybind preset.
432
+ *
433
+ * Pre-conditions:
434
+ * - prefs file must exist (no auto-setup here — `new` only makes sense
435
+ * after the user has already configured launch)
436
+ * - we must be inside a tmux client (switch-client needs a current
437
+ * client; outside tmux there is no session to swap from)
438
+ * - the user's preferred CLI must be installed
439
+ * - tmux must be on PATH (it's a prerequisite for being "inside tmux"
440
+ * so this should always hold, but we guard defensively)
441
+ *
442
+ * Returns void on success (user is now inside the new session via
443
+ * switch-client; the parent process exits cleanly with status 0). All
444
+ * failure paths call `fail()` which calls `process.exit(1)`.
445
+ *
446
+ * @param {string | undefined} name - worktree name; omit for same-dir
447
+ * @returns {Promise<void>}
448
+ */
449
+ async function runNew(name) {
450
+ if (!(await prefsExist())) {
451
+ fail(
452
+ new OperationFailedError("agileflow launch new requires prefs first", {
453
+ suggestion: "run `agileflow launch setup` to create launch-prefs.json",
454
+ }),
455
+ { command: "launch" },
456
+ );
457
+ }
458
+
459
+ if (!isInsideTmux()) {
460
+ fail(
461
+ new OperationFailedError(
462
+ "agileflow launch new only works inside an existing tmux session",
463
+ {
464
+ suggestion:
465
+ "run `agileflow launch` first to start a session, then use Alt+s / Alt+n inside it",
466
+ },
467
+ ),
468
+ { command: "launch" },
469
+ );
470
+ }
471
+
472
+ if (!tmuxAvailable()) {
473
+ fail(
474
+ new OperationFailedError(
475
+ "tmux is not available — required for `launch new`",
476
+ { suggestion: "install tmux and try again" },
477
+ ),
478
+ { command: "launch" },
479
+ );
480
+ }
481
+
482
+ const { prefs } = await loadPrefsOrFail();
483
+ const { resolved, tried } = resolveCli(prefs);
484
+ if (!resolved) {
485
+ fail(
486
+ new OperationFailedError(
487
+ `no configured AI CLI is installed (tried ${tried.join(", ")})`,
488
+ {
489
+ suggestion:
490
+ "install one of the supported CLIs (claude, codex, cursor-agent, aider), " +
491
+ "or run `agileflow launch setup` to update your fallback order",
492
+ },
493
+ ),
494
+ { command: "launch" },
495
+ );
496
+ }
497
+
498
+ try {
499
+ await runParallelSpawn({
500
+ bin: resolved.bin,
501
+ name,
502
+ prefs,
503
+ });
504
+ } catch (err) {
505
+ const code = err && err.code;
506
+ let suggestion = "re-run with DEBUG=1 for a stack trace";
507
+ if (code === "EWT_DIR_EXISTS") {
508
+ suggestion =
509
+ "remove the existing worktree directory or pick a different name";
510
+ } else if (code === "EWT_BRANCH_EXISTS") {
511
+ suggestion = "the branch already exists — pick a different name";
512
+ } else if (code === "EWT_NOT_REPO") {
513
+ suggestion =
514
+ "run from inside a git repository, or omit the name for a same-dir session";
515
+ } else if (code === "EWT_NO_HEAD") {
516
+ suggestion =
517
+ "check out a branch first (HEAD is detached), or pass an explicit base via prefs";
518
+ } else if (code === "EWT_BAD_NAME") {
519
+ suggestion =
520
+ "pick a name with letters, digits, dot, underscore, or hyphen";
521
+ } else if (code === "EWT_CREATE") {
522
+ suggestion =
523
+ "git worktree add failed; inspect the repo state and try again, or omit the name for a same-dir session";
524
+ } else if (code === "ETMUX_CREATE") {
525
+ suggestion =
526
+ "tmux session creation failed; verify tmux works (`tmux new-session -d -s test && tmux kill-session -t test`)";
527
+ } else if (code === "ETMUX_SWITCH") {
528
+ // The session is alive but switch-client didn't take. Tell the user
529
+ // exactly how to attach to it manually.
530
+ suggestion =
531
+ "switch-client failed but the new session is still running — attach with `tmux attach -t <session-name>` (see error message above for the name)";
532
+ }
533
+ fail(
534
+ new OperationFailedError(
535
+ `launch new failed: ${err && err.message ? err.message : String(err)}`,
536
+ { suggestion, cause: err },
537
+ ),
538
+ { command: "launch" },
539
+ );
540
+ }
541
+ // runParallelSpawn returns normally after switch-client. We don't
542
+ // process.exit — the user is now inside the new session and this
543
+ // invocation finishes cleanly with exit code 0.
544
+ }
545
+
546
+ /**
547
+ * `agileflow launch restore` — bulk-restore every session in the
548
+ * registry that isn't currently alive on the tmux server. Used after a
549
+ * reboot (or `tmux kill-server`) to bring back the tabs the user had
550
+ * before. Idempotent.
551
+ *
552
+ * @returns {Promise<void>}
553
+ */
554
+ async function runRestoreCommand() {
555
+ if (!(await prefsExist())) {
556
+ fail(
557
+ new OperationFailedError(
558
+ "agileflow launch restore requires prefs first",
559
+ {
560
+ suggestion:
561
+ "run `agileflow launch setup` to create launch-prefs.json",
562
+ },
563
+ ),
564
+ { command: "launch" },
565
+ );
566
+ }
567
+ if (!tmuxAvailable()) {
568
+ fail(
569
+ new OperationFailedError(
570
+ "tmux is not available — required for `launch restore`",
571
+ { suggestion: "install tmux and try again" },
572
+ ),
573
+ { command: "launch" },
574
+ );
575
+ }
576
+ const { prefs } = await loadPrefsOrFail();
577
+ const reg = loadRegistry();
578
+ if (reg.sessions.length === 0) {
579
+ // eslint-disable-next-line no-console
580
+ console.error(
581
+ "agileflow launch: no saved sessions to restore (registry is empty).",
582
+ );
583
+ return;
584
+ }
585
+
586
+ const result = runRestore({ prefs });
587
+ // eslint-disable-next-line no-console
588
+ console.error(
589
+ `agileflow launch: restored ${result.restored}, already-alive ${result.alreadyAlive}, ` +
590
+ `skipped ${result.skipped}, failed ${result.failed}`,
591
+ );
592
+ if (result.failed > 0 || result.skipped > 0) {
593
+ for (const note of result.notes) {
594
+ // eslint-disable-next-line no-console
595
+ console.error(` ${note.name}: ${note.reason}`);
596
+ }
597
+ }
598
+ }
599
+
600
+ /**
601
+ * `agileflow launch ls` — print a one-line-per-session table of every
602
+ * known session with its current state. Read-only; no prefs required.
603
+ *
604
+ * @returns {Promise<void>}
605
+ */
606
+ async function runLs() {
607
+ const rows = listSessions();
608
+ if (rows.length === 0) {
609
+ // eslint-disable-next-line no-console
610
+ console.log("No saved sessions. Run `agileflow launch` to create one.");
611
+ return;
612
+ }
613
+ // Pinned entries float to the top so the user sees their "always keep"
614
+ // sessions first. Within each group, original registry order is
615
+ // preserved (which is roughly creation order).
616
+ rows.sort(
617
+ (a, b) => (b.pinned === true ? 1 : 0) - (a.pinned === true ? 1 : 0),
618
+ );
619
+ // Column widths sized to the longest value, capped to keep wide cwds
620
+ // from blowing past the terminal. Leading column reserves a glyph for
621
+ // the pin marker so pinned/unpinned rows align.
622
+ const nameW = Math.max(4, ...rows.map((r) => r.name.length));
623
+ const cliW = Math.max(3, ...rows.map((r) => r.cli.length));
624
+ const stateW = "missing-cwd".length;
625
+ const pinMark = (r) => (r.pinned ? "★" : " ");
626
+ const fmt = (r) =>
627
+ `${pinMark(r)} ${r.name.padEnd(nameW)} ${r.cli.padEnd(cliW)} ${r.state.padEnd(stateW)} ${r.cwd}${
628
+ r.worktree && r.worktree.branch ? ` [wt ${r.worktree.branch}]` : ""
629
+ }`;
630
+ // eslint-disable-next-line no-console
631
+ console.log(
632
+ ` ${"NAME".padEnd(nameW)} ${"CLI".padEnd(cliW)} ${"STATE".padEnd(stateW)} CWD`,
633
+ );
634
+ for (const r of rows) {
635
+ // eslint-disable-next-line no-console
636
+ console.log(fmt(r));
637
+ }
638
+ }
639
+
640
+ /**
641
+ * `agileflow launch kill <name>` — kill the tmux session if alive,
642
+ * forget the registry entry, and optionally remove its git worktree.
643
+ *
644
+ * @param {string | undefined} name
645
+ * @returns {Promise<void>}
646
+ */
647
+ async function runKill(name) {
648
+ if (!name) {
649
+ fail(
650
+ new OperationFailedError(
651
+ "agileflow launch kill requires a session name",
652
+ {
653
+ suggestion: "run `agileflow launch ls` to see available names",
654
+ },
655
+ ),
656
+ { command: "launch" },
657
+ );
658
+ }
659
+ const reg = loadRegistry();
660
+ const entry = reg.sessions.find((s) => s.name === name);
661
+ if (!entry) {
662
+ fail(
663
+ new OperationFailedError(`no session named "${name}" in the registry`, {
664
+ suggestion: "run `agileflow launch ls` to see available names",
665
+ }),
666
+ { command: "launch" },
667
+ );
668
+ }
669
+ // Surface the worktree question only when there's something to remove —
670
+ // missing worktree dirs don't need a prompt, just forget the entry.
671
+ let removeWorktreeFlag = false;
672
+ if (
673
+ entry.worktree &&
674
+ entry.worktree.path &&
675
+ fs.existsSync(entry.worktree.path)
676
+ ) {
677
+ const choice = await prompts.confirm({
678
+ message: questionMessage(
679
+ `Also remove the worktree at ${entry.worktree.path}?`,
680
+ `branch: ${entry.worktree.branch} — this runs \`git worktree remove -f\` and \`git branch -D\`.`,
681
+ ),
682
+ initialValue: true,
683
+ });
684
+ if (prompts.isCancel(choice)) {
685
+ prompts.cancel("Kill cancelled.");
686
+ process.exit(0);
687
+ }
688
+ removeWorktreeFlag = !!choice;
689
+ }
690
+ const result = killBySessionName({
691
+ name,
692
+ removeWorktree: removeWorktreeFlag,
693
+ });
694
+ if (!result.ok) {
695
+ fail(
696
+ new OperationFailedError(
697
+ `could not kill "${name}": ${result.reason || "unknown reason"}`,
698
+ { suggestion: "run `agileflow launch ls` to confirm the name" },
699
+ ),
700
+ { command: "launch" },
701
+ );
702
+ }
703
+ /** @type {string[]} */
704
+ const summary = [];
705
+ summary.push(
706
+ result.wasAlive
707
+ ? `Killed tmux session "${name}" and forgot it.`
708
+ : `Forgot dormant session "${name}".`,
709
+ );
710
+ if (result.worktree) {
711
+ if (result.worktree.removed && result.worktree.branchRemoved) {
712
+ summary.push(`Removed worktree + branch.`);
713
+ } else if (result.worktree.removed) {
714
+ summary.push(`Removed worktree (branch removal failed).`);
715
+ } else {
716
+ summary.push(`Worktree removal failed: ${result.worktree.stderr}`);
717
+ }
718
+ }
719
+ // eslint-disable-next-line no-console
720
+ console.log(summary.join("\n"));
721
+ }
722
+
723
+ /**
724
+ * `agileflow launch attach <name>` — attach to a named session, lazily
725
+ * restoring it from the registry if the tmux server doesn't have it.
726
+ *
727
+ * @param {string | undefined} name
728
+ * @returns {Promise<void>}
729
+ */
730
+ async function runAttachByName(name) {
731
+ if (!name) {
732
+ fail(
733
+ new OperationFailedError(
734
+ "agileflow launch attach requires a session name",
735
+ {
736
+ suggestion: "run `agileflow launch ls` to see available names",
737
+ },
738
+ ),
739
+ { command: "launch" },
740
+ );
741
+ }
742
+ if (!tmuxAvailable()) {
743
+ fail(
744
+ new OperationFailedError(
745
+ "tmux is not available — required for `launch attach`",
746
+ { suggestion: "install tmux and try again" },
747
+ ),
748
+ { command: "launch" },
749
+ );
750
+ }
751
+ const { prefs } = await loadPrefsOrFail();
752
+ const result = await attachByName({
753
+ name,
754
+ prefs,
755
+ agileflowBin: resolveAgileflowBin(),
756
+ });
757
+ if (!result.ok) {
758
+ /** @type {string} */
759
+ let suggestion;
760
+ if (result.reason === "not in registry") {
761
+ suggestion = "run `agileflow launch ls` to see available names";
762
+ } else if (result.reason === "cwd missing") {
763
+ suggestion = `the original directory has been deleted — run \`agileflow launch kill ${name}\` to forget it`;
764
+ } else {
765
+ suggestion = "check tmux state and the registry file";
766
+ }
767
+ fail(
768
+ new OperationFailedError(
769
+ `could not attach "${name}": ${result.reason || "unknown reason"}`,
770
+ { suggestion },
771
+ ),
772
+ { command: "launch" },
773
+ );
774
+ }
775
+ // Always exit with the attach's exit code so shell pipelines see the
776
+ // right status. Defensive default of 0 covers the unlikely case where
777
+ // the attach result doesn't carry a numeric exitCode — better to exit
778
+ // cleanly than leave the parent process hung in the terminal.
779
+ const exitCode =
780
+ result.attach &&
781
+ typeof result.attach === "object" &&
782
+ typeof result.attach.exitCode === "number"
783
+ ? result.attach.exitCode
784
+ : 0;
785
+ process.exit(exitCode);
786
+ }
787
+
788
+ /**
789
+ * `agileflow launch prune` — interactive cleanup of dormant entries
790
+ * whose original directory has been deleted, or whose worktree path no
791
+ * longer exists.
792
+ *
793
+ * @returns {Promise<void>}
794
+ */
795
+ async function runPrune() {
796
+ const candidates = pruneCandidates();
797
+ if (candidates.length === 0) {
798
+ // eslint-disable-next-line no-console
799
+ console.log(
800
+ "Nothing to prune — every registered session still has a live cwd.",
801
+ );
802
+ return;
803
+ }
804
+ const options = candidates.map((c) => ({
805
+ value: c.name,
806
+ label: c.name,
807
+ hint: `${c.cli} — ${c.reason}`,
808
+ }));
809
+ const selection = await prompts.multiselect({
810
+ message: questionMessage(
811
+ `Select session(s) to forget (${candidates.length} candidate(s))`,
812
+ "Forgetting drops the registry entry; worktree dirs are only removed if they still exist.",
813
+ ),
814
+ options,
815
+ initialValues: options.map((o) => o.value),
816
+ required: false,
817
+ });
818
+ if (prompts.isCancel(selection)) {
819
+ prompts.cancel("Prune cancelled.");
820
+ process.exit(0);
821
+ }
822
+ if (!Array.isArray(selection) || selection.length === 0) {
823
+ // eslint-disable-next-line no-console
824
+ console.log("No sessions selected. Nothing to do.");
825
+ return;
826
+ }
827
+ const result = applyPrune({
828
+ selections: selection.map((name) => ({ name })),
829
+ // Worktree removal is skipped here: the candidates that surface ARE
830
+ // the ones whose dirs are already missing OR whose cwd is missing.
831
+ // For "dir missing" entries there's no worktree to remove; for
832
+ // "cwd missing" the worktree path may still exist as a stranded
833
+ // directory. We surface it but don't auto-rm to avoid surprising
834
+ // users — they can `launch kill <name>` for targeted removal.
835
+ removeWorktrees: false,
836
+ });
837
+ // eslint-disable-next-line no-console
838
+ console.log(
839
+ `Forgot ${result.forgotten} session(s), removed ${result.worktreesRemoved} worktree(s).`,
840
+ );
841
+ if (result.errors.length > 0) {
842
+ for (const e of result.errors) {
843
+ // eslint-disable-next-line no-console
844
+ console.error(` ${e.name}: ${e.error}`);
845
+ }
846
+ }
847
+ }
848
+
849
+ /**
850
+ * `agileflow launch doctor` — read-only health check. Exits 1 if any
851
+ * check fails (tmux missing, preferred CLI missing, registry malformed).
852
+ * Warnings don't fail the doctor.
853
+ *
854
+ * @returns {Promise<void>}
855
+ */
856
+ async function runDoctor() {
857
+ const report = await runDoctorChecks();
858
+ for (const c of report.checks) {
859
+ const symbol = c.status === "pass" ? "✓" : c.status === "warn" ? "⚠" : "✗";
860
+ // eslint-disable-next-line no-console
861
+ console.log(`${symbol} ${c.id}: ${c.message}`);
862
+ if (c.fix) {
863
+ // eslint-disable-next-line no-console
864
+ console.log(` fix: ${c.fix}`);
865
+ }
866
+ }
867
+ if (anyFailed(report)) {
868
+ process.exit(1);
869
+ }
870
+ }
871
+
872
+ /**
873
+ * `agileflow launch pin <name>` / `unpin <name>` — flip the pinned flag
874
+ * on a registry entry. Pinned entries skip `prune` and arrive pre-
875
+ * selected in the auto-restore picker.
876
+ *
877
+ * @param {string | undefined} name
878
+ * @param {boolean} pinned
879
+ * @returns {Promise<void>}
880
+ */
881
+ async function runPin(name, pinned) {
882
+ const action = pinned ? "pin" : "unpin";
883
+ if (!name) {
884
+ fail(
885
+ new OperationFailedError(
886
+ `agileflow launch ${action} requires a session name`,
887
+ { suggestion: "run `agileflow launch ls` to see available names" },
888
+ ),
889
+ { command: "launch" },
890
+ );
891
+ }
892
+ const ok = pinSession(name, pinned);
893
+ if (!ok) {
894
+ fail(
895
+ new OperationFailedError(`no session named "${name}" in the registry`, {
896
+ suggestion: "run `agileflow launch ls` to see available names",
897
+ }),
898
+ { command: "launch" },
899
+ );
900
+ }
901
+ // eslint-disable-next-line no-console
902
+ console.log(`${pinned ? "Pinned" : "Unpinned"} "${name}".`);
903
+ }
904
+
905
+ /**
906
+ * `agileflow launch where` — show which prefs files contributed to the
907
+ * effective config in this directory. Useful for debugging "why is this
908
+ * repo picking codex when my global says claude?" surprises.
909
+ *
910
+ * @returns {Promise<void>}
911
+ */
912
+ async function runWhere() {
913
+ const cascaded = await loadCascadedPrefs();
914
+ // eslint-disable-next-line no-console
915
+ console.log(
916
+ "Active launch prefs in this directory (lowest → highest precedence):",
917
+ );
918
+ for (const s of cascaded.sources) {
919
+ const label =
920
+ s.layer === "defaults"
921
+ ? "built-in defaults"
922
+ : s.layer === "global"
923
+ ? `global ${s.path}`
924
+ : `project ${s.path}`;
925
+ // eslint-disable-next-line no-console
926
+ console.log(` ${label}`);
927
+ }
928
+ // eslint-disable-next-line no-console
929
+ console.log("");
930
+ // eslint-disable-next-line no-console
931
+ console.log("Effective values:");
932
+ // eslint-disable-next-line no-console
933
+ console.log(` cli.preferred ${cascaded.prefs.cli.preferred}`);
934
+ // eslint-disable-next-line no-console
935
+ console.log(
936
+ ` cli.fallbackOrder ${cascaded.prefs.cli.fallbackOrder.join(" → ")}`,
937
+ );
938
+ // eslint-disable-next-line no-console
939
+ console.log(
940
+ ` tmux ${cascaded.prefs.tmux.enabled ? "on" : "off"} (status ${cascaded.prefs.tmux.statusPosition})`,
941
+ );
942
+ // eslint-disable-next-line no-console
943
+ console.log(` keybinds ${cascaded.prefs.keybinds.preset}`);
944
+ // eslint-disable-next-line no-console
945
+ console.log(
946
+ ` af alias ${cascaded.prefs.aliases.af.enabled ? "on" : "off"}`,
947
+ );
948
+ }
949
+
950
+ /**
951
+ * Hidden subcommand wired to the `Alt+w` tab close keybind. Captures
952
+ * the current tmux window's name + pane cwd via `tmux display-message`,
953
+ * pushes onto the closed-windows log, then `kill-window`s. Designed to
954
+ * be called from a tmux `run-shell` action — no UI, no exceptions
955
+ * propagated to the user (failures only log to stderr so they appear in
956
+ * the tmux pane error overlay if the user surfaces it).
957
+ *
958
+ * Ordering: kill-window FIRST (with an explicit `-t session:index`
959
+ * target captured atomically from display-message), then push to the
960
+ * log only on kill success. This is the inverse of the obvious order
961
+ * but it avoids two real bugs caught in pre-commit audit:
962
+ * (a) Phantom log entry — if kill fails (permission, race) we'd
963
+ * otherwise leave a "closed" record pointing at a still-alive
964
+ * window, and Alt+T would duplicate it.
965
+ * (b) Wrong-window kill — a bare `kill-window` with no target acts
966
+ * on whatever window has focus at that instant, which can drift
967
+ * between display-message and the kill if the user switches
968
+ * windows in another pane. Explicit `-t` pins it.
969
+ *
970
+ * Trade-off: if push fails (lock contention etc.) the window is gone
971
+ * but Alt+T can't undo it — acceptable, since the inverse failure
972
+ * (logged but alive) is worse.
973
+ *
974
+ * @param {{
975
+ * runner?: ReturnType<typeof defaultTmuxRunner>,
976
+ * pushClosedImpl?: typeof closedWindows.pushClosed,
977
+ * }} [deps]
978
+ * @returns {Promise<void>}
979
+ */
980
+ async function runInternalCloseWindow(deps = {}) {
981
+ const runner = deps.runner || defaultTmuxRunner();
982
+ const pushClosedImpl = deps.pushClosedImpl || closedWindows.pushClosed;
983
+ // ASCII Unit Separator — never appears in a session/window name or
984
+ // filesystem path, so splitting on it is unambiguous.
985
+ const DELIM = "\x1f";
986
+ const fmt = `#S${DELIM}#I${DELIM}#W${DELIM}#{pane_current_path}`;
987
+ const probe = runner.runSync(["display-message", "-p", "-F", fmt]);
988
+ if (probe.status !== 0) {
989
+ // eslint-disable-next-line no-console
990
+ console.error(
991
+ `agileflow launch __close-window: tmux display-message failed: ${probe.stderr || "unknown"}`,
992
+ );
993
+ return;
994
+ }
995
+ const parts = (probe.stdout || "").trimEnd().split(DELIM);
996
+ if (parts.length !== 4) {
997
+ // eslint-disable-next-line no-console
998
+ console.error(
999
+ `agileflow launch __close-window: unexpected display-message output (got ${parts.length} fields)`,
1000
+ );
1001
+ return;
1002
+ }
1003
+ const [sessionName, windowIndex, windowName, cwd] = parts;
1004
+ if (!sessionName || !windowIndex || !cwd) {
1005
+ // eslint-disable-next-line no-console
1006
+ console.error(
1007
+ "agileflow launch __close-window: missing session/index/cwd; skipping kill",
1008
+ );
1009
+ return;
1010
+ }
1011
+ // Kill first with the explicit target captured above. If this fails
1012
+ // we abort without touching the log — the window is still alive and
1013
+ // a phantom entry would mislead Alt+T into resurrecting a duplicate.
1014
+ const kill = runner.runSync([
1015
+ "kill-window",
1016
+ "-t",
1017
+ `${sessionName}:${windowIndex}`,
1018
+ ]);
1019
+ if (kill.status !== 0) {
1020
+ // eslint-disable-next-line no-console
1021
+ console.error(
1022
+ `agileflow launch __close-window: kill-window failed: ${kill.stderr || "unknown"}`,
1023
+ );
1024
+ return;
1025
+ }
1026
+ try {
1027
+ pushClosedImpl({ sessionName, name: windowName || "", cwd });
1028
+ } catch (err) {
1029
+ // Window is already gone; push failure means Alt+T can't undo
1030
+ // this particular close. Surface for visibility but don't throw —
1031
+ // a tmux keybind run-shell can't usefully recover.
1032
+ // eslint-disable-next-line no-console
1033
+ console.error(
1034
+ `agileflow launch __close-window: log push failed (window already closed): ${err && err.message ? err.message : err}`,
1035
+ );
1036
+ }
1037
+ }
1038
+
1039
+ /**
1040
+ * Hidden subcommand wired to the `Alt+T` restore keybind. Pops the
1041
+ * most recent closed entry for the current tmux session and spawns a
1042
+ * new window in its cwd with the original name. No-op when the log is
1043
+ * empty for this session — quieter than printing a "nothing to undo"
1044
+ * message, since the user just sees their layout unchanged.
1045
+ *
1046
+ * @param {{
1047
+ * runner?: ReturnType<typeof defaultTmuxRunner>,
1048
+ * popClosedImpl?: typeof closedWindows.popClosed,
1049
+ * }} [deps]
1050
+ * @returns {Promise<void>}
1051
+ */
1052
+ async function runInternalRestoreWindow(deps = {}) {
1053
+ const runner = deps.runner || defaultTmuxRunner();
1054
+ const popClosedImpl = deps.popClosedImpl || closedWindows.popClosed;
1055
+ const pushClosedImpl = deps.pushClosedImpl || closedWindows.pushClosed;
1056
+ const probe = runner.runSync(["display-message", "-p", "-F", "#S"]);
1057
+ if (probe.status !== 0) {
1058
+ // eslint-disable-next-line no-console
1059
+ console.error(
1060
+ `agileflow launch __restore-window: tmux display-message failed: ${probe.stderr || "unknown"}`,
1061
+ );
1062
+ return;
1063
+ }
1064
+ const sessionName = (probe.stdout || "").trim();
1065
+ if (!sessionName) return;
1066
+ /** @type {ReturnType<typeof closedWindows.popClosed>} */
1067
+ let entry;
1068
+ try {
1069
+ entry = popClosedImpl(sessionName);
1070
+ } catch (err) {
1071
+ // eslint-disable-next-line no-console
1072
+ console.error(
1073
+ `agileflow launch __restore-window: log pop failed: ${err && err.message ? err.message : err}`,
1074
+ );
1075
+ return;
1076
+ }
1077
+ if (!entry) {
1078
+ // Empty stack — silent. The user pressed Alt+T with nothing to undo.
1079
+ return;
1080
+ }
1081
+ const args = ["new-window", "-t", sessionName, "-c", entry.cwd];
1082
+ if (entry.name) args.push("-n", entry.name);
1083
+ const create = runner.runSync(args);
1084
+ if (create.status !== 0) {
1085
+ // eslint-disable-next-line no-console
1086
+ console.error(
1087
+ `agileflow launch __restore-window: new-window failed: ${create.stderr || "unknown"}`,
1088
+ );
1089
+ // Re-push so the user doesn't lose their undo entry — pop already
1090
+ // mutated the log, so a failed new-window without re-push means
1091
+ // pressing Alt+T again would skip THIS entry and pop the NEXT one,
1092
+ // double-losing data.
1093
+ try {
1094
+ pushClosedImpl({
1095
+ sessionName,
1096
+ name: entry.name,
1097
+ cwd: entry.cwd,
1098
+ });
1099
+ } catch (pushErr) {
1100
+ // eslint-disable-next-line no-console
1101
+ console.error(
1102
+ `agileflow launch __restore-window: failed to re-push entry after new-window failure: ${pushErr && pushErr.message ? pushErr.message : pushErr}`,
1103
+ );
1104
+ }
1105
+ }
1106
+ }
1107
+
1108
+ /**
1109
+ * Auto-restore check on bare `agileflow launch`. Fires only when:
1110
+ * - tmux is available (we use sessionExists to count alive sessions)
1111
+ * - the registry has entries
1112
+ * - none of those entries' sessions are currently alive on the
1113
+ * server (typical post-reboot state — tmux server is brand-new)
1114
+ *
1115
+ * Prompts the user yes/no. On yes, calls runRestore and falls through
1116
+ * so the normal engine flow attaches to (or creates) the cwd's session
1117
+ * afterwards.
1118
+ *
1119
+ * @param {import("../../runtime/launch/defaults.js").LaunchPrefs} prefs
1120
+ * @returns {Promise<void>}
1121
+ */
1122
+ async function maybeOfferAutoRestore(prefs) {
1123
+ if (!tmuxAvailable()) return;
1124
+ const reg = loadRegistry();
1125
+ if (reg.sessions.length === 0) return;
1126
+
1127
+ // If ANY registered session is alive, the server isn't fresh — skip
1128
+ // the bulk-restore prompt. The user is likely just launching a new
1129
+ // window in an already-running server.
1130
+ const runner = defaultTmuxRunner();
1131
+ const { sessionExists } = require("../../runtime/launch/tmux.js");
1132
+ for (const s of reg.sessions) {
1133
+ if (sessionExists(s.name, runner)) return;
1134
+ }
1135
+
1136
+ // eslint-disable-next-line no-console
1137
+ console.log("\n" + logoBanner(pkg.version) + "\n");
1138
+ prompts.intro("agileflow launch — saved sessions detected");
1139
+ prompts.log.info(
1140
+ `Found ${reg.sessions.length} saved session(s) from before this tmux server started.`,
1141
+ );
1142
+
1143
+ // Multi-select picker: every session is an option, pinned entries
1144
+ // (and entries with worktrees — these are usually intentional Alt+n
1145
+ // work-in-progress) come pre-selected. Default-selecting nothing
1146
+ // would surprise users coming from v3 (which restored all), so when
1147
+ // no session is pinned we default-select everything.
1148
+ const sorted = reg.sessions.slice().sort((a, b) => {
1149
+ const ap = a.pinned === true ? 1 : 0;
1150
+ const bp = b.pinned === true ? 1 : 0;
1151
+ if (ap !== bp) return bp - ap;
1152
+ return 0;
1153
+ });
1154
+ const options = sorted.map((s) => ({
1155
+ value: s.name,
1156
+ label: `${s.pinned ? "★ " : " "}${s.name}`,
1157
+ hint: `${s.cli} — ${s.cwd}${s.worktree && s.worktree.branch ? ` [wt ${s.worktree.branch}]` : ""}`,
1158
+ }));
1159
+ const anyPinned = sorted.some((s) => s.pinned === true);
1160
+ const initial = anyPinned
1161
+ ? sorted.filter((s) => s.pinned === true).map((s) => s.name)
1162
+ : sorted.map((s) => s.name);
1163
+
1164
+ const selection = await prompts.multiselect({
1165
+ message: questionMessage(
1166
+ "Pick which sessions to restore",
1167
+ "Pinned (★) entries are pre-selected. Space toggles, Enter confirms, Ctrl+C cancels everything.",
1168
+ ),
1169
+ options,
1170
+ initialValues: initial,
1171
+ required: false,
1172
+ });
1173
+ // Distinguish Ctrl+C ("cancel everything") from explicit "no selections"
1174
+ // ("skip restore but keep going"). The two used to be one branch and
1175
+ // both fell through to runEngine — surprising for users who pressed
1176
+ // Ctrl+C expecting nothing further to happen.
1177
+ if (prompts.isCancel(selection)) {
1178
+ prompts.cancel("Launch cancelled. No sessions restored.");
1179
+ process.exit(0);
1180
+ }
1181
+ /** @type {string[]} */
1182
+ const chosen = Array.isArray(selection) ? selection : [];
1183
+ if (chosen.length === 0) {
1184
+ prompts.outro(
1185
+ "Skipped. Run `agileflow launch restore` later to bring them back.",
1186
+ );
1187
+ return;
1188
+ }
1189
+ const result = runRestore({ prefs, onlyNames: chosen });
1190
+ prompts.outro(
1191
+ `Restored ${result.restored} session(s). Continuing into the current directory's session...`,
1192
+ );
1193
+ if (result.failed > 0 || result.skipped > 0) {
1194
+ for (const note of result.notes) {
1195
+ // eslint-disable-next-line no-console
1196
+ console.error(` ${note.name}: ${note.reason}`);
1197
+ }
1198
+ }
1199
+ }
1200
+
1201
+ /**
1202
+ * Commander action for `agileflow launch [sub] [name]`.
1203
+ *
1204
+ * Commander v12 invokes action with positional args first, options last:
1205
+ * `action((sub, name, options) => ...)` for `.command("launch [sub] [name]")`.
1206
+ * The `name` is only meaningful when `sub === "new"`; ignored otherwise.
1207
+ *
1208
+ * @param {string | undefined} sub
1209
+ * @param {string | undefined} nameArg
1210
+ * @param {Record<string, unknown>} [_options]
1211
+ */
1212
+ async function launch(sub, nameArg, _options) {
1213
+ try {
1214
+ if (sub === "new") {
1215
+ await runNew(nameArg);
1216
+ return;
1217
+ }
1218
+ if (sub === "__exec") {
1219
+ // Hidden subcommand invoked by tmux itself when a session boots.
1220
+ // `nameArg` is the registry key. runExec loads the entry, spawns
1221
+ // the right CLI with its resume args, captures the new UUID after
1222
+ // exit, and process.exits with the CLI's status.
1223
+ if (!nameArg) {
1224
+ fail(
1225
+ new OperationFailedError(
1226
+ "agileflow launch __exec requires a session name",
1227
+ { suggestion: "this command is invoked by tmux internally" },
1228
+ ),
1229
+ { command: "launch" },
1230
+ );
1231
+ }
1232
+ await runExec(nameArg);
1233
+ return;
1234
+ }
1235
+ if (sub === "restore") {
1236
+ await runRestoreCommand();
1237
+ return;
1238
+ }
1239
+ if (sub === "ls") {
1240
+ await runLs();
1241
+ return;
1242
+ }
1243
+ if (sub === "kill") {
1244
+ await runKill(nameArg);
1245
+ return;
1246
+ }
1247
+ if (sub === "attach") {
1248
+ await runAttachByName(nameArg);
1249
+ return;
1250
+ }
1251
+ if (sub === "prune") {
1252
+ await runPrune();
1253
+ return;
1254
+ }
1255
+ if (sub === "doctor") {
1256
+ await runDoctor();
1257
+ return;
1258
+ }
1259
+ if (sub === "pin") {
1260
+ await runPin(nameArg, true);
1261
+ return;
1262
+ }
1263
+ if (sub === "unpin") {
1264
+ await runPin(nameArg, false);
1265
+ return;
1266
+ }
1267
+ if (sub === "where") {
1268
+ await runWhere();
1269
+ return;
1270
+ }
1271
+ if (sub === "__close-window") {
1272
+ // Hidden subcommand invoked from tmux keybind (Alt+w). Captures
1273
+ // the current window's name + pane cwd, pushes onto the
1274
+ // closed-windows log, then issues kill-window so Alt+T can
1275
+ // resurrect it later. No UI; failures are silent.
1276
+ await runInternalCloseWindow();
1277
+ return;
1278
+ }
1279
+ if (sub === "__restore-window") {
1280
+ // Hidden subcommand invoked from tmux keybind (Alt+T). Pops the
1281
+ // most recent closed entry for the current session and spawns
1282
+ // a new window in that cwd with the original name. No-op when
1283
+ // the log is empty for this session.
1284
+ await runInternalRestoreWindow();
1285
+ return;
1286
+ }
1287
+ if (sub && sub !== "setup") {
1288
+ fail(
1289
+ new OperationFailedError(`unknown launch subcommand: ${sub}`, {
1290
+ suggestion:
1291
+ "use `agileflow launch`, `agileflow launch setup`, `agileflow launch new [name]`, `agileflow launch restore`, `agileflow launch ls`, `agileflow launch kill <name>`, `agileflow launch attach <name>`, `agileflow launch prune`, `agileflow launch doctor`, `agileflow launch pin <name>`, `agileflow launch unpin <name>`, or `agileflow launch where`",
1292
+ }),
1293
+ { command: "launch" },
1294
+ );
1295
+ }
1296
+
1297
+ const hasPrefs = await prefsExist();
1298
+ const flow = decideFlow({ sub, hasPrefs });
1299
+
1300
+ if (flow === "setup") {
1301
+ await runSetup();
1302
+ return;
1303
+ }
1304
+
1305
+ if (flow === "first-run-setup") {
1306
+ // Walk the user through setup, then immediately launch — they
1307
+ // expect `agileflow launch` to do something on first invocation,
1308
+ // not just configure and exit. Use the prefs returned from
1309
+ // runSetup directly so a failed reload can't tell the user to
1310
+ // "re-run setup" when they just finished doing exactly that.
1311
+ const prefs = await runSetup();
1312
+ // eslint-disable-next-line no-console
1313
+ console.log("");
1314
+ await runEngine(prefs);
1315
+ return;
1316
+ }
1317
+
1318
+ const { prefs } = await loadPrefsOrFail();
1319
+ // Auto-restore prompt before engine: if tmux is up, the registry
1320
+ // has entries, and none of them are currently alive on the server,
1321
+ // ask the user whether to bulk-restore. After they choose, the
1322
+ // engine still runs and either attaches to (or creates) the cwd's
1323
+ // canonical session.
1324
+ await maybeOfferAutoRestore(prefs);
1325
+ await runEngine(prefs);
1326
+ } catch (err) {
1327
+ // Preserve typed AgileflowError subclasses (OperationFailedError,
1328
+ // InvalidArgumentError, MissingFileError) with their `suggestion`
1329
+ // intact. A `name` string compare would miss subclasses — they each
1330
+ // override `name` to their own class name.
1331
+ if (err instanceof AgileflowError) throw err;
1332
+
1333
+ // TOCTOU: the PATH probe in resolveCli passed, but the binary was
1334
+ // removed before spawn. Surface the same actionable hint as the
1335
+ // no-CLI-installed path, not the generic "re-run with DEBUG=1".
1336
+ if (err && err.code === "ENOENT") {
1337
+ fail(
1338
+ new OperationFailedError(
1339
+ `AI CLI not found at launch time: ${err.message}`,
1340
+ {
1341
+ suggestion:
1342
+ "install one of the supported CLIs (claude, codex, cursor-agent, aider), " +
1343
+ "or run `agileflow launch setup` to update your fallback order",
1344
+ cause: err,
1345
+ },
1346
+ ),
1347
+ { command: "launch" },
1348
+ );
1349
+ }
1350
+
1351
+ // Binary exists but is not executable — distinct fix from "install".
1352
+ if (err && err.code === "EACCES") {
1353
+ fail(
1354
+ new OperationFailedError(`AI CLI is not executable: ${err.message}`, {
1355
+ suggestion:
1356
+ "check file permissions on the CLI binary, or re-install it",
1357
+ cause: err,
1358
+ }),
1359
+ { command: "launch" },
1360
+ );
1361
+ }
1362
+
1363
+ fail(
1364
+ new OperationFailedError(
1365
+ `launch failed: ${err && err.message ? err.message : String(err)}`,
1366
+ { suggestion: "re-run with DEBUG=1 for a stack trace", cause: err },
1367
+ ),
1368
+ { command: "launch" },
1369
+ );
1370
+ }
1371
+ }
1372
+
1373
+ module.exports = launch;
1374
+ module.exports.decideFlow = decideFlow;
1375
+ module.exports.runSetup = runSetup;
1376
+ module.exports.runEngine = runEngine;
1377
+ module.exports.runNew = runNew;
1378
+ module.exports.runLs = runLs;
1379
+ module.exports.runKill = runKill;
1380
+ module.exports.runAttachByName = runAttachByName;
1381
+ module.exports.runPrune = runPrune;
1382
+ module.exports.runDoctor = runDoctor;
1383
+ module.exports.runPin = runPin;
1384
+ module.exports.runWhere = runWhere;
1385
+ module.exports.shouldOfferOrphanCleanup = shouldOfferOrphanCleanup;