workflow-ai 1.1.0 → 1.3.0

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