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,638 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FileSystemStorage = void 0;
4
+ const config_1 = require("../config");
5
+ const storage_callbacks_1 = require("./storage-callbacks");
6
+ const task_o_matic_error_1 = require("../../utils/task-o-matic-error");
7
+ const logger_1 = require("../logger");
8
+ class FileSystemStorage {
9
+ callbacks;
10
+ constructor(callbacks) {
11
+ // If no callbacks provided, use default file system callbacks
12
+ // We use configManager to get the base directory for the default implementation
13
+ this.callbacks =
14
+ callbacks || (0, storage_callbacks_1.createFileSystemCallbacks)(config_1.configManager.getTaskOMaticDir());
15
+ }
16
+ sanitizeForFilename(name) {
17
+ return name.replace(/[\/\?%*:|"<>]/g, "-");
18
+ }
19
+ validateTaskId(taskId) {
20
+ if (!taskId || typeof taskId !== "string" || taskId.trim() === "") {
21
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, "Task ID must be a non-empty string", {
22
+ context: "validateTaskId",
23
+ suggestions: ["Provide a valid task ID string"],
24
+ metadata: { taskId },
25
+ });
26
+ }
27
+ }
28
+ validateTaskRequest(task) {
29
+ if (!task || typeof task !== "object") {
30
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, "Task request must be a valid object", {
31
+ context: "validateTaskRequest",
32
+ suggestions: ["Provide a valid task request object"],
33
+ });
34
+ }
35
+ if (!task.title ||
36
+ typeof task.title !== "string" ||
37
+ task.title.trim() === "") {
38
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, "Task title is required and must be a non-empty string", {
39
+ context: "validateTaskRequest - title validation",
40
+ suggestions: ["Provide a non-empty title for the task"],
41
+ });
42
+ }
43
+ if (task.parentId && typeof task.parentId !== "string") {
44
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, "Parent ID must be a string if provided", {
45
+ context: "validateTaskRequest - parentId validation",
46
+ suggestions: ["Provide a valid parent ID string or omit the field"],
47
+ metadata: { parentId: task.parentId },
48
+ });
49
+ }
50
+ if (task.estimatedEffort &&
51
+ !["small", "medium", "large"].includes(task.estimatedEffort)) {
52
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, "Estimated effort must be 'small', 'medium', or 'large'", {
53
+ context: "validateTaskRequest - estimatedEffort validation",
54
+ suggestions: ["Use 'small', 'medium', or 'large' for estimatedEffort"],
55
+ metadata: { estimatedEffort: task.estimatedEffort },
56
+ });
57
+ }
58
+ if (task.dependencies && !Array.isArray(task.dependencies)) {
59
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, "Dependencies must be an array if provided", {
60
+ context: "validateTaskRequest - dependencies validation",
61
+ suggestions: ["Provide dependencies as an array of task IDs"],
62
+ });
63
+ }
64
+ if (task.tags && !Array.isArray(task.tags)) {
65
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, "Tags must be an array if provided", {
66
+ context: "validateTaskRequest - tags validation",
67
+ suggestions: ["Provide tags as an array of strings"],
68
+ });
69
+ }
70
+ }
71
+ async loadTasksData() {
72
+ try {
73
+ const content = await this.callbacks.read("tasks.json");
74
+ if (!content) {
75
+ return { tasks: [], nextId: 1 };
76
+ }
77
+ return JSON.parse(content);
78
+ }
79
+ catch (error) {
80
+ logger_1.logger.error(`Failed to read tasks file: ${error}`);
81
+ return { tasks: [], nextId: 1 };
82
+ }
83
+ }
84
+ async saveTasksData(data) {
85
+ try {
86
+ await this.callbacks.write("tasks.json", JSON.stringify(data, null, 2));
87
+ }
88
+ catch (error) {
89
+ throw (0, task_o_matic_error_1.formatStorageError)("write tasks.json", error instanceof Error ? error : undefined);
90
+ }
91
+ }
92
+ findTaskInHierarchy(tasks, id) {
93
+ for (let i = 0; i < tasks.length; i++) {
94
+ const task = tasks[i];
95
+ if (task.id === id) {
96
+ return { task, parent: null, index: i };
97
+ }
98
+ if (task.subtasks) {
99
+ const result = this.findTaskInHierarchy(task.subtasks, id);
100
+ if (result.task) {
101
+ return { ...result, parent: task };
102
+ }
103
+ }
104
+ }
105
+ return { task: null, parent: null, index: -1 };
106
+ }
107
+ flattenTasks(tasks) {
108
+ const result = [];
109
+ for (const task of tasks) {
110
+ const { subtasks, ...taskWithoutSubtasks } = task;
111
+ result.push(taskWithoutSubtasks);
112
+ if (subtasks) {
113
+ result.push(...this.flattenTasks(subtasks));
114
+ }
115
+ }
116
+ return result;
117
+ }
118
+ // Tasks
119
+ async getTasks() {
120
+ const data = await this.loadTasksData();
121
+ return this.flattenTasks(data.tasks);
122
+ }
123
+ async getTopLevelTasks() {
124
+ const data = await this.loadTasksData();
125
+ return data.tasks;
126
+ }
127
+ async getTask(id) {
128
+ this.validateTaskId(id);
129
+ const data = await this.loadTasksData();
130
+ const result = this.findTaskInHierarchy(data.tasks, id);
131
+ return result.task;
132
+ }
133
+ async createTask(task, aiMetadata) {
134
+ this.validateTaskRequest(task);
135
+ const data = await this.loadTasksData();
136
+ let id;
137
+ if (task.parentId) {
138
+ const parentResult = this.findTaskInHierarchy(data.tasks, task.parentId);
139
+ if (!parentResult.task) {
140
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.TASK_NOT_FOUND, `Parent task with ID ${task.parentId} not found`, {
141
+ context: "createTask - parent validation",
142
+ suggestions: [
143
+ "Create the parent task first",
144
+ "Check that the parent ID is correct",
145
+ "List all tasks to see available parent IDs",
146
+ ],
147
+ metadata: { parentId: task.parentId },
148
+ });
149
+ }
150
+ const siblingCount = (parentResult.task.subtasks?.length || 0) + 1;
151
+ id = `${task.parentId}.${siblingCount}`;
152
+ }
153
+ else {
154
+ if (task.id && typeof task.id === "string") {
155
+ id = task.id;
156
+ }
157
+ else {
158
+ id = data.nextId.toString();
159
+ data.nextId++;
160
+ }
161
+ }
162
+ if (task.dependencies && task.dependencies.length > 0) {
163
+ for (const depId of task.dependencies) {
164
+ const depExists = this.taskExists(data.tasks, depId);
165
+ if (!depExists) {
166
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.TASK_NOT_FOUND, `Dependency task not found: ${depId}`, {
167
+ context: "createTask - dependency validation",
168
+ suggestions: [
169
+ "Create the dependency task first",
170
+ "Check that the dependency ID is correct",
171
+ "Remove the dependency from the task",
172
+ ],
173
+ metadata: { dependencyId: depId, taskDependencies: task.dependencies },
174
+ });
175
+ }
176
+ }
177
+ if (this.wouldCreateCircularDependency(data.tasks, id, task.dependencies)) {
178
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.STORAGE_INTEGRITY_ERROR, `Circular dependency detected for task ${id}`, {
179
+ context: "createTask - circular dependency check",
180
+ suggestions: [
181
+ "Remove circular dependencies from the task",
182
+ "Review the dependency chain",
183
+ ],
184
+ metadata: { taskId: id, dependencies: task.dependencies },
185
+ });
186
+ }
187
+ }
188
+ let contentFile;
189
+ let description = task.description || "";
190
+ if (task.content && task.content.length > 200) {
191
+ contentFile = await this.saveTaskContent(id, task.content);
192
+ description = task.description || task.content.substring(0, 200) + "...";
193
+ }
194
+ else if (task.content) {
195
+ description = task.description || task.content;
196
+ }
197
+ const newTask = {
198
+ id,
199
+ title: task.title,
200
+ description,
201
+ contentFile,
202
+ status: task.status || "todo",
203
+ estimatedEffort: task.estimatedEffort,
204
+ dependencies: task.dependencies,
205
+ tags: task.tags,
206
+ subtasks: [],
207
+ createdAt: Date.now(),
208
+ updatedAt: Date.now(),
209
+ prdFile: task.prdFile,
210
+ };
211
+ if (task.parentId) {
212
+ const parentResult = this.findTaskInHierarchy(data.tasks, task.parentId);
213
+ if (parentResult.task) {
214
+ if (!parentResult.task.subtasks) {
215
+ parentResult.task.subtasks = [];
216
+ }
217
+ parentResult.task.subtasks.push(newTask);
218
+ }
219
+ }
220
+ else {
221
+ data.tasks.push(newTask);
222
+ }
223
+ await this.saveTasksData(data);
224
+ if (aiMetadata) {
225
+ await this.saveTaskAIMetadata({
226
+ ...aiMetadata,
227
+ taskId: id,
228
+ generatedAt: Date.now(),
229
+ });
230
+ }
231
+ return newTask;
232
+ }
233
+ async updateTask(id, updates) {
234
+ this.validateTaskId(id);
235
+ if (!updates || typeof updates !== "object") {
236
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, "Updates must be a valid object", {
237
+ context: "updateTask - updates validation",
238
+ suggestions: ["Provide a valid updates object with task properties"],
239
+ });
240
+ }
241
+ const data = await this.loadTasksData();
242
+ const result = this.findTaskInHierarchy(data.tasks, id);
243
+ if (!result.task)
244
+ return null;
245
+ const updatedTask = {
246
+ ...result.task,
247
+ ...updates,
248
+ id,
249
+ updatedAt: Date.now(),
250
+ };
251
+ if (result.parent) {
252
+ const parentIndex = result.parent.subtasks.findIndex((t) => t.id === id);
253
+ result.parent.subtasks[parentIndex] = updatedTask;
254
+ }
255
+ else {
256
+ const taskIndex = data.tasks.findIndex((t) => t.id === id);
257
+ data.tasks[taskIndex] = updatedTask;
258
+ }
259
+ await this.saveTasksData(data);
260
+ return updatedTask;
261
+ }
262
+ async deleteTask(id) {
263
+ this.validateTaskId(id);
264
+ const data = await this.loadTasksData();
265
+ const result = this.findTaskInHierarchy(data.tasks, id);
266
+ if (!result.task)
267
+ return false;
268
+ if (result.parent) {
269
+ const parentIndex = result.parent.subtasks.findIndex((t) => t.id === id);
270
+ result.parent.subtasks.splice(parentIndex, 1);
271
+ }
272
+ else {
273
+ const taskIndex = data.tasks.findIndex((t) => t.id === id);
274
+ data.tasks.splice(taskIndex, 1);
275
+ }
276
+ await this.saveTasksData(data);
277
+ return true;
278
+ }
279
+ async getSubtasks(parentId) {
280
+ const data = await this.loadTasksData();
281
+ const result = this.findTaskInHierarchy(data.tasks, parentId);
282
+ return result.task?.subtasks || [];
283
+ }
284
+ taskExists(tasks, taskId) {
285
+ const exactMatch = this.findTaskInHierarchy(tasks, taskId).task;
286
+ if (exactMatch)
287
+ return true;
288
+ const taskPrefixedId = taskId.startsWith("task-")
289
+ ? taskId.substring(5)
290
+ : `task-${taskId}`;
291
+ const prefixedMatch = this.findTaskInHierarchy(tasks, taskPrefixedId).task;
292
+ if (prefixedMatch)
293
+ return true;
294
+ if (taskId.startsWith("task-")) {
295
+ const numericId = taskId.substring(5);
296
+ const numericMatch = this.findTaskInHierarchy(tasks, numericId).task;
297
+ if (numericMatch)
298
+ return true;
299
+ }
300
+ return false;
301
+ }
302
+ wouldCreateCircularDependency(tasks, newTaskId, dependencies) {
303
+ const visited = new Set();
304
+ const checkCircular = (taskId) => {
305
+ if (visited.has(taskId)) {
306
+ return true;
307
+ }
308
+ if (taskId === newTaskId) {
309
+ return true;
310
+ }
311
+ visited.add(taskId);
312
+ const task = this.findTaskInHierarchy(tasks, taskId).task;
313
+ if (task && task.dependencies) {
314
+ for (const depId of task.dependencies) {
315
+ if (checkCircular(depId)) {
316
+ return true;
317
+ }
318
+ }
319
+ }
320
+ visited.delete(taskId);
321
+ return false;
322
+ };
323
+ for (const depId of dependencies) {
324
+ visited.clear();
325
+ if (checkCircular(depId)) {
326
+ return true;
327
+ }
328
+ }
329
+ return false;
330
+ }
331
+ async loadAIMetadata() {
332
+ try {
333
+ const content = await this.callbacks.read("ai-metadata.json");
334
+ if (!content)
335
+ return [];
336
+ return JSON.parse(content);
337
+ }
338
+ catch (error) {
339
+ logger_1.logger.error(`Failed to read AI metadata file: ${error}`);
340
+ return [];
341
+ }
342
+ }
343
+ async saveAIMetadata(metadata) {
344
+ await this.callbacks.write("ai-metadata.json", JSON.stringify(metadata, null, 2));
345
+ }
346
+ async getTaskAIMetadata(taskId) {
347
+ const metadata = await this.loadAIMetadata();
348
+ return metadata.find((meta) => meta.taskId === taskId) || null;
349
+ }
350
+ async saveTaskAIMetadata(metadata) {
351
+ const allMetadata = await this.loadAIMetadata();
352
+ const existingIndex = allMetadata.findIndex((meta) => meta.taskId === metadata.taskId);
353
+ if (existingIndex >= 0) {
354
+ allMetadata[existingIndex] = metadata;
355
+ }
356
+ else {
357
+ allMetadata.push(metadata);
358
+ }
359
+ await this.saveAIMetadata(allMetadata);
360
+ }
361
+ async deleteTaskAIMetadata(taskId) {
362
+ const metadata = await this.loadAIMetadata();
363
+ const filtered = metadata.filter((meta) => meta.taskId !== taskId);
364
+ await this.saveAIMetadata(filtered);
365
+ }
366
+ async saveTaskContent(taskId, content) {
367
+ this.validateTaskId(taskId);
368
+ if (typeof content !== "string") {
369
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, "Content must be a string", {
370
+ context: "Content validation",
371
+ suggestions: ["Provide content as a string"],
372
+ });
373
+ }
374
+ const contentFileName = `tasks/${taskId}.md`;
375
+ try {
376
+ await this.callbacks.write(contentFileName, content);
377
+ }
378
+ catch (error) {
379
+ throw (0, task_o_matic_error_1.formatStorageError)("write task content", error instanceof Error ? error : undefined);
380
+ }
381
+ return contentFileName;
382
+ }
383
+ async saveEnhancedTaskContent(taskId, content) {
384
+ this.validateTaskId(taskId);
385
+ if (typeof content !== "string") {
386
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, "Content must be a string", {
387
+ context: "Content validation",
388
+ suggestions: ["Provide content as a string"],
389
+ });
390
+ }
391
+ const contentFileName = `tasks/enhanced/${taskId}.md`;
392
+ try {
393
+ await this.callbacks.write(contentFileName, content);
394
+ }
395
+ catch (error) {
396
+ throw (0, task_o_matic_error_1.formatStorageError)("write enhanced task content", error instanceof Error ? error : undefined);
397
+ }
398
+ return contentFileName;
399
+ }
400
+ async getTaskContent(taskId) {
401
+ this.validateTaskId(taskId);
402
+ const contentFileName = `tasks/${taskId}.md`;
403
+ try {
404
+ return await this.callbacks.read(contentFileName);
405
+ }
406
+ catch (error) {
407
+ logger_1.logger.error(`Failed to read task content for ${taskId}: ${error}`);
408
+ return null;
409
+ }
410
+ }
411
+ async deleteTaskContent(taskId) {
412
+ this.validateTaskId(taskId);
413
+ const contentFileName = `tasks/${taskId}.md`;
414
+ await this.callbacks.delete(contentFileName);
415
+ }
416
+ async saveContext7Documentation(library, query, content) {
417
+ const sanitizedLibrary = this.sanitizeForFilename(library);
418
+ const sanitizedQuery = this.sanitizeForFilename(query);
419
+ const filePath = `docs/${sanitizedLibrary}/${sanitizedQuery}.md`;
420
+ await this.callbacks.write(filePath, content);
421
+ return filePath;
422
+ }
423
+ async getDocumentationFile(fileName) {
424
+ const filePath = `docs/${fileName}`;
425
+ try {
426
+ return await this.callbacks.read(filePath);
427
+ }
428
+ catch (error) {
429
+ logger_1.logger.error(`Failed to read documentation file ${fileName}: ${error}`);
430
+ return null;
431
+ }
432
+ }
433
+ async listDocumentationFiles() {
434
+ try {
435
+ const files = await this.callbacks.list("docs/");
436
+ // Filter for markdown/text files and remove "docs/" prefix for compatibility
437
+ return files
438
+ .filter((f) => f.endsWith(".md") || f.endsWith(".txt"))
439
+ .map((f) => (f.startsWith("docs/") ? f.substring(5) : f));
440
+ }
441
+ catch (error) {
442
+ logger_1.logger.error(`Failed to list documentation files: ${error}`);
443
+ return [];
444
+ }
445
+ }
446
+ async migrateTaskContent() {
447
+ const data = await this.loadTasksData();
448
+ let migratedCount = 0;
449
+ const migrateTask = async (task) => {
450
+ let updatedTask = { ...task };
451
+ if ("content" in task && task.content && !task.contentFile) {
452
+ const oldContent = task.content;
453
+ if (oldContent.length > 200) {
454
+ const contentFile = `tasks/${task.id}.md`;
455
+ await this.callbacks.write(contentFile, oldContent);
456
+ updatedTask.contentFile = contentFile;
457
+ updatedTask.description =
458
+ task.description || oldContent.substring(0, 200) + "...";
459
+ }
460
+ else {
461
+ updatedTask.description = task.description || oldContent;
462
+ }
463
+ const { content: _, ...taskWithoutContent } = updatedTask;
464
+ updatedTask = taskWithoutContent;
465
+ migratedCount++;
466
+ }
467
+ if (task.subtasks) {
468
+ updatedTask.subtasks = await Promise.all(task.subtasks.map(migrateTask));
469
+ }
470
+ return updatedTask;
471
+ };
472
+ data.tasks = await Promise.all(data.tasks.map(migrateTask));
473
+ if (migratedCount > 0) {
474
+ await this.saveTasksData(data);
475
+ }
476
+ return migratedCount;
477
+ }
478
+ async cleanupOrphanedContent() {
479
+ const data = await this.loadTasksData();
480
+ const allTasks = this.flattenTasks(data.tasks);
481
+ const validContentFiles = new Set(allTasks
482
+ .filter((task) => task.contentFile)
483
+ .map((task) => task.contentFile));
484
+ let cleanedCount = 0;
485
+ try {
486
+ const files = await this.callbacks.list("tasks/");
487
+ for (const file of files) {
488
+ // file is a full key like "tasks/123.md"
489
+ // validContentFiles contains relative paths like "tasks/123.md"
490
+ // So we can check directly
491
+ if (file.endsWith(".md")) {
492
+ if (!validContentFiles.has(file)) {
493
+ try {
494
+ await this.callbacks.delete(file);
495
+ cleanedCount++;
496
+ logger_1.logger.info(`Cleaned up orphaned content file: ${file}`);
497
+ }
498
+ catch (error) {
499
+ logger_1.logger.error(`Failed to delete orphaned file ${file}: ${error}`);
500
+ }
501
+ }
502
+ }
503
+ }
504
+ }
505
+ catch (error) {
506
+ logger_1.logger.error(`Failed to cleanup orphaned content: ${error}`);
507
+ }
508
+ return cleanedCount;
509
+ }
510
+ async validateStorageIntegrity() {
511
+ const issues = [];
512
+ try {
513
+ const data = await this.loadTasksData();
514
+ if (!Array.isArray(data.tasks)) {
515
+ issues.push("Tasks data is not an array");
516
+ }
517
+ if (typeof data.nextId !== "number" || data.nextId < 1) {
518
+ issues.push("Invalid nextId in tasks data");
519
+ }
520
+ const allTasks = this.flattenTasks(data.tasks);
521
+ const taskIds = allTasks.map((task) => task.id);
522
+ const duplicateIds = taskIds.filter((id, index) => taskIds.indexOf(id) !== index);
523
+ if (duplicateIds.length > 0) {
524
+ issues.push(`Duplicate task IDs found: ${duplicateIds.join(", ")}`);
525
+ }
526
+ for (const task of allTasks) {
527
+ if (task.dependencies) {
528
+ for (const depId of task.dependencies) {
529
+ if (!taskIds.includes(depId)) {
530
+ issues.push(`Task ${task.id} has invalid dependency: ${depId}`);
531
+ }
532
+ }
533
+ }
534
+ }
535
+ }
536
+ catch (error) {
537
+ issues.push(`Storage validation error: ${error instanceof Error ? error.message : "Unknown error"}`);
538
+ }
539
+ return {
540
+ isValid: issues.length === 0,
541
+ issues,
542
+ };
543
+ }
544
+ async savePlan(taskId, plan) {
545
+ this.validateTaskId(taskId);
546
+ const planFile = `plans/${taskId}.json`;
547
+ try {
548
+ const planData = {
549
+ taskId,
550
+ plan,
551
+ createdAt: Date.now(),
552
+ updatedAt: Date.now(),
553
+ };
554
+ await this.callbacks.write(planFile, JSON.stringify(planData, null, 2));
555
+ }
556
+ catch (error) {
557
+ throw (0, task_o_matic_error_1.formatStorageError)(`write plan for task ${taskId}`, error instanceof Error ? error : undefined);
558
+ }
559
+ }
560
+ async getPlan(taskId) {
561
+ this.validateTaskId(taskId);
562
+ const planFile = `plans/${taskId}.json`;
563
+ try {
564
+ const content = await this.callbacks.read(planFile);
565
+ if (!content)
566
+ return null;
567
+ return JSON.parse(content);
568
+ }
569
+ catch (error) {
570
+ throw (0, task_o_matic_error_1.formatStorageError)(`read plan for task ${taskId}`, error instanceof Error ? error : undefined);
571
+ }
572
+ }
573
+ async listPlans() {
574
+ try {
575
+ const plans = [];
576
+ const files = await this.callbacks.list("plans/");
577
+ for (const file of files) {
578
+ if (file.endsWith(".json")) {
579
+ // file is "plans/123.json"
580
+ const taskId = file.replace("plans/", "").replace(".json", "");
581
+ const planData = await this.getPlan(taskId);
582
+ if (planData) {
583
+ plans.push({
584
+ taskId,
585
+ plan: planData.plan,
586
+ createdAt: planData.createdAt,
587
+ updatedAt: planData.updatedAt,
588
+ });
589
+ }
590
+ }
591
+ }
592
+ return plans.sort((a, b) => b.updatedAt - a.updatedAt);
593
+ }
594
+ catch (error) {
595
+ throw (0, task_o_matic_error_1.formatStorageError)("list plans", error instanceof Error ? error : undefined);
596
+ }
597
+ }
598
+ async deletePlan(taskId) {
599
+ this.validateTaskId(taskId);
600
+ const planFile = `plans/${taskId}.json`;
601
+ try {
602
+ await this.callbacks.delete(planFile);
603
+ return true;
604
+ }
605
+ catch (error) {
606
+ return false;
607
+ }
608
+ }
609
+ async saveTaskDocumentation(taskId, documentation) {
610
+ this.validateTaskId(taskId);
611
+ if (typeof documentation !== "string") {
612
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, "Documentation must be a string", {
613
+ context: "Documentation validation",
614
+ suggestions: ["Provide documentation as a string"],
615
+ });
616
+ }
617
+ const documentationFileName = `docs/tasks/${taskId}.md`;
618
+ try {
619
+ await this.callbacks.write(documentationFileName, documentation);
620
+ }
621
+ catch (error) {
622
+ throw (0, task_o_matic_error_1.formatStorageError)("write task documentation", error instanceof Error ? error : undefined);
623
+ }
624
+ return documentationFileName;
625
+ }
626
+ async getTaskDocumentation(taskId) {
627
+ this.validateTaskId(taskId);
628
+ const documentationFileName = `docs/tasks/${taskId}.md`;
629
+ try {
630
+ return await this.callbacks.read(documentationFileName);
631
+ }
632
+ catch (error) {
633
+ logger_1.logger.error(`Failed to read task documentation for ${taskId}: ${error}`);
634
+ return null;
635
+ }
636
+ }
637
+ }
638
+ exports.FileSystemStorage = FileSystemStorage;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Simple storage callbacks - just read/write key-value pairs
3
+ * This allows the library to be used with ANY storage backend (DB, Redis, S3, etc.)
4
+ */
5
+ export interface StorageCallbacks {
6
+ read: (key: string) => Promise<string | null>;
7
+ write: (key: string, value: string) => Promise<void>;
8
+ delete: (key: string) => Promise<void>;
9
+ list: (prefix?: string) => Promise<string[]>;
10
+ exists: (key: string) => Promise<boolean>;
11
+ }
12
+ /**
13
+ * Default file system callbacks (Node.js environment)
14
+ * Uses fs/promises to implement the storage interface
15
+ */
16
+ export declare function createFileSystemCallbacks(baseDir?: string): StorageCallbacks;
17
+ //# sourceMappingURL=storage-callbacks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-callbacks.d.ts","sourceRoot":"","sources":["../../../src/lib/storage/storage-callbacks.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAE/B,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAG9C,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAGrD,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAGvC,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAG7C,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3C;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,MAAsB,GAC9B,gBAAgB,CAwFlB"}