workflow-ai 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (593) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +105 -7
  3. package/configs/pipeline.yaml +23 -2
  4. package/package.json +44 -44
  5. package/src/lib/operations/tickets.mjs +305 -207
  6. package/src/lib/utils.mjs +286 -286
  7. package/src/runner.mjs +314 -34
  8. package/src/scripts/check-conditions.js +2 -2
  9. package/src/scripts/get-next-id.js +144 -41
  10. package/src/scripts/move-ticket.js +225 -68
  11. package/src/scripts/pick-next-task.js +753 -93
  12. package/src/skills/coach/SKILL.md +1 -1
  13. package/src/skills/manual-testing/SKILL.md +2 -0
  14. package/src/scripts/tests/timeout-cascade.test.js +0 -28
  15. package/src/skills/analyze-report/README.md +0 -44
  16. package/src/skills/analyze-report/algorithms/progress-assessment.md +0 -108
  17. package/src/skills/analyze-report/knowledge/analysis-frameworks.md +0 -66
  18. package/src/skills/analyze-report/knowledge/report-structure.md +0 -61
  19. package/src/skills/analyze-report/scripts/calc-plan-metrics.js +0 -234
  20. package/src/skills/analyze-report/templates/analysis-report.md +0 -80
  21. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-001/current/claude-sonnet/trial-1.md +0 -5
  22. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-001/current/claude-sonnet/trial-2.md +0 -98
  23. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-001/current/claude-sonnet/trial-3.md +0 -99
  24. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-001/current/judge.json +0 -163
  25. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-001/current/kilo-deepseek/trial-1.md +0 -89
  26. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-001/current/kilo-deepseek/trial-2.md +0 -88
  27. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-001/current/kilo-deepseek/trial-3.md +0 -100
  28. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-001/current/kilo-glm/trial-1.md +0 -77
  29. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-001/current/kilo-glm/trial-2.md +0 -64
  30. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-001/current/kilo-glm/trial-3.md +0 -110
  31. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-001/current/kilo-minimax/trial-1.md +0 -74
  32. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-001/current/kilo-minimax/trial-2.md +0 -38
  33. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-001/current/kilo-minimax/trial-3.md +0 -61
  34. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-001/current/meta.json +0 -115
  35. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-001-evidence-from-log.yaml +0 -60
  36. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-002/current/claude-sonnet/trial-1.md +0 -90
  37. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-002/current/claude-sonnet/trial-2.md +0 -89
  38. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-002/current/claude-sonnet/trial-3.md +0 -5
  39. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-002/current/judge.json +0 -163
  40. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-002/current/kilo-deepseek/trial-1.md +0 -84
  41. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-002/current/kilo-deepseek/trial-2.md +0 -77
  42. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-002/current/kilo-deepseek/trial-3.md +0 -89
  43. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-002/current/kilo-glm/trial-1.md +0 -103
  44. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-002/current/kilo-glm/trial-2.md +0 -103
  45. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-002/current/kilo-glm/trial-3.md +0 -103
  46. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-002/current/kilo-minimax/trial-1.md +0 -93
  47. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-002/current/kilo-minimax/trial-2.md +0 -93
  48. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-002/current/kilo-minimax/trial-3.md +0 -86
  49. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-002/current/meta.json +0 -115
  50. package/src/skills/analyze-report/tests/cases/TC-ANALYZE-REPORT-002-result-block-format.yaml +0 -44
  51. package/src/skills/analyze-report/tests/fixtures/REPORT-002-incorrect-attribution.md +0 -27
  52. package/src/skills/analyze-report/tests/fixtures/pipeline-2026-04-06_qa-001-skip.log +0 -32
  53. package/src/skills/analyze-report/tests/index.yaml +0 -25
  54. package/src/skills/analyze-report/tests/rubrics/evidence-from-log.md +0 -22
  55. package/src/skills/analyze-report/tests/rubrics/result-block-format.md +0 -22
  56. package/src/skills/analyze-report/workflows/progress.md +0 -158
  57. package/src/skills/analyze-report/workflows/retrospective.md +0 -143
  58. package/src/skills/coach/README.md +0 -43
  59. package/src/skills/coach/SKILL.md.legacy +0 -157
  60. package/src/skills/coach/algorithms/gap-analysis.md +0 -69
  61. package/src/skills/coach/algorithms/improvement-prioritization.md +0 -62
  62. package/src/skills/coach/algorithms/skill-scoring.md +0 -80
  63. package/src/skills/coach/knowledge/audit-applied-changes-clean.txt +0 -11
  64. package/src/skills/coach/knowledge/backlog-management.md +0 -67
  65. package/src/skills/coach/knowledge/backlog-management.md.legacy +0 -90
  66. package/src/skills/coach/knowledge/common-antipatterns.md +0 -76
  67. package/src/skills/coach/knowledge/prompt-engineering.md +0 -45
  68. package/src/skills/coach/knowledge/shared-knowledge-guide.md +0 -44
  69. package/src/skills/coach/knowledge/skill-anatomy.md +0 -49
  70. package/src/skills/coach/knowledge/test-authorship.md +0 -141
  71. package/src/skills/coach/templates/audit-report.md +0 -39
  72. package/src/skills/coach/templates/coach-backlog-init.yaml +0 -14
  73. package/src/skills/coach/templates/coach-backlog-init.yaml.legacy +0 -10
  74. package/src/skills/coach/templates/improvement-plan.md +0 -42
  75. package/src/skills/coach/templates/new-skill.md +0 -95
  76. package/src/skills/coach/tests/cases/TC-COACH-001/current/claude-sonnet/trial-1.md +0 -58
  77. package/src/skills/coach/tests/cases/TC-COACH-001/current/claude-sonnet/trial-2.md +0 -65
  78. package/src/skills/coach/tests/cases/TC-COACH-001/current/claude-sonnet/trial-3.md +0 -58
  79. package/src/skills/coach/tests/cases/TC-COACH-001/current/judge.json +0 -151
  80. package/src/skills/coach/tests/cases/TC-COACH-001/current/kilo-deepseek/trial-1.md +0 -46
  81. package/src/skills/coach/tests/cases/TC-COACH-001/current/kilo-deepseek/trial-2.md +0 -0
  82. package/src/skills/coach/tests/cases/TC-COACH-001/current/kilo-deepseek/trial-3.md +0 -75
  83. package/src/skills/coach/tests/cases/TC-COACH-001/current/kilo-glm/trial-1.md +0 -81
  84. package/src/skills/coach/tests/cases/TC-COACH-001/current/kilo-glm/trial-2.md +0 -101
  85. package/src/skills/coach/tests/cases/TC-COACH-001/current/kilo-glm/trial-3.md +0 -91
  86. package/src/skills/coach/tests/cases/TC-COACH-001/current/kilo-minimax/trial-1.md +0 -48
  87. package/src/skills/coach/tests/cases/TC-COACH-001/current/kilo-minimax/trial-2.md +0 -30
  88. package/src/skills/coach/tests/cases/TC-COACH-001/current/kilo-minimax/trial-3.md +0 -55
  89. package/src/skills/coach/tests/cases/TC-COACH-001/current/meta.json +0 -94
  90. package/src/skills/coach/tests/cases/TC-COACH-001-evidence-based-temporal-diagram.yaml +0 -53
  91. package/src/skills/coach/tests/cases/TC-COACH-002/current/claude-sonnet/trial-1.md +0 -46
  92. package/src/skills/coach/tests/cases/TC-COACH-002/current/claude-sonnet/trial-2.md +0 -50
  93. package/src/skills/coach/tests/cases/TC-COACH-002/current/claude-sonnet/trial-3.md +0 -48
  94. package/src/skills/coach/tests/cases/TC-COACH-002/current/judge.json +0 -151
  95. package/src/skills/coach/tests/cases/TC-COACH-002/current/kilo-deepseek/trial-1.md +0 -0
  96. package/src/skills/coach/tests/cases/TC-COACH-002/current/kilo-deepseek/trial-2.md +0 -37
  97. package/src/skills/coach/tests/cases/TC-COACH-002/current/kilo-deepseek/trial-3.md +0 -30
  98. package/src/skills/coach/tests/cases/TC-COACH-002/current/kilo-glm/trial-1.md +0 -23
  99. package/src/skills/coach/tests/cases/TC-COACH-002/current/kilo-glm/trial-2.md +0 -29
  100. package/src/skills/coach/tests/cases/TC-COACH-002/current/kilo-glm/trial-3.md +0 -35
  101. package/src/skills/coach/tests/cases/TC-COACH-002/current/kilo-minimax/trial-1.md +0 -13
  102. package/src/skills/coach/tests/cases/TC-COACH-002/current/kilo-minimax/trial-2.md +0 -19
  103. package/src/skills/coach/tests/cases/TC-COACH-002/current/kilo-minimax/trial-3.md +0 -33
  104. package/src/skills/coach/tests/cases/TC-COACH-002/current/meta.json +0 -94
  105. package/src/skills/coach/tests/cases/TC-COACH-002-root-cause-first.yaml +0 -57
  106. package/src/skills/coach/tests/fixtures/pipeline-2026-04-06_id-collision.log +0 -77
  107. package/src/skills/coach/tests/index.yaml +0 -29
  108. package/src/skills/coach/tests/rubrics/calibration/evidence-based-bad.md +0 -13
  109. package/src/skills/coach/tests/rubrics/calibration/evidence-based-good.md +0 -29
  110. package/src/skills/coach/tests/rubrics/evidence-based.md +0 -26
  111. package/src/skills/coach/tests/rubrics/root-cause-first.md +0 -21
  112. package/src/skills/coach/workflows/analyze.md +0 -79
  113. package/src/skills/coach/workflows/analyze.md.legacy +0 -64
  114. package/src/skills/coach/workflows/audit.md +0 -74
  115. package/src/skills/coach/workflows/audit.md.legacy +0 -59
  116. package/src/skills/coach/workflows/create.md +0 -80
  117. package/src/skills/coach/workflows/create.md.legacy +0 -67
  118. package/src/skills/coach/workflows/improve.md +0 -71
  119. package/src/skills/coach/workflows/improve.md.legacy +0 -60
  120. package/src/skills/coach/workflows/research.md +0 -55
  121. package/src/skills/coach/workflows/review.md +0 -52
  122. package/src/skills/coach/workflows/review.md.legacy +0 -48
  123. package/src/skills/coach/workflows/test.md +0 -97
  124. package/src/skills/create-plan/README.md +0 -39
  125. package/src/skills/create-plan/algorithms/risk-assessment.md +0 -73
  126. package/src/skills/create-plan/knowledge/plan-completeness.md +0 -67
  127. package/src/skills/create-plan/knowledge/plan-lifecycle.md +0 -33
  128. package/src/skills/create-plan/knowledge/task-verification-pairs.md +0 -151
  129. package/src/skills/create-plan/knowledge/test-hygiene.md +0 -47
  130. package/src/skills/create-plan/scripts/validate-completeness.js +0 -182
  131. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-001/current/claude-sonnet/trial-1.md +0 -5
  132. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-001/current/claude-sonnet/trial-2.md +0 -39
  133. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-001/current/claude-sonnet/trial-3.md +0 -35
  134. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-001/current/judge.json +0 -167
  135. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-001/current/kilo-deepseek/trial-1.md +0 -5
  136. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-001/current/kilo-deepseek/trial-2.md +0 -10
  137. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-001/current/kilo-deepseek/trial-3.md +0 -5
  138. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-001/current/kilo-glm/trial-1.md +0 -26
  139. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-001/current/kilo-glm/trial-2.md +0 -86
  140. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-001/current/kilo-glm/trial-3.md +0 -5
  141. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-001/current/kilo-minimax/trial-1.md +0 -11
  142. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-001/current/kilo-minimax/trial-2.md +0 -15
  143. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-001/current/kilo-minimax/trial-3.md +0 -14
  144. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-001/current/meta.json +0 -119
  145. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-001-validate-completeness.yaml +0 -41
  146. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-002/current/claude-sonnet/trial-1.md +0 -25
  147. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-002/current/claude-sonnet/trial-2.md +0 -30
  148. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-002/current/claude-sonnet/trial-3.md +0 -37
  149. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-002/current/judge.json +0 -164
  150. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-002/current/kilo-deepseek/trial-1.md +0 -3
  151. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-002/current/kilo-deepseek/trial-2.md +0 -11
  152. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-002/current/kilo-deepseek/trial-3.md +0 -13
  153. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-002/current/kilo-glm/trial-1.md +0 -44
  154. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-002/current/kilo-glm/trial-2.md +0 -5
  155. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-002/current/kilo-glm/trial-3.md +0 -49
  156. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-002/current/kilo-minimax/trial-1.md +0 -6
  157. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-002/current/kilo-minimax/trial-2.md +0 -11
  158. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-002/current/kilo-minimax/trial-3.md +0 -16
  159. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-002/current/meta.json +0 -116
  160. package/src/skills/create-plan/tests/cases/TC-CREATE-PLAN-002-task-granularity.yaml +0 -39
  161. package/src/skills/create-plan/tests/index.yaml +0 -25
  162. package/src/skills/create-plan/tests/rubrics/task-granularity.md +0 -21
  163. package/src/skills/create-plan/tests/rubrics/validate-completeness.md +0 -21
  164. package/src/skills/create-plan/workflows/create.md +0 -136
  165. package/src/skills/create-report/README.md +0 -40
  166. package/src/skills/create-report/algorithms/metric-calculation.md +0 -93
  167. package/src/skills/create-report/knowledge/report-metrics.md +0 -82
  168. package/src/skills/create-report/scripts/calc-metrics.js +0 -383
  169. package/src/skills/create-report/tests/cases/TC-CREATE-REPORT-001/current/claude-sonnet/trial-1.md +0 -25
  170. package/src/skills/create-report/tests/cases/TC-CREATE-REPORT-001/current/claude-sonnet/trial-2.md +0 -26
  171. package/src/skills/create-report/tests/cases/TC-CREATE-REPORT-001/current/claude-sonnet/trial-3.md +0 -28
  172. package/src/skills/create-report/tests/cases/TC-CREATE-REPORT-001/current/judge.json +0 -163
  173. package/src/skills/create-report/tests/cases/TC-CREATE-REPORT-001/current/kilo-deepseek/trial-1.md +0 -4
  174. package/src/skills/create-report/tests/cases/TC-CREATE-REPORT-001/current/kilo-deepseek/trial-2.md +0 -3
  175. package/src/skills/create-report/tests/cases/TC-CREATE-REPORT-001/current/kilo-deepseek/trial-3.md +0 -6
  176. package/src/skills/create-report/tests/cases/TC-CREATE-REPORT-001/current/kilo-glm/trial-1.md +0 -8
  177. package/src/skills/create-report/tests/cases/TC-CREATE-REPORT-001/current/kilo-glm/trial-2.md +0 -12
  178. package/src/skills/create-report/tests/cases/TC-CREATE-REPORT-001/current/kilo-glm/trial-3.md +0 -7
  179. package/src/skills/create-report/tests/cases/TC-CREATE-REPORT-001/current/kilo-minimax/trial-1.md +0 -12
  180. package/src/skills/create-report/tests/cases/TC-CREATE-REPORT-001/current/kilo-minimax/trial-2.md +0 -22
  181. package/src/skills/create-report/tests/cases/TC-CREATE-REPORT-001/current/kilo-minimax/trial-3.md +0 -13
  182. package/src/skills/create-report/tests/cases/TC-CREATE-REPORT-001/current/meta.json +0 -115
  183. package/src/skills/create-report/tests/cases/TC-CREATE-REPORT-001-root-cause-attribution.yaml +0 -57
  184. package/src/skills/create-report/tests/index.yaml +0 -20
  185. package/src/skills/create-report/tests/rubrics/root-cause-attribution.md +0 -21
  186. package/src/skills/create-report/workflows/standard.md +0 -175
  187. package/src/skills/decompose-gaps/README.md +0 -39
  188. package/src/skills/decompose-gaps/algorithms/scope-check.md +0 -110
  189. package/src/skills/decompose-gaps/knowledge/scope-validation.md +0 -65
  190. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/claude-sonnet/trial-1.md +0 -41
  191. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/claude-sonnet/trial-2.md +0 -41
  192. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/claude-sonnet/trial-3.md +0 -56
  193. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/judge.json +0 -164
  194. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-deepseek/trial-1.md +0 -25
  195. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-deepseek/trial-2.md +0 -17
  196. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-deepseek/trial-3.md +0 -22
  197. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-glm/trial-1.md +0 -25
  198. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-glm/trial-2.md +0 -5
  199. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-glm/trial-3.md +0 -29
  200. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-minimax/trial-1.md +0 -27
  201. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-minimax/trial-2.md +0 -35
  202. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/kilo-minimax/trial-3.md +0 -18
  203. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001/current/meta.json +0 -116
  204. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-001-scope-exclusion.yaml +0 -46
  205. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/claude-sonnet/trial-1.md +0 -27
  206. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/claude-sonnet/trial-2.md +0 -30
  207. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/claude-sonnet/trial-3.md +0 -27
  208. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/judge.json +0 -163
  209. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-deepseek/trial-1.md +0 -0
  210. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-deepseek/trial-2.md +0 -15
  211. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-deepseek/trial-3.md +0 -7
  212. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-glm/trial-1.md +0 -21
  213. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-glm/trial-2.md +0 -38
  214. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-glm/trial-3.md +0 -16
  215. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-minimax/trial-1.md +0 -5
  216. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-minimax/trial-2.md +0 -10
  217. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/kilo-minimax/trial-3.md +0 -9
  218. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002/current/meta.json +0 -115
  219. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-002-glob-before-write.yaml +0 -36
  220. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/claude-sonnet/trial-1.md +0 -30
  221. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/claude-sonnet/trial-2.md +0 -30
  222. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/claude-sonnet/trial-3.md +0 -30
  223. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/judge.json +0 -165
  224. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-deepseek/trial-1.md +0 -5
  225. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-deepseek/trial-2.md +0 -26
  226. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-deepseek/trial-3.md +0 -5
  227. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-glm/trial-1.md +0 -39
  228. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-glm/trial-2.md +0 -37
  229. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-glm/trial-3.md +0 -45
  230. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-minimax/trial-1.md +0 -26
  231. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-minimax/trial-2.md +0 -27
  232. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/kilo-minimax/trial-3.md +0 -7
  233. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003/current/meta.json +0 -117
  234. package/src/skills/decompose-gaps/tests/cases/TC-DECOMPOSE-GAPS-003-parent-plan-mandatory.yaml +0 -41
  235. package/src/skills/decompose-gaps/tests/index.yaml +0 -30
  236. package/src/skills/decompose-gaps/tests/rubrics/glob-before-write.md +0 -21
  237. package/src/skills/decompose-gaps/tests/rubrics/parent-plan-mandatory.md +0 -22
  238. package/src/skills/decompose-gaps/tests/rubrics/scope-exclusion.md +0 -21
  239. package/src/skills/decompose-gaps/workflows/decompose.md +0 -123
  240. package/src/skills/decompose-plan/README.md +0 -43
  241. package/src/skills/decompose-plan/algorithms/deduplication.md +0 -101
  242. package/src/skills/decompose-plan/knowledge/atomicity-checklist.md +0 -139
  243. package/src/skills/decompose-plan/knowledge/capabilities.md +0 -68
  244. package/src/skills/decompose-plan/knowledge/human-task-rules.md +0 -82
  245. package/src/skills/decompose-plan/knowledge/scope-guard-checklist.md +0 -73
  246. package/src/skills/decompose-plan/scripts/check-atomicity-limit.js +0 -47
  247. package/src/skills/decompose-plan/scripts/check-duplicates.js +0 -323
  248. package/src/skills/decompose-plan/scripts/verify-atomicity.js +0 -408
  249. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-001/current/claude-sonnet/trial-1.md +0 -30
  250. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-001/current/claude-sonnet/trial-2.md +0 -36
  251. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-001/current/claude-sonnet/trial-3.md +0 -37
  252. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-001/current/judge.json +0 -163
  253. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-001/current/kilo-deepseek/trial-1.md +0 -20
  254. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-001/current/kilo-deepseek/trial-2.md +0 -17
  255. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-001/current/kilo-deepseek/trial-3.md +0 -28
  256. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-001/current/kilo-glm/trial-1.md +0 -114
  257. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-001/current/kilo-glm/trial-2.md +0 -137
  258. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-001/current/kilo-glm/trial-3.md +0 -188
  259. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-001/current/kilo-minimax/trial-1.md +0 -0
  260. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-001/current/kilo-minimax/trial-2.md +0 -32
  261. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-001/current/kilo-minimax/trial-3.md +0 -110
  262. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-001/current/meta.json +0 -115
  263. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-001-atomicity-no-1to1.yaml +0 -56
  264. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-002/current/claude-sonnet/trial-1.md +0 -47
  265. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-002/current/claude-sonnet/trial-2.md +0 -54
  266. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-002/current/claude-sonnet/trial-3.md +0 -43
  267. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-002/current/judge.json +0 -163
  268. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-002/current/kilo-deepseek/trial-1.md +0 -15
  269. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-002/current/kilo-deepseek/trial-2.md +0 -5
  270. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-002/current/kilo-deepseek/trial-3.md +0 -12
  271. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-002/current/kilo-glm/trial-1.md +0 -34
  272. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-002/current/kilo-glm/trial-2.md +0 -30
  273. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-002/current/kilo-glm/trial-3.md +0 -35
  274. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-002/current/kilo-minimax/trial-1.md +0 -0
  275. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-002/current/kilo-minimax/trial-2.md +0 -31
  276. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-002/current/kilo-minimax/trial-3.md +0 -0
  277. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-002/current/meta.json +0 -115
  278. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-002-get-next-id-mandatory.yaml +0 -44
  279. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-003/current/claude-sonnet/trial-1.md +0 -21
  280. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-003/current/claude-sonnet/trial-2.md +0 -38
  281. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-003/current/claude-sonnet/trial-3.md +0 -30
  282. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-003/current/judge.json +0 -163
  283. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-003/current/kilo-deepseek/trial-1.md +0 -31
  284. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-003/current/kilo-deepseek/trial-2.md +0 -35
  285. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-003/current/kilo-deepseek/trial-3.md +0 -48
  286. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-003/current/kilo-glm/trial-1.md +0 -167
  287. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-003/current/kilo-glm/trial-2.md +0 -62
  288. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-003/current/kilo-glm/trial-3.md +0 -174
  289. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-003/current/kilo-minimax/trial-1.md +0 -0
  290. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-003/current/kilo-minimax/trial-2.md +0 -0
  291. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-003/current/kilo-minimax/trial-3.md +0 -0
  292. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-003/current/meta.json +0 -115
  293. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-003-verbatim-dod-transfer.yaml +0 -42
  294. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/claude-sonnet/trial-1.md +0 -55
  295. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/claude-sonnet/trial-2.md +0 -49
  296. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/claude-sonnet/trial-3.md +0 -49
  297. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/judge.json +0 -163
  298. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-deepseek/trial-1.md +0 -104
  299. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-deepseek/trial-2.md +0 -45
  300. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-deepseek/trial-3.md +0 -58
  301. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-glm/trial-1.md +0 -193
  302. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-glm/trial-2.md +0 -202
  303. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-glm/trial-3.md +0 -155
  304. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-minimax/trial-1.md +0 -52
  305. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-minimax/trial-2.md +0 -17
  306. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/kilo-minimax/trial-3.md +0 -0
  307. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004/current/meta.json +0 -115
  308. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-004-executor-atomicity.yaml +0 -64
  309. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/claude-sonnet/trial-1.md +0 -59
  310. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/claude-sonnet/trial-2.md +0 -204
  311. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/claude-sonnet/trial-3.md +0 -213
  312. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/judge.json +0 -163
  313. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-deepseek/trial-1.md +0 -0
  314. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-deepseek/trial-2.md +0 -57
  315. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-deepseek/trial-3.md +0 -54
  316. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-glm/trial-1.md +0 -147
  317. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-glm/trial-2.md +0 -165
  318. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-glm/trial-3.md +0 -133
  319. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-minimax/trial-1.md +0 -81
  320. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-minimax/trial-2.md +0 -108
  321. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/kilo-minimax/trial-3.md +0 -3
  322. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005/current/meta.json +0 -114
  323. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-005-capabilities-registry.yaml +0 -78
  324. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/claude-sonnet/trial-1.md +0 -225
  325. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/claude-sonnet/trial-2.md +0 -66
  326. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/claude-sonnet/trial-3.md +0 -36
  327. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/judge.json +0 -163
  328. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-deepseek/trial-1.md +0 -42
  329. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-deepseek/trial-2.md +0 -67
  330. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-deepseek/trial-3.md +0 -40
  331. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-glm/trial-1.md +0 -122
  332. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-glm/trial-2.md +0 -131
  333. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-glm/trial-3.md +0 -138
  334. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-minimax/trial-1.md +0 -41
  335. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-minimax/trial-2.md +0 -88
  336. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/kilo-minimax/trial-3.md +0 -0
  337. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006/current/meta.json +0 -115
  338. package/src/skills/decompose-plan/tests/cases/TC-DECOMPOSE-PLAN-006-dod-threshold.yaml +0 -72
  339. package/src/skills/decompose-plan/tests/index.yaml +0 -45
  340. package/src/skills/decompose-plan/tests/rubrics/atomicity-no-1to1.md +0 -21
  341. package/src/skills/decompose-plan/tests/rubrics/capabilities-registry.md +0 -21
  342. package/src/skills/decompose-plan/tests/rubrics/dod-threshold.md +0 -21
  343. package/src/skills/decompose-plan/tests/rubrics/executor-atomicity.md +0 -21
  344. package/src/skills/decompose-plan/tests/rubrics/get-next-id-mandatory.md +0 -21
  345. package/src/skills/decompose-plan/tests/rubrics/verbatim-dod-transfer.md +0 -21
  346. package/src/skills/decompose-plan/workflows/decompose.md +0 -305
  347. package/src/skills/deep-research/README.md +0 -36
  348. package/src/skills/deep-research/algorithms/source-scoring.md +0 -63
  349. package/src/skills/deep-research/algorithms/synthesis.md +0 -67
  350. package/src/skills/deep-research/knowledge/data-validation.md +0 -44
  351. package/src/skills/deep-research/knowledge/perplexity-config.md +0 -30
  352. package/src/skills/deep-research/knowledge/research-methodology.md +0 -54
  353. package/src/skills/deep-research/knowledge/source-evaluation.md +0 -33
  354. package/src/skills/deep-research/scripts/perplexity-research.js +0 -315
  355. package/src/skills/deep-research/templates/brief-summary.md +0 -25
  356. package/src/skills/deep-research/templates/research-report.md +0 -76
  357. package/src/skills/deep-research/tests/cases/TC-DEEP-RESEARCH-001/current/claude-haiku/trial-1.md +0 -48
  358. package/src/skills/deep-research/tests/cases/TC-DEEP-RESEARCH-001/current/claude-haiku/trial-2.md +0 -88
  359. package/src/skills/deep-research/tests/cases/TC-DEEP-RESEARCH-001/current/claude-haiku/trial-3.md +0 -56
  360. package/src/skills/deep-research/tests/cases/TC-DEEP-RESEARCH-001/current/judge.json +0 -163
  361. package/src/skills/deep-research/tests/cases/TC-DEEP-RESEARCH-001/current/kilo-free/trial-1.md +0 -58
  362. package/src/skills/deep-research/tests/cases/TC-DEEP-RESEARCH-001/current/kilo-free/trial-2.md +0 -249
  363. package/src/skills/deep-research/tests/cases/TC-DEEP-RESEARCH-001/current/kilo-free/trial-3.md +0 -44
  364. package/src/skills/deep-research/tests/cases/TC-DEEP-RESEARCH-001/current/kilo-glm/trial-1.md +0 -96
  365. package/src/skills/deep-research/tests/cases/TC-DEEP-RESEARCH-001/current/kilo-glm/trial-2.md +0 -56
  366. package/src/skills/deep-research/tests/cases/TC-DEEP-RESEARCH-001/current/kilo-glm/trial-3.md +0 -94
  367. package/src/skills/deep-research/tests/cases/TC-DEEP-RESEARCH-001/current/kilo-glm-air/trial-1.md +0 -11
  368. package/src/skills/deep-research/tests/cases/TC-DEEP-RESEARCH-001/current/kilo-glm-air/trial-2.md +0 -1
  369. package/src/skills/deep-research/tests/cases/TC-DEEP-RESEARCH-001/current/kilo-glm-air/trial-3.md +0 -1
  370. package/src/skills/deep-research/tests/cases/TC-DEEP-RESEARCH-001/current/meta.json +0 -115
  371. package/src/skills/deep-research/tests/cases/TC-DEEP-RESEARCH-001-self-check-url.yaml +0 -58
  372. package/src/skills/deep-research/tests/index.yaml +0 -20
  373. package/src/skills/deep-research/tests/rubrics/self-check-url.md +0 -34
  374. package/src/skills/deep-research/workflows/base-checklist.md +0 -19
  375. package/src/skills/deep-research/workflows/benchmark.md +0 -38
  376. package/src/skills/deep-research/workflows/competitor.md +0 -44
  377. package/src/skills/deep-research/workflows/custom.md +0 -32
  378. package/src/skills/deep-research/workflows/market.md +0 -44
  379. package/src/skills/deep-research/workflows/technology.md +0 -40
  380. package/src/skills/deep-research/workflows/trend.md +0 -40
  381. package/src/skills/execute-task/README.md +0 -44
  382. package/src/skills/execute-task/algorithms/execution-strategy.md +0 -136
  383. package/src/skills/execute-task/knowledge/context-checkpoints.md +0 -75
  384. package/src/skills/execute-task/knowledge/ticket-structure.md +0 -70
  385. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-001/current/claude-haiku/trial-1.md +0 -5
  386. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-001/current/claude-haiku/trial-2.md +0 -5
  387. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-001/current/claude-haiku/trial-3.md +0 -5
  388. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-001/current/judge.json +0 -124
  389. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-001/current/kilo-free/trial-1.md +0 -4
  390. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-001/current/kilo-free/trial-2.md +0 -4
  391. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-001/current/kilo-free/trial-3.md +0 -4
  392. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-001/current/kilo-glm-air/trial-1.md +0 -4
  393. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-001/current/kilo-glm-air/trial-2.md +0 -4
  394. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-001/current/kilo-glm-air/trial-3.md +0 -11
  395. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-001/current/meta.json +0 -88
  396. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-001-no-ticket-creation.yaml +0 -48
  397. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-002/current/claude-haiku/trial-1.md +0 -5
  398. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-002/current/claude-haiku/trial-2.md +0 -6
  399. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-002/current/claude-haiku/trial-3.md +0 -5
  400. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-002/current/judge.json +0 -124
  401. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-002/current/kilo-free/trial-1.md +0 -4
  402. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-002/current/kilo-free/trial-2.md +0 -4
  403. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-002/current/kilo-free/trial-3.md +0 -8
  404. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-002/current/kilo-glm-air/trial-1.md +0 -9
  405. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-002/current/kilo-glm-air/trial-2.md +0 -26
  406. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-002/current/kilo-glm-air/trial-3.md +0 -4
  407. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-002/current/meta.json +0 -89
  408. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-002-no-duplicate-dod.yaml +0 -44
  409. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-003/current/claude-haiku/trial-1.md +0 -5
  410. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-003/current/claude-haiku/trial-2.md +0 -5
  411. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-003/current/claude-haiku/trial-3.md +0 -5
  412. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-003/current/judge.json +0 -46
  413. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-003/current/meta.json +0 -37
  414. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-003-verification-proportionality.yaml +0 -46
  415. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-004/current/claude-haiku/trial-1.md +0 -18
  416. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-004/current/claude-haiku/trial-2.md +0 -16
  417. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-004/current/claude-haiku/trial-3.md +0 -14
  418. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-004/current/judge.json +0 -124
  419. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-004/current/kilo-free/trial-1.md +0 -5
  420. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-004/current/kilo-free/trial-2.md +0 -5
  421. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-004/current/kilo-free/trial-3.md +0 -1
  422. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-004/current/kilo-glm-air/trial-1.md +0 -8
  423. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-004/current/kilo-glm-air/trial-2.md +0 -5
  424. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-004/current/kilo-glm-air/trial-3.md +0 -4
  425. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-004/current/meta.json +0 -89
  426. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-004-no-foreign-ticket-edit.yaml +0 -50
  427. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-005/current/claude-haiku/trial-1.md +0 -5
  428. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-005/current/claude-haiku/trial-2.md +0 -5
  429. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-005/current/claude-haiku/trial-3.md +0 -5
  430. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-005/current/judge.json +0 -124
  431. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-005/current/kilo-free/trial-1.md +0 -15
  432. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-005/current/kilo-free/trial-2.md +0 -4
  433. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-005/current/kilo-free/trial-3.md +0 -5
  434. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-005/current/kilo-glm-air/trial-1.md +0 -11
  435. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-005/current/kilo-glm-air/trial-2.md +0 -11
  436. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-005/current/kilo-glm-air/trial-3.md +0 -4
  437. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-005/current/meta.json +0 -88
  438. package/src/skills/execute-task/tests/cases/TC-EXECUTE-TASK-005-ticket-fields-updated.yaml +0 -39
  439. package/src/skills/execute-task/tests/fixtures/IMPL-902-create-file.md +0 -41
  440. package/src/skills/execute-task/tests/fixtures/IMPL-904-current-task.md +0 -40
  441. package/src/skills/execute-task/tests/fixtures/IMPL-906-fill-ticket.md +0 -42
  442. package/src/skills/execute-task/tests/fixtures/QA-901-button-click.md +0 -41
  443. package/src/skills/execute-task/tests/fixtures/QA-903-visual-figma.md +0 -40
  444. package/src/skills/execute-task/tests/fixtures/TASK-905-done-with-typo.md +0 -36
  445. package/src/skills/execute-task/tests/index.yaml +0 -39
  446. package/src/skills/execute-task/tests/rubrics/no-duplicate-dod.md +0 -22
  447. package/src/skills/execute-task/tests/rubrics/no-foreign-ticket-edit.md +0 -20
  448. package/src/skills/execute-task/tests/rubrics/no-ticket-creation.md +0 -21
  449. package/src/skills/execute-task/tests/rubrics/ticket-fields-updated.md +0 -23
  450. package/src/skills/execute-task/tests/rubrics/verification-proportionality.md +0 -22
  451. package/src/skills/execute-task/workflows/execute.md +0 -104
  452. package/src/skills/manual-testing/README.md +0 -63
  453. package/src/skills/manual-testing/algorithms/blocked-tool-strategy.md +0 -74
  454. package/src/skills/manual-testing/algorithms/bug-severity.md +0 -73
  455. package/src/skills/manual-testing/algorithms/mcp-budget.md +0 -97
  456. package/src/skills/manual-testing/algorithms/test-prioritization.md +0 -69
  457. package/src/skills/manual-testing/knowledge/browser-extension-testing.md +0 -102
  458. package/src/skills/manual-testing/knowledge/browser-tools.md +0 -114
  459. package/src/skills/manual-testing/knowledge/desktop-tools-advanced.md +0 -92
  460. package/src/skills/manual-testing/knowledge/desktop-tools-core.md +0 -76
  461. package/src/skills/manual-testing/knowledge/sandbox-advanced.md +0 -83
  462. package/src/skills/manual-testing/knowledge/sandbox-core.md +0 -67
  463. package/src/skills/manual-testing/knowledge/stateful-edge-cases.md +0 -69
  464. package/src/skills/manual-testing/knowledge/test-case-design.md +0 -107
  465. package/src/skills/manual-testing/knowledge/testing-types.md +0 -45
  466. package/src/skills/manual-testing/templates/bug-report.md +0 -52
  467. package/src/skills/manual-testing/templates/test-case.md +0 -34
  468. package/src/skills/manual-testing/templates/test-plan.md +0 -97
  469. package/src/skills/manual-testing/templates/test-session-report.md +0 -56
  470. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/claude-sonnet/trial-1.md +0 -34
  471. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/claude-sonnet/trial-2.md +0 -32
  472. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/claude-sonnet/trial-3.md +0 -30
  473. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/judge.json +0 -163
  474. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/kilo-deepseek/trial-1.md +0 -0
  475. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/kilo-deepseek/trial-2.md +0 -7
  476. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/kilo-deepseek/trial-3.md +0 -0
  477. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/kilo-glm/trial-1.md +0 -4
  478. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/kilo-glm/trial-2.md +0 -15
  479. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/kilo-glm/trial-3.md +0 -8
  480. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/kilo-minimax/trial-1.md +0 -5
  481. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/kilo-minimax/trial-2.md +0 -7
  482. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/kilo-minimax/trial-3.md +0 -7
  483. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001/current/meta.json +0 -114
  484. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-001-sandbox-mandatory.yaml +0 -38
  485. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/claude-sonnet/trial-1.md +0 -44
  486. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/claude-sonnet/trial-2.md +0 -32
  487. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/claude-sonnet/trial-3.md +0 -47
  488. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/judge.json +0 -163
  489. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/kilo-deepseek/trial-1.md +0 -19
  490. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/kilo-deepseek/trial-2.md +0 -15
  491. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/kilo-deepseek/trial-3.md +0 -24
  492. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/kilo-glm/trial-1.md +0 -19
  493. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/kilo-glm/trial-2.md +0 -13
  494. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/kilo-glm/trial-3.md +0 -18
  495. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/kilo-minimax/trial-1.md +0 -21
  496. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/kilo-minimax/trial-2.md +0 -15
  497. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/kilo-minimax/trial-3.md +0 -14
  498. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002/current/meta.json +0 -114
  499. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-002-visual-tc-screenshot.yaml +0 -37
  500. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003/current/claude-sonnet/trial-1.md +0 -76
  501. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003/current/claude-sonnet/trial-2.md +0 -71
  502. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003/current/claude-sonnet/trial-3.md +0 -85
  503. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003/current/judge.json +0 -46
  504. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003/current/meta.json +0 -36
  505. package/src/skills/manual-testing/tests/cases/TC-MANUAL-TESTING-003-qa-non-ui-assertion.yaml +0 -65
  506. package/src/skills/manual-testing/tests/index.yaml +0 -30
  507. package/src/skills/manual-testing/tests/last-run-tc001-sonnet.log +0 -140
  508. package/src/skills/manual-testing/tests/last-run-tc002.log +0 -1
  509. package/src/skills/manual-testing/tests/last-run.log +0 -1469
  510. package/src/skills/manual-testing/tests/rubrics/qa-non-ui-assertion.md +0 -31
  511. package/src/skills/manual-testing/tests/rubrics/sandbox-mandatory.md +0 -20
  512. package/src/skills/manual-testing/tests/rubrics/visual-tc-screenshot.md +0 -21
  513. package/src/skills/manual-testing/workflows/acceptance.md +0 -80
  514. package/src/skills/manual-testing/workflows/exploratory.md +0 -84
  515. package/src/skills/manual-testing/workflows/regression.md +0 -76
  516. package/src/skills/manual-testing/workflows/smoke.md +0 -109
  517. package/src/skills/manual-testing/workflows/test-plan.md +0 -75
  518. package/src/skills/review-result/README.md +0 -59
  519. package/src/skills/review-result/algorithms/verification.md +0 -112
  520. package/src/skills/review-result/knowledge/baseline-snapshot-validation.md +0 -67
  521. package/src/skills/review-result/knowledge/dod-patterns.md +0 -116
  522. package/src/skills/review-result/knowledge/test-hygiene.md +0 -44
  523. package/src/skills/review-result/scripts/verify-artifacts.js +0 -497
  524. package/src/skills/review-result/templates/verdict.md +0 -153
  525. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/claude-haiku/trial-1.md +0 -22
  526. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/claude-haiku/trial-2.md +0 -7
  527. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/claude-haiku/trial-3.md +0 -21
  528. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/claude-sonnet/trial-1.md +0 -6
  529. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/claude-sonnet/trial-2.md +0 -6
  530. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/claude-sonnet/trial-3.md +0 -6
  531. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/judge.json +0 -164
  532. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/kilo-deepseek/trial-1.md +0 -5
  533. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/kilo-deepseek/trial-2.md +0 -7
  534. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/kilo-deepseek/trial-3.md +0 -6
  535. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/kilo-glm/trial-1.md +0 -49
  536. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/kilo-glm/trial-2.md +0 -28
  537. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/kilo-glm/trial-3.md +0 -37
  538. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/kilo-minimax/trial-1.md +0 -22
  539. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/kilo-minimax/trial-2.md +0 -13
  540. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/kilo-minimax/trial-3.md +0 -21
  541. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001/current/meta.json +0 -116
  542. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-001-visual-tc-trigger.yaml +0 -51
  543. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/claude-haiku/trial-1.md +0 -23
  544. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/claude-haiku/trial-2.md +0 -22
  545. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/claude-haiku/trial-3.md +0 -28
  546. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/claude-sonnet/trial-1.md +0 -4
  547. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/claude-sonnet/trial-2.md +0 -4
  548. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/claude-sonnet/trial-3.md +0 -4
  549. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/judge.json +0 -163
  550. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/kilo-deepseek/trial-1.md +0 -4
  551. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/kilo-deepseek/trial-2.md +0 -0
  552. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/kilo-deepseek/trial-3.md +0 -4
  553. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/kilo-glm/trial-1.md +0 -39
  554. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/kilo-glm/trial-2.md +0 -25
  555. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/kilo-glm/trial-3.md +0 -32
  556. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/kilo-minimax/trial-1.md +0 -34
  557. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/kilo-minimax/trial-2.md +0 -8
  558. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/kilo-minimax/trial-3.md +0 -23
  559. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002/current/meta.json +0 -115
  560. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-002-path-line-suffix.yaml +0 -39
  561. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/claude-sonnet/trial-1.md +0 -40
  562. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/claude-sonnet/trial-2.md +0 -15
  563. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/claude-sonnet/trial-3.md +0 -7
  564. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/judge.json +0 -163
  565. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-deepseek/trial-1.md +0 -5
  566. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-deepseek/trial-2.md +0 -5
  567. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-deepseek/trial-3.md +0 -11
  568. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-glm/trial-1.md +0 -16
  569. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-glm/trial-2.md +0 -18
  570. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-glm/trial-3.md +0 -17
  571. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-minimax/trial-1.md +0 -17
  572. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-minimax/trial-2.md +0 -31
  573. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/kilo-minimax/trial-3.md +0 -5
  574. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003/current/meta.json +0 -115
  575. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-003-test-isolation.yaml +0 -50
  576. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-004/current/claude-sonnet/trial-1.md +0 -5
  577. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-004/current/claude-sonnet/trial-2.md +0 -5
  578. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-004/current/claude-sonnet/trial-3.md +0 -6
  579. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-004/current/judge.json +0 -46
  580. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-004/current/meta.json +0 -37
  581. package/src/skills/review-result/tests/cases/TC-REVIEW-RESULT-004-baseline-snapshot.yaml +0 -50
  582. package/src/skills/review-result/tests/fixtures/IMPL-902-path-with-line.md +0 -43
  583. package/src/skills/review-result/tests/fixtures/QA-901-visual-button.md +0 -46
  584. package/src/skills/review-result/tests/fixtures/QA-904-test-isolation-violation/QA-904.md +0 -51
  585. package/src/skills/review-result/tests/fixtures/QA-904-test-isolation-violation/example-test.mjs +0 -36
  586. package/src/skills/review-result/tests/fixtures/QA-905-baseline-regex-instead-of-snapshot/QA-905.md +0 -62
  587. package/src/skills/review-result/tests/fixtures/QA-905-baseline-regex-instead-of-snapshot/baseline.test.mjs +0 -124
  588. package/src/skills/review-result/tests/index.yaml +0 -35
  589. package/src/skills/review-result/tests/rubrics/baseline-snapshot.md +0 -20
  590. package/src/skills/review-result/tests/rubrics/path-line-suffix.md +0 -19
  591. package/src/skills/review-result/tests/rubrics/test-isolation.md +0 -20
  592. package/src/skills/review-result/tests/rubrics/visual-tc-trigger.md +0 -19
  593. package/src/skills/review-result/workflows/review.md +0 -209
@@ -1,125 +1,785 @@
1
1
  #!/usr/bin/env node
2
+
3
+ /**
4
+ * pick-next-task.js - Скрипт для выбора следующего тикета из директории ready/
5
+ *
6
+ * Использование:
7
+ * node pick-next-task.js
8
+ *
9
+ * Выводит результат в формате:
10
+ * ---RESULT---
11
+ * status: found
12
+ * ticket_id: IMPL-001
13
+ * ---RESULT---
14
+ *
15
+ * или если задач нет:
16
+ * ---RESULT---
17
+ * status: empty
18
+ * ---RESULT---
19
+ */
20
+
21
+ import fs from 'fs';
22
+ import path from 'path';
2
23
  import { findProjectRoot } from 'workflow-ai/lib/find-root.mjs';
3
- import { parseFrontmatter, printResult, normalizePlanId, extractPlanId, loadTicketMovementRules, checkAndClosePlan, getLastReviewStatus, serializeFrontmatter } from 'workflow-ai/lib/utils.mjs';
24
+ import { parseFrontmatter, printResult, normalizePlanId, extractPlanId, getLastReviewStatus, serializeFrontmatter, loadTicketMovementRules, checkAndClosePlan } from 'workflow-ai/lib/utils.mjs';
4
25
  import { createLogger } from 'workflow-ai/lib/logger.mjs';
5
- import { pickNextEffective } from 'workflow-ai/lib/operations/tickets.mjs';
6
- import fs from 'fs';
7
- import path from 'node:path';
8
26
 
9
27
  const logger = createLogger();
28
+
29
+ // Корень проекта
10
30
  const PROJECT_DIR = findProjectRoot();
11
- const WD = path.join(PROJECT_DIR, '.workflow');
12
- const TD = (d) => path.join(WD, 'tickets', d);
31
+ // Базовая директория workflow
32
+ const WORKFLOW_DIR = path.join(PROJECT_DIR, '.workflow');
33
+ const TICKETS_DIR = path.join(WORKFLOW_DIR, 'tickets');
34
+ const READY_DIR = path.join(TICKETS_DIR, 'ready');
35
+ const DONE_DIR = path.join(TICKETS_DIR, 'done');
36
+ const IN_PROGRESS_DIR = path.join(TICKETS_DIR, 'in-progress');
37
+ const BLOCKED_DIR = path.join(TICKETS_DIR, 'blocked');
38
+ const REVIEW_DIR = path.join(TICKETS_DIR, 'review');
39
+ const ARCHIVE_DIR = path.join(TICKETS_DIR, 'archive');
40
+ const BACKLOG_DIR = path.join(TICKETS_DIR, 'backlog');
41
+
42
+
43
+ /**
44
+ * Проверяет условие (condition) тикета
45
+ */
46
+ function checkCondition(condition) {
47
+ const { type, value } = condition;
48
+
49
+ switch (type) {
50
+ case 'file_exists':
51
+ const filePath = path.isAbsolute(value) ? value : path.join(PROJECT_DIR, value);
52
+ return fs.existsSync(filePath);
53
+
54
+ case 'file_not_exists':
55
+ const filePath2 = path.isAbsolute(value) ? value : path.join(PROJECT_DIR, value);
56
+ return !fs.existsSync(filePath2);
57
+
58
+ case 'tasks_completed':
59
+ // Проверяет, что указанные задачи выполнены (находятся в done/)
60
+ if (!value || (Array.isArray(value) && value.length === 0)) return true;
61
+ const ids = Array.isArray(value) ? value : [value];
62
+ return ids.every(taskId => {
63
+ const donePath = path.join(DONE_DIR, `${taskId}.md`);
64
+ const archivePath = path.join(ARCHIVE_DIR, `${taskId}.md`);
65
+ return fs.existsSync(donePath) || fs.existsSync(archivePath);
66
+ });
67
+
68
+ case 'date_after':
69
+ return new Date() > new Date(value);
70
+
71
+ case 'date_before':
72
+ return new Date() < new Date(value);
73
+
74
+ case 'manual_approval':
75
+ // Для ручного подтверждения всегда возвращаем false
76
+ // Требуется явное одобрение
77
+ return false;
78
+
79
+ default:
80
+ logger.warn(`Unknown condition type: ${type}`);
81
+ return true;
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Парсит секцию "## Ревью" тикета и возвращает все записи ревью.
87
+ * @param {string} content - Содержимое тикета
88
+ * @returns {Array<{date: string, status: string, comment: string}>}
89
+ */
90
+ function parseReviewSection(content) {
91
+ if (!content) return [];
92
+
93
+ const headerIdx = content.search(/^##\s*Ревью\s*$/m);
94
+ if (headerIdx === -1) return [];
95
+
96
+ const bodyStart = content.indexOf('\n', headerIdx);
97
+ if (bodyStart === -1) return [];
98
+
99
+ const nextH2 = content.indexOf('\n## ', bodyStart);
100
+ const reviewSection = (nextH2 === -1
101
+ ? content.slice(bodyStart + 1)
102
+ : content.slice(bodyStart + 1, nextH2)).trim();
103
+
104
+ const reviews = [];
105
+
106
+ const tableRows = reviewSection.split('\n').filter(line => line.trim().startsWith('|'));
107
+ if (tableRows.length >= 2) {
108
+ const dataRows = tableRows.slice(2).filter(row => {
109
+ const cells = row.split('|').map(c => c.trim()).filter(c => c);
110
+ return cells.length >= 2;
111
+ });
112
+
113
+ for (const row of dataRows) {
114
+ const cells = row.split('|').map(c => c.trim()).filter(c => c);
115
+ const date = cells[0] || '';
116
+ const statusRaw = cells[1]?.toLowerCase() || '';
117
+ const comment = cells[2] || '';
118
+ let status = null;
119
+ if (statusRaw.includes('passed')) status = 'passed';
120
+ else if (statusRaw.includes('failed')) status = 'failed';
121
+ else if (statusRaw.includes('skipped')) status = 'skipped';
122
+
123
+ if (status) {
124
+ reviews.push({ date, status, comment });
125
+ }
126
+ }
127
+ }
128
+
129
+ const listItems = reviewSection.split('\n').filter(line => line.trim().match(/^[-*]\s/));
130
+ for (const item of listItems) {
131
+ const trimmed = item.trim();
132
+ const dateMatch = trimmed.match(/^[-*]\s*(\d{4}-\d{2}-\d{2})/);
133
+ const statusMatch = trimmed.match(/:\s*(passed|failed|skipped)\b/i);
134
+ if (dateMatch && statusMatch) {
135
+ reviews.push({
136
+ date: dateMatch[1],
137
+ status: statusMatch[1].toLowerCase(),
138
+ comment: trimmed.replace(/^[-*]\s*\d{4}-\d{2}-\d{2}:\s*(passed|failed|skipped)\b/i, '').trim()
139
+ });
140
+ }
141
+ }
142
+
143
+ return reviews;
144
+ }
145
+
146
+ /**
147
+ * Вычисляет метрики ревью-итераций для всех тикетов
148
+ * @returns {object} Метрики: iterations, avgTimeToFirstPassed, failedVsPassed
149
+ */
150
+ function calculateReviewMetrics() {
151
+ const allDirs = [BACKLOG_DIR, READY_DIR, IN_PROGRESS_DIR, BLOCKED_DIR, REVIEW_DIR, DONE_DIR, ARCHIVE_DIR];
152
+ const ticketMetrics = {};
153
+ let totalFailed = 0;
154
+ let totalPassed = 0;
155
+ let firstPassedTimes = [];
156
+
157
+ for (const dir of allDirs) {
158
+ if (!fs.existsSync(dir)) continue;
159
+
160
+ const files = fs.readdirSync(dir).filter(f => f.endsWith('.md') && f !== '.gitkeep.md');
161
+
162
+ for (const file of files) {
163
+ const filePath = path.join(dir, file);
164
+ try {
165
+ const content = fs.readFileSync(filePath, 'utf8');
166
+ const { frontmatter } = parseFrontmatter(content);
167
+ const ticketId = frontmatter.id || file.replace('.md', '');
168
+
169
+ const reviews = parseReviewSection(content);
170
+ if (reviews.length === 0) continue;
171
+
172
+ ticketMetrics[ticketId] = reviews.length;
173
+
174
+ for (const review of reviews) {
175
+ if (review.status === 'failed') totalFailed++;
176
+ else if (review.status === 'passed') totalPassed++;
177
+ }
13
178
 
179
+ const firstPassed = reviews.find(r => r.status === 'passed');
180
+ if (firstPassed && firstPassed.date) {
181
+ const ticketCreated = new Date(frontmatter.created_at || '1970-01-01');
182
+ const passedDate = new Date(firstPassed.date);
183
+ const daysToPass = Math.floor((passedDate - ticketCreated) / (1000 * 60 * 60 * 24));
184
+ if (daysToPass >= 0) {
185
+ firstPassedTimes.push(daysToPass);
186
+ }
187
+ }
188
+ } catch (e) {
189
+ // Skip errors
190
+ }
191
+ }
192
+ }
193
+
194
+ const avgTimeToFirstPassed = firstPassedTimes.length > 0
195
+ ? Math.round(firstPassedTimes.reduce((a, b) => a + b, 0) / firstPassedTimes.length)
196
+ : null;
197
+
198
+ return {
199
+ iterations_per_ticket: ticketMetrics,
200
+ total_failed: totalFailed,
201
+ total_passed: totalPassed,
202
+ avg_time_to_first_passed_days: avgTimeToFirstPassed,
203
+ tickets_with_reviews: Object.keys(ticketMetrics).length
204
+ };
205
+ }
206
+
207
+ /**
208
+ * Проверяет зависимости тикета
209
+ */
210
+ function checkDependencies(dependencies) {
211
+ if (!dependencies || dependencies.length === 0) {
212
+ return true;
213
+ }
214
+
215
+ return dependencies.every(depId => {
216
+ const donePath = path.join(DONE_DIR, `${depId}.md`);
217
+ const archivePath = path.join(ARCHIVE_DIR, `${depId}.md`);
218
+ return fs.existsSync(donePath) || fs.existsSync(archivePath);
219
+ });
220
+ }
221
+
222
+ /**
223
+ * Авто-коррекция тикетов на основе статуса ревью.
224
+ * Сканирует все директории и перемещает тикеты по правилам из конфига.
225
+ *
226
+ * @param {object} config - Конфигурация правил перемещения
227
+ * @returns {object} Результат: { moved: Array<{id, from, to, reason}> }
228
+ */
14
229
  function autoCorrectTickets(config) {
15
230
  const moved = [];
16
- if (!config?.rules) return { moved };
17
- const dirMap = { backlog: 'backlog', ready: 'ready', in_progress: 'in-progress', blocked: 'blocked', review: 'review', done: 'done', archive: 'archive' };
18
- for (const [dirName, rules] of Object.entries(config.rules)) {
19
- const s = TD(dirMap[dirName]);
20
- if (!fs.existsSync(s)) continue;
21
- for (const f of fs.readdirSync(s).filter(x => x.endsWith('.md') && x !== '.gitkeep.md')) {
22
- const fp = path.join(s, f);
231
+
232
+ const dirMap = {
233
+ backlog: BACKLOG_DIR,
234
+ ready: READY_DIR,
235
+ in_progress: IN_PROGRESS_DIR,
236
+ blocked: BLOCKED_DIR,
237
+ review: REVIEW_DIR,
238
+ done: DONE_DIR,
239
+ archive: ARCHIVE_DIR
240
+ };
241
+
242
+ /**
243
+ * Перемещает тикет из одной директории в другую
244
+ */
245
+ function moveTicket(ticketId, fromDir, toDir, reason) {
246
+ const fromPath = path.join(fromDir, `${ticketId}.md`);
247
+ const toPath = path.join(toDir, `${ticketId}.md`);
248
+
249
+ if (!fs.existsSync(fromPath)) {
250
+ return false;
251
+ }
252
+
253
+ try {
254
+ const content = fs.readFileSync(fromPath, 'utf8');
255
+ const { frontmatter, body } = parseFrontmatter(content);
256
+
257
+ frontmatter.updated_at = new Date().toISOString();
258
+
259
+ if (toDir === DONE_DIR && !frontmatter.completed_at) {
260
+ frontmatter.completed_at = new Date().toISOString();
261
+ }
262
+
263
+ const newContent = serializeFrontmatter(frontmatter) + body;
264
+ fs.writeFileSync(toPath, newContent, 'utf8');
265
+
266
+ fs.unlinkSync(fromPath);
267
+
268
+ console.log(`[AUTO-CORRECT] ${ticketId}: ${path.basename(fromDir)} → ${path.basename(toDir)} (${reason})`);
269
+
270
+ moved.push({
271
+ id: ticketId,
272
+ from: path.basename(fromDir),
273
+ to: path.basename(toDir),
274
+ reason
275
+ });
276
+
277
+ return true;
278
+ } catch (e) {
279
+ logger.error(`Failed to move ticket ${ticketId}: ${e.message}`);
280
+ return false;
281
+ }
282
+ }
283
+
284
+ /**
285
+ * Обрабатывает тикеты в указанной директории
286
+ */
287
+ function processDirectory(dir, rules, dirName) {
288
+ if (!fs.existsSync(dir)) return;
289
+
290
+ const files = fs.readdirSync(dir)
291
+ .filter(f => f.endsWith('.md') && f !== '.gitkeep.md');
292
+
293
+ for (const file of files) {
294
+ const filePath = path.join(dir, file);
23
295
  try {
24
- const { frontmatter, body } = parseFrontmatter(fs.readFileSync(fp, 'utf8'));
25
- const tid = frontmatter.id || f.replace('.md', '');
26
- const rs = getLastReviewStatus(fs.readFileSync(fp, 'utf8'));
27
- for (const r of rules) {
28
- if ((r.condition === null ? rs === null : rs === r.condition)) {
29
- const td = TD(r.to_dir);
30
- const tp = path.join(td, `${tid}.md`);
31
- frontmatter.updated_at = new Date().toISOString();
32
- if (r.to_dir === 'done' && !frontmatter.completed_at) frontmatter.completed_at = new Date().toISOString();
33
- if (!fs.existsSync(td)) fs.mkdirSync(td, { recursive: true });
34
- fs.writeFileSync(tp, serializeFrontmatter(frontmatter) + body, 'utf8');
35
- fs.unlinkSync(fp);
36
- moved.push({ id: tid, from: dirMap[dirName], to: r.to_dir });
296
+ const content = fs.readFileSync(filePath, 'utf8');
297
+ const { frontmatter } = parseFrontmatter(content);
298
+ const ticketId = frontmatter.id || file.replace('.md', '');
299
+
300
+ const reviewStatus = getLastReviewStatus(content);
301
+
302
+ for (const rule of rules) {
303
+ const ruleCondition = rule.condition;
304
+ let shouldMove = false;
305
+
306
+ if (ruleCondition === null) {
307
+ shouldMove = reviewStatus === null;
308
+ } else {
309
+ shouldMove = reviewStatus === ruleCondition;
310
+ }
311
+
312
+ if (shouldMove) {
313
+ const targetDirName = rule.to_dir;
314
+ const targetDir = dirMap[targetDirName];
315
+ if (targetDir) {
316
+ moveTicket(ticketId, dir, targetDir, rule.reason);
317
+ }
37
318
  break;
38
319
  }
39
320
  }
40
- } catch (e) { logger.warn(`Failed ${f}: ${e.message}`); }
321
+ } catch (e) {
322
+ logger.warn(`Failed to process ticket ${file}: ${e.message}`);
323
+ }
41
324
  }
42
325
  }
326
+
327
+ if (!config || !config.rules) {
328
+ logger.error('Ticket movement rules config not loaded');
329
+ return { moved };
330
+ }
331
+
332
+ const rulesConfig = config.rules;
333
+
334
+ for (const [dirName, rules] of Object.entries(rulesConfig)) {
335
+ const dir = dirMap[dirName];
336
+ if (dir) {
337
+ processDirectory(dir, rules, dirName);
338
+ }
339
+ }
340
+
43
341
  return { moved };
44
342
  }
45
343
 
46
- function archiveTicketsOfArchivedPlans() {
47
- const ad = path.join(WD, 'plans', 'archive');
48
- if (!fs.existsSync(ad)) return { archived: [] };
49
- const aids = new Set(fs.readdirSync(ad).filter(f => f.endsWith('.md')).map(f => normalizePlanId(f)).filter(Boolean));
50
- if (!aids.size) return { archived: [] };
51
- const dd = TD('done');
52
- const adir = TD('archive');
53
- if (!fs.existsSync(dd)) return { archived: [] };
54
- const archived = [];
55
- for (const f of fs.readdirSync(dd).filter(x => x.endsWith('.md') && x !== '.gitkeep.md')) {
344
+ /**
345
+ * Считывает все тикеты из директории ready/
346
+ */
347
+ function readReadyTickets() {
348
+ if (!fs.existsSync(READY_DIR)) {
349
+ return [];
350
+ }
351
+
352
+ const files = fs.readdirSync(READY_DIR)
353
+ .filter(f => f.endsWith('.md') && f !== '.gitkeep.md');
354
+
355
+ const tickets = [];
356
+
357
+ for (const file of files) {
358
+ const filePath = path.join(READY_DIR, file);
56
359
  try {
57
- const { frontmatter, body } = parseFrontmatter(fs.readFileSync(path.join(dd, f), 'utf8'));
58
- const pid = normalizePlanId(frontmatter.parent_plan);
59
- if (!pid || !aids.has(pid)) continue;
60
- const tid = frontmatter.id || f.replace('.md', '');
61
- frontmatter.updated_at = frontmatter.archived_at = new Date().toISOString();
62
- if (!fs.existsSync(adir)) fs.mkdirSync(adir, { recursive: true });
63
- fs.writeFileSync(path.join(adir, f), serializeFrontmatter(frontmatter) + body, 'utf8');
64
- fs.unlinkSync(path.join(dd, f));
65
- archived.push(tid);
66
- } catch (e) {}
360
+ const content = fs.readFileSync(filePath, 'utf8');
361
+ const { frontmatter } = parseFrontmatter(content);
362
+
363
+ tickets.push({
364
+ id: frontmatter.id || file.replace('.md', ''),
365
+ frontmatter,
366
+ filePath
367
+ });
368
+ } catch (e) {
369
+ console.error(`[WARN] Failed to read ticket ${file}: ${e.message}`);
370
+ }
67
371
  }
68
- return { archived };
372
+
373
+ return tickets;
69
374
  }
70
375
 
71
- function calculateReviewMetrics() {
72
- const dirs = ['backlog', 'ready', 'in-progress', 'blocked', 'review', 'done', 'archive'].map(d => TD(d));
73
- const m = {}, tf = 0, tp = 0, fpt = [];
74
- for (const d of dirs) {
75
- if (!fs.existsSync(d)) continue;
76
- for (const f of fs.readdirSync(d).filter(x => x.endsWith('.md') && x !== '.gitkeep.md')) {
376
+ /**
377
+ * Считывает все тикеты из директории review/
378
+ */
379
+ function readReviewTickets() {
380
+ if (!fs.existsSync(path.join(TICKETS_DIR, 'review'))) {
381
+ return [];
382
+ }
383
+
384
+ const files = fs.readdirSync(path.join(TICKETS_DIR, 'review'))
385
+ .filter(f => f.endsWith('.md') && f !== '.gitkeep.md');
386
+
387
+ const tickets = [];
388
+
389
+ for (const file of files) {
390
+ const filePath = path.join(TICKETS_DIR, 'review', file);
391
+ try {
392
+ const content = fs.readFileSync(filePath, 'utf8');
393
+ const { frontmatter } = parseFrontmatter(content);
394
+
395
+ tickets.push({
396
+ id: frontmatter.id || file.replace('.md', ''),
397
+ frontmatter,
398
+ filePath
399
+ });
400
+ } catch (e) {
401
+ console.error(`[WARN] Failed to read ticket ${file}: ${e.message}`);
402
+ }
403
+ }
404
+
405
+ return tickets;
406
+ }
407
+
408
+ /**
409
+ * Считывает все тикеты из директории in-progress/
410
+ */
411
+ function readInProgressTickets() {
412
+ if (!fs.existsSync(IN_PROGRESS_DIR)) {
413
+ return [];
414
+ }
415
+
416
+ const files = fs.readdirSync(IN_PROGRESS_DIR)
417
+ .filter(f => f.endsWith('.md') && f !== '.gitkeep.md');
418
+
419
+ const tickets = [];
420
+
421
+ for (const file of files) {
422
+ const filePath = path.join(IN_PROGRESS_DIR, file);
423
+ try {
424
+ const content = fs.readFileSync(filePath, 'utf8');
425
+ const { frontmatter } = parseFrontmatter(content);
426
+
427
+ tickets.push({
428
+ id: frontmatter.id || file.replace('.md', ''),
429
+ frontmatter,
430
+ filePath
431
+ });
432
+ } catch (e) {
433
+ console.error(`[WARN] Failed to read in-progress ticket ${file}: ${e.message}`);
434
+ }
435
+ }
436
+
437
+ return tickets;
438
+ }
439
+
440
+ /**
441
+ * Проверяет, заполнен ли раздел результатов (Summary) в тикете
442
+ */
443
+ function hasFilledResult(body) {
444
+ const resultSectionRegex = /^##\s*(Результат выполнения|Result)\s*$/m;
445
+ const sectionStart = body.search(resultSectionRegex);
446
+
447
+ if (sectionStart === -1) {
448
+ return false;
449
+ }
450
+
451
+ const nextSectionRegex = /^##\s+/gm;
452
+ nextSectionRegex.lastIndex = sectionStart + 1;
453
+ const nextSectionMatch = nextSectionRegex.exec(body);
454
+ const sectionEnd = nextSectionMatch ? nextSectionMatch.index : body.length;
455
+
456
+ const sectionContent = body.substring(sectionStart, sectionEnd);
457
+
458
+ const summaryRegex = /^###\s*(Summary|Что сделано)\s*$/m;
459
+ const summaryStart = sectionContent.search(summaryRegex);
460
+
461
+ if (summaryStart === -1) {
462
+ return false;
463
+ }
464
+
465
+ const nextSubsectionRegex = /^###\s+/gm;
466
+ nextSubsectionRegex.lastIndex = summaryStart + 1;
467
+ const nextSubsectionMatch = nextSubsectionRegex.exec(sectionContent);
468
+ const summaryEnd = nextSubsectionMatch ? nextSubsectionMatch.index : sectionContent.length;
469
+
470
+ const summaryContent = sectionContent.substring(summaryStart, summaryEnd);
471
+ const withoutComments = summaryContent.replace(/<!--[\s\S]*?-->/g, '').trim();
472
+
473
+ return withoutComments.length > 0;
474
+ }
475
+
476
+ /**
477
+ * Находит завершённые тикеты в in-progress/ (с заполненным Summary)
478
+ * Возвращает массив id тикетов
479
+ */
480
+ function findCompletedInProgress() {
481
+ if (!fs.existsSync(IN_PROGRESS_DIR)) {
482
+ return [];
483
+ }
484
+
485
+ const files = fs.readdirSync(IN_PROGRESS_DIR)
486
+ .filter(f => f.endsWith('.md') && f !== '.gitkeep.md');
487
+
488
+ const completed = [];
489
+
490
+ for (const file of files) {
491
+ const filePath = path.join(IN_PROGRESS_DIR, file);
492
+ try {
493
+ const content = fs.readFileSync(filePath, 'utf8');
494
+ const { frontmatter, body } = parseFrontmatter(content);
495
+
496
+ if (!hasFilledResult(body)) {
497
+ continue;
498
+ }
499
+
500
+ completed.push({
501
+ id: frontmatter.id || file.replace('.md', ''),
502
+ frontmatter,
503
+ filePath
504
+ });
505
+ } catch (e) {
506
+ console.error(`[WARN] Failed to read in-progress ticket ${file}: ${e.message}`);
507
+ }
508
+ }
509
+
510
+ return completed;
511
+ }
512
+
513
+ /**
514
+ * Выбирает следующий тикет для выполнения
515
+ */
516
+ function filterByPlan(tickets, planId) {
517
+ if (!planId) return tickets;
518
+ return tickets.filter(t => normalizePlanId(t.frontmatter.parent_plan) === planId);
519
+ }
520
+
521
+ function pickNextTicket(planId) {
522
+ const tickets = filterByPlan(readReadyTickets(), planId);
523
+
524
+ if (tickets.length === 0) {
525
+ // Если ready/ пуст, проверяем review/ — нужно завершить ревью
526
+ let reviewTickets = filterByPlan(readReviewTickets(), planId);
527
+
528
+ if (reviewTickets.length === 0) {
529
+ // Нет тикетов ни в ready/, ни в review/ — проверяем in-progress/
530
+ // на завершённые тикеты (с заполненным Summary)
531
+ const completedInProgress = filterByPlan(findCompletedInProgress(), planId);
532
+ if (completedInProgress.length > 0) {
533
+ const first = completedInProgress[0];
534
+ logger.info(`Found completed ticket in in-progress/: ${first.id}`);
535
+ return {
536
+ status: 'completed_in_progress',
537
+ ticket_id: first.id
538
+ };
539
+ }
540
+
541
+ // Нет завершённых — проверяем незавершённые тикеты в in-progress/
542
+ const allInProgress = filterByPlan(readInProgressTickets(), planId);
543
+ if (allInProgress.length > 0) {
544
+ const first = allInProgress[0];
545
+ logger.info(`Found incomplete ticket in in-progress/: ${first.id}`);
546
+ return {
547
+ status: 'in_progress',
548
+ ticket_id: first.id,
549
+ priority: first.frontmatter.priority,
550
+ title: first.frontmatter.title,
551
+ type: first.frontmatter.type,
552
+ required_capabilities: JSON.stringify(first.frontmatter.required_capabilities || [])
553
+ };
554
+ }
555
+ }
556
+
557
+ if (reviewTickets.length > 0) {
558
+ return {
559
+ status: 'in_review',
560
+ ticket_id: reviewTickets[0].id,
561
+ priority: reviewTickets[0].frontmatter.priority,
562
+ title: reviewTickets[0].frontmatter.title,
563
+ type: reviewTickets[0].frontmatter.type,
564
+ required_capabilities: JSON.stringify(reviewTickets[0].frontmatter.required_capabilities || [])
565
+ };
566
+ }
567
+ return { status: 'empty', reason: 'No tickets in ready/' };
568
+ }
569
+
570
+ // Фильтрация по условиям и зависимостям
571
+ const eligibleTickets = tickets.filter(ticket => {
572
+ const { frontmatter } = ticket;
573
+
574
+ // Пропускаем тикеты, требующие ручного выполнения
575
+ if (frontmatter.type === 'human') {
576
+ logger.info(`Skipping ticket ${ticket.id}: type is 'human' (requires manual execution)`);
577
+ return false;
578
+ }
579
+
580
+ // Проверка условий
581
+ const conditions = frontmatter.conditions || [];
582
+ const conditionsMet = conditions.every(checkCondition);
583
+ if (!conditionsMet) {
584
+ return false;
585
+ }
586
+
587
+ // Проверка зависимостей
588
+ const dependencies = frontmatter.dependencies || [];
589
+ const depsMet = checkDependencies(dependencies);
590
+ if (!depsMet) {
591
+ return false;
592
+ }
593
+
594
+ // Обнаружение и удаление дубликатов: тикет не должен существовать в других колонках
595
+ const ticketFileName = `${ticket.id}.md`;
596
+ const otherDirs = [DONE_DIR, IN_PROGRESS_DIR, REVIEW_DIR, BLOCKED_DIR];
597
+ const duplicateDir = otherDirs.find(dir =>
598
+ fs.existsSync(path.join(dir, ticketFileName))
599
+ );
600
+ if (duplicateDir) {
601
+ const dirName = path.basename(duplicateDir);
602
+ logger.warn(`Duplicate detected: ${ticket.id} exists in ready/ and ${dirName}/. Moving ready/ copy to archive/`);
603
+ const archivePath = path.join(ARCHIVE_DIR, ticketFileName);
77
604
  try {
78
- const fp = path.join(d, f);
79
- const { frontmatter } = parseFrontmatter(fs.readFileSync(fp, 'utf8'));
80
- const content = fs.readFileSync(fp, 'utf8');
81
- const hi = content.search(/^##\s*Ревью\s*$/m);
82
- if (hi === -1) continue;
83
- const r = content.substring(hi).split('\n## ')[0].split('\n').filter(l => l.includes('|') && l.includes('passed'));
84
- if (!r.length) continue;
85
- const tid = frontmatter.id || f.replace('.md', '');
86
- m[tid] = r.length;
87
- tp += r.length;
88
- const firstPassDate = r.find(l => l.includes('passed'))?.split('|')[1]?.trim();
89
- // Note: simplified date extraction — actual test uses table parsing
90
- } catch (e) {}
91
- }
92
- }
93
- return { iterations_per_ticket: m, total_failed: tf, total_passed: tp, avg_time_to_first_passed_days: null, tickets_with_reviews: Object.keys(m).length };
605
+ fs.mkdirSync(ARCHIVE_DIR, { recursive: true });
606
+ fs.renameSync(ticket.filePath, archivePath);
607
+ } catch (err) {
608
+ logger.error(`Failed to archive duplicate ${ticket.id}: ${err.message}`);
609
+ }
610
+ return false;
611
+ }
612
+
613
+ return true;
614
+ });
615
+
616
+ if (eligibleTickets.length === 0) {
617
+ return {
618
+ status: 'empty',
619
+ reason: 'No eligible tickets (conditions/dependencies not met)'
620
+ };
621
+ }
622
+
623
+ // Сортировка по приоритету (меньше = важнее), затем по created_at
624
+ eligibleTickets.sort((a, b) => {
625
+ const priorityA = a.frontmatter.priority || 999;
626
+ const priorityB = b.frontmatter.priority || 999;
627
+
628
+ if (priorityA !== priorityB) {
629
+ return priorityA - priorityB;
630
+ }
631
+
632
+ // При равном приоритете - по дате создания (старые первые)
633
+ const dateA = new Date(a.frontmatter.created_at || '9999-12-31');
634
+ const dateB = new Date(b.frontmatter.created_at || '9999-12-31');
635
+ return dateA - dateB;
636
+ });
637
+
638
+ const selected = eligibleTickets[0];
639
+
640
+ return {
641
+ status: 'found',
642
+ ticket_id: selected.id,
643
+ priority: selected.frontmatter.priority,
644
+ title: selected.frontmatter.title,
645
+ type: selected.frontmatter.type,
646
+ required_capabilities: JSON.stringify(selected.frontmatter.required_capabilities || [])
647
+ };
94
648
  }
95
649
 
650
+ /**
651
+ * Архивирует все done-тикеты, принадлежащие архивным планам (plans/archive/).
652
+ * Сканирует все планы в plans/archive/, находит их тикеты в done/ и перемещает в archive/.
653
+ */
654
+ function archiveTicketsOfArchivedPlans() {
655
+ const archivedPlansDir = path.join(WORKFLOW_DIR, 'plans', 'archive');
656
+ if (!fs.existsSync(archivedPlansDir)) return { archived: [] };
657
+
658
+ // Собираем ID всех архивных планов
659
+ const archivedPlanIds = new Set();
660
+ const planFiles = fs.readdirSync(archivedPlansDir).filter(f => f.endsWith('.md'));
661
+ for (const file of planFiles) {
662
+ const id = normalizePlanId(file);
663
+ if (id) archivedPlanIds.add(id);
664
+ }
665
+
666
+ if (archivedPlanIds.size === 0) return { archived: [] };
667
+
668
+ if (!fs.existsSync(DONE_DIR)) return { archived: [] };
669
+
670
+ if (!fs.existsSync(ARCHIVE_DIR)) {
671
+ fs.mkdirSync(ARCHIVE_DIR, { recursive: true });
672
+ }
673
+
674
+ const archived = [];
675
+ const files = fs.readdirSync(DONE_DIR).filter(f => f.endsWith('.md') && f !== '.gitkeep.md');
676
+
677
+ for (const file of files) {
678
+ const filePath = path.join(DONE_DIR, file);
679
+ try {
680
+ const content = fs.readFileSync(filePath, 'utf8');
681
+ const { frontmatter, body } = parseFrontmatter(content);
682
+ const ticketPlanId = normalizePlanId(frontmatter.parent_plan);
683
+
684
+ if (!ticketPlanId || !archivedPlanIds.has(ticketPlanId)) continue;
685
+
686
+ const ticketId = frontmatter.id || file.replace('.md', '');
687
+
688
+ frontmatter.updated_at = new Date().toISOString();
689
+ frontmatter.archived_at = new Date().toISOString();
690
+
691
+ const destPath = path.join(ARCHIVE_DIR, file);
692
+ fs.writeFileSync(destPath, serializeFrontmatter(frontmatter) + body, 'utf8');
693
+ fs.unlinkSync(filePath);
694
+
695
+ archived.push(ticketId);
696
+ logger.info(`[ARCHIVE] ${ticketId}: done → archive (plan ${ticketPlanId} is archived)`);
697
+ } catch (e) {
698
+ logger.warn(`Failed to archive ticket ${file}: ${e.message}`);
699
+ }
700
+ }
701
+
702
+ return { archived };
703
+ }
704
+
705
+ // Main entry point
96
706
  async function main() {
97
707
  const planId = extractPlanId();
98
- if (planId) logger.info(`Filtering by plan_id: ${planId}`);
99
- let mcfg = null;
708
+
709
+ if (planId) {
710
+ logger.info(`Filtering by plan_id: ${planId}`);
711
+ }
712
+
713
+ const configPath = path.join(WORKFLOW_DIR, 'config', 'ticket-movement-rules.yaml');
714
+ let movementConfig = null;
100
715
  try {
101
- mcfg = loadTicketMovementRules(path.join(WD, 'config', 'ticket-movement-rules.yaml'));
716
+ movementConfig = loadTicketMovementRules(configPath);
102
717
  logger.info('Loaded ticket movement rules from config');
103
- } catch (e) { logger.warn(`Failed to load config: ${e.message}`); }
718
+ } catch (e) {
719
+ logger.warn(`Failed to load ticket movement config: ${e.message}`);
720
+ }
721
+
104
722
  logger.info('Running auto-correction...');
105
- const cr = autoCorrectTickets(mcfg);
106
- if (cr.moved.length > 0) logger.info(`Auto-corrected ${cr.moved.length} ticket(s)`);
107
- const ar = archiveTicketsOfArchivedPlans();
108
- if (ar.archived.length > 0) logger.info(`Archived ${ar.archived.length} ticket(s)`);
723
+ const correctionResult = autoCorrectTickets(movementConfig);
724
+ if (correctionResult.moved.length > 0) {
725
+ logger.info(`Auto-corrected ${correctionResult.moved.length} ticket(s)`);
726
+ }
727
+
728
+ // Архивируем done-тикеты архивных планов
729
+ const archiveResult = archiveTicketsOfArchivedPlans();
730
+ if (archiveResult.archived.length > 0) {
731
+ logger.info(`Archived ${archiveResult.archived.length} ticket(s) from archived plans: ${archiveResult.archived.join(', ')}`);
732
+ }
733
+
109
734
  if (planId) {
110
- const cl = checkAndClosePlan(WD, planId);
111
- if (cl.closed) logger.info(`Plan ${planId} closed: all ${cl.total} done`);
112
- else if (cl.total > 0) logger.info(`Plan ${planId}: ${cl.done}/${cl.total} done`);
113
- }
114
- logger.info('Scanning for next ticket...');
115
- const result = await pickNextEffective(PROJECT_DIR, planId);
116
- if (result.status === 'found') logger.info(`Selected: ${result.ticket_id} (${result.title})`);
117
- else logger.info(`Status: ${result.status}`);
118
- const rm = calculateReviewMetrics();
119
- const md = path.join(WD, 'metrics');
120
- if (!fs.existsSync(md)) fs.mkdirSync(md, { recursive: true });
121
- fs.writeFileSync(path.join(md, 'review-metrics.json'), JSON.stringify(rm, null, 2), 'utf8');
122
- printResult({ ...result, auto_corrected: cr.moved.length, moved_tickets: cr.moved.map(x => x.id).join(','), review_metrics: rm });
123
- if (result.status === 'empty') process.exit(0);
735
+ const closeResult = checkAndClosePlan(WORKFLOW_DIR, planId);
736
+ if (closeResult.closed) {
737
+ logger.info(`Plan ${planId} closed: all ${closeResult.total} tickets done`);
738
+ } else if (closeResult.total > 0) {
739
+ logger.info(`Plan ${planId} progress: ${closeResult.done}/${closeResult.total} tickets done`);
740
+ }
741
+ }
742
+
743
+ logger.info(`Scanning ready/ directory: ${READY_DIR}`);
744
+
745
+ const result = pickNextTicket(planId);
746
+
747
+ if (result.status === 'found') {
748
+ logger.info(`Selected ticket: ${result.ticket_id} (${result.title})`);
749
+ logger.info(`Priority: ${result.priority}, Type: ${result.type}`);
750
+ } else {
751
+ logger.info(result.reason);
752
+ }
753
+
754
+ logger.info('Calculating review metrics...');
755
+ const reviewMetrics = calculateReviewMetrics();
756
+ logger.info(`Found ${reviewMetrics.tickets_with_reviews} tickets with reviews`);
757
+ logger.info(`Total failed: ${reviewMetrics.total_failed}, passed: ${reviewMetrics.total_passed}`);
758
+
759
+ const metricsDir = path.join(WORKFLOW_DIR, 'metrics');
760
+ if (!fs.existsSync(metricsDir)) {
761
+ fs.mkdirSync(metricsDir, { recursive: true });
762
+ }
763
+ const metricsFile = path.join(metricsDir, 'review-metrics.json');
764
+ fs.writeFileSync(metricsFile, JSON.stringify(reviewMetrics, null, 2), 'utf8');
765
+ logger.info(`Metrics saved to ${metricsFile}`);
766
+
767
+ const finalResult = {
768
+ ...result,
769
+ auto_corrected: correctionResult.moved.length,
770
+ moved_tickets: correctionResult.moved.map(m => m.id).join(','),
771
+ review_metrics: JSON.stringify(reviewMetrics)
772
+ };
773
+
774
+ printResult(finalResult);
775
+
776
+ if (result.status === 'empty') {
777
+ process.exit(0);
778
+ }
124
779
  }
125
- main().catch(e => { logger.error(e.message); printResult({ status: 'error', error: e.message }); process.exit(1); });
780
+
781
+ main().catch(e => {
782
+ logger.error(e.message);
783
+ printResult({ status: 'error', error: e.message });
784
+ process.exit(1);
785
+ });