task-o-matic-core 0.1.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 (447) hide show
  1. package/README.md +646 -0
  2. package/dist/index.d.ts +27 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +46 -0
  5. package/dist/lib/ai-service/ai-operations.d.ts +45 -0
  6. package/dist/lib/ai-service/ai-operations.d.ts.map +1 -0
  7. package/dist/lib/ai-service/ai-operations.js +60 -0
  8. package/dist/lib/ai-service/base-operations.d.ts +43 -0
  9. package/dist/lib/ai-service/base-operations.d.ts.map +1 -0
  10. package/dist/lib/ai-service/base-operations.js +119 -0
  11. package/dist/lib/ai-service/documentation-operations.d.ts +18 -0
  12. package/dist/lib/ai-service/documentation-operations.d.ts.map +1 -0
  13. package/dist/lib/ai-service/documentation-operations.js +308 -0
  14. package/dist/lib/ai-service/filesystem-tools.d.ts +69 -0
  15. package/dist/lib/ai-service/filesystem-tools.d.ts.map +1 -0
  16. package/dist/lib/ai-service/filesystem-tools.js +70 -0
  17. package/dist/lib/ai-service/json-parser.d.ts +34 -0
  18. package/dist/lib/ai-service/json-parser.d.ts.map +1 -0
  19. package/dist/lib/ai-service/json-parser.js +177 -0
  20. package/dist/lib/ai-service/mcp-client.d.ts +9 -0
  21. package/dist/lib/ai-service/mcp-client.d.ts.map +1 -0
  22. package/dist/lib/ai-service/mcp-client.js +48 -0
  23. package/dist/lib/ai-service/model-provider.d.ts +12 -0
  24. package/dist/lib/ai-service/model-provider.d.ts.map +1 -0
  25. package/dist/lib/ai-service/model-provider.js +146 -0
  26. package/dist/lib/ai-service/prd-operations.d.ts +25 -0
  27. package/dist/lib/ai-service/prd-operations.d.ts.map +1 -0
  28. package/dist/lib/ai-service/prd-operations.js +592 -0
  29. package/dist/lib/ai-service/research-tools.d.ts +4 -0
  30. package/dist/lib/ai-service/research-tools.d.ts.map +1 -0
  31. package/dist/lib/ai-service/research-tools.js +8 -0
  32. package/dist/lib/ai-service/retry-handler.d.ts +8 -0
  33. package/dist/lib/ai-service/retry-handler.d.ts.map +1 -0
  34. package/dist/lib/ai-service/retry-handler.js +63 -0
  35. package/dist/lib/ai-service/task-operations.d.ts +13 -0
  36. package/dist/lib/ai-service/task-operations.d.ts.map +1 -0
  37. package/dist/lib/ai-service/task-operations.js +220 -0
  38. package/dist/lib/benchmark/registry.d.ts +11 -0
  39. package/dist/lib/benchmark/registry.d.ts.map +1 -0
  40. package/dist/lib/benchmark/registry.js +212 -0
  41. package/dist/lib/benchmark/runner.d.ts +6 -0
  42. package/dist/lib/benchmark/runner.d.ts.map +1 -0
  43. package/dist/lib/benchmark/runner.js +150 -0
  44. package/dist/lib/benchmark/storage.d.ts +13 -0
  45. package/dist/lib/benchmark/storage.d.ts.map +1 -0
  46. package/dist/lib/benchmark/storage.js +100 -0
  47. package/dist/lib/benchmark/types.d.ts +104 -0
  48. package/dist/lib/benchmark/types.d.ts.map +1 -0
  49. package/dist/lib/benchmark/types.js +2 -0
  50. package/dist/lib/better-t-stack-cli.d.ts +50 -0
  51. package/dist/lib/better-t-stack-cli.d.ts.map +1 -0
  52. package/dist/lib/better-t-stack-cli.js +428 -0
  53. package/dist/lib/bootstrap/cli-bootstrap.d.ts +14 -0
  54. package/dist/lib/bootstrap/cli-bootstrap.d.ts.map +1 -0
  55. package/dist/lib/bootstrap/cli-bootstrap.js +322 -0
  56. package/dist/lib/bootstrap/index.d.ts +3 -0
  57. package/dist/lib/bootstrap/index.d.ts.map +1 -0
  58. package/dist/lib/bootstrap/index.js +18 -0
  59. package/dist/lib/bootstrap/medusa-bootstrap.d.ts +14 -0
  60. package/dist/lib/bootstrap/medusa-bootstrap.d.ts.map +1 -0
  61. package/dist/lib/bootstrap/medusa-bootstrap.js +215 -0
  62. package/dist/lib/config-validation.d.ts +215 -0
  63. package/dist/lib/config-validation.d.ts.map +1 -0
  64. package/dist/lib/config-validation.js +254 -0
  65. package/dist/lib/config.d.ts +55 -0
  66. package/dist/lib/config.d.ts.map +1 -0
  67. package/dist/lib/config.js +351 -0
  68. package/dist/lib/context-builder.d.ts +66 -0
  69. package/dist/lib/context-builder.d.ts.map +1 -0
  70. package/dist/lib/context-builder.js +322 -0
  71. package/dist/lib/executors/claude-code-executor.d.ts +9 -0
  72. package/dist/lib/executors/claude-code-executor.d.ts.map +1 -0
  73. package/dist/lib/executors/claude-code-executor.js +69 -0
  74. package/dist/lib/executors/codex-executor.d.ts +9 -0
  75. package/dist/lib/executors/codex-executor.d.ts.map +1 -0
  76. package/dist/lib/executors/codex-executor.js +73 -0
  77. package/dist/lib/executors/executor-factory.d.ts +5 -0
  78. package/dist/lib/executors/executor-factory.d.ts.map +1 -0
  79. package/dist/lib/executors/executor-factory.js +27 -0
  80. package/dist/lib/executors/gemini-executor.d.ts +9 -0
  81. package/dist/lib/executors/gemini-executor.d.ts.map +1 -0
  82. package/dist/lib/executors/gemini-executor.js +67 -0
  83. package/dist/lib/executors/kilo-executor.d.ts +9 -0
  84. package/dist/lib/executors/kilo-executor.d.ts.map +1 -0
  85. package/dist/lib/executors/kilo-executor.js +69 -0
  86. package/dist/lib/executors/opencode-executor.d.ts +9 -0
  87. package/dist/lib/executors/opencode-executor.d.ts.map +1 -0
  88. package/dist/lib/executors/opencode-executor.js +67 -0
  89. package/dist/lib/git-utils.d.ts +88 -0
  90. package/dist/lib/git-utils.d.ts.map +1 -0
  91. package/dist/lib/git-utils.js +242 -0
  92. package/dist/lib/hooks.d.ts +73 -0
  93. package/dist/lib/hooks.d.ts.map +1 -0
  94. package/dist/lib/hooks.js +62 -0
  95. package/dist/lib/index.d.ts +100 -0
  96. package/dist/lib/index.d.ts.map +1 -0
  97. package/dist/lib/index.js +143 -0
  98. package/dist/lib/logger.d.ts +20 -0
  99. package/dist/lib/logger.d.ts.map +1 -0
  100. package/dist/lib/logger.js +32 -0
  101. package/dist/lib/notifications.d.ts +7 -0
  102. package/dist/lib/notifications.d.ts.map +1 -0
  103. package/dist/lib/notifications.js +81 -0
  104. package/dist/lib/prompt-builder.d.ts +70 -0
  105. package/dist/lib/prompt-builder.d.ts.map +1 -0
  106. package/dist/lib/prompt-builder.js +344 -0
  107. package/dist/lib/prompt-registry.d.ts +22 -0
  108. package/dist/lib/prompt-registry.d.ts.map +1 -0
  109. package/dist/lib/prompt-registry.js +409 -0
  110. package/dist/lib/provider-defaults.json +32 -0
  111. package/dist/lib/storage/file-system.d.ts +57 -0
  112. package/dist/lib/storage/file-system.d.ts.map +1 -0
  113. package/dist/lib/storage/file-system.js +638 -0
  114. package/dist/lib/storage/storage-callbacks.d.ts +17 -0
  115. package/dist/lib/storage/storage-callbacks.d.ts.map +1 -0
  116. package/dist/lib/storage/storage-callbacks.js +94 -0
  117. package/dist/lib/storage/types.d.ts +43 -0
  118. package/dist/lib/storage/types.d.ts.map +1 -0
  119. package/dist/lib/storage/types.js +2 -0
  120. package/dist/lib/task-execution-core.d.ts +7 -0
  121. package/dist/lib/task-execution-core.d.ts.map +1 -0
  122. package/dist/lib/task-execution-core.js +381 -0
  123. package/dist/lib/task-execution.d.ts +7 -0
  124. package/dist/lib/task-execution.d.ts.map +1 -0
  125. package/dist/lib/task-execution.js +40 -0
  126. package/dist/lib/task-loop-execution.d.ts +7 -0
  127. package/dist/lib/task-loop-execution.d.ts.map +1 -0
  128. package/dist/lib/task-loop-execution.js +156 -0
  129. package/dist/lib/task-planning.d.ts +29 -0
  130. package/dist/lib/task-planning.d.ts.map +1 -0
  131. package/dist/lib/task-planning.js +103 -0
  132. package/dist/lib/task-review.d.ts +27 -0
  133. package/dist/lib/task-review.d.ts.map +1 -0
  134. package/dist/lib/task-review.js +103 -0
  135. package/dist/lib/validation.d.ts +26 -0
  136. package/dist/lib/validation.d.ts.map +1 -0
  137. package/dist/lib/validation.js +98 -0
  138. package/dist/prompts/documentation-detection.d.ts +2 -0
  139. package/dist/prompts/documentation-detection.d.ts.map +1 -0
  140. package/dist/prompts/documentation-detection.js +24 -0
  141. package/dist/prompts/documentation-recap.d.ts +3 -0
  142. package/dist/prompts/documentation-recap.d.ts.map +1 -0
  143. package/dist/prompts/documentation-recap.js +13 -0
  144. package/dist/prompts/index.d.ts +15 -0
  145. package/dist/prompts/index.d.ts.map +1 -0
  146. package/dist/prompts/index.js +30 -0
  147. package/dist/prompts/prd-combination.d.ts +2 -0
  148. package/dist/prompts/prd-combination.d.ts.map +1 -0
  149. package/dist/prompts/prd-combination.js +35 -0
  150. package/dist/prompts/prd-generation.d.ts +2 -0
  151. package/dist/prompts/prd-generation.d.ts.map +1 -0
  152. package/dist/prompts/prd-generation.js +49 -0
  153. package/dist/prompts/prd-parsing.d.ts +3 -0
  154. package/dist/prompts/prd-parsing.d.ts.map +1 -0
  155. package/dist/prompts/prd-parsing.js +172 -0
  156. package/dist/prompts/prd-question-answer.d.ts +3 -0
  157. package/dist/prompts/prd-question-answer.d.ts.map +1 -0
  158. package/dist/prompts/prd-question-answer.js +27 -0
  159. package/dist/prompts/prd-question.d.ts +3 -0
  160. package/dist/prompts/prd-question.d.ts.map +1 -0
  161. package/dist/prompts/prd-question.js +40 -0
  162. package/dist/prompts/prd-rework.d.ts +3 -0
  163. package/dist/prompts/prd-rework.d.ts.map +1 -0
  164. package/dist/prompts/prd-rework.js +81 -0
  165. package/dist/prompts/prd-suggest-stack.d.ts +3 -0
  166. package/dist/prompts/prd-suggest-stack.d.ts.map +1 -0
  167. package/dist/prompts/prd-suggest-stack.js +99 -0
  168. package/dist/prompts/task-breakdown.d.ts +3 -0
  169. package/dist/prompts/task-breakdown.d.ts.map +1 -0
  170. package/dist/prompts/task-breakdown.js +151 -0
  171. package/dist/prompts/task-enhancement.d.ts +3 -0
  172. package/dist/prompts/task-enhancement.d.ts.map +1 -0
  173. package/dist/prompts/task-enhancement.js +140 -0
  174. package/dist/prompts/task-execution.d.ts +3 -0
  175. package/dist/prompts/task-execution.d.ts.map +1 -0
  176. package/dist/prompts/task-execution.js +24 -0
  177. package/dist/prompts/task-planning.d.ts +3 -0
  178. package/dist/prompts/task-planning.d.ts.map +1 -0
  179. package/dist/prompts/task-planning.js +66 -0
  180. package/dist/prompts/workflow-assistance.d.ts +32 -0
  181. package/dist/prompts/workflow-assistance.d.ts.map +1 -0
  182. package/dist/prompts/workflow-assistance.js +130 -0
  183. package/dist/prompts/workflow-prompts.d.ts +9 -0
  184. package/dist/prompts/workflow-prompts.d.ts.map +1 -0
  185. package/dist/prompts/workflow-prompts.js +93 -0
  186. package/dist/services/benchmark.d.ts +26 -0
  187. package/dist/services/benchmark.d.ts.map +1 -0
  188. package/dist/services/benchmark.js +343 -0
  189. package/dist/services/prd.d.ts +136 -0
  190. package/dist/services/prd.d.ts.map +1 -0
  191. package/dist/services/prd.js +550 -0
  192. package/dist/services/tasks.d.ts +388 -0
  193. package/dist/services/tasks.d.ts.map +1 -0
  194. package/dist/services/tasks.js +1150 -0
  195. package/dist/services/workflow-ai-assistant.d.ts +74 -0
  196. package/dist/services/workflow-ai-assistant.d.ts.map +1 -0
  197. package/dist/services/workflow-ai-assistant.js +175 -0
  198. package/dist/services/workflow-benchmark.d.ts +34 -0
  199. package/dist/services/workflow-benchmark.d.ts.map +1 -0
  200. package/dist/services/workflow-benchmark.js +318 -0
  201. package/dist/services/workflow.d.ts +107 -0
  202. package/dist/services/workflow.d.ts.map +1 -0
  203. package/dist/services/workflow.js +580 -0
  204. package/dist/test/hooks.test.d.ts +2 -0
  205. package/dist/test/hooks.test.d.ts.map +1 -0
  206. package/dist/test/hooks.test.js +67 -0
  207. package/dist/test/integration/callbacks.test.d.ts +2 -0
  208. package/dist/test/integration/callbacks.test.d.ts.map +1 -0
  209. package/dist/test/integration/callbacks.test.js +64 -0
  210. package/dist/test/lib/ai-service/task-operations.test.d.ts +2 -0
  211. package/dist/test/lib/ai-service/task-operations.test.d.ts.map +1 -0
  212. package/dist/test/lib/ai-service/task-operations.test.js +362 -0
  213. package/dist/test/lib/config.test.d.ts +2 -0
  214. package/dist/test/lib/config.test.d.ts.map +1 -0
  215. package/dist/test/lib/config.test.js +128 -0
  216. package/dist/test/lib/git-utils.test.d.ts +2 -0
  217. package/dist/test/lib/git-utils.test.d.ts.map +1 -0
  218. package/dist/test/lib/git-utils.test.js +168 -0
  219. package/dist/test/mocks/mock-ai-operations.d.ts +15 -0
  220. package/dist/test/mocks/mock-ai-operations.d.ts.map +1 -0
  221. package/dist/test/mocks/mock-ai-operations.js +107 -0
  222. package/dist/test/mocks/mock-context-builder.d.ts +10 -0
  223. package/dist/test/mocks/mock-context-builder.d.ts.map +1 -0
  224. package/dist/test/mocks/mock-context-builder.js +81 -0
  225. package/dist/test/mocks/mock-model-provider.d.ts +7 -0
  226. package/dist/test/mocks/mock-model-provider.d.ts.map +1 -0
  227. package/dist/test/mocks/mock-model-provider.js +21 -0
  228. package/dist/test/mocks/mock-service-factory.d.ts +11 -0
  229. package/dist/test/mocks/mock-service-factory.d.ts.map +1 -0
  230. package/dist/test/mocks/mock-service-factory.js +61 -0
  231. package/dist/test/mocks/mock-storage.d.ts +50 -0
  232. package/dist/test/mocks/mock-storage.d.ts.map +1 -0
  233. package/dist/test/mocks/mock-storage.js +145 -0
  234. package/dist/test/model-parsing.test.d.ts +2 -0
  235. package/dist/test/model-parsing.test.d.ts.map +1 -0
  236. package/dist/test/model-parsing.test.js +73 -0
  237. package/dist/test/services/task-service.test.d.ts +2 -0
  238. package/dist/test/services/task-service.test.d.ts.map +1 -0
  239. package/dist/test/services/task-service.test.js +459 -0
  240. package/dist/test/storage.test.d.ts +2 -0
  241. package/dist/test/storage.test.d.ts.map +1 -0
  242. package/dist/test/storage.test.js +207 -0
  243. package/dist/test/task-loop-git.test.d.ts +2 -0
  244. package/dist/test/task-loop-git.test.d.ts.map +1 -0
  245. package/dist/test/task-loop-git.test.js +95 -0
  246. package/dist/test/test-mock-setup.d.ts +26 -0
  247. package/dist/test/test-mock-setup.d.ts.map +1 -0
  248. package/dist/test/test-mock-setup.js +41 -0
  249. package/dist/test/test-setup.d.ts +9 -0
  250. package/dist/test/test-setup.d.ts.map +1 -0
  251. package/dist/test/test-setup.js +44 -0
  252. package/dist/test/test-utils.d.ts +22 -0
  253. package/dist/test/test-utils.d.ts.map +1 -0
  254. package/dist/test/test-utils.js +37 -0
  255. package/dist/test/utils/ai-operation-utility.test.d.ts +2 -0
  256. package/dist/test/utils/ai-operation-utility.test.d.ts.map +1 -0
  257. package/dist/test/utils/ai-operation-utility.test.js +290 -0
  258. package/dist/test/utils/error-handling.test.d.ts +2 -0
  259. package/dist/test/utils/error-handling.test.d.ts.map +1 -0
  260. package/dist/test/utils/error-handling.test.js +231 -0
  261. package/dist/test/utils/file-utils.test.d.ts +2 -0
  262. package/dist/test/utils/file-utils.test.d.ts.map +1 -0
  263. package/dist/test/utils/file-utils.test.js +76 -0
  264. package/dist/test/utils/id-generator.test.d.ts +2 -0
  265. package/dist/test/utils/id-generator.test.d.ts.map +1 -0
  266. package/dist/test/utils/id-generator.test.js +41 -0
  267. package/dist/test/utils/model-parser.test.d.ts +2 -0
  268. package/dist/test/utils/model-parser.test.d.ts.map +1 -0
  269. package/dist/test/utils/model-parser.test.js +65 -0
  270. package/dist/test/validation.test.d.ts +2 -0
  271. package/dist/test/validation.test.d.ts.map +1 -0
  272. package/dist/test/validation.test.js +22 -0
  273. package/dist/types/callbacks.d.ts +30 -0
  274. package/dist/types/callbacks.d.ts.map +1 -0
  275. package/dist/types/callbacks.js +2 -0
  276. package/dist/types/index.d.ts +435 -0
  277. package/dist/types/index.d.ts.map +1 -0
  278. package/dist/types/index.js +30 -0
  279. package/dist/types/mcp.d.ts +3 -0
  280. package/dist/types/mcp.d.ts.map +1 -0
  281. package/dist/types/mcp.js +3 -0
  282. package/dist/types/options.d.ts +112 -0
  283. package/dist/types/options.d.ts.map +1 -0
  284. package/dist/types/options.js +2 -0
  285. package/dist/types/results.d.ts +200 -0
  286. package/dist/types/results.d.ts.map +1 -0
  287. package/dist/types/results.js +2 -0
  288. package/dist/types/workflow-options.d.ts +82 -0
  289. package/dist/types/workflow-options.d.ts.map +1 -0
  290. package/dist/types/workflow-options.js +2 -0
  291. package/dist/types/workflow-results.d.ts +82 -0
  292. package/dist/types/workflow-results.d.ts.map +1 -0
  293. package/dist/types/workflow-results.js +2 -0
  294. package/dist/utils/ai-config-builder.d.ts +14 -0
  295. package/dist/utils/ai-config-builder.d.ts.map +1 -0
  296. package/dist/utils/ai-config-builder.js +22 -0
  297. package/dist/utils/ai-operation-utility.d.ts +142 -0
  298. package/dist/utils/ai-operation-utility.d.ts.map +1 -0
  299. package/dist/utils/ai-operation-utility.js +303 -0
  300. package/dist/utils/ai-service-factory.d.ts +34 -0
  301. package/dist/utils/ai-service-factory.d.ts.map +1 -0
  302. package/dist/utils/ai-service-factory.js +99 -0
  303. package/dist/utils/error-utils.d.ts +70 -0
  304. package/dist/utils/error-utils.d.ts.map +1 -0
  305. package/dist/utils/error-utils.js +104 -0
  306. package/dist/utils/file-utils.d.ts +107 -0
  307. package/dist/utils/file-utils.d.ts.map +1 -0
  308. package/dist/utils/file-utils.js +171 -0
  309. package/dist/utils/id-generator.d.ts +92 -0
  310. package/dist/utils/id-generator.d.ts.map +1 -0
  311. package/dist/utils/id-generator.js +146 -0
  312. package/dist/utils/metadata-utils.d.ts +40 -0
  313. package/dist/utils/metadata-utils.d.ts.map +1 -0
  314. package/dist/utils/metadata-utils.js +43 -0
  315. package/dist/utils/model-executor-parser.d.ts +38 -0
  316. package/dist/utils/model-executor-parser.d.ts.map +1 -0
  317. package/dist/utils/model-executor-parser.js +69 -0
  318. package/dist/utils/model-parser.d.ts +6 -0
  319. package/dist/utils/model-parser.d.ts.map +1 -0
  320. package/dist/utils/model-parser.js +49 -0
  321. package/dist/utils/stack-formatter.d.ts +12 -0
  322. package/dist/utils/stack-formatter.d.ts.map +1 -0
  323. package/dist/utils/stack-formatter.js +36 -0
  324. package/dist/utils/storage-utils.d.ts +49 -0
  325. package/dist/utils/storage-utils.d.ts.map +1 -0
  326. package/dist/utils/storage-utils.js +80 -0
  327. package/dist/utils/streaming-utils.d.ts +38 -0
  328. package/dist/utils/streaming-utils.d.ts.map +1 -0
  329. package/dist/utils/streaming-utils.js +64 -0
  330. package/dist/utils/task-o-matic-error.d.ts +206 -0
  331. package/dist/utils/task-o-matic-error.d.ts.map +1 -0
  332. package/dist/utils/task-o-matic-error.js +304 -0
  333. package/package.json +40 -0
  334. package/src/index.ts +36 -0
  335. package/src/lib/ai-service/ai-operations.ts +310 -0
  336. package/src/lib/ai-service/base-operations.ts +139 -0
  337. package/src/lib/ai-service/documentation-operations.ts +438 -0
  338. package/src/lib/ai-service/filesystem-tools.ts +73 -0
  339. package/src/lib/ai-service/gemini-proxy.ts.bak +52 -0
  340. package/src/lib/ai-service/json-parser.ts +203 -0
  341. package/src/lib/ai-service/mcp-client.ts +54 -0
  342. package/src/lib/ai-service/model-provider.ts +192 -0
  343. package/src/lib/ai-service/prd-operations.ts +854 -0
  344. package/src/lib/ai-service/research-tools.ts +207 -0
  345. package/src/lib/ai-service/retry-handler.ts +89 -0
  346. package/src/lib/ai-service/task-operations.ts +342 -0
  347. package/src/lib/benchmark/registry.ts +307 -0
  348. package/src/lib/benchmark/runner.ts +190 -0
  349. package/src/lib/benchmark/storage.ts +140 -0
  350. package/src/lib/benchmark/types.ts +121 -0
  351. package/src/lib/better-t-stack-cli.ts +524 -0
  352. package/src/lib/bootstrap/cli-bootstrap.ts +397 -0
  353. package/src/lib/bootstrap/index.ts +2 -0
  354. package/src/lib/bootstrap/medusa-bootstrap.ts +261 -0
  355. package/src/lib/config-validation.ts +278 -0
  356. package/src/lib/config.ts +435 -0
  357. package/src/lib/context-builder.ts +383 -0
  358. package/src/lib/executors/claude-code-executor.ts +83 -0
  359. package/src/lib/executors/codex-executor.ts +85 -0
  360. package/src/lib/executors/executor-factory.ts +28 -0
  361. package/src/lib/executors/gemini-executor.ts +80 -0
  362. package/src/lib/executors/kilo-executor.ts +83 -0
  363. package/src/lib/executors/opencode-executor.ts +81 -0
  364. package/src/lib/git-utils.ts +334 -0
  365. package/src/lib/hooks.ts +121 -0
  366. package/src/lib/index.ts +166 -0
  367. package/src/lib/logger.ts +43 -0
  368. package/src/lib/notifications.ts +103 -0
  369. package/src/lib/prompt-builder.ts +471 -0
  370. package/src/lib/prompt-registry.ts +491 -0
  371. package/src/lib/provider-defaults.json +32 -0
  372. package/src/lib/storage/file-system.ts +864 -0
  373. package/src/lib/storage/storage-callbacks.ts +120 -0
  374. package/src/lib/storage/types.ts +58 -0
  375. package/src/lib/task-execution-core.ts +591 -0
  376. package/src/lib/task-execution.ts +59 -0
  377. package/src/lib/task-loop-execution.ts +214 -0
  378. package/src/lib/task-planning.ts +157 -0
  379. package/src/lib/task-review.ts +138 -0
  380. package/src/lib/validation.ts +140 -0
  381. package/src/prompts/documentation-detection.ts +21 -0
  382. package/src/prompts/documentation-recap.ts +11 -0
  383. package/src/prompts/index.ts +14 -0
  384. package/src/prompts/prd-combination.ts +32 -0
  385. package/src/prompts/prd-generation.ts +46 -0
  386. package/src/prompts/prd-parsing.ts +170 -0
  387. package/src/prompts/prd-question-answer.ts +25 -0
  388. package/src/prompts/prd-question.ts +38 -0
  389. package/src/prompts/prd-rework.ts +79 -0
  390. package/src/prompts/prd-suggest-stack.ts +97 -0
  391. package/src/prompts/task-breakdown.ts +149 -0
  392. package/src/prompts/task-enhancement.ts +138 -0
  393. package/src/prompts/task-execution.ts +22 -0
  394. package/src/prompts/task-planning.ts +64 -0
  395. package/src/prompts/workflow-assistance.ts +151 -0
  396. package/src/prompts/workflow-prompts.ts +97 -0
  397. package/src/services/benchmark.ts +433 -0
  398. package/src/services/prd.ts +845 -0
  399. package/src/services/tasks.ts +1515 -0
  400. package/src/services/workflow-ai-assistant.ts +298 -0
  401. package/src/services/workflow-benchmark.ts +339 -0
  402. package/src/services/workflow.ts +779 -0
  403. package/src/test/hooks.test.ts +77 -0
  404. package/src/test/integration/callbacks.test.ts +39 -0
  405. package/src/test/lib/ai-service/task-operations.test.ts +430 -0
  406. package/src/test/lib/config.test.ts +150 -0
  407. package/src/test/lib/git-utils.test.ts +198 -0
  408. package/src/test/mocks/mock-ai-operations.ts +205 -0
  409. package/src/test/mocks/mock-context-builder.ts +84 -0
  410. package/src/test/mocks/mock-model-provider.ts +21 -0
  411. package/src/test/mocks/mock-service-factory.ts +64 -0
  412. package/src/test/mocks/mock-storage.ts +204 -0
  413. package/src/test/model-parsing.test.ts +78 -0
  414. package/src/test/services/task-service.test.ts +551 -0
  415. package/src/test/storage.test.ts +206 -0
  416. package/src/test/task-loop-git.test.ts +142 -0
  417. package/src/test/test-mock-setup.ts +46 -0
  418. package/src/test/test-setup.ts +48 -0
  419. package/src/test/test-utils.ts +45 -0
  420. package/src/test/utils/ai-operation-utility.test.ts +306 -0
  421. package/src/test/utils/error-handling.test.ts +241 -0
  422. package/src/test/utils/file-utils.test.ts +80 -0
  423. package/src/test/utils/id-generator.test.ts +44 -0
  424. package/src/test/utils/model-parser.test.ts +67 -0
  425. package/src/test/validation.test.ts +19 -0
  426. package/src/types/callbacks.ts +14 -0
  427. package/src/types/index.ts +628 -0
  428. package/src/types/mcp.ts +5 -0
  429. package/src/types/options.ts +165 -0
  430. package/src/types/results.ts +216 -0
  431. package/src/types/workflow-options.ts +113 -0
  432. package/src/types/workflow-results.ts +87 -0
  433. package/src/utils/ai-config-builder.ts +33 -0
  434. package/src/utils/ai-operation-utility.ts +380 -0
  435. package/src/utils/ai-service-factory.ts +125 -0
  436. package/src/utils/error-utils.ts +124 -0
  437. package/src/utils/file-utils.ts +197 -0
  438. package/src/utils/id-generator.ts +168 -0
  439. package/src/utils/metadata-utils.ts +48 -0
  440. package/src/utils/model-executor-parser.ts +80 -0
  441. package/src/utils/model-parser.ts +58 -0
  442. package/src/utils/stack-formatter.ts +53 -0
  443. package/src/utils/storage-utils.ts +94 -0
  444. package/src/utils/streaming-utils.ts +91 -0
  445. package/src/utils/task-o-matic-error.ts +393 -0
  446. package/tsconfig.json +20 -0
  447. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,591 @@
1
+ import {
2
+ formatTaskNotFoundError,
3
+ createStandardError,
4
+ TaskOMaticErrorCodes,
5
+ } from "../utils/task-o-matic-error";
6
+ import { taskService } from "../services/tasks";
7
+ import {
8
+ TaskExecutionConfig,
9
+ TaskExecutionResult,
10
+ TaskExecutionAttempt,
11
+ ExecutorTool,
12
+ ExecutorConfig,
13
+ Task,
14
+ } from "../types";
15
+ import { ExecutorFactory } from "./executors/executor-factory";
16
+ import { runValidations, formatVerificationError } from "./validation";
17
+ import { getContextBuilder } from "../utils/ai-service-factory";
18
+ import { hooks } from "./hooks";
19
+ import { PromptBuilder } from "./prompt-builder";
20
+ import { executePlanningPhase } from "./task-planning";
21
+ import { executeReviewPhase } from "./task-review";
22
+ import {
23
+ captureGitState,
24
+ extractCommitInfo,
25
+ autoCommit,
26
+ hasNewCommitsSince,
27
+ GitState,
28
+ } from "./git-utils";
29
+ import { logger } from "./logger";
30
+
31
+ /**
32
+ * Execute a single task with all features (retry, planning, review, etc.)
33
+ * This is the core unified execution logic used by both execute and execute-loop commands
34
+ */
35
+ export async function executeTaskCore(
36
+ taskId: string,
37
+ config: TaskExecutionConfig
38
+ ): Promise<TaskExecutionResult> {
39
+ const {
40
+ tool,
41
+ executorConfig,
42
+ customMessage,
43
+ verificationCommands = [],
44
+ enableRetry = false,
45
+ maxRetries = 3,
46
+ tryModels,
47
+ enablePlanPhase = false,
48
+ planModel,
49
+ reviewPlan = false,
50
+ enableReviewPhase = false,
51
+ reviewModel,
52
+ autoCommit: enableAutoCommit = false,
53
+ executeSubtasks = true,
54
+ includePrd = false,
55
+ dry = false,
56
+ onPlanReview,
57
+ } = config;
58
+
59
+ // Load task
60
+ const task = await taskService.getTask(taskId);
61
+ if (!task) {
62
+ throw formatTaskNotFoundError(taskId);
63
+ }
64
+
65
+ // Check if task has subtasks and should execute them recursively
66
+ if (executeSubtasks && !customMessage) {
67
+ const subtasks = await taskService.getSubtasks(taskId);
68
+ if (subtasks.length > 0) {
69
+ return await executeTaskWithSubtasks(task, subtasks, config);
70
+ }
71
+ }
72
+
73
+ // ----------------------------------------------------------------------
74
+ // PLANNING PHASE
75
+ // ----------------------------------------------------------------------
76
+ let planContent: string | undefined;
77
+
78
+ if (enablePlanPhase) {
79
+ const planningResult = await executePlanningPhase(task, tool, {
80
+ planModel,
81
+ reviewPlan,
82
+ autoCommit: enableAutoCommit,
83
+ dry,
84
+ onPlanReview,
85
+ });
86
+
87
+ if (planningResult.success && planningResult.planContent) {
88
+ planContent = planningResult.planContent;
89
+ }
90
+ }
91
+
92
+ // ----------------------------------------------------------------------
93
+ // EXECUTION PHASE (with optional retry logic)
94
+ // ----------------------------------------------------------------------
95
+ const attempts: TaskExecutionAttempt[] = [];
96
+
97
+ if (enableRetry) {
98
+ // Execute with retry logic
99
+ return await executeTaskWithRetry(task, config, attempts, planContent);
100
+ } else {
101
+ // Execute once without retry (simpler path for execute command)
102
+ return await executeSingleAttempt(
103
+ task,
104
+ config,
105
+ attempts,
106
+ planContent,
107
+ 1,
108
+ maxRetries
109
+ );
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Execute task with subtasks recursively
115
+ */
116
+ async function executeTaskWithSubtasks(
117
+ task: Task,
118
+ subtasks: Task[],
119
+ config: TaskExecutionConfig
120
+ ): Promise<TaskExecutionResult> {
121
+ const { dry, includeCompleted = false } = config;
122
+
123
+ logger.info(
124
+ `📋 Task has ${subtasks.length} subtasks, executing recursively...`
125
+ );
126
+
127
+ const subtaskResults: TaskExecutionResult[] = [];
128
+ let allSuccess = true;
129
+
130
+ // Execute subtasks one by one
131
+ for (let i = 0; i < subtasks.length; i++) {
132
+ const subtask = subtasks[i];
133
+
134
+ // Skip completed subtasks unless includeCompleted is set
135
+ if (!includeCompleted && subtask.status === "completed") {
136
+ logger.info(
137
+ `⏭️ Skipping completed subtask: ${subtask.title} (${subtask.id})`
138
+ );
139
+ continue;
140
+ }
141
+
142
+ logger.progress(
143
+ `\n[${i + 1}/${subtasks.length}] Executing subtask: ${subtask.title} (${
144
+ subtask.id
145
+ })`
146
+ );
147
+
148
+ try {
149
+ const result = await executeTaskCore(subtask.id, config);
150
+ subtaskResults.push(result);
151
+
152
+ if (!result.success) {
153
+ allSuccess = false;
154
+ logger.error(
155
+ `❌ Failed to execute subtask ${subtask.id}: ${subtask.title}`
156
+ );
157
+ break; // Stop on first failure
158
+ }
159
+ } catch (error) {
160
+ allSuccess = false;
161
+ logger.error(
162
+ `❌ Failed to execute subtask ${subtask.id}: ${
163
+ error instanceof Error ? error.message : "Unknown error"
164
+ }`
165
+ );
166
+ break;
167
+ }
168
+ }
169
+
170
+ // After all subtasks are done (or on failure), update the main task status
171
+ if (!dry) {
172
+ if (allSuccess) {
173
+ await taskService.setTaskStatus(task.id, "completed");
174
+ logger.success(`✅ Main task ${task.title} completed after all subtasks`);
175
+ } else {
176
+ await taskService.setTaskStatus(task.id, "todo");
177
+ logger.error(
178
+ `❌ Main task ${task.title} failed due to subtask failure, status reset to todo`
179
+ );
180
+ }
181
+ }
182
+
183
+ return {
184
+ success: allSuccess,
185
+ attempts: [], // Parent task doesn't have its own attempts
186
+ subtaskResults,
187
+ };
188
+ }
189
+
190
+ /**
191
+ * Execute task with retry logic
192
+ */
193
+ async function executeTaskWithRetry(
194
+ task: Task,
195
+ config: TaskExecutionConfig,
196
+ attempts: TaskExecutionAttempt[],
197
+ planContent?: string
198
+ ): Promise<TaskExecutionResult> {
199
+ const {
200
+ tool,
201
+ maxRetries = 3,
202
+ tryModels,
203
+ verificationCommands = [],
204
+ enableReviewPhase = false,
205
+ reviewModel,
206
+ autoCommit: enableAutoCommit = false,
207
+ dry = false,
208
+ } = config;
209
+
210
+ let currentAttempt = 1;
211
+ let lastError: string | undefined;
212
+
213
+ while (currentAttempt <= maxRetries) {
214
+ // Determine which executor and model to use for this attempt
215
+ let currentExecutor = tool;
216
+ let currentModel: string | undefined;
217
+
218
+ if (tryModels && tryModels.length > 0) {
219
+ const modelConfigIndex = Math.min(
220
+ currentAttempt - 1,
221
+ tryModels.length - 1
222
+ );
223
+ const modelConfig = tryModels[modelConfigIndex];
224
+
225
+ if (modelConfig.executor) {
226
+ currentExecutor = modelConfig.executor;
227
+ }
228
+ if (modelConfig.model) {
229
+ currentModel = modelConfig.model;
230
+ }
231
+ }
232
+
233
+ logger.info(
234
+ `\n🎯 Attempt ${currentAttempt}/${maxRetries} for task: ${task.title} (${task.id})`
235
+ );
236
+
237
+ if (currentModel) {
238
+ logger.progress(
239
+ ` Using executor: ${currentExecutor} with model: ${currentModel}`
240
+ );
241
+ } else {
242
+ logger.progress(` Using executor: ${currentExecutor}`);
243
+ }
244
+
245
+ // Build retry context if this is a retry attempt
246
+ let retryContext = "";
247
+ if (currentAttempt > 1 && lastError) {
248
+ const retryParts: string[] = [];
249
+ retryParts.push(`# RETRY ATTEMPT ${currentAttempt}/${maxRetries}\n\n`);
250
+
251
+ if (currentModel) {
252
+ retryParts.push(
253
+ `**Note**: You are ${currentExecutor} using the ${currentModel} model. This is a more capable model than the previous attempt.\n\n`
254
+ );
255
+ }
256
+
257
+ retryParts.push(
258
+ `## Previous Attempt Failed With Error:\n\n${lastError}\n\n`
259
+ );
260
+ retryParts.push(
261
+ `Please analyze the error carefully and fix it. The error might be due to:\n`
262
+ );
263
+ retryParts.push(`- Syntax errors\n`);
264
+ retryParts.push(`- Logic errors\n`);
265
+ retryParts.push(`- Missing dependencies or imports\n`);
266
+ retryParts.push(`- Incorrect configuration\n`);
267
+ retryParts.push(`- Build or test failures\n\n`);
268
+ retryParts.push(
269
+ `Please fix the error above and complete the task successfully.\n\n`
270
+ );
271
+ retryContext = retryParts.join("");
272
+ }
273
+
274
+ // Update executor config for this attempt
275
+ const attemptConfig: TaskExecutionConfig = {
276
+ ...config,
277
+ tool: currentExecutor,
278
+ executorConfig: {
279
+ ...config.executorConfig,
280
+ model: currentModel,
281
+ continueLastSession: currentAttempt > 1, // Resume session on retries
282
+ },
283
+ };
284
+
285
+ try {
286
+ const result = await executeSingleAttempt(
287
+ task,
288
+ attemptConfig,
289
+ attempts,
290
+ planContent,
291
+ currentAttempt,
292
+ maxRetries,
293
+ retryContext
294
+ );
295
+
296
+ // Check if all verifications passed
297
+ const allVerificationsPassed =
298
+ result.attempts[result.attempts.length - 1]?.verificationResults?.every(
299
+ (r) => r.success
300
+ ) ?? true;
301
+
302
+ if (!allVerificationsPassed) {
303
+ const failedVerification = result.attempts[
304
+ result.attempts.length - 1
305
+ ]?.verificationResults?.find((r) => !r.success);
306
+ lastError = `Verification command "${failedVerification?.command}" failed:\n${failedVerification?.error}`;
307
+ currentAttempt++;
308
+ continue;
309
+ }
310
+
311
+ // ----------------------------------------------------------------------
312
+ // AI REVIEW PHASE
313
+ // ----------------------------------------------------------------------
314
+ if (enableReviewPhase && !dry) {
315
+ const reviewResult = await executeReviewPhase(task, {
316
+ reviewModel,
317
+ planContent,
318
+ dry,
319
+ });
320
+
321
+ if (!reviewResult.approved) {
322
+ lastError = `AI Review Failed:\n${reviewResult.feedback}`;
323
+ logger.error(
324
+ `❌ AI Review Rejected Changes: ${reviewResult.feedback}`
325
+ );
326
+ currentAttempt++;
327
+ continue;
328
+ } else {
329
+ logger.success(`✅ AI Review Approved: ${reviewResult.feedback}`);
330
+ result.reviewFeedback = reviewResult.feedback;
331
+ }
332
+ }
333
+
334
+ // Success! Return the result
335
+ return result;
336
+ } catch (error) {
337
+ lastError = error instanceof Error ? error.message : String(error);
338
+ logger.error(
339
+ `❌ Task execution failed on attempt ${currentAttempt}: ${lastError}`
340
+ );
341
+
342
+ if (!dry && currentAttempt < maxRetries) {
343
+ await taskService.setTaskStatus(task.id, "todo");
344
+ logger.warn("⏸ Task status reset to todo for retry");
345
+ }
346
+
347
+ currentAttempt++;
348
+ }
349
+ }
350
+
351
+ // All retries exhausted
352
+ if (!dry) {
353
+ await taskService.setTaskStatus(task.id, "todo");
354
+ logger.error("❌ All retry attempts exhausted, task status reset to todo");
355
+ }
356
+
357
+ return {
358
+ success: false,
359
+ attempts,
360
+ };
361
+ }
362
+
363
+ /**
364
+ * Execute a single attempt of the task
365
+ */
366
+ async function executeSingleAttempt(
367
+ task: Task,
368
+ config: TaskExecutionConfig,
369
+ attempts: TaskExecutionAttempt[],
370
+ planContent: string | undefined,
371
+ attemptNumber: number,
372
+ maxRetries: number,
373
+ retryContext?: string
374
+ ): Promise<TaskExecutionResult> {
375
+ const {
376
+ tool,
377
+ executorConfig,
378
+ customMessage,
379
+ verificationCommands = [],
380
+ autoCommit: enableAutoCommit = false,
381
+ includePrd = false,
382
+ dry = false,
383
+ } = config;
384
+
385
+ const attemptStartTime = Date.now();
386
+
387
+ logger.info(
388
+ `🎯 ${dry ? "DRY RUN" : "Executing"} task: ${task.title} (${task.id})`
389
+ );
390
+
391
+ // Capture git state before execution
392
+ const gitStateBefore = await captureGitState();
393
+
394
+ // Build execution message
395
+ let executionMessage: string;
396
+
397
+ if (customMessage) {
398
+ // Use custom message override
399
+ executionMessage = customMessage;
400
+ logger.progress("📝 Using custom execution message");
401
+ } else {
402
+ // Build comprehensive execution message with full context
403
+ const contextBuilder = getContextBuilder();
404
+ const taskContext = await contextBuilder.buildContext(task.id);
405
+
406
+ // Get task plan if available
407
+ const storedPlanData = await taskService.getTaskPlan(task.id);
408
+ let finalPlan: string | undefined;
409
+ if (planContent) {
410
+ finalPlan = `${planContent}\n\nPlease follow this plan to implement the task.`;
411
+ } else if (storedPlanData) {
412
+ finalPlan = storedPlanData.plan;
413
+ }
414
+
415
+ // Build execution prompt using PromptBuilder
416
+ const promptResult = PromptBuilder.buildExecutionPrompt({
417
+ taskTitle: task.title,
418
+ taskDescription: task.description,
419
+ taskPlan: finalPlan,
420
+ stack: taskContext.stack,
421
+ documentation: taskContext.documentation,
422
+ retryContext,
423
+ prdContent: includePrd ? taskContext.prdContent : undefined,
424
+ });
425
+
426
+ if (!promptResult.success) {
427
+ throw createStandardError(
428
+ TaskOMaticErrorCodes.CONFIGURATION_ERROR,
429
+ `Failed to build execution prompt: ${promptResult.error}`
430
+ );
431
+ }
432
+
433
+ executionMessage = promptResult.prompt!;
434
+ }
435
+
436
+ // Update task status to in-progress
437
+ if (!dry) {
438
+ await taskService.setTaskStatus(task.id, "in-progress");
439
+ logger.warn("⏳ Task status updated to in-progress");
440
+ }
441
+
442
+ // Emit execution:start event
443
+ await hooks.emit("execution:start", { taskId: task.id, tool });
444
+
445
+ try {
446
+ // Create executor and run
447
+ const executor = ExecutorFactory.create(tool, executorConfig);
448
+
449
+ // Log session resumption if applicable
450
+ if (executorConfig?.continueLastSession && attemptNumber > 1) {
451
+ logger.progress(
452
+ "🔄 Resuming previous session to provide error feedback to AI"
453
+ );
454
+ }
455
+
456
+ await executor.execute(executionMessage, dry, executorConfig);
457
+
458
+ // Run verification commands
459
+ const verificationResults = await runValidations(verificationCommands, dry);
460
+
461
+ const allVerificationsPassed = verificationResults.every((r) => r.success);
462
+
463
+ if (!allVerificationsPassed) {
464
+ const failedVerification = verificationResults.find((r) => !r.success);
465
+ const formattedError = formatVerificationError(failedVerification!);
466
+
467
+ attempts.push({
468
+ attemptNumber,
469
+ success: false,
470
+ error: formattedError,
471
+ executor: tool,
472
+ model: executorConfig?.model,
473
+ verificationResults,
474
+ timestamp: Date.now() - attemptStartTime,
475
+ });
476
+
477
+ logger.error(
478
+ `❌ Task execution failed verification on attempt ${attemptNumber}`
479
+ );
480
+
481
+ // Don't throw - return failure so retry loop can handle with session continuation
482
+ // This enables automatic error feedback to the AI
483
+ return {
484
+ success: false,
485
+ attempts,
486
+ };
487
+ }
488
+
489
+ // Extract commit info if enabled
490
+ let commitInfo: { message: string; files: string[] } | undefined;
491
+
492
+ if (enableAutoCommit && !dry) {
493
+ logger.info("📝 Checking git state for auto-commit...");
494
+
495
+ // Check if agent already committed during execution
496
+ const agentCommitted = await hasNewCommitsSince(
497
+ gitStateBefore.beforeHead || ""
498
+ );
499
+
500
+ if (agentCommitted) {
501
+ logger.info(
502
+ "📝 Agent already committed changes during execution, skipping auto-commit"
503
+ );
504
+ } else {
505
+ const gitStateAfter = await captureGitState();
506
+
507
+ if (gitStateAfter.hasUncommittedChanges) {
508
+ const gitState: GitState = {
509
+ beforeHead: gitStateBefore.beforeHead || "",
510
+ afterHead: gitStateAfter.afterHead || "",
511
+ hasUncommittedChanges: gitStateAfter.hasUncommittedChanges || false,
512
+ };
513
+
514
+ commitInfo = await extractCommitInfo(
515
+ task.id,
516
+ task.title,
517
+ executionMessage,
518
+ gitState
519
+ );
520
+
521
+ logger.success(`✅ Commit message: ${commitInfo.message}`);
522
+ if (commitInfo.files.length > 0) {
523
+ logger.success(`📁 Changed files: ${commitInfo.files.join(", ")}`);
524
+ }
525
+
526
+ // Auto-commit the changes
527
+ await autoCommit(commitInfo);
528
+ } else {
529
+ logger.info("📝 No uncommitted changes to commit");
530
+ }
531
+ }
532
+ }
533
+
534
+ // Update task status to completed
535
+ if (!dry) {
536
+ await taskService.setTaskStatus(task.id, "completed");
537
+ logger.success("✅ Task execution completed successfully");
538
+ }
539
+
540
+ // Record successful attempt
541
+ attempts.push({
542
+ attemptNumber,
543
+ success: true,
544
+ executor: tool,
545
+ model: executorConfig?.model,
546
+ verificationResults,
547
+ commitInfo,
548
+ timestamp: Date.now() - attemptStartTime,
549
+ });
550
+
551
+ // Emit execution:end event
552
+ await hooks.emit("execution:end", { taskId: task.id, success: true });
553
+
554
+ return {
555
+ success: true,
556
+ attempts,
557
+ commitInfo,
558
+ planContent,
559
+ };
560
+ } catch (error) {
561
+ const errorMessage = error instanceof Error ? error.message : String(error);
562
+
563
+ // Record failed attempt if not already recorded
564
+ if (
565
+ attempts.length === 0 ||
566
+ attempts[attempts.length - 1].attemptNumber !== attemptNumber
567
+ ) {
568
+ attempts.push({
569
+ attemptNumber,
570
+ success: false,
571
+ error: errorMessage,
572
+ executor: tool,
573
+ model: executorConfig?.model,
574
+ timestamp: Date.now() - attemptStartTime,
575
+ });
576
+ }
577
+
578
+ // Emit execution:error event
579
+ await hooks.emit("execution:error", {
580
+ taskId: task.id,
581
+ error: error instanceof Error ? error : new Error(String(error)),
582
+ });
583
+
584
+ if (!dry) {
585
+ await taskService.setTaskStatus(task.id, "todo");
586
+ logger.error("❌ Task execution failed, status reset to todo");
587
+ }
588
+
589
+ throw error;
590
+ }
591
+ }
@@ -0,0 +1,59 @@
1
+ import { ExecuteTaskOptions, TaskExecutionConfig } from "../types";
2
+ import { executeTaskCore } from "./task-execution-core";
3
+
4
+ /**
5
+ * Execute a task using an external coding assistant
6
+ * This is the simplified entry point that delegates to the unified core
7
+ */
8
+ export async function executeTask(options: ExecuteTaskOptions): Promise<void> {
9
+ const {
10
+ taskId,
11
+ tool = "opencode",
12
+ message,
13
+ model,
14
+ continueSession,
15
+ dry = false,
16
+ validate = [],
17
+ maxRetries,
18
+ tryModels,
19
+ plan,
20
+ planModel,
21
+ reviewPlan,
22
+ review,
23
+ reviewModel,
24
+ autoCommit,
25
+ includePrd,
26
+ } = options;
27
+
28
+ // Build unified task execution config
29
+ const config: TaskExecutionConfig = {
30
+ tool,
31
+ executorConfig: {
32
+ model,
33
+ continueLastSession: continueSession,
34
+ },
35
+ customMessage: message,
36
+ verificationCommands: validate,
37
+ enableRetry: maxRetries !== undefined && maxRetries > 0, // Opt-in retry
38
+ maxRetries: maxRetries || 3,
39
+ tryModels,
40
+ enablePlanPhase: plan,
41
+ planModel,
42
+ reviewPlan,
43
+ enableReviewPhase: review,
44
+ reviewModel,
45
+ autoCommit,
46
+ executeSubtasks: true, // Always execute subtasks in execute command
47
+ includePrd,
48
+ dry,
49
+ };
50
+
51
+ // Delegate to unified core execution
52
+ const result = await executeTaskCore(taskId, config);
53
+
54
+ // Throw error if execution failed (maintains backward compatibility)
55
+ if (!result.success) {
56
+ const lastAttempt = result.attempts[result.attempts.length - 1];
57
+ throw new Error(lastAttempt?.error || "Task execution failed");
58
+ }
59
+ }