@poetic-ai/poetic 1.42.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 (782) hide show
  1. package/.github/SECURITY.md +47 -0
  2. package/.nvmrc +1 -0
  3. package/.poetic/README.md +37 -0
  4. package/.poetic/providers/catalog.json +12051 -0
  5. package/.poetic/providers/pricing.json +1272 -0
  6. package/.poetic/providers/registry.json +3369 -0
  7. package/CHANGELOG.md +552 -0
  8. package/CODE_OF_CONDUCT.md +40 -0
  9. package/CONTRIBUTING.md +23 -0
  10. package/INSTALL.md +454 -0
  11. package/LICENSE +21 -0
  12. package/README.md +474 -0
  13. package/dist/BasicOptimizationCompetitionRunner-5H5TBYO4.js +153 -0
  14. package/dist/ExecutionTracker-UVONC4C6.js +16 -0
  15. package/dist/OptimizationConfig-7DFY2TST.js +17 -0
  16. package/dist/OptimizationEngine-JIMGP3LY.js +1597 -0
  17. package/dist/PromptStore-U6ZD3ZMQ.js +18 -0
  18. package/dist/actions-LUJPINLJ.js +322 -0
  19. package/dist/agent-ingest-3DJUJ7FU.js +53 -0
  20. package/dist/aggregator-DNCBINFO.js +12 -0
  21. package/dist/ai-judge-5QT5QJVU.js +156 -0
  22. package/dist/allowlist-grounding-RO6HKUFI.js +16 -0
  23. package/dist/allowlist-utils-23V7TJ3G.js +28 -0
  24. package/dist/anchored-turn-service-JULUCUIK.js +489 -0
  25. package/dist/api-transport-4TYTNLTJ.js +1087 -0
  26. package/dist/apply-completion-mode-AW2MOS3R.js +89 -0
  27. package/dist/artifact-migrator-23L45ISD.js +267 -0
  28. package/dist/ask-HWVV6QFR.js +135 -0
  29. package/dist/auth-5KEDKAPP.js +67 -0
  30. package/dist/auth-7TT3JINV.js +78 -0
  31. package/dist/auth-E6XUNZ5M.js +68 -0
  32. package/dist/auth-H3XDZE22.js +134 -0
  33. package/dist/auth-OC4E6633.js +71 -0
  34. package/dist/auth-S4CTX4GQ.js +44 -0
  35. package/dist/auth-YLH3S7EY.js +69 -0
  36. package/dist/auth-liveness-TDDEZY3T.js +46 -0
  37. package/dist/auto-optimizer-VPRWOWGU.js +80 -0
  38. package/dist/autoloop-cleanup-JOGKTLWA.js +109 -0
  39. package/dist/autoloop-evidence-gates-PCDALGVJ.js +38 -0
  40. package/dist/autoloop-gate-policy-Z7FVJVXV.js +175 -0
  41. package/dist/autoloop-helpers-2KTK43GL.js +22 -0
  42. package/dist/autoloop-ledger-W7QO62PX.js +96 -0
  43. package/dist/autoloop-ledger-subscriber-Z5RW5EIE.js +162 -0
  44. package/dist/autoloop-run-defaults-FERGRZGP.js +19 -0
  45. package/dist/autoloop-run-lock-CT2NWSV3.js +197 -0
  46. package/dist/autoloop-success-J2VKKBXQ.js +85 -0
  47. package/dist/autoloop-termination-summary-RN75F422.js +58 -0
  48. package/dist/autoloop-trajectory-XFIEXP5Z.js +282 -0
  49. package/dist/autoloop-wall-clock-T7ZVIQOC.js +12 -0
  50. package/dist/autonomous-loop-controller-PW4XVFGQ.js +4120 -0
  51. package/dist/backend-P3DAYRP7.js +29 -0
  52. package/dist/background-executor-CBN552V4.js +257 -0
  53. package/dist/backlog-execution-intent-U4XYPTV6.js +15 -0
  54. package/dist/backup-active-store-5WXG6SXT.js +17 -0
  55. package/dist/backup-telemetry-db-XGLXAA3N.js +254 -0
  56. package/dist/basic-competition-master-VCSBJVRN.js +344 -0
  57. package/dist/branch-archive-manager-RP6FP3ZC.js +254 -0
  58. package/dist/branch-cleanup-manager-RSHAI7YR.js +20 -0
  59. package/dist/build-gate-YHGRB4QB.js +71 -0
  60. package/dist/change-summary-WY7J5TOX.js +33 -0
  61. package/dist/chunk-23A26CSN.js +123 -0
  62. package/dist/chunk-27UTJD3M.js +265 -0
  63. package/dist/chunk-2A5CILN3.js +310 -0
  64. package/dist/chunk-2AQUWJPW.js +225 -0
  65. package/dist/chunk-2BZ53J6J.js +2344 -0
  66. package/dist/chunk-2DY5KNVM.js +276 -0
  67. package/dist/chunk-2EIA4RBE.js +659 -0
  68. package/dist/chunk-2IUXIGQD.js +1064 -0
  69. package/dist/chunk-2N42MS2Z.js +2193 -0
  70. package/dist/chunk-2QJ3H3L7.js +42 -0
  71. package/dist/chunk-2QLYTVYX.js +791 -0
  72. package/dist/chunk-2VSQMRCB.js +18 -0
  73. package/dist/chunk-2XQXYBM2.js +130 -0
  74. package/dist/chunk-2YFUIER7.js +426 -0
  75. package/dist/chunk-34CNP2HB.js +148 -0
  76. package/dist/chunk-35P3W3JX.js +456 -0
  77. package/dist/chunk-36PEBZAF.js +18 -0
  78. package/dist/chunk-3AOKYKA7.js +22 -0
  79. package/dist/chunk-3BCUNHKF.js +475 -0
  80. package/dist/chunk-3FLXLLB7.js +26 -0
  81. package/dist/chunk-3FOZ2VHV.js +100 -0
  82. package/dist/chunk-3G6FZCRF.js +106 -0
  83. package/dist/chunk-3M57DADF.js +44 -0
  84. package/dist/chunk-3S62LLWJ.js +543 -0
  85. package/dist/chunk-3ZPQLGV7.js +2904 -0
  86. package/dist/chunk-44N5WZZH.js +45 -0
  87. package/dist/chunk-45FPSA3B.js +125 -0
  88. package/dist/chunk-4BJ3O4RQ.js +929 -0
  89. package/dist/chunk-4BOP7T6L.js +2321 -0
  90. package/dist/chunk-4BTDUT2S.js +42 -0
  91. package/dist/chunk-4CSS7WVI.js +143 -0
  92. package/dist/chunk-4CUY7AFY.js +247 -0
  93. package/dist/chunk-4GSN5O5J.js +62 -0
  94. package/dist/chunk-4HN6DF7V.js +1027 -0
  95. package/dist/chunk-4IAPOG5V.js +415 -0
  96. package/dist/chunk-4IYIZQWV.js +48 -0
  97. package/dist/chunk-4NXPXE62.js +84 -0
  98. package/dist/chunk-4RCCF5BR.js +712 -0
  99. package/dist/chunk-4V7NAQ4R.js +19527 -0
  100. package/dist/chunk-4VJITV4P.js +445 -0
  101. package/dist/chunk-4YX7J6QL.js +1859 -0
  102. package/dist/chunk-527OBWQB.js +338 -0
  103. package/dist/chunk-5D4A7E3D.js +448 -0
  104. package/dist/chunk-5DLKYTQX.js +4003 -0
  105. package/dist/chunk-5EERLVZB.js +139 -0
  106. package/dist/chunk-5H72XE4H.js +256 -0
  107. package/dist/chunk-5HDP7XZG.js +91 -0
  108. package/dist/chunk-5LAMRH4X.js +969 -0
  109. package/dist/chunk-5LTN43AS.js +1972 -0
  110. package/dist/chunk-5RBHQYDB.js +2206 -0
  111. package/dist/chunk-5WCQRDRB.js +588 -0
  112. package/dist/chunk-5WRLK5KW.js +700 -0
  113. package/dist/chunk-5ZCXC23G.js +595 -0
  114. package/dist/chunk-6BM72ZMG.js +31 -0
  115. package/dist/chunk-6EDAJH2I.js +68 -0
  116. package/dist/chunk-6EQKFDBH.js +457 -0
  117. package/dist/chunk-6MFRHTRI.js +115 -0
  118. package/dist/chunk-6TZJRKNW.js +321 -0
  119. package/dist/chunk-6V7HGQFZ.js +20 -0
  120. package/dist/chunk-6VWVO2TU.js +3746 -0
  121. package/dist/chunk-6Y5TWI7H.js +146 -0
  122. package/dist/chunk-6Y5U7UFY.js +91 -0
  123. package/dist/chunk-6ZLAK3XG.js +14 -0
  124. package/dist/chunk-72XCRQED.js +34 -0
  125. package/dist/chunk-72YTZMAM.js +589 -0
  126. package/dist/chunk-73BBJOKA.js +263 -0
  127. package/dist/chunk-73NCTWKL.js +188 -0
  128. package/dist/chunk-77I6G4CO.js +1 -0
  129. package/dist/chunk-7DHRDWFS.js +3104 -0
  130. package/dist/chunk-7DNSNKJV.js +78 -0
  131. package/dist/chunk-7FMJVYBS.js +307 -0
  132. package/dist/chunk-7GDRQBQC.js +419 -0
  133. package/dist/chunk-7GPCEFUV.js +270 -0
  134. package/dist/chunk-7IL4A2PP.js +948 -0
  135. package/dist/chunk-7MMLMXO6.js +3679 -0
  136. package/dist/chunk-7QCZSLBH.js +1 -0
  137. package/dist/chunk-7R2WLDOS.js +62 -0
  138. package/dist/chunk-7T7RUJI7.js +949 -0
  139. package/dist/chunk-A2WKSVX7.js +43 -0
  140. package/dist/chunk-A3YGID55.js +133 -0
  141. package/dist/chunk-A722DEVA.js +14 -0
  142. package/dist/chunk-ACDIT7OP.js +1376 -0
  143. package/dist/chunk-ACKIPAOJ.js +302 -0
  144. package/dist/chunk-APPNGGN7.js +365 -0
  145. package/dist/chunk-APV6MK5E.js +137 -0
  146. package/dist/chunk-ASEP3M2W.js +968 -0
  147. package/dist/chunk-AT4TNPWW.js +2931 -0
  148. package/dist/chunk-ATVKCSGT.js +250 -0
  149. package/dist/chunk-AURFMVCD.js +899 -0
  150. package/dist/chunk-AX6GWE7V.js +47 -0
  151. package/dist/chunk-AY5EWJPF.js +385 -0
  152. package/dist/chunk-BAV2HJXS.js +194 -0
  153. package/dist/chunk-BBHRN366.js +89 -0
  154. package/dist/chunk-BBPSTTPA.js +1004 -0
  155. package/dist/chunk-BDATUDDJ.js +992 -0
  156. package/dist/chunk-BKE5PG5L.js +20414 -0
  157. package/dist/chunk-BLPHWMDK.js +797 -0
  158. package/dist/chunk-BSE4R6XD.js +322 -0
  159. package/dist/chunk-BXGMAU4A.js +396 -0
  160. package/dist/chunk-BXI4NXL3.js +507 -0
  161. package/dist/chunk-BZU2O43F.js +1125 -0
  162. package/dist/chunk-C3L6YQ7P.js +147 -0
  163. package/dist/chunk-C57KJOUQ.js +121 -0
  164. package/dist/chunk-CCV7BPSY.js +118 -0
  165. package/dist/chunk-CD7ISXA4.js +826 -0
  166. package/dist/chunk-CE5OZBYY.js +21 -0
  167. package/dist/chunk-CFBIG37O.js +154 -0
  168. package/dist/chunk-CJC6GZ46.js +457 -0
  169. package/dist/chunk-CKCDGXIV.js +408 -0
  170. package/dist/chunk-CKNX3TTP.js +10338 -0
  171. package/dist/chunk-CLKSETWE.js +10 -0
  172. package/dist/chunk-CP7H3HSP.js +1552 -0
  173. package/dist/chunk-CPLEWXNZ.js +66 -0
  174. package/dist/chunk-CQM3A35X.js +844 -0
  175. package/dist/chunk-CS6P76D3.js +103 -0
  176. package/dist/chunk-CTLUBNCW.js +622 -0
  177. package/dist/chunk-CUSRN6RJ.js +632 -0
  178. package/dist/chunk-D5EP5D2W.js +26 -0
  179. package/dist/chunk-D5RYINO7.js +412 -0
  180. package/dist/chunk-DBFS4HMH.js +751 -0
  181. package/dist/chunk-DC4ZYMXJ.js +115 -0
  182. package/dist/chunk-DCBZP442.js +9243 -0
  183. package/dist/chunk-DCYF7EKG.js +26 -0
  184. package/dist/chunk-DDMAFNUK.js +5351 -0
  185. package/dist/chunk-DF5SLDE4.js +966 -0
  186. package/dist/chunk-DJFW7SMX.js +348 -0
  187. package/dist/chunk-DQFLLBJW.js +121 -0
  188. package/dist/chunk-DSFM56OA.js +1203 -0
  189. package/dist/chunk-DTY4APYV.js +218 -0
  190. package/dist/chunk-DXH5JBRS.js +437 -0
  191. package/dist/chunk-E3NTPHEO.js +194 -0
  192. package/dist/chunk-E74LUIID.js +302 -0
  193. package/dist/chunk-EI57M5BI.js +194 -0
  194. package/dist/chunk-EJ4ZAWLV.js +305 -0
  195. package/dist/chunk-EJGCZGUF.js +1483 -0
  196. package/dist/chunk-EK2U3YEG.js +486 -0
  197. package/dist/chunk-ELMFYNV7.js +109 -0
  198. package/dist/chunk-ENRGKNR5.js +25 -0
  199. package/dist/chunk-ETYDXCK7.js +679 -0
  200. package/dist/chunk-EYRH3W74.js +239 -0
  201. package/dist/chunk-F23DIWNN.js +1024 -0
  202. package/dist/chunk-F5JO7HAS.js +94 -0
  203. package/dist/chunk-F7ER6ANO.js +174 -0
  204. package/dist/chunk-FATUVIIN.js +374 -0
  205. package/dist/chunk-FC23CTXV.js +322 -0
  206. package/dist/chunk-FD4ERYEG.js +22 -0
  207. package/dist/chunk-FH7WOJAE.js +79 -0
  208. package/dist/chunk-FHOWVDF5.js +1342 -0
  209. package/dist/chunk-FKAUPHMR.js +96 -0
  210. package/dist/chunk-FONNFJXA.js +137 -0
  211. package/dist/chunk-FQ7FSZRW.js +75 -0
  212. package/dist/chunk-FRG57FPM.js +240 -0
  213. package/dist/chunk-FUVP64ER.js +31 -0
  214. package/dist/chunk-FYOILAN5.js +6818 -0
  215. package/dist/chunk-G35UYQ6Z.js +69 -0
  216. package/dist/chunk-G36W2T2S.js +1143 -0
  217. package/dist/chunk-G3L2L5XZ.js +49 -0
  218. package/dist/chunk-G4THLFV3.js +148 -0
  219. package/dist/chunk-GAFJEYLK.js +29 -0
  220. package/dist/chunk-GFGYB2ZU.js +1689 -0
  221. package/dist/chunk-GG6KJYW6.js +85 -0
  222. package/dist/chunk-GHHFDU2U.js +55 -0
  223. package/dist/chunk-GHTZSQB7.js +57 -0
  224. package/dist/chunk-GK37ILCX.js +1231 -0
  225. package/dist/chunk-GKN3HMN4.js +2809 -0
  226. package/dist/chunk-GNVDBVJP.js +156 -0
  227. package/dist/chunk-GPEL3FBM.js +924 -0
  228. package/dist/chunk-GPSNGPZS.js +1604 -0
  229. package/dist/chunk-GSGD5E4C.js +30 -0
  230. package/dist/chunk-GSUQJJXQ.js +331 -0
  231. package/dist/chunk-GSV226X6.js +110 -0
  232. package/dist/chunk-H2AYQIHW.js +224 -0
  233. package/dist/chunk-H66DXFS5.js +1374 -0
  234. package/dist/chunk-H6G7QRMQ.js +35 -0
  235. package/dist/chunk-H7JAGHZT.js +59 -0
  236. package/dist/chunk-H7ZEFECA.js +316 -0
  237. package/dist/chunk-HAC6EHZZ.js +79 -0
  238. package/dist/chunk-HIO33P3G.js +19 -0
  239. package/dist/chunk-HMVQIPH3.js +547 -0
  240. package/dist/chunk-HOYBYAOA.js +257 -0
  241. package/dist/chunk-HX5P3CSP.js +1784 -0
  242. package/dist/chunk-I46EG2XQ.js +65 -0
  243. package/dist/chunk-I4NPDSCB.js +279 -0
  244. package/dist/chunk-I5WRT7ZR.js +514 -0
  245. package/dist/chunk-IC7I6YIJ.js +301 -0
  246. package/dist/chunk-IDCSOZVN.js +78 -0
  247. package/dist/chunk-IFCBYECK.js +112 -0
  248. package/dist/chunk-IFZCPEY2.js +66 -0
  249. package/dist/chunk-IKFP2KUR.js +48 -0
  250. package/dist/chunk-IRFBN336.js +878 -0
  251. package/dist/chunk-IUXNGKA6.js +152 -0
  252. package/dist/chunk-IV2RVAN7.js +1356 -0
  253. package/dist/chunk-IZYIQQ7X.js +53 -0
  254. package/dist/chunk-J3UUR7DE.js +210 -0
  255. package/dist/chunk-J54VUAY2.js +566 -0
  256. package/dist/chunk-J62KPGII.js +464 -0
  257. package/dist/chunk-J6P3FWWW.js +130 -0
  258. package/dist/chunk-JKBHJQMT.js +434 -0
  259. package/dist/chunk-JLS65NUQ.js +14 -0
  260. package/dist/chunk-JOSYEJKY.js +141 -0
  261. package/dist/chunk-JPKSXKNB.js +94 -0
  262. package/dist/chunk-JQNJB2BB.js +2440 -0
  263. package/dist/chunk-JRVNSWSQ.js +2626 -0
  264. package/dist/chunk-JSWMRQYG.js +28 -0
  265. package/dist/chunk-JZKNBBIB.js +152 -0
  266. package/dist/chunk-K54Y7MLK.js +160 -0
  267. package/dist/chunk-K65546RE.js +183 -0
  268. package/dist/chunk-KM3F7SYE.js +702 -0
  269. package/dist/chunk-KNDYMVWN.js +102 -0
  270. package/dist/chunk-KNT72VR6.js +132 -0
  271. package/dist/chunk-KP6YILMU.js +482 -0
  272. package/dist/chunk-KQEBSK3T.js +274 -0
  273. package/dist/chunk-KT6VHSPF.js +84 -0
  274. package/dist/chunk-KTMW65UX.js +14 -0
  275. package/dist/chunk-KZ5CJVBP.js +1813 -0
  276. package/dist/chunk-L4427KOE.js +26 -0
  277. package/dist/chunk-L6OM4A22.js +189 -0
  278. package/dist/chunk-L7E6XCRA.js +1042 -0
  279. package/dist/chunk-L7JZLXQL.js +173 -0
  280. package/dist/chunk-LAMKBTXX.js +40 -0
  281. package/dist/chunk-LDCF2MKN.js +132 -0
  282. package/dist/chunk-LEIIWPWQ.js +78 -0
  283. package/dist/chunk-LFTQVYBB.js +31 -0
  284. package/dist/chunk-LG3PDRTR.js +2872 -0
  285. package/dist/chunk-LGHII5ET.js +23 -0
  286. package/dist/chunk-LH5QY22X.js +1205 -0
  287. package/dist/chunk-LIVJ6266.js +438 -0
  288. package/dist/chunk-LKRAR3IH.js +276 -0
  289. package/dist/chunk-LO23NABI.js +3063 -0
  290. package/dist/chunk-LO3X5NLS.js +326 -0
  291. package/dist/chunk-LPITVM7M.js +339 -0
  292. package/dist/chunk-LR5IJIGV.js +810 -0
  293. package/dist/chunk-LRGMHROI.js +79 -0
  294. package/dist/chunk-LUVKFFWR.js +315 -0
  295. package/dist/chunk-LWCBNGH6.js +35 -0
  296. package/dist/chunk-LWTN3WRV.js +260 -0
  297. package/dist/chunk-M3HQYKQX.js +308 -0
  298. package/dist/chunk-M6GVSPEH.js +1016 -0
  299. package/dist/chunk-MF5HP6XV.js +221 -0
  300. package/dist/chunk-MHLCBZJB.js +328 -0
  301. package/dist/chunk-MN6PL4AN.js +120 -0
  302. package/dist/chunk-MOEY65Z6.js +5678 -0
  303. package/dist/chunk-MQ4WA34C.js +206 -0
  304. package/dist/chunk-MWHF5V7U.js +223 -0
  305. package/dist/chunk-MWHLBPNU.js +211 -0
  306. package/dist/chunk-MWK5UZQ3.js +1068 -0
  307. package/dist/chunk-MYLH2S4G.js +64 -0
  308. package/dist/chunk-MZ5WYKNA.js +28 -0
  309. package/dist/chunk-N4VTRA7K.js +131 -0
  310. package/dist/chunk-N5DX4JAK.js +12 -0
  311. package/dist/chunk-N65O4XTH.js +5011 -0
  312. package/dist/chunk-NEQUQHOX.js +223 -0
  313. package/dist/chunk-NGK6PEOG.js +25 -0
  314. package/dist/chunk-NJVD4PWE.js +1033 -0
  315. package/dist/chunk-NM6PMYY4.js +768 -0
  316. package/dist/chunk-NN4PJDHP.js +708 -0
  317. package/dist/chunk-NP2V3L7K.js +226 -0
  318. package/dist/chunk-NRLY536M.js +260 -0
  319. package/dist/chunk-NRNE225N.js +1270 -0
  320. package/dist/chunk-NS2K2GTP.js +605 -0
  321. package/dist/chunk-NS33V3IM.js +51 -0
  322. package/dist/chunk-NSHASMZZ.js +71 -0
  323. package/dist/chunk-NWOYOA6H.js +378 -0
  324. package/dist/chunk-NWRUSEXG.js +322 -0
  325. package/dist/chunk-NZGDAWIP.js +1905 -0
  326. package/dist/chunk-O47UOKU3.js +395 -0
  327. package/dist/chunk-O4G2W3ST.js +9831 -0
  328. package/dist/chunk-O6V4PNLO.js +63 -0
  329. package/dist/chunk-OA4GPILI.js +624 -0
  330. package/dist/chunk-OGMSYL6J.js +227 -0
  331. package/dist/chunk-OIS7J26S.js +319 -0
  332. package/dist/chunk-OMX5VL43.js +79 -0
  333. package/dist/chunk-ON3G73BU.js +264 -0
  334. package/dist/chunk-OPYFYTWQ.js +220 -0
  335. package/dist/chunk-OQ6K46CK.js +1734 -0
  336. package/dist/chunk-OYZYO7TV.js +47 -0
  337. package/dist/chunk-OZ4REHIN.js +4386 -0
  338. package/dist/chunk-P47VN5F4.js +282 -0
  339. package/dist/chunk-P5I4X7A7.js +353 -0
  340. package/dist/chunk-P6VQROCO.js +594 -0
  341. package/dist/chunk-P7CQGPLS.js +30 -0
  342. package/dist/chunk-PCAGC5MR.js +1763 -0
  343. package/dist/chunk-PFTQBXS6.js +5181 -0
  344. package/dist/chunk-PGSPX4SU.js +15 -0
  345. package/dist/chunk-PIKLF7BM.js +432 -0
  346. package/dist/chunk-PJWJ3SAV.js +22 -0
  347. package/dist/chunk-PKIFMV72.js +100 -0
  348. package/dist/chunk-PL37JDNA.js +189 -0
  349. package/dist/chunk-PTH5E5XO.js +195 -0
  350. package/dist/chunk-PW6AXLQC.js +4128 -0
  351. package/dist/chunk-PYITM4N2.js +79 -0
  352. package/dist/chunk-PZ5AY32C.js +10 -0
  353. package/dist/chunk-Q3RO7N35.js +45 -0
  354. package/dist/chunk-Q3WIC6GQ.js +2670 -0
  355. package/dist/chunk-Q5XIXSHX.js +271 -0
  356. package/dist/chunk-QGJDMEOV.js +34 -0
  357. package/dist/chunk-QNOB37UH.js +58 -0
  358. package/dist/chunk-QOCOVLUH.js +462 -0
  359. package/dist/chunk-QTCJ5CC5.js +172 -0
  360. package/dist/chunk-QVFV5IP2.js +232 -0
  361. package/dist/chunk-QVZMFDYG.js +29 -0
  362. package/dist/chunk-R35PEUKH.js +511 -0
  363. package/dist/chunk-R4UWBC35.js +200 -0
  364. package/dist/chunk-R6MLCREW.js +44 -0
  365. package/dist/chunk-R6W23LKN.js +254 -0
  366. package/dist/chunk-R7XDDX2A.js +4007 -0
  367. package/dist/chunk-RDFRCT64.js +168 -0
  368. package/dist/chunk-RE5VZDFQ.js +58 -0
  369. package/dist/chunk-RGROYC2G.js +638 -0
  370. package/dist/chunk-RGWHUI5E.js +68 -0
  371. package/dist/chunk-RHVG6UNL.js +205 -0
  372. package/dist/chunk-RI4EX2QE.js +18 -0
  373. package/dist/chunk-RJAAKDRX.js +17 -0
  374. package/dist/chunk-ROMHOSMQ.js +185 -0
  375. package/dist/chunk-RWREC3KJ.js +517 -0
  376. package/dist/chunk-RYNETRDJ.js +118 -0
  377. package/dist/chunk-RZY7RKM5.js +500 -0
  378. package/dist/chunk-S2MNWFAG.js +52 -0
  379. package/dist/chunk-S2VQCZO4.js +22 -0
  380. package/dist/chunk-S54MKU6V.js +117 -0
  381. package/dist/chunk-S5OIDFRM.js +302 -0
  382. package/dist/chunk-SCW4ZF6R.js +150 -0
  383. package/dist/chunk-SLS2N4PH.js +2213 -0
  384. package/dist/chunk-SNLBO4BF.js +247 -0
  385. package/dist/chunk-SP3LFU6B.js +60 -0
  386. package/dist/chunk-SQQTDDQA.js +537 -0
  387. package/dist/chunk-STV6LYYE.js +45 -0
  388. package/dist/chunk-SURZ2WFE.js +326 -0
  389. package/dist/chunk-SZ7DL357.js +1047 -0
  390. package/dist/chunk-T5E4NQCM.js +5742 -0
  391. package/dist/chunk-TAJPCXSB.js +13 -0
  392. package/dist/chunk-TAOOYK3P.js +358 -0
  393. package/dist/chunk-TDSEX5CF.js +24 -0
  394. package/dist/chunk-TFTGP7Z7.js +174 -0
  395. package/dist/chunk-TGON4N4O.js +197 -0
  396. package/dist/chunk-TGQZHDY2.js +2373 -0
  397. package/dist/chunk-TJJZ2OKV.js +6783 -0
  398. package/dist/chunk-TRSVUPCX.js +25 -0
  399. package/dist/chunk-TSXGRLPR.js +107 -0
  400. package/dist/chunk-U2S3YEX3.js +224 -0
  401. package/dist/chunk-U45RTRGY.js +818 -0
  402. package/dist/chunk-U6C3VVWS.js +13 -0
  403. package/dist/chunk-UDMS5AD3.js +307 -0
  404. package/dist/chunk-UGX7GI37.js +94 -0
  405. package/dist/chunk-UH3JJSHK.js +1 -0
  406. package/dist/chunk-UHRBTZYY.js +208 -0
  407. package/dist/chunk-UHT2KRG5.js +193 -0
  408. package/dist/chunk-UI2F6DJ5.js +118 -0
  409. package/dist/chunk-UMAKSB4Z.js +284 -0
  410. package/dist/chunk-UR2IBGIM.js +521 -0
  411. package/dist/chunk-UUH2RVKS.js +585 -0
  412. package/dist/chunk-UVJ4PJDK.js +4533 -0
  413. package/dist/chunk-V53UG2OT.js +9924 -0
  414. package/dist/chunk-V72RMBM4.js +48 -0
  415. package/dist/chunk-VBNCKCCI.js +16 -0
  416. package/dist/chunk-VNSYKC25.js +24 -0
  417. package/dist/chunk-VPHVFK4A.js +1984 -0
  418. package/dist/chunk-VTLNJQ44.js +133 -0
  419. package/dist/chunk-VTW7HP3R.js +100 -0
  420. package/dist/chunk-VVGEPBPS.js +218 -0
  421. package/dist/chunk-VVLLL7I4.js +166 -0
  422. package/dist/chunk-VX3UMWB7.js +483 -0
  423. package/dist/chunk-VXF4Q3FW.js +20 -0
  424. package/dist/chunk-W3JMT2YY.js +712 -0
  425. package/dist/chunk-WDUORIHF.js +877 -0
  426. package/dist/chunk-WDVTY4U6.js +148 -0
  427. package/dist/chunk-WIFZCHEG.js +12566 -0
  428. package/dist/chunk-WIRN3F75.js +736 -0
  429. package/dist/chunk-WMPU2UOV.js +82 -0
  430. package/dist/chunk-WTOKKE2V.js +784 -0
  431. package/dist/chunk-WX5IRLF6.js +740 -0
  432. package/dist/chunk-WZ6U3O7I.js +1581 -0
  433. package/dist/chunk-XAONGNST.js +57 -0
  434. package/dist/chunk-XB5YLCLB.js +13 -0
  435. package/dist/chunk-XEP5NQ5Y.js +688 -0
  436. package/dist/chunk-XGYF2QMZ.js +351 -0
  437. package/dist/chunk-XHEKQENB.js +255 -0
  438. package/dist/chunk-XNO4FM6X.js +1124 -0
  439. package/dist/chunk-XPHKYHO4.js +878 -0
  440. package/dist/chunk-XPK2I4NC.js +405 -0
  441. package/dist/chunk-XPU2XADL.js +2175 -0
  442. package/dist/chunk-XQD2B6BB.js +507 -0
  443. package/dist/chunk-XT2ZQVTC.js +558 -0
  444. package/dist/chunk-XTXJGGUV.js +351 -0
  445. package/dist/chunk-XUXVDPSZ.js +50 -0
  446. package/dist/chunk-XV7NZL4B.js +57 -0
  447. package/dist/chunk-XZE4XARH.js +563 -0
  448. package/dist/chunk-XZYR5EDO.js +152 -0
  449. package/dist/chunk-Y3J4JMTU.js +61 -0
  450. package/dist/chunk-Y55LZN5U.js +52 -0
  451. package/dist/chunk-Y5VN7DMP.js +112 -0
  452. package/dist/chunk-Y67VAHN4.js +459 -0
  453. package/dist/chunk-YAXSKEUH.js +3544 -0
  454. package/dist/chunk-YB3JD4E6.js +975 -0
  455. package/dist/chunk-YESZJFK6.js +220 -0
  456. package/dist/chunk-YGXKOBQQ.js +292 -0
  457. package/dist/chunk-YMX76IOS.js +31 -0
  458. package/dist/chunk-YOTXESEH.js +257 -0
  459. package/dist/chunk-YTYIEZQY.js +119 -0
  460. package/dist/chunk-YVORHQ2S.js +579 -0
  461. package/dist/chunk-Z2CUQDAR.js +3429 -0
  462. package/dist/chunk-Z2KYOFHS.js +7000 -0
  463. package/dist/chunk-Z6PC7QX6.js +161 -0
  464. package/dist/chunk-ZDTGECTN.js +235 -0
  465. package/dist/chunk-ZIPWI2LY.js +151 -0
  466. package/dist/chunk-ZSKKMTQJ.js +554 -0
  467. package/dist/chunk-ZTT5IVPY.js +1160 -0
  468. package/dist/chunk-ZX65UI5W.js +78 -0
  469. package/dist/chunk-ZYG7GGKO.js +218 -0
  470. package/dist/chunk-ZZZUL4OF.js +38 -0
  471. package/dist/cli-utils-IXL26KJT.js +40 -0
  472. package/dist/cli-validation-WLXWLUJL.js +111 -0
  473. package/dist/commit-utils-P7CRJF5N.js +202 -0
  474. package/dist/compete-config-resolver-R5ULXMYH.js +76 -0
  475. package/dist/compete-request-62JESVET.js +364 -0
  476. package/dist/compete-results-QEPG6FZX.js +208 -0
  477. package/dist/competition-outcome-tracker-R32OOZ43.js +38 -0
  478. package/dist/config-JCOKXOQT.js +166 -0
  479. package/dist/config-audit-EL3GHXS7.js +360 -0
  480. package/dist/config-explain-TNILDEVJ.js +12 -0
  481. package/dist/config-loader-VPFPFO4B.js +38 -0
  482. package/dist/config-manager-7T4E2BQO.js +67 -0
  483. package/dist/config-validator-KKOHOW7O.js +72 -0
  484. package/dist/cost-YC42XUF3.js +53 -0
  485. package/dist/coverage-orchestrator-CISNKJC2.js +772 -0
  486. package/dist/coverage-scanner-YVD62MLH.js +12 -0
  487. package/dist/createCompetitionRunner-LJG6ZQSO.js +46 -0
  488. package/dist/data-migration-state-VJK64DLT.js +31 -0
  489. package/dist/db-migrator-XSEIOGWY.js +34 -0
  490. package/dist/discovery-JGYGDD25.js +25 -0
  491. package/dist/doctor-GJOYE7AE.js +186 -0
  492. package/dist/domain-analyzer-AWF3RP6E.js +29 -0
  493. package/dist/ensure-initialized-744DIZEZ.js +52 -0
  494. package/dist/entry.js +940 -0
  495. package/dist/environment-YS45U5ZI.js +81 -0
  496. package/dist/error-parser-core-PPZ36A4S.js +50 -0
  497. package/dist/escalation-ladder-MKTCEGSA.js +130 -0
  498. package/dist/evaluation-context-KV4GZNN7.js +35 -0
  499. package/dist/evidence-plan-resolver-GBSYSAPX.js +85 -0
  500. package/dist/execution-data-writer-3ODTBDLH.js +53 -0
  501. package/dist/execution-policy-applier-ZHD3DCF3.js +31 -0
  502. package/dist/execution-preflight-Z4Y64V3I.js +209 -0
  503. package/dist/execution-roles-R3DPPMD3.js +66 -0
  504. package/dist/exit-code-error-Z4SW2DVK.js +14 -0
  505. package/dist/external-temp-cleanup-N2RZH4QP.js +311 -0
  506. package/dist/factory-XBN7DFIM.js +149 -0
  507. package/dist/file-utils-XIVR2ZMA.js +47 -0
  508. package/dist/flywheel-autoloop-executor-UILGOFFK.js +249 -0
  509. package/dist/flywheel-competition-executor-JOBEXTRB.js +259 -0
  510. package/dist/flywheel-executor-6JFLA6J5.js +369 -0
  511. package/dist/flywheel-git-isolation-UC5NIEVU.js +48 -0
  512. package/dist/flywheel-manifest-5UC4VBMA.js +108 -0
  513. package/dist/flywheel-model-defaults-7CVKP53V.js +27 -0
  514. package/dist/flywheel-preflight-XEY5SHM6.js +104 -0
  515. package/dist/flywheel-resume-7HELH7QS.js +23 -0
  516. package/dist/flywheel-safety-7U7DPOAP.js +28 -0
  517. package/dist/flywheel-scope-decision-ZHKF6ZIN.js +11 -0
  518. package/dist/get-telemetry-logger-DPVWWIYY.js +73 -0
  519. package/dist/git-worktree-IY6V6DUO.js +18 -0
  520. package/dist/github-pr-manager-4LXEKJTA.js +211 -0
  521. package/dist/guidance-profile-config-E7XJL2VP.js +117 -0
  522. package/dist/guidance-profile-renderer-QK2YMAAP.js +21 -0
  523. package/dist/index-query-4JEUKA44.js +31 -0
  524. package/dist/index.js +108661 -0
  525. package/dist/instructions-6BURLQJC.js +64 -0
  526. package/dist/invoke-provider-auth-GRUYP44M.js +223 -0
  527. package/dist/judge-scoring.json +80 -0
  528. package/dist/judge-test.js +555 -0
  529. package/dist/lab-mode-OTWVHN63.js +39 -0
  530. package/dist/lab-utils-BJRFLGK4.js +23 -0
  531. package/dist/linux-host-class-UY4KVLFD.js +29 -0
  532. package/dist/llm-judge-executor-F7Z3HO77.js +133 -0
  533. package/dist/local-executor-CEHWE2PL.js +223 -0
  534. package/dist/logger-33TR6EE5.js +72 -0
  535. package/dist/loop-spec-XTLQAVZ7.js +191 -0
  536. package/dist/manager-2HJG5CLT.js +25 -0
  537. package/dist/matrix-prompt-builder-6UDN5X3F.js +497 -0
  538. package/dist/matrix-result-parser-7W35EUOV.js +15 -0
  539. package/dist/metadata-HQ43NDEK.js +22 -0
  540. package/dist/model-invocations-db-QBO4Y7WZ.js +38 -0
  541. package/dist/monitor-XGYBG2DW.js +72 -0
  542. package/dist/next-PB5ZXZKB.js +90 -0
  543. package/dist/next-ZBDK725T.js +69 -0
  544. package/dist/optimization-config-resolver-O6WKR47U.js +75 -0
  545. package/dist/package-3YCWIQQ5.js +10 -0
  546. package/dist/parallel-orchestrator-NL7YJJU2.js +297 -0
  547. package/dist/parallel-worker.js +279 -0
  548. package/dist/parse-git-status-PIAF3OTP.js +10 -0
  549. package/dist/path-security-ETTH6TZL.js +39 -0
  550. package/dist/pattern-bank-UNJR5ADV.js +15 -0
  551. package/dist/plan-backlog-list-fast-VAGYBV3J.js +270 -0
  552. package/dist/plan-backlog-show-fast-SG2CZPW3.js +406 -0
  553. package/dist/plan-sprint-list-fast-LURAX47V.js +162 -0
  554. package/dist/plan-sprint-status-fast-FJAODCHD.js +208 -0
  555. package/dist/plan-task-status-fast-HNYBMQI4.js +349 -0
  556. package/dist/plan-to-flywheel-Z4U3GWPN.js +456 -0
  557. package/dist/planning-backlog-3CQ5QQBQ.js +319 -0
  558. package/dist/poetic-root-V5DNXEAE.js +17 -0
  559. package/dist/preflight-OPANWMME.js +12 -0
  560. package/dist/process-registry-PDZJPTAS.js +27 -0
  561. package/dist/process-scanner-C22SYXYD.js +22 -0
  562. package/dist/processes-KMQUD7HY.js +29 -0
  563. package/dist/processes-json-fast-IBDXZ6WW.js +135 -0
  564. package/dist/profile-SE5EVXAP.js +149 -0
  565. package/dist/prompts-WZZPGWBX.js +168 -0
  566. package/dist/protected-branches-RNTEX7ET.js +57 -0
  567. package/dist/provider-aware-resource-manager-QBTZJMNP.js +18 -0
  568. package/dist/provider-matrix-N5X57V3Y.js +154 -0
  569. package/dist/provider-matrix-renderer-MZDWKKID.js +139 -0
  570. package/dist/provider-output-forwarding-DERID3TP.js +30 -0
  571. package/dist/provider-registry-J5NRBJKI.js +128 -0
  572. package/dist/provider-temp-cleanup-KYGLF6YU.js +14 -0
  573. package/dist/prune-engine-Q6E2DXBN.js +451 -0
  574. package/dist/quality-gate-YRHMQAEI.js +70 -0
  575. package/dist/quickstart-FIRLKGJI.js +62 -0
  576. package/dist/readiness-VZTMSG6J.js +96 -0
  577. package/dist/registry-YODFY77A.js +153 -0
  578. package/dist/repair-helpers-TTV5FEF4.js +117 -0
  579. package/dist/repo-root-2IGD4H7X.js +22 -0
  580. package/dist/resolution-engine-D6TX6FRG.js +127 -0
  581. package/dist/resolve-provider-cli-O2P6XZBZ.js +35 -0
  582. package/dist/restore-telemetry-db-BQL6DTQF.js +360 -0
  583. package/dist/result-streamer-WEHW476R.js +19 -0
  584. package/dist/routing-events-DHPUZDDF.js +27 -0
  585. package/dist/routing-history-store-UWCEXAP3.js +46 -0
  586. package/dist/routing-planner-F5WQEUOM.js +160 -0
  587. package/dist/run-poetic-tui-J6LWRJUP.js +13517 -0
  588. package/dist/run-simulation.js +376 -0
  589. package/dist/runner-CS2TNGHA.js +1092 -0
  590. package/dist/runner-HHH7ZN2Z.js +1571 -0
  591. package/dist/safety-OCC4KJJR.js +64 -0
  592. package/dist/safety-stanza-7SV3HGG3.js +60 -0
  593. package/dist/sandbox-32QXJEMV.js +81 -0
  594. package/dist/sandbox-RSO7VP6V.js +94 -0
  595. package/dist/schema-extensions.sql +234 -0
  596. package/dist/security-2KI5XNDG.js +17 -0
  597. package/dist/setup-bb-plugin-QAQWZCV5.js +738 -0
  598. package/dist/setup-claude-code-P7BTTSPO.js +317 -0
  599. package/dist/setup-temp-cleanup-GASCWZ2I.js +20 -0
  600. package/dist/shared-utils-D6U6UREP.js +37 -0
  601. package/dist/simple-artifact-goal-OTXNGZY6.js +25 -0
  602. package/dist/sprint-UIXPYOXQ.js +338 -0
  603. package/dist/sprint-bridge-4BHMSC3M.js +68 -0
  604. package/dist/sprint-execution-service-2B7WHL5L.js +311 -0
  605. package/dist/sprint-manager-IDQUDNQI.js +91 -0
  606. package/dist/sqlite-wrapper-UDWCTNLJ.js +17 -0
  607. package/dist/stale-cleanup-orchestrator-XWXV7KCZ.js +62 -0
  608. package/dist/storage-access-F6ALDN4S.js +22 -0
  609. package/dist/synthesis-XD6EDVHF.js +185 -0
  610. package/dist/task-classifier-LNLXSHOM.js +494 -0
  611. package/dist/task-list-fast-PTMA4LUC.js +147 -0
  612. package/dist/task-manager-XAT7GOWB.js +93 -0
  613. package/dist/task-splitter-U7DJ7W6A.js +79 -0
  614. package/dist/task-type-detector-OLVOMXZO.js +21 -0
  615. package/dist/task-type-resolver-KKNQYSB4.js +42 -0
  616. package/dist/telemetry-5HWBBXLX.js +131 -0
  617. package/dist/telemetry-health-tracker-DMSSGBZ2.js +11 -0
  618. package/dist/telemetry-path-resolver-7ICSG276.js +28 -0
  619. package/dist/telemetry-reliability-XUOZNZZ6.js +125 -0
  620. package/dist/token-estimator-MEQUL3EJ.js +37 -0
  621. package/dist/transports-KNSSV2V4.js +255 -0
  622. package/dist/unified-cost-tracker-4TFRBVPR.js +35 -0
  623. package/dist/unified-state-cleanup-LJPF2BOW.js +276 -0
  624. package/dist/universal-cost-calculator-BAJV35GA.js +42 -0
  625. package/dist/user-agents-GHUGCSKN.js +22 -0
  626. package/dist/variant-delivery-state-KLRNG6XA.js +33 -0
  627. package/dist/variant-state-cleanup-MZGGLQAJ.js +280 -0
  628. package/dist/variant-success-PJXWE3ZV.js +12 -0
  629. package/dist/variant-worker-KUWKBLAH.js +4196 -0
  630. package/dist/variant-worker.js +24 -0
  631. package/dist/variants-JE2FSAQS.js +233 -0
  632. package/dist/verification-toolchains-V24UHW6Q.js +28 -0
  633. package/dist/verify-commands-H3DTCSGI.js +37 -0
  634. package/dist/warning-EGQGUUIO.js +12 -0
  635. package/dist/work-edge-RWEDWJZF.js +49 -0
  636. package/dist/work-item-writer-WHAVZXAY.js +19 -0
  637. package/dist/worker-7SA2VS2Y.js +1435 -0
  638. package/dist/worker.js +19 -0
  639. package/dist/worktree-metrics-3DFUYVYE.js +26 -0
  640. package/dist/writeback-VZKHYHSN.js +44 -0
  641. package/docs/CLI_REFERENCE.md +7042 -0
  642. package/docs/PROVIDER_SETUP.md +1570 -0
  643. package/docs/README.md +96 -0
  644. package/docs/TROUBLESHOOTING.md +2232 -0
  645. package/docs/getting-started/QUICK_START.md +294 -0
  646. package/docs/getting-started/README.md +188 -0
  647. package/docs/getting-started/SETUP.md +52 -0
  648. package/docs/reference/AGENT_CONTEXT.md +38 -0
  649. package/docs/reference/PROVIDER_RELEASE_TIERS.md +34 -0
  650. package/docs/reference/README.md +381 -0
  651. package/docs/reference/SECURITY.md +262 -0
  652. package/integrations/bb-plugin-poetic/README.md +362 -0
  653. package/integrations/bb-plugin-poetic/app.css +341 -0
  654. package/integrations/bb-plugin-poetic/app.tsx +5059 -0
  655. package/integrations/bb-plugin-poetic/package.json +45 -0
  656. package/integrations/bb-plugin-poetic/server.ts +444 -0
  657. package/integrations/bb-plugin-poetic/src/adapter.ts +3312 -0
  658. package/integrations/bb-plugin-poetic/src/backlog-authoring-model.ts +150 -0
  659. package/integrations/bb-plugin-poetic/src/backlog-authoring-schema.ts +355 -0
  660. package/integrations/bb-plugin-poetic/src/backlog-authoring-service.ts +419 -0
  661. package/integrations/bb-plugin-poetic/src/backlog-authoring-view.ts +1026 -0
  662. package/integrations/bb-plugin-poetic/src/competition-defaults-schema.ts +122 -0
  663. package/integrations/bb-plugin-poetic/src/competition-defaults-service.ts +105 -0
  664. package/integrations/bb-plugin-poetic/src/competition-defaults-view.ts +138 -0
  665. package/integrations/bb-plugin-poetic/src/contract.ts +615 -0
  666. package/integrations/bb-plugin-poetic/src/finalize-model.ts +205 -0
  667. package/integrations/bb-plugin-poetic/src/finalize-schema.ts +158 -0
  668. package/integrations/bb-plugin-poetic/src/finalize-service.ts +382 -0
  669. package/integrations/bb-plugin-poetic/src/finalize-view.ts +159 -0
  670. package/integrations/bb-plugin-poetic/src/judge-operations-readback.ts +303 -0
  671. package/integrations/bb-plugin-poetic/src/judge-operations-schema.ts +33 -0
  672. package/integrations/bb-plugin-poetic/src/judge-operations-view.ts +459 -0
  673. package/integrations/bb-plugin-poetic/src/model.ts +1302 -0
  674. package/integrations/bb-plugin-poetic/src/monitor-service.ts +233 -0
  675. package/integrations/bb-plugin-poetic/src/panel-read-ux.ts +97 -0
  676. package/integrations/bb-plugin-poetic/src/patch-preview-schema.ts +166 -0
  677. package/integrations/bb-plugin-poetic/src/patch-preview-service.ts +480 -0
  678. package/integrations/bb-plugin-poetic/src/patch-preview-view.ts +109 -0
  679. package/integrations/bb-plugin-poetic/src/planning-readback.ts +204 -0
  680. package/integrations/bb-plugin-poetic/src/planning-service.ts +594 -0
  681. package/integrations/bb-plugin-poetic/src/planning-workspace-schema.ts +95 -0
  682. package/integrations/bb-plugin-poetic/src/planning-workspace.ts +323 -0
  683. package/integrations/bb-plugin-poetic/src/poll-handoff.ts +136 -0
  684. package/integrations/bb-plugin-poetic/src/project-target-server.ts +21 -0
  685. package/integrations/bb-plugin-poetic/src/project-target.ts +45 -0
  686. package/integrations/bb-plugin-poetic/src/reference-index.ts +192 -0
  687. package/integrations/bb-plugin-poetic/src/repository-schema.ts +30 -0
  688. package/integrations/bb-plugin-poetic/src/result-explorer-view.ts +597 -0
  689. package/integrations/bb-plugin-poetic/src/result-readback-model.ts +163 -0
  690. package/integrations/bb-plugin-poetic/src/result-readback-schema.ts +319 -0
  691. package/integrations/bb-plugin-poetic/src/result-readback-service.ts +333 -0
  692. package/integrations/bb-plugin-poetic/src/run-page-view.ts +177 -0
  693. package/integrations/bb-plugin-poetic/src/setup-config-schema.ts +291 -0
  694. package/integrations/bb-plugin-poetic/src/setup-config-service.ts +590 -0
  695. package/integrations/bb-plugin-poetic/src/setup-config-view.ts +413 -0
  696. package/integrations/bb-plugin-poetic/src/sprint-close-model.ts +150 -0
  697. package/integrations/bb-plugin-poetic/src/sprint-close-schema.ts +136 -0
  698. package/integrations/bb-plugin-poetic/src/sprint-close-service.ts +341 -0
  699. package/integrations/bb-plugin-poetic/src/sprint-close-view.ts +116 -0
  700. package/integrations/bb-plugin-poetic/src/sprint-composition-model.ts +714 -0
  701. package/integrations/bb-plugin-poetic/src/sprint-composition-readback.ts +231 -0
  702. package/integrations/bb-plugin-poetic/src/sprint-composition-schema.ts +601 -0
  703. package/integrations/bb-plugin-poetic/src/sprint-composition-service.ts +775 -0
  704. package/integrations/bb-plugin-poetic/src/sprint-composition-view.ts +1221 -0
  705. package/integrations/bb-plugin-poetic/src/task-authoring-model.ts +567 -0
  706. package/integrations/bb-plugin-poetic/src/task-authoring-schema.ts +635 -0
  707. package/integrations/bb-plugin-poetic/src/task-authoring-service.ts +842 -0
  708. package/integrations/bb-plugin-poetic/src/task-authoring-view.ts +1227 -0
  709. package/integrations/bb-plugin-poetic/src/task-detail-readback.ts +56 -0
  710. package/integrations/bb-plugin-poetic/src/task-detail-schema.ts +144 -0
  711. package/integrations/bb-plugin-poetic/src/task-navigation.ts +446 -0
  712. package/integrations/bb-plugin-poetic/src/workbench-route.ts +74 -0
  713. package/integrations/bb-plugin-poetic/tests/host-contract.test.ts +773 -0
  714. package/integrations/bb-plugin-poetic/tsconfig.json +18 -0
  715. package/integrations/bb-plugin-poetic/types/PROVENANCE.json +52 -0
  716. package/integrations/bb-plugin-poetic/types/bb-plugin-sdk-app.d.ts +1444 -0
  717. package/integrations/bb-plugin-poetic/types/bb-plugin-sdk.d.ts +13030 -0
  718. package/integrations/bb-plugin-poetic/vitest.host.config.ts +71 -0
  719. package/npm-shrinkwrap.json +4950 -0
  720. package/package.json +331 -0
  721. package/schemas/README.md +80 -0
  722. package/schemas/config-v1.schema.json +136 -0
  723. package/schemas/execution-config.schema.json +47 -0
  724. package/schemas/judge-scoring.schema.json +370 -0
  725. package/schemas/poetic.config.schema.json +2214 -0
  726. package/schemas/provider-config.schema.json +203 -0
  727. package/schemas/telemetry-config.schema.json +79 -0
  728. package/schemas/user-preferences.schema.json +141 -0
  729. package/scripts/assert-node-runtime.mjs +140 -0
  730. package/scripts/preflight-native.mjs +49 -0
  731. package/scripts/preinstall-node-check.mjs +78 -0
  732. package/scripts/setup-git-hooks.mjs +24 -0
  733. package/scripts/sync.sh +2722 -0
  734. package/scripts/write-node-launcher.sh +108 -0
  735. package/src/resources/gemini/slash-packs/default/plan.toml +15 -0
  736. package/src/resources/gemini/slash-packs/default/summary.toml +16 -0
  737. package/src/resources/gemini/slash-packs/default/tests.toml +16 -0
  738. package/templates/.poetic/README.md +37 -0
  739. package/templates/.poetic/agents/README.md +296 -0
  740. package/templates/.poetic/agents/api-documenter.md +147 -0
  741. package/templates/.poetic/agents/backend-architect.md +31 -0
  742. package/templates/.poetic/agents/code-reviewer.md +157 -0
  743. package/templates/.poetic/agents/data-scientist.md +179 -0
  744. package/templates/.poetic/agents/database-optimizer.md +145 -0
  745. package/templates/.poetic/agents/debugger.md +31 -0
  746. package/templates/.poetic/agents/deployment-engineer.md +164 -0
  747. package/templates/.poetic/agents/devops-troubleshooter.md +139 -0
  748. package/templates/.poetic/agents/frontend-developer.md +150 -0
  749. package/templates/.poetic/agents/javascript-pro.md +36 -0
  750. package/templates/.poetic/agents/performance-engineer.md +151 -0
  751. package/templates/.poetic/agents/python-pro.md +137 -0
  752. package/templates/.poetic/agents/test-automator.md +147 -0
  753. package/templates/.poetic/agents/typescript-pro.md +34 -0
  754. package/templates/.poetic/config/poetic.config.jsonc +69 -0
  755. package/templates/.poetic/config/project-context.template.json +6 -0
  756. package/templates/.poetic/config/task-type-aliases.presets/kanban.yaml +14 -0
  757. package/templates/.poetic/config/task-type-aliases.presets/scrum.yaml +17 -0
  758. package/templates/.poetic/config/task-type-aliases.presets/xp.yaml +12 -0
  759. package/templates/.poetic/config/task-type-aliases.yaml +28 -0
  760. package/templates/.poetic/gitignore.template +55 -0
  761. package/templates/.poetic/task-types/analysis.yaml +40 -0
  762. package/templates/.poetic/task-types/architecture.yaml +38 -0
  763. package/templates/.poetic/task-types/doc.yaml +35 -0
  764. package/templates/.poetic/task-types/feature.yaml +23 -0
  765. package/templates/.poetic/task-types/general.yaml +6 -0
  766. package/templates/.poetic/task-types/security.yaml +39 -0
  767. package/templates/AGENTS.template.md +99 -0
  768. package/templates/CLAUDE.template.md +1 -0
  769. package/templates/GEMINI.template.md +1 -0
  770. package/templates/builtin-workflows/code-review.yaml +73 -0
  771. package/templates/builtin-workflows/compete-streak.yaml +78 -0
  772. package/templates/builtin-workflows/hello-verify.yaml +10 -0
  773. package/templates/builtin-workflows/judge-regression.yaml +114 -0
  774. package/templates/builtin-workflows/skills/code-review/SKILL.md +60 -0
  775. package/templates/builtin-workflows/skills/hello-verify/SKILL.md +6 -0
  776. package/templates/guard-kit/GUARD_SETUP.md.template +255 -0
  777. package/templates/guard-kit/check.mjs.template +777 -0
  778. package/templates/guard-kit/config.json.template +6 -0
  779. package/templates/guard-kit/poetic-guard.yml.template +189 -0
  780. package/templates/profiles/README.md +56 -0
  781. package/templates/profiles/frontier-claude.json +27 -0
  782. package/templates/profiles/frontier-codex.json +26 -0
@@ -0,0 +1,1972 @@
1
+ import {
2
+ StaleVersionError
3
+ } from "./chunk-TDSEX5CF.js";
4
+ import {
5
+ generateEnhancements,
6
+ hintsFromEnhancements,
7
+ toEnhancementSet,
8
+ toPersistedFormat
9
+ } from "./chunk-LIVJ6266.js";
10
+ import {
11
+ BUILT_IN_VARIANT_STRATEGIES
12
+ } from "./chunk-VXF4Q3FW.js";
13
+ import {
14
+ getDefaultActivityForCategory
15
+ } from "./chunk-4RCCF5BR.js";
16
+ import {
17
+ isTaskStatus,
18
+ validateStateTransition
19
+ } from "./chunk-KNT72VR6.js";
20
+ import {
21
+ classifyTaskDependency,
22
+ loadAllItems
23
+ } from "./chunk-3BCUNHKF.js";
24
+ import {
25
+ getArchiveShard,
26
+ getArchivedFilePath
27
+ } from "./chunk-OYZYO7TV.js";
28
+ import {
29
+ generateId,
30
+ isValidId
31
+ } from "./chunk-VNSYKC25.js";
32
+ import {
33
+ assertCompletionContractsMet,
34
+ normalizeCompletionContracts
35
+ } from "./chunk-R35PEUKH.js";
36
+ import {
37
+ getPlanningRoot,
38
+ withIndexRegeneration
39
+ } from "./chunk-OPYFYTWQ.js";
40
+ import {
41
+ getBucketArchivePathByKind,
42
+ getBucketByName,
43
+ getBucketPathByKind
44
+ } from "./chunk-HOYBYAOA.js";
45
+ import {
46
+ assertSafePlanningFileId,
47
+ ensureDirectoryExists,
48
+ listMarkdownFiles,
49
+ listMarkdownFilesRecursive,
50
+ listMarkdownFilesRecursiveStrict,
51
+ readMarkdownFile,
52
+ resolvePlanningItemPath,
53
+ writeMarkdownFile
54
+ } from "./chunk-OIS7J26S.js";
55
+ import {
56
+ emitCustomWarning
57
+ } from "./chunk-EJGCZGUF.js";
58
+
59
+ // src/planning/task-manager.ts
60
+ import * as crypto from "crypto";
61
+ import * as fs from "fs/promises";
62
+ import * as path from "path";
63
+ function isBuiltInStrategy(value) {
64
+ return typeof value === "string" && BUILT_IN_VARIANT_STRATEGIES.includes(value);
65
+ }
66
+ function emitTaskManagerWarning(message, metadata) {
67
+ emitCustomWarning(
68
+ "WARN" /* WARN */,
69
+ "configuration" /* CONFIGURATION */,
70
+ message,
71
+ {
72
+ subsystem: "planning/task-manager",
73
+ executionPhase: "execution"
74
+ },
75
+ { metadata, skipConsole: true }
76
+ );
77
+ }
78
+ function parseNumber(value, fallback) {
79
+ if (typeof value === "number" && Number.isFinite(value)) return value;
80
+ if (typeof value === "string") {
81
+ const parsed = Number.parseFloat(value);
82
+ if (Number.isFinite(parsed)) return parsed;
83
+ }
84
+ return fallback;
85
+ }
86
+ function parseOptionalNumber(value) {
87
+ if (typeof value === "number" && Number.isFinite(value)) return value;
88
+ if (typeof value === "string") {
89
+ const parsed = Number.parseFloat(value);
90
+ if (Number.isFinite(parsed)) return parsed;
91
+ }
92
+ return void 0;
93
+ }
94
+ var RUNTIME_ESTIMATE_PROVENANCES = ["heuristic", "telemetry", "blended", "explicit"];
95
+ var RUNTIME_ESTIMATE_CONFIDENCES = ["low", "medium", "high"];
96
+ function coerceRuntimeEstimateFields(frontMatter) {
97
+ const result = {};
98
+ const minutes = parseOptionalNumber(frontMatter.expectedRuntimeMinutes);
99
+ if (typeof minutes === "number" && minutes > 0) {
100
+ result.expectedRuntimeMinutes = minutes;
101
+ }
102
+ const provenance = frontMatter.runtimeEstimateProvenance;
103
+ if (typeof provenance === "string" && RUNTIME_ESTIMATE_PROVENANCES.includes(provenance)) {
104
+ result.runtimeEstimateProvenance = provenance;
105
+ }
106
+ const confidence = frontMatter.runtimeEstimateConfidence;
107
+ if (typeof confidence === "string" && RUNTIME_ESTIMATE_CONFIDENCES.includes(confidence)) {
108
+ result.runtimeEstimateConfidence = confidence;
109
+ }
110
+ return result;
111
+ }
112
+ var VALID_STAGE_OUTPUT_TYPES = [
113
+ "diff",
114
+ "files",
115
+ "text",
116
+ "testResults",
117
+ "json"
118
+ ];
119
+ function coerceStageOutputs(value) {
120
+ if (!value || typeof value !== "object") return void 0;
121
+ const outputs = {};
122
+ for (const [key, raw] of Object.entries(value)) {
123
+ if (!key || typeof key !== "string") continue;
124
+ if (typeof raw !== "string") continue;
125
+ if (!VALID_STAGE_OUTPUT_TYPES.includes(raw)) continue;
126
+ outputs[key] = raw;
127
+ }
128
+ return Object.keys(outputs).length > 0 ? outputs : void 0;
129
+ }
130
+ function coerceStageValidationOverride(value) {
131
+ if (!value || typeof value !== "object") return void 0;
132
+ const raw = value;
133
+ const enabled = typeof raw.enabled === "boolean" ? raw.enabled : void 0;
134
+ const target = typeof raw.target === "string" ? raw.target : void 0;
135
+ const threshold = parseOptionalNumber(raw.threshold);
136
+ const maxRetries = parseOptionalNumber(raw.maxRetries);
137
+ const requiredFiles = Array.isArray(raw.requiredFiles) ? raw.requiredFiles.filter(
138
+ (value2) => typeof value2 === "string" && value2.trim().length > 0
139
+ ) : void 0;
140
+ const checks = Array.isArray(raw.checks) ? raw.checks : void 0;
141
+ const semanticChecks = Array.isArray(raw.semanticChecks) ? raw.semanticChecks : void 0;
142
+ if (enabled === void 0 && target === void 0 && threshold === void 0 && maxRetries === void 0 && requiredFiles === void 0 && checks === void 0 && semanticChecks === void 0) {
143
+ return void 0;
144
+ }
145
+ return {
146
+ ...enabled !== void 0 ? { enabled } : {},
147
+ ...target ? { target } : {},
148
+ ...threshold !== void 0 ? { threshold } : {},
149
+ ...maxRetries !== void 0 ? { maxRetries } : {},
150
+ ...requiredFiles && requiredFiles.length > 0 ? { requiredFiles } : {},
151
+ ...checks ? { checks } : {},
152
+ ...semanticChecks ? { semanticChecks } : {}
153
+ };
154
+ }
155
+ function coerceVariantSpec(value) {
156
+ if (typeof value === "string") {
157
+ const [providerRaw, strategyRaw2] = value.split(":").map((v) => v.trim());
158
+ if (!providerRaw) return null;
159
+ const strategy2 = isBuiltInStrategy(strategyRaw2) ? strategyRaw2 : void 0;
160
+ return { provider: providerRaw, ...strategy2 ? { strategy: strategy2 } : {} };
161
+ }
162
+ if (!value || typeof value !== "object") return null;
163
+ const raw = value;
164
+ const provider = typeof raw.provider === "string" ? raw.provider : void 0;
165
+ if (!provider) return null;
166
+ const model = typeof raw.model === "string" ? raw.model : void 0;
167
+ const strategyRaw = typeof raw.strategy === "string" ? raw.strategy : void 0;
168
+ const strategy = isBuiltInStrategy(strategyRaw) ? strategyRaw : void 0;
169
+ const reasoning = typeof raw.reasoning === "string" ? raw.reasoning : void 0;
170
+ return {
171
+ provider,
172
+ ...model ? { model } : {},
173
+ ...strategy ? { strategy } : {},
174
+ ...reasoning ? { reasoning } : {}
175
+ };
176
+ }
177
+ function coerceCompetitionConfig(value) {
178
+ if (!value || typeof value !== "object") return void 0;
179
+ const raw = value;
180
+ const variantsRaw = raw.variants;
181
+ const variants = Array.isArray(variantsRaw) ? variantsRaw.map(coerceVariantSpec).filter((v) => Boolean(v)) : [];
182
+ if (variants.length === 0) return void 0;
183
+ const judgeConfigRaw = raw.judgeConfig;
184
+ const judgeConfig = judgeConfigRaw && typeof judgeConfigRaw === "object" ? {
185
+ type: (() => {
186
+ const obj = judgeConfigRaw;
187
+ const typeRaw = obj.type;
188
+ if (typeof typeRaw === "string" && (typeRaw === "multi-lens" || typeRaw === "multi-agent" || typeRaw === "ai")) {
189
+ return typeRaw;
190
+ }
191
+ return void 0;
192
+ })(),
193
+ threshold: parseOptionalNumber(judgeConfigRaw.threshold),
194
+ runComparison: (() => {
195
+ const value2 = judgeConfigRaw.runComparison;
196
+ return typeof value2 === "boolean" ? value2 : void 0;
197
+ })()
198
+ } : void 0;
199
+ const preserveCandidates = typeof raw.preserveCandidates === "boolean" ? raw.preserveCandidates : void 0;
200
+ const applyWinner = typeof raw.applyWinner === "boolean" ? raw.applyWinner : void 0;
201
+ const tieBreakerRaw = raw.tieBreaker;
202
+ const tieBreaker = tieBreakerRaw && typeof tieBreakerRaw === "object" ? {
203
+ mode: (() => {
204
+ const obj = tieBreakerRaw;
205
+ const modeRaw = obj.mode;
206
+ if (modeRaw === "prefer-first-ranked" || modeRaw === "prefer-strategy" || modeRaw === "prefer-low-drift" || modeRaw === "prefer-smaller-diff" || modeRaw === "prefer-low-drift-then-diff") {
207
+ return modeRaw;
208
+ }
209
+ return void 0;
210
+ })(),
211
+ strategy: (() => {
212
+ const obj = tieBreakerRaw;
213
+ const strategyRaw = obj.strategy;
214
+ if (strategyRaw === "conservative" || strategyRaw === "innovative") {
215
+ return strategyRaw;
216
+ }
217
+ return void 0;
218
+ })()
219
+ } : void 0;
220
+ const normalizedTieBreaker = tieBreaker?.mode ? {
221
+ mode: tieBreaker.mode,
222
+ ...tieBreaker.strategy ? { strategy: tieBreaker.strategy } : {}
223
+ } : void 0;
224
+ const verificationPolicyRaw = typeof raw.verificationPolicy === "string" ? raw.verificationPolicy : void 0;
225
+ const verificationPolicy = verificationPolicyRaw === "findings" || verificationPolicyRaw === "blocking" ? verificationPolicyRaw : void 0;
226
+ const repairRaw = raw.repairOnFindings;
227
+ const repairObj = repairRaw && typeof repairRaw === "object" ? repairRaw : null;
228
+ const repairOnFindings = repairObj ? {
229
+ enabled: Boolean(repairObj.enabled),
230
+ ...parseOptionalNumber(repairObj.maxIterations) !== void 0 ? {
231
+ maxIterations: parseOptionalNumber(repairObj.maxIterations)
232
+ } : {},
233
+ ...parseOptionalNumber(repairObj.timeboxMs) !== void 0 ? { timeboxMs: parseOptionalNumber(repairObj.timeboxMs) } : {}
234
+ } : void 0;
235
+ const result = {
236
+ variants,
237
+ ...judgeConfig?.type ? {
238
+ judgeConfig: {
239
+ type: judgeConfig.type,
240
+ ...Number.isFinite(judgeConfig.threshold) ? { threshold: judgeConfig.threshold } : {},
241
+ ...judgeConfig.runComparison !== void 0 ? { runComparison: judgeConfig.runComparison } : {}
242
+ }
243
+ } : {},
244
+ ...preserveCandidates !== void 0 ? { preserveCandidates } : {},
245
+ ...applyWinner !== void 0 ? { applyWinner } : {},
246
+ ...verificationPolicy ? { verificationPolicy } : {},
247
+ ...repairOnFindings ? { repairOnFindings } : {},
248
+ ...normalizedTieBreaker ? { tieBreaker: normalizedTieBreaker } : {}
249
+ };
250
+ return result;
251
+ }
252
+ function coerceFlywheelConfig(value) {
253
+ if (!value || typeof value !== "object") return void 0;
254
+ const raw = value;
255
+ const typeRaw = typeof raw.type === "string" ? raw.type : void 0;
256
+ const type = typeRaw === "standard" || typeRaw === "competition" || typeRaw === "verify" || typeRaw === "refinement" || typeRaw === "autoloop" ? typeRaw : void 0;
257
+ const inputs = Array.isArray(raw.inputs) ? raw.inputs.filter(
258
+ (v) => typeof v === "string" && v.length > 0
259
+ ) : void 0;
260
+ const allowlist = Array.isArray(raw.allowlist) ? raw.allowlist.filter((v) => typeof v === "string" && v.length > 0) : void 0;
261
+ const allowDenylist = Array.isArray(raw.allowDenylist) ? raw.allowDenylist.filter(
262
+ (v) => typeof v === "string" && v.length > 0
263
+ ) : void 0;
264
+ const allowlistModeRaw = typeof raw.allowlistMode === "string" ? raw.allowlistMode : void 0;
265
+ const allowlistMode = allowlistModeRaw === "off" || allowlistModeRaw === "warn" || allowlistModeRaw === "strict" || allowlistModeRaw === "filter" ? allowlistModeRaw : void 0;
266
+ const verifyRaw = raw.verify;
267
+ const verifyObj = verifyRaw && typeof verifyRaw === "object" ? verifyRaw : null;
268
+ const verify = verifyObj && Array.isArray(verifyObj.commands) ? {
269
+ commands: verifyObj.commands.filter(
270
+ (v) => typeof v === "string" && v.length > 0
271
+ )
272
+ } : void 0;
273
+ const outputs = coerceStageOutputs(raw.outputs);
274
+ const validation = coerceStageValidationOverride(raw.validation);
275
+ const competition = coerceCompetitionConfig(raw.competition);
276
+ const allowEmptyResults = typeof raw.allowEmptyResults === "boolean" ? raw.allowEmptyResults : void 0;
277
+ const autoloopRaw = raw.autoloop;
278
+ const autoloopObj = autoloopRaw && typeof autoloopRaw === "object" ? autoloopRaw : null;
279
+ const autoloop = autoloopObj ? {
280
+ ...parseOptionalNumber(autoloopObj.maxIterations) !== void 0 ? {
281
+ maxIterations: parseOptionalNumber(autoloopObj.maxIterations)
282
+ } : {},
283
+ ...parseOptionalNumber(autoloopObj.timeboxMs) !== void 0 ? { timeboxMs: parseOptionalNumber(autoloopObj.timeboxMs) } : {},
284
+ ...parseOptionalNumber(autoloopObj.minProgress) !== void 0 ? {
285
+ minProgress: parseOptionalNumber(autoloopObj.minProgress)
286
+ } : {},
287
+ ...typeof autoloopObj.stopOnQualityGate === "boolean" ? { stopOnQualityGate: autoloopObj.stopOnQualityGate } : {},
288
+ ...Array.isArray(autoloopObj.qualityGateCommands) ? {
289
+ qualityGateCommands: autoloopObj.qualityGateCommands.filter(
290
+ (v) => typeof v === "string" && v.length > 0
291
+ )
292
+ } : {}
293
+ } : void 0;
294
+ const hasAutoloopFields = Boolean(
295
+ autoloop && (autoloop.maxIterations !== void 0 || autoloop.timeboxMs !== void 0 || autoloop.minProgress !== void 0 || autoloop.stopOnQualityGate !== void 0 || Array.isArray(autoloop.qualityGateCommands) && autoloop.qualityGateCommands.length > 0)
296
+ );
297
+ if (!type && (!inputs || inputs.length === 0) && (!allowlist || allowlist.length === 0) && (!allowDenylist || allowDenylist.length === 0) && !allowlistMode && !verify && !outputs && !validation && !competition && allowEmptyResults === void 0 && !hasAutoloopFields)
298
+ return void 0;
299
+ return {
300
+ ...type ? { type } : {},
301
+ ...inputs && inputs.length > 0 ? { inputs } : {},
302
+ ...allowlist && allowlist.length > 0 ? { allowlist } : {},
303
+ ...allowDenylist && allowDenylist.length > 0 ? { allowDenylist } : {},
304
+ ...allowlistMode ? { allowlistMode } : {},
305
+ ...verify && verify.commands.length > 0 ? { verify } : {},
306
+ ...outputs ? { outputs } : {},
307
+ ...validation ? { validation } : {},
308
+ ...competition ? { competition } : {},
309
+ ...allowEmptyResults !== void 0 ? { allowEmptyResults } : {},
310
+ ...hasAutoloopFields ? { autoloop } : {}
311
+ };
312
+ }
313
+ function coerceTaskYAML(frontMatter) {
314
+ const id = typeof frontMatter.id === "string" ? frontMatter.id : "";
315
+ if (!id) {
316
+ throw new Error('Invalid task frontmatter: missing required field "id"');
317
+ }
318
+ const originalSprintId = typeof frontMatter.originalSprintId === "string" && frontMatter.originalSprintId ? frontMatter.originalSprintId : void 0;
319
+ const sprintId = typeof frontMatter.sprintId === "string" && frontMatter.sprintId || typeof frontMatter.sprint_id === "string" && frontMatter.sprint_id || originalSprintId || "";
320
+ if (!sprintId) {
321
+ throw new Error(`Invalid task frontmatter for '${id}': missing required field "sprintId"`);
322
+ }
323
+ assertSafePlanningFileId(id, "taskId");
324
+ assertSafePlanningFileId(sprintId, "sprintId");
325
+ if (originalSprintId) {
326
+ assertSafePlanningFileId(originalSprintId, "originalSprintId");
327
+ }
328
+ const title = typeof frontMatter.title === "string" ? frontMatter.title : "";
329
+ if (!title) {
330
+ throw new Error(`Invalid task frontmatter for '${id}': missing required field "title"`);
331
+ }
332
+ const version = parseNumber(frontMatter.version, 0);
333
+ const statusRaw = typeof frontMatter.status === "string" ? frontMatter.status : "todo";
334
+ const statusMap = {
335
+ // Canonical statuses
336
+ todo: "todo",
337
+ in_progress: "in_progress",
338
+ review: "review",
339
+ done: "done",
340
+ blocked: "blocked",
341
+ cancelled: "cancelled",
342
+ canceled: "cancelled",
343
+ // Legacy statuses (kebab-case and alternatives)
344
+ pending: "todo",
345
+ "in-progress": "in_progress",
346
+ completed: "done",
347
+ archived: "done"
348
+ };
349
+ const status = statusMap[statusRaw] ?? "todo";
350
+ const priorityRaw = typeof frontMatter.priority === "string" ? frontMatter.priority : "P2";
351
+ const priority = priorityRaw === "P0" || priorityRaw === "P1" || priorityRaw === "P2" || priorityRaw === "P3" ? priorityRaw : "P2";
352
+ const dependencies = Array.isArray(frontMatter.dependencies) ? frontMatter.dependencies.filter((v) => typeof v === "string") : [];
353
+ const subtasksRaw = Array.isArray(frontMatter.subtasks) ? frontMatter.subtasks : [];
354
+ const subtasks = subtasksRaw.map((st) => {
355
+ if (!st || typeof st !== "object") return null;
356
+ const stObj = st;
357
+ const text = typeof stObj.text === "string" ? stObj.text : "";
358
+ if (!text) return null;
359
+ return {
360
+ text,
361
+ completed: Boolean(stObj.completed)
362
+ };
363
+ }).filter((v) => Boolean(v));
364
+ const createdAt = typeof frontMatter.created_at === "string" && frontMatter.created_at || typeof frontMatter.created === "string" && frontMatter.created || (/* @__PURE__ */ new Date()).toISOString();
365
+ const updatedAt = typeof frontMatter.updated_at === "string" && frontMatter.updated_at || typeof frontMatter.updated === "string" && frontMatter.updated || createdAt;
366
+ const metadataRaw = frontMatter.metadata;
367
+ let metadata = metadataRaw && typeof metadataRaw === "object" ? {
368
+ executionIntent: metadataRaw.executionIntent === "analysis" || metadataRaw.executionIntent === "edit" ? metadataRaw.executionIntent : void 0
369
+ } : void 0;
370
+ const routingRaw = frontMatter.routing;
371
+ let routing;
372
+ if (routingRaw && typeof routingRaw === "object") {
373
+ const routingObj = routingRaw;
374
+ const provider = typeof routingObj.provider === "string" ? routingObj.provider : void 0;
375
+ const model = typeof routingObj.model === "string" ? routingObj.model : void 0;
376
+ const strategyRaw = typeof routingObj.strategy === "string" ? routingObj.strategy : void 0;
377
+ const strategy = isBuiltInStrategy(strategyRaw) ? strategyRaw : void 0;
378
+ const reasoning = typeof routingObj.reasoning === "string" ? routingObj.reasoning : void 0;
379
+ const profile = typeof routingObj.profile === "string" ? routingObj.profile : void 0;
380
+ if (provider || model || strategy || reasoning || profile) {
381
+ routing = { provider, model, strategy, reasoning, profile };
382
+ }
383
+ }
384
+ const executionIntentRaw = frontMatter.executionIntent;
385
+ if (!metadata?.executionIntent && (executionIntentRaw === "analysis" || executionIntentRaw === "edit")) {
386
+ metadata = { executionIntent: executionIntentRaw };
387
+ }
388
+ if (!routing) {
389
+ const provider = typeof frontMatter.provider === "string" ? frontMatter.provider : void 0;
390
+ const model = typeof frontMatter.model === "string" ? frontMatter.model : void 0;
391
+ if (provider && provider !== "multi" || model) {
392
+ routing = {
393
+ provider: provider && provider !== "multi" ? provider : void 0,
394
+ model
395
+ };
396
+ }
397
+ }
398
+ const flywheel = coerceFlywheelConfig(frontMatter.flywheel);
399
+ const taskClassificationRaw = frontMatter.taskClassification;
400
+ let taskClassification;
401
+ if (taskClassificationRaw && typeof taskClassificationRaw === "object") {
402
+ const classObj = taskClassificationRaw;
403
+ const categoryRaw = typeof classObj.category === "string" ? classObj.category : void 0;
404
+ const activityRaw = typeof classObj.activity === "string" ? classObj.activity : void 0;
405
+ const validCategories = ["execute", "review", "analyze", "test", "document"];
406
+ const validActivities = [
407
+ "planning",
408
+ "research",
409
+ "architecture",
410
+ "design",
411
+ "development",
412
+ "debugging"
413
+ ];
414
+ const category = categoryRaw && validCategories.includes(categoryRaw) ? categoryRaw : void 0;
415
+ let activity = activityRaw && validActivities.includes(activityRaw) ? activityRaw : void 0;
416
+ if (category && !activity) {
417
+ activity = getDefaultActivityForCategory(category);
418
+ }
419
+ if (category || activity) {
420
+ taskClassification = { category, activity };
421
+ }
422
+ }
423
+ const taskTypeRaw = frontMatter.taskType ?? frontMatter.task_type;
424
+ const taskType = typeof taskTypeRaw === "string" && taskTypeRaw.trim().length > 0 ? taskTypeRaw.trim() : void 0;
425
+ const declaredType = typeof frontMatter.declaredType === "string" ? frontMatter.declaredType : void 0;
426
+ const declaredMethodology = typeof frontMatter.declaredMethodology === "string" ? frontMatter.declaredMethodology : void 0;
427
+ const resolvedTaskTypeId = typeof frontMatter.resolvedTaskTypeId === "string" ? frontMatter.resolvedTaskTypeId : void 0;
428
+ const hints = Array.isArray(frontMatter.hints) ? frontMatter.hints.filter((h) => typeof h === "string") : void 0;
429
+ function coerceEnhancementIntent(value) {
430
+ if (!value || typeof value !== "object") return void 0;
431
+ const obj = value;
432
+ const categoryRaw = typeof obj.category === "string" ? obj.category : void 0;
433
+ const activityRaw = typeof obj.activity === "string" ? obj.activity : void 0;
434
+ const confidenceRaw = typeof obj.confidence === "number" ? obj.confidence : void 0;
435
+ const validCategories = ["execute", "review", "analyze", "test", "document"];
436
+ const validActivities = [
437
+ "planning",
438
+ "research",
439
+ "architecture",
440
+ "design",
441
+ "development",
442
+ "debugging"
443
+ ];
444
+ const category = categoryRaw && validCategories.includes(categoryRaw) ? categoryRaw : void 0;
445
+ const activity = activityRaw && validActivities.includes(activityRaw) ? activityRaw : void 0;
446
+ if (!category || !activity) return void 0;
447
+ const confidence = typeof confidenceRaw === "number" && confidenceRaw >= 0 && confidenceRaw <= 1 ? confidenceRaw : void 0;
448
+ if (confidence === void 0) return void 0;
449
+ return { category, activity, confidence };
450
+ }
451
+ const enhancementSetRaw = frontMatter.enhancementSet;
452
+ const enhancementSet = enhancementSetRaw && typeof enhancementSetRaw === "object" ? (() => {
453
+ const obj = enhancementSetRaw;
454
+ const version2 = obj.version === 1 ? 1 : void 0;
455
+ const intentRaw = obj.intent;
456
+ if (version2 !== 1 || !intentRaw || typeof intentRaw !== "object") return void 0;
457
+ const intent = coerceEnhancementIntent(intentRaw);
458
+ if (!intent) return void 0;
459
+ const enhancementsRaw = obj.enhancements ?? void 0;
460
+ const enhancements2 = Array.isArray(
461
+ enhancementsRaw
462
+ ) ? enhancementsRaw.map((e) => {
463
+ if (!e || typeof e !== "object") return null;
464
+ const eObj = e;
465
+ const kind = typeof eObj.kind === "string" ? eObj.kind : void 0;
466
+ const snippet = typeof eObj.snippet === "string" ? eObj.snippet : void 0;
467
+ if (!kind || !snippet) return null;
468
+ return { kind, snippet };
469
+ }).filter(
470
+ (e) => e !== null
471
+ ) : void 0;
472
+ if (!enhancements2) return void 0;
473
+ const acceptanceCriteriaRaw = obj.acceptanceCriteria;
474
+ const acceptanceCriteria = Array.isArray(acceptanceCriteriaRaw) ? acceptanceCriteriaRaw.map((c) => {
475
+ if (!c || typeof c !== "object") return null;
476
+ const cObj = c;
477
+ const id2 = typeof cObj.id === "string" ? cObj.id : void 0;
478
+ const description = typeof cObj.description === "string" ? cObj.description : void 0;
479
+ if (!id2 || !description) return null;
480
+ const weight = typeof cObj.weight === "number" ? cObj.weight : void 0;
481
+ const verification = cObj.verification && typeof cObj.verification === "object" ? cObj.verification : void 0;
482
+ return {
483
+ id: id2,
484
+ description,
485
+ weight,
486
+ verification
487
+ };
488
+ }).filter((c) => c !== null) : void 0;
489
+ const constraintsRaw = obj.constraints;
490
+ const constraints = Array.isArray(constraintsRaw) ? constraintsRaw.map((c) => {
491
+ if (!c || typeof c !== "object") return null;
492
+ const cObj = c;
493
+ const id2 = typeof cObj.id === "string" ? cObj.id : void 0;
494
+ const rule = typeof cObj.rule === "string" ? cObj.rule : void 0;
495
+ if (!id2 || !rule) return null;
496
+ const penaltyPoints = typeof cObj.penaltyPoints === "number" ? cObj.penaltyPoints : void 0;
497
+ const scope = cObj.scope && typeof cObj.scope === "object" ? cObj.scope : void 0;
498
+ const allowIf = Array.isArray(cObj.allowIf) ? cObj.allowIf : void 0;
499
+ return {
500
+ id: id2,
501
+ rule,
502
+ penaltyPoints,
503
+ scope,
504
+ allowIf
505
+ };
506
+ }).filter((c) => c !== null) : void 0;
507
+ const artifactSourcesRaw = obj.artifactSources;
508
+ const artifactSources = artifactSourcesRaw && typeof artifactSourcesRaw === "object" ? (() => {
509
+ const a = artifactSourcesRaw;
510
+ const preferred = Array.isArray(a.preferred) ? a.preferred.filter((v) => typeof v === "string") : void 0;
511
+ const fallback = Array.isArray(a.fallback) ? a.fallback.filter((v) => typeof v === "string") : void 0;
512
+ if (!preferred && !fallback) return void 0;
513
+ return { preferred, fallback };
514
+ })() : void 0;
515
+ return {
516
+ version: 1,
517
+ intent,
518
+ enhancements: enhancements2,
519
+ acceptanceCriteria,
520
+ constraints,
521
+ artifactSources
522
+ };
523
+ })() : void 0;
524
+ const enhancementsLegacyRaw = frontMatter.enhancements;
525
+ const enhancementsLegacy = Array.isArray(
526
+ enhancementsLegacyRaw
527
+ ) ? enhancementsLegacyRaw.map((e) => {
528
+ if (!e || typeof e !== "object") return null;
529
+ const obj = e;
530
+ const kind = typeof obj.kind === "string" ? obj.kind : void 0;
531
+ const snippet = typeof obj.snippet === "string" ? obj.snippet : void 0;
532
+ if (!kind || !snippet) return null;
533
+ return { kind, snippet };
534
+ }).filter((e) => e !== null) : void 0;
535
+ const enhancements = enhancementSet?.enhancements ?? enhancementsLegacy;
536
+ const blockedReason = typeof frontMatter.blockedReason === "string" && frontMatter.blockedReason.trim() ? frontMatter.blockedReason.trim() : void 0;
537
+ const blockedReasonHistory = Array.isArray(frontMatter.blockedReasonHistory) ? frontMatter.blockedReasonHistory.filter(
538
+ (value) => typeof value === "string" && value.trim().length > 0
539
+ ) : void 0;
540
+ const forceCompletedFrom = isTaskStatus(frontMatter.forceCompletedFrom) && frontMatter.forceCompletedFrom !== "done" ? frontMatter.forceCompletedFrom : void 0;
541
+ const originalBlockedReason = typeof frontMatter.originalBlockedReason === "string" && frontMatter.originalBlockedReason.trim() ? frontMatter.originalBlockedReason.trim() : void 0;
542
+ const cancelledAt = typeof frontMatter.cancelledAt === "string" && frontMatter.cancelledAt.trim() ? frontMatter.cancelledAt.trim() : void 0;
543
+ const cancelledReason = typeof frontMatter.cancelledReason === "string" && frontMatter.cancelledReason.trim() ? frontMatter.cancelledReason.trim() : void 0;
544
+ const completionContract = normalizeCompletionContracts(frontMatter.completionContract);
545
+ const appliedTransitions = Array.isArray(frontMatter.appliedTransitions) ? frontMatter.appliedTransitions.filter(
546
+ (value) => typeof value === "string" && value.length > 0
547
+ ) : void 0;
548
+ const lastTransitionReason = typeof frontMatter.lastTransitionReason === "string" && frontMatter.lastTransitionReason.trim() ? frontMatter.lastTransitionReason.trim() : void 0;
549
+ const statusBypassAudit = Array.isArray(frontMatter.statusBypassAudit) ? frontMatter.statusBypassAudit.map((entry) => {
550
+ if (!entry || typeof entry !== "object") return null;
551
+ const obj = entry;
552
+ const fromStatus = obj.fromStatus;
553
+ const toStatus = obj.toStatus;
554
+ const reason = typeof obj.reason === "string" ? obj.reason.trim() : "";
555
+ const at = typeof obj.at === "string" ? obj.at : "";
556
+ if (!isTaskStatus(fromStatus) || !isTaskStatus(toStatus) || !reason || !at) {
557
+ return null;
558
+ }
559
+ const actor = typeof obj.actor === "string" && obj.actor.trim() ? obj.actor.trim() : void 0;
560
+ return { at, fromStatus, toStatus, reason, actor };
561
+ }).filter(
562
+ (entry) => Boolean(entry)
563
+ ) : void 0;
564
+ return {
565
+ ...frontMatter,
566
+ id,
567
+ kind: "task",
568
+ version,
569
+ sprintId,
570
+ originalSprintId,
571
+ backlogItemId: typeof frontMatter.backlogItemId === "string" ? frontMatter.backlogItemId : void 0,
572
+ planArtifactPath: typeof frontMatter.planArtifactPath === "string" ? frontMatter.planArtifactPath : void 0,
573
+ resultArtifactPath: typeof frontMatter.resultArtifactPath === "string" ? frontMatter.resultArtifactPath : void 0,
574
+ planIntentHash: typeof frontMatter.planIntentHash === "string" ? frontMatter.planIntentHash : void 0,
575
+ planStageId: typeof frontMatter.planStageId === "string" ? frontMatter.planStageId : void 0,
576
+ splitStrategy: frontMatter.splitStrategy === "ai" || frontMatter.splitStrategy === "rule-based" ? frontMatter.splitStrategy : void 0,
577
+ splitMode: frontMatter.splitMode === "rule" || frontMatter.splitMode === "shadow" || frontMatter.splitMode === "llm" ? frontMatter.splitMode : void 0,
578
+ splitTaskType: typeof frontMatter.splitTaskType === "string" ? frontMatter.splitTaskType : void 0,
579
+ taskType,
580
+ declaredType,
581
+ declaredMethodology,
582
+ resolvedTaskTypeId,
583
+ title,
584
+ status,
585
+ priority,
586
+ assignee: typeof frontMatter.assignee === "string" ? frontMatter.assignee : void 0,
587
+ estimatedHours: parseNumber(frontMatter.estimatedHours, 0),
588
+ // AI runtime estimate fields: preserved only when present and valid. Never
589
+ // synthesized — a legacy task without them stays without them (no fake data).
590
+ ...coerceRuntimeEstimateFields(frontMatter),
591
+ timeLoggedHours: parseNumber(frontMatter.timeLoggedHours, 0),
592
+ dependencies,
593
+ subtasks,
594
+ hints,
595
+ enhancements,
596
+ enhancementSet,
597
+ routing,
598
+ flywheel,
599
+ taskClassification,
600
+ blockedReason,
601
+ blockedReasonHistory,
602
+ forceCompletedFrom,
603
+ originalBlockedReason,
604
+ statusBypassAudit,
605
+ ...completionContract.length > 0 ? { completionContract } : {},
606
+ ...appliedTransitions && appliedTransitions.length > 0 ? { appliedTransitions } : {},
607
+ ...lastTransitionReason ? { lastTransitionReason } : {},
608
+ metadata,
609
+ created_at: createdAt,
610
+ updated_at: updatedAt,
611
+ started_at: typeof frontMatter.started_at === "string" ? frontMatter.started_at : void 0,
612
+ completed_at: typeof frontMatter.completed_at === "string" ? frontMatter.completed_at : void 0,
613
+ cancelledAt,
614
+ cancelledReason
615
+ };
616
+ }
617
+ async function generateTaskId(sprintId, title) {
618
+ void sprintId;
619
+ void title;
620
+ return generateId(/* @__PURE__ */ new Date());
621
+ }
622
+ async function createTask(title, sprintId, options = {}, repoRoot) {
623
+ const result = await createTaskWithGuidance(title, sprintId, options, repoRoot);
624
+ return result.task;
625
+ }
626
+ async function createTaskWithGuidance(title, sprintId, options = {}, repoRoot) {
627
+ const planningRoot = repoRoot ?? getPlanningRoot();
628
+ return withIndexRegeneration(planningRoot, async () => {
629
+ const tasksDir = getBucketPathByKind("task", planningRoot);
630
+ await ensureDirectoryExists(tasksDir);
631
+ assertSafePlanningFileId(sprintId, "sprintId");
632
+ const taskId = await generateTaskId(sprintId, title);
633
+ const filePath = resolvePlanningItemPath(tasksDir, taskId, { label: "taskId" });
634
+ const dependencies = [...new Set(options.dependencies ?? [])];
635
+ if (dependencies.includes(taskId)) {
636
+ throw new Error(`Task cannot depend on itself: ${taskId}`);
637
+ }
638
+ if (dependencies.length > 0) {
639
+ const taskPath = getBucketPathByKind("task", planningRoot);
640
+ const taskArchivePath = getBucketArchivePathByKind("task", planningRoot);
641
+ const allItems = await loadAllItems(planningRoot, [taskPath, taskArchivePath]);
642
+ const allIds = new Set(allItems.map((item) => item.id));
643
+ const missingDependencies = dependencies.filter((depId) => !allIds.has(depId));
644
+ if (missingDependencies.length > 0) {
645
+ throw new Error(`Dependency task not found: ${missingDependencies.join(", ")}`);
646
+ }
647
+ }
648
+ const now = (/* @__PURE__ */ new Date()).toISOString();
649
+ const task = {
650
+ id: taskId,
651
+ kind: "task",
652
+ version: 1,
653
+ sprintId,
654
+ backlogItemId: options.backlogItemId,
655
+ planArtifactPath: options.planArtifactPath,
656
+ planIntentHash: options.planIntentHash,
657
+ planStageId: options.planStageId,
658
+ splitStrategy: options.splitStrategy,
659
+ splitMode: options.splitMode,
660
+ splitTaskType: options.splitTaskType,
661
+ // Declared terminology (verbatim, opaque) + its resolved canonical id are
662
+ // carried through from the originating backlog item / decomposition so the
663
+ // declared term actually reaches sprint workflow resolution. Only set when
664
+ // present so legacy tasks stay clean.
665
+ ...typeof options.declaredType === "string" && options.declaredType.length > 0 ? { declaredType: options.declaredType } : {},
666
+ ...typeof options.declaredMethodology === "string" && options.declaredMethodology.length > 0 ? { declaredMethodology: options.declaredMethodology } : {},
667
+ ...typeof options.resolvedTaskTypeId === "string" && options.resolvedTaskTypeId.length > 0 ? { resolvedTaskTypeId: options.resolvedTaskTypeId } : {},
668
+ title,
669
+ status: "todo",
670
+ priority: options.priority ?? "P2",
671
+ assignee: options.assignee,
672
+ estimatedHours: options.estimatedHours ?? 4,
673
+ // AI runtime estimate is optional and never defaulted (absence is honest,
674
+ // not zero/fake). estimatedHours default is untouched.
675
+ ...typeof options.expectedRuntimeMinutes === "number" && options.expectedRuntimeMinutes > 0 ? { expectedRuntimeMinutes: options.expectedRuntimeMinutes } : {},
676
+ ...options.runtimeEstimateProvenance ? { runtimeEstimateProvenance: options.runtimeEstimateProvenance } : {},
677
+ ...options.runtimeEstimateConfidence ? { runtimeEstimateConfidence: options.runtimeEstimateConfidence } : {},
678
+ timeLoggedHours: 0,
679
+ dependencies,
680
+ subtasks: options.subtasks || [],
681
+ routing: options.routing,
682
+ flywheel: options.flywheel,
683
+ created_at: now,
684
+ updated_at: now
685
+ };
686
+ const description = typeof options.description === "string" && options.description.trim().length > 0 ? options.description.trim() : "Task created from sprint planning.";
687
+ let guidance;
688
+ if (options.planStageId) {
689
+ guidance = {
690
+ intent: { category: "execute", activity: "development", confidence: 1 },
691
+ enhancements: [],
692
+ quickReply: "",
693
+ nextCommands: []
694
+ };
695
+ } else {
696
+ guidance = generateEnhancements({
697
+ title,
698
+ description,
699
+ id: taskId,
700
+ itemKind: "task",
701
+ sprintId
702
+ });
703
+ const persistedEnhancements = toPersistedFormat(guidance.enhancements);
704
+ if (persistedEnhancements.length > 0) {
705
+ task.enhancements = persistedEnhancements;
706
+ task.enhancementSet = toEnhancementSet(guidance);
707
+ }
708
+ const hints = hintsFromEnhancements(guidance.enhancements);
709
+ if (hints.length > 0) task.hints = hints;
710
+ }
711
+ const body = `# Task: ${title}
712
+
713
+ **Sprint**: ${sprintId}
714
+ **Status**: To Do
715
+ **Estimated**: ${task.estimatedHours > 0 ? `${task.estimatedHours}h` : "unestimated"}
716
+ ${task.planArtifactPath ? `**Plan Artifact**: ${task.planArtifactPath}
717
+ ` : ""}${task.planStageId ? `**Plan Stage**: ${task.planStageId}
718
+ ` : ""}
719
+
720
+ ## Description
721
+
722
+ ${description}
723
+
724
+ ## Subtasks
725
+
726
+ ${task.subtasks.length > 0 ? task.subtasks.map((st, _i) => `- [ ] ${st.text}`).join("\n") : "(No subtasks defined)"}
727
+
728
+ ## Notes
729
+
730
+ Created on ${now}
731
+ `;
732
+ await writeMarkdownFile(
733
+ filePath,
734
+ task,
735
+ body
736
+ );
737
+ return { task, filePath, guidance };
738
+ });
739
+ }
740
+ function formatTaskStatusLabel(status) {
741
+ switch (status) {
742
+ case "todo":
743
+ return "To Do";
744
+ case "in_progress":
745
+ return "In Progress";
746
+ case "review":
747
+ return "Review";
748
+ case "done":
749
+ return "Done";
750
+ case "blocked":
751
+ return "Blocked";
752
+ case "cancelled":
753
+ return "Cancelled";
754
+ default:
755
+ return "To Do";
756
+ }
757
+ }
758
+ function updateTaskBodyStatusLine(body, status) {
759
+ const desiredLine = `**Status**: ${formatTaskStatusLabel(status)}`;
760
+ if (/^\*\*Status\*\*:/m.test(body)) {
761
+ return body.replace(/^\*\*Status\*\*:\s*.*$/m, desiredLine);
762
+ }
763
+ const afterSprint = body.match(/^\*\*Sprint\*\*:\s*.*$/m);
764
+ if (afterSprint?.index !== void 0) {
765
+ const insertAt = afterSprint.index + afterSprint[0].length;
766
+ return `${body.slice(0, insertAt)}
767
+ ${desiredLine}${body.slice(insertAt)}`;
768
+ }
769
+ return `${desiredLine}
770
+
771
+ ${body}`;
772
+ }
773
+ function normalizeDescriptionSectionContent(description) {
774
+ const trimmed = description.trim();
775
+ const headingMatch = trimmed.match(/^##\s+Description\b[^\n]*\n?/i);
776
+ if (!headingMatch) return trimmed;
777
+ return trimmed.slice(headingMatch[0].length).trim();
778
+ }
779
+ function isTaskHeaderMetadataLine(line) {
780
+ const trimmed = line.trim();
781
+ return /^#\s+Task:/i.test(trimmed) || /^\*\*(?:Sprint|Status|Estimated|Plan Artifact|Plan Stage)\*\*:/i.test(trimmed);
782
+ }
783
+ function keepTaskHeaderMetadata(prefix) {
784
+ const lines = prefix.split("\n");
785
+ let lastMetadataLineIndex = -1;
786
+ for (let index = 0; index < lines.length; index += 1) {
787
+ if (isTaskHeaderMetadataLine(lines[index] ?? "")) {
788
+ lastMetadataLineIndex = index;
789
+ }
790
+ }
791
+ if (lastMetadataLineIndex < 0) return "";
792
+ return lines.slice(0, lastMetadataLineIndex + 1).join("\n").trimEnd();
793
+ }
794
+ function updateTaskBodyDescriptionSection(body, description) {
795
+ const content = normalizeDescriptionSectionContent(description);
796
+ const section = `## Description
797
+
798
+ ${content}`;
799
+ const existingHeading = body.match(/^##\s+Description\b[^\n]*$/im);
800
+ if (existingHeading?.index !== void 0) {
801
+ const headingStart = existingHeading.index;
802
+ const afterHeading = headingStart + existingHeading[0].length;
803
+ const nextSectionRelative = body.slice(afterHeading).search(/\n##\s+/);
804
+ const sectionEnd = nextSectionRelative >= 0 ? afterHeading + nextSectionRelative : body.length;
805
+ const before = body.slice(0, headingStart).trimEnd();
806
+ const after = body.slice(sectionEnd).trimStart();
807
+ return `${before}
808
+
809
+ ${section}${after ? `
810
+
811
+ ${after}` : ""}`.trim();
812
+ }
813
+ const insertBefore = body.search(
814
+ /^##\s+(?:Subtasks|Checklist|Notes|Activity|Acceptance Criteria)\b/im
815
+ );
816
+ if (insertBefore >= 0) {
817
+ const before = keepTaskHeaderMetadata(body.slice(0, insertBefore));
818
+ const after = body.slice(insertBefore).trimStart();
819
+ return `${before ? `${before}
820
+
821
+ ` : ""}${section}
822
+
823
+ ${after}`.trim();
824
+ }
825
+ const existingMetadata = keepTaskHeaderMetadata(body);
826
+ if (!existingMetadata) return `${section}
827
+ `;
828
+ return `${existingMetadata}
829
+
830
+ ${section}`;
831
+ }
832
+ async function updateTaskFields(taskId, updates) {
833
+ const planningRoot = getPlanningRoot();
834
+ if (updates.description !== void 0 && updates.body !== void 0) {
835
+ throw new Error("Cannot update both description and body in one operation");
836
+ }
837
+ if (updates.body !== void 0 && updates.body.trim().length === 0) {
838
+ throw new Error("Task body cannot be empty");
839
+ }
840
+ return withIndexRegeneration(planningRoot, async () => {
841
+ const lookup = await getTask(taskId, { includeArchive: false });
842
+ const { frontMatter, body } = await readMarkdownFile(lookup.filePath);
843
+ const nextFrontMatter = {
844
+ ...frontMatter,
845
+ ...lookup.yaml
846
+ };
847
+ if (updates.title !== void 0) {
848
+ const title = updates.title.trim();
849
+ if (!title) throw new Error("Task title cannot be empty");
850
+ nextFrontMatter.title = title;
851
+ }
852
+ if (updates.priority !== void 0) {
853
+ nextFrontMatter.priority = updates.priority;
854
+ }
855
+ if (updates.estimatedHours !== void 0) {
856
+ nextFrontMatter.estimatedHours = updates.estimatedHours;
857
+ }
858
+ if (updates.expectedRuntimeMinutes !== void 0) {
859
+ nextFrontMatter.expectedRuntimeMinutes = updates.expectedRuntimeMinutes;
860
+ }
861
+ if (updates.assignee !== void 0) {
862
+ const assignee = updates.assignee?.trim() ?? "";
863
+ if (assignee) {
864
+ nextFrontMatter.assignee = assignee;
865
+ } else {
866
+ delete nextFrontMatter.assignee;
867
+ }
868
+ }
869
+ nextFrontMatter.updated_at = (/* @__PURE__ */ new Date()).toISOString();
870
+ nextFrontMatter.version = (lookup.yaml.version ?? 0) + 1;
871
+ const updatedTask = coerceTaskYAML(nextFrontMatter);
872
+ const nextBody = updates.body !== void 0 ? updates.body.trim() : updates.description !== void 0 ? updateTaskBodyDescriptionSection(body, updates.description) : body;
873
+ await writeMarkdownFile(
874
+ lookup.filePath,
875
+ nextFrontMatter,
876
+ updateTaskBodyStatusLine(nextBody, updatedTask.status)
877
+ );
878
+ return updatedTask;
879
+ });
880
+ }
881
+ async function updateTaskStatus(taskId, newStatus, options = {}) {
882
+ const planningRoot = getPlanningRoot();
883
+ const bypassReasonPre = options.bypassValidation?.reason.trim();
884
+ let contractEval;
885
+ if (newStatus === "done" && !bypassReasonPre) {
886
+ const preEval = await readTaskForCompletionEval(taskId, planningRoot);
887
+ if (preEval.task.status !== "done" && (preEval.task.completionContract?.length ?? 0) > 0) {
888
+ const evaluatedVersion = preEval.task.version;
889
+ const contractKey = completionContractSnapshotKey(preEval.task.completionContract);
890
+ await assertCompletionContractsMet({
891
+ contracts: preEval.task.completionContract,
892
+ bypassReason: bypassReasonPre,
893
+ workingDir: options.completionContractRoot
894
+ });
895
+ contractEval = { evaluatedVersion, contractKey };
896
+ }
897
+ }
898
+ return withIndexRegeneration(planningRoot, async () => {
899
+ const tasksDir = getBucketPathByKind("task", planningRoot);
900
+ const files = await listMarkdownFiles(tasksDir);
901
+ const taskFile = files.find((f) => path.basename(f) === `${taskId}.md`);
902
+ if (!taskFile) {
903
+ throw new Error(`Task not found: ${taskId}`);
904
+ }
905
+ const { frontMatter, body } = await readMarkdownFile(taskFile);
906
+ const task = coerceTaskYAML(frontMatter);
907
+ const currentVersion = task.version;
908
+ if (options.expectedVersion !== void 0 && currentVersion !== options.expectedVersion) {
909
+ throw new StaleVersionError(currentVersion, options.expectedVersion, taskId);
910
+ }
911
+ if (task.status === newStatus && newStatus !== "blocked") {
912
+ if (options?.resultArtifactPath && task.resultArtifactPath !== options.resultArtifactPath) {
913
+ task.resultArtifactPath = options.resultArtifactPath;
914
+ task.updated_at = (/* @__PURE__ */ new Date()).toISOString();
915
+ task.version = currentVersion + 1;
916
+ await writeMarkdownFile(
917
+ taskFile,
918
+ task,
919
+ updateTaskBodyStatusLine(body, task.status)
920
+ );
921
+ }
922
+ return task;
923
+ }
924
+ const bypass = options.bypassValidation;
925
+ const bypassReason = bypass?.reason.trim();
926
+ if (bypass && !bypassReason) {
927
+ throw new Error("Task status validation bypass requires a reason");
928
+ }
929
+ if (!bypass) {
930
+ const transition = await validateStateTransition(
931
+ planningRoot,
932
+ taskId,
933
+ task.status,
934
+ newStatus
935
+ );
936
+ if (!transition.success) {
937
+ const details = transition.errors?.length ? `: ${transition.errors.join("; ")}` : "";
938
+ throw new Error(`${transition.message}${details}`);
939
+ }
940
+ }
941
+ if (newStatus === "done") {
942
+ if (contractEval) {
943
+ if (currentVersion !== contractEval.evaluatedVersion || completionContractSnapshotKey(task.completionContract) !== contractEval.contractKey) {
944
+ throw new StaleVersionError(
945
+ currentVersion,
946
+ contractEval.evaluatedVersion,
947
+ taskId,
948
+ "completionContract",
949
+ "concurrent task mutation between completion-contract evaluation and status write"
950
+ );
951
+ }
952
+ } else {
953
+ await assertCompletionContractsMet({
954
+ contracts: task.completionContract,
955
+ bypassReason,
956
+ workingDir: options.completionContractRoot
957
+ });
958
+ }
959
+ }
960
+ const previousStatus = task.status;
961
+ task.status = newStatus;
962
+ task.updated_at = (/* @__PURE__ */ new Date()).toISOString();
963
+ task.version = currentVersion + 1;
964
+ if (bypass && bypassReason) {
965
+ task.statusBypassAudit = [
966
+ ...task.statusBypassAudit ?? [],
967
+ {
968
+ at: task.updated_at,
969
+ fromStatus: previousStatus,
970
+ toStatus: newStatus,
971
+ reason: bypassReason,
972
+ ...bypass.actor ? { actor: bypass.actor } : {}
973
+ }
974
+ ];
975
+ }
976
+ if (previousStatus === "blocked" && newStatus === "blocked" && task.blockedReason && options?.blockedReason && task.blockedReason !== options.blockedReason) {
977
+ task.blockedReasonHistory = [...task.blockedReasonHistory ?? [], task.blockedReason];
978
+ }
979
+ if (newStatus === "blocked" && options?.blockedReason) {
980
+ task.blockedReason = options.blockedReason;
981
+ } else if (newStatus !== "blocked") {
982
+ task.blockedReason = void 0;
983
+ }
984
+ if (newStatus === "in_progress" && !task.started_at) {
985
+ task.started_at = task.updated_at;
986
+ }
987
+ if (newStatus === "done") {
988
+ task.completed_at = task.updated_at;
989
+ } else if (previousStatus === "done") {
990
+ task.completed_at = void 0;
991
+ }
992
+ if (previousStatus === "cancelled" && newStatus !== "cancelled") {
993
+ task.cancelledAt = void 0;
994
+ task.cancelledReason = void 0;
995
+ }
996
+ if (options?.resultArtifactPath) {
997
+ task.resultArtifactPath = options.resultArtifactPath;
998
+ }
999
+ await writeMarkdownFile(
1000
+ taskFile,
1001
+ task,
1002
+ updateTaskBodyStatusLine(body, task.status)
1003
+ );
1004
+ if (newStatus === "done") {
1005
+ const unblockedTaskIds = await autoUnblockDependentTasks(task.id, planningRoot);
1006
+ if (unblockedTaskIds.length > 0) {
1007
+ options.onDependentsUnblocked?.(unblockedTaskIds);
1008
+ }
1009
+ }
1010
+ if (task.sprintId) {
1011
+ try {
1012
+ const { refreshSprintMarkdown } = await import("./sprint-manager-IDQUDNQI.js");
1013
+ await refreshSprintMarkdown(task.sprintId);
1014
+ } catch (refreshError) {
1015
+ const msg = refreshError instanceof Error ? refreshError.message : String(refreshError);
1016
+ emitTaskManagerWarning("Failed to refresh sprint markdown after task status change", {
1017
+ sprintId: task.sprintId,
1018
+ taskId: task.id,
1019
+ error: msg
1020
+ });
1021
+ }
1022
+ }
1023
+ return task;
1024
+ });
1025
+ }
1026
+ async function updateTaskStatusWithTransitionValidation(taskId, newStatus, options) {
1027
+ const { isArchived } = await getTask(taskId, {
1028
+ includeArchive: true
1029
+ });
1030
+ if (isArchived) {
1031
+ throw new Error(
1032
+ `Cannot update archived task "${taskId}". Reopen or restore the task before changing status.`
1033
+ );
1034
+ }
1035
+ return updateTaskStatus(taskId, newStatus, options);
1036
+ }
1037
+ async function addTaskDependency(taskId, dependsOnTaskId) {
1038
+ const planningRoot = getPlanningRoot();
1039
+ return withIndexRegeneration(planningRoot, async () => {
1040
+ const tasksDir = getBucketPathByKind("task", planningRoot);
1041
+ const files = await listMarkdownFiles(tasksDir);
1042
+ const taskFile = files.find((f) => path.basename(f) === `${taskId}.md`);
1043
+ if (!taskFile) {
1044
+ throw new Error(`Task not found: ${taskId}`);
1045
+ }
1046
+ const { frontMatter, body } = await readMarkdownFile(taskFile);
1047
+ const task = coerceTaskYAML(frontMatter);
1048
+ if (task.dependencies.includes(dependsOnTaskId)) {
1049
+ throw new Error(`Dependency already exists: ${taskId} \u2192 ${dependsOnTaskId}`);
1050
+ }
1051
+ if (task.id === dependsOnTaskId) {
1052
+ throw new Error(`Task cannot depend on itself: ${taskId}`);
1053
+ }
1054
+ const taskPath = getBucketPathByKind("task", planningRoot);
1055
+ const taskArchivePath = getBucketArchivePathByKind("task", planningRoot);
1056
+ const allItems = await loadAllItems(planningRoot, [taskPath, taskArchivePath]);
1057
+ const dependencyExists = allItems.some((item) => item.id === dependsOnTaskId);
1058
+ if (!dependencyExists) {
1059
+ throw new Error(`Dependency task not found: ${dependsOnTaskId}`);
1060
+ }
1061
+ const createsCycle = hasDependencyPath(dependsOnTaskId, task.id, allItems);
1062
+ if (createsCycle) {
1063
+ throw new Error(
1064
+ `Circular dependency detected: adding ${task.id} -> ${dependsOnTaskId} would create a cycle`
1065
+ );
1066
+ }
1067
+ task.dependencies.push(dependsOnTaskId);
1068
+ task.updated_at = (/* @__PURE__ */ new Date()).toISOString();
1069
+ task.version = task.version + 1;
1070
+ await writeMarkdownFile(
1071
+ taskFile,
1072
+ task,
1073
+ body
1074
+ );
1075
+ return task;
1076
+ });
1077
+ }
1078
+ async function removeTaskDependency(taskId, dependsOnTaskId) {
1079
+ const planningRoot = getPlanningRoot();
1080
+ return withIndexRegeneration(planningRoot, async () => {
1081
+ const tasksDir = getBucketPathByKind("task", planningRoot);
1082
+ const files = await listMarkdownFiles(tasksDir);
1083
+ const taskFile = files.find((f) => path.basename(f) === `${taskId}.md`);
1084
+ if (!taskFile) {
1085
+ throw new Error(`Task not found: ${taskId}`);
1086
+ }
1087
+ const { frontMatter, body } = await readMarkdownFile(taskFile);
1088
+ const task = coerceTaskYAML(frontMatter);
1089
+ if (!task.dependencies.includes(dependsOnTaskId)) {
1090
+ throw new Error(`Dependency not found on task: ${taskId} \u2192 ${dependsOnTaskId}`);
1091
+ }
1092
+ task.dependencies = task.dependencies.filter((id) => id !== dependsOnTaskId);
1093
+ task.updated_at = (/* @__PURE__ */ new Date()).toISOString();
1094
+ task.version += 1;
1095
+ await writeMarkdownFile(
1096
+ taskFile,
1097
+ task,
1098
+ body
1099
+ );
1100
+ return task;
1101
+ });
1102
+ }
1103
+ function hasDependencyPath(startTaskId, targetTaskId, allItems, visited = /* @__PURE__ */ new Set()) {
1104
+ if (startTaskId === targetTaskId) {
1105
+ return true;
1106
+ }
1107
+ if (visited.has(startTaskId)) {
1108
+ return false;
1109
+ }
1110
+ visited.add(startTaskId);
1111
+ const task = allItems.find((item) => item.id === startTaskId);
1112
+ const dependencies = task?.frontMatter.dependencies;
1113
+ if (!Array.isArray(dependencies) || dependencies.length === 0) {
1114
+ return false;
1115
+ }
1116
+ for (const depId of dependencies) {
1117
+ if (hasDependencyPath(depId, targetTaskId, allItems, visited)) {
1118
+ return true;
1119
+ }
1120
+ }
1121
+ return false;
1122
+ }
1123
+ async function autoUnblockDependentTasks(completedTaskId, planningRoot) {
1124
+ const tasksDir = getBucketPathByKind("task", planningRoot);
1125
+ const files = await listMarkdownFiles(tasksDir);
1126
+ const unblockedTaskIds = [];
1127
+ const rewrites = [];
1128
+ for (const filePath of files) {
1129
+ try {
1130
+ const { frontMatter, body } = await readMarkdownFile(filePath);
1131
+ const task = coerceTaskYAML(frontMatter);
1132
+ if (task.id === completedTaskId) continue;
1133
+ if (task.status !== "blocked") continue;
1134
+ if (!task.dependencies.includes(completedTaskId)) continue;
1135
+ let hasRemainingBlockers = false;
1136
+ for (const depId of task.dependencies) {
1137
+ const dep = await getTaskDependency(depId, { sprintId: task.sprintId });
1138
+ if (dep.missing || !dep.satisfied) {
1139
+ hasRemainingBlockers = true;
1140
+ break;
1141
+ }
1142
+ }
1143
+ if (hasRemainingBlockers) continue;
1144
+ task.status = "todo";
1145
+ task.blockedReason = void 0;
1146
+ task.updated_at = (/* @__PURE__ */ new Date()).toISOString();
1147
+ task.version = task.version + 1;
1148
+ rewrites.push({
1149
+ filePath,
1150
+ originalFrontMatter: frontMatter,
1151
+ originalBody: body,
1152
+ nextFrontMatter: task,
1153
+ nextBody: updateTaskBodyStatusLine(body, task.status),
1154
+ taskId: task.id
1155
+ });
1156
+ } catch {
1157
+ }
1158
+ }
1159
+ const applied = [];
1160
+ for (const rewrite of rewrites) {
1161
+ try {
1162
+ await writeMarkdownFile(rewrite.filePath, rewrite.nextFrontMatter, rewrite.nextBody);
1163
+ applied.push(rewrite);
1164
+ unblockedTaskIds.push(rewrite.taskId);
1165
+ } catch (error) {
1166
+ for (const previous of applied.reverse()) {
1167
+ await writeMarkdownFile(
1168
+ previous.filePath,
1169
+ previous.originalFrontMatter,
1170
+ previous.originalBody
1171
+ ).catch(() => void 0);
1172
+ }
1173
+ throw error;
1174
+ }
1175
+ }
1176
+ return unblockedTaskIds;
1177
+ }
1178
+ async function validateTaskExecution(taskId, options = {}) {
1179
+ const { includeArchive = false } = options;
1180
+ const { yaml: task } = await getTask(taskId, { includeArchive });
1181
+ const blockers = [];
1182
+ if (task.status === "blocked") {
1183
+ blockers.push(`${taskId} (blocked)`);
1184
+ }
1185
+ for (const depId of task.dependencies) {
1186
+ const dep = await getTaskDependency(depId, { sprintId: task.sprintId });
1187
+ if (dep.missing) {
1188
+ blockers.push(`${depId} (not found)`);
1189
+ continue;
1190
+ }
1191
+ if (!dep.satisfied) {
1192
+ blockers.push(`${depId} (status: ${dep.task?.status ?? "unknown"})`);
1193
+ }
1194
+ }
1195
+ return {
1196
+ canExecute: blockers.length === 0,
1197
+ blockers
1198
+ };
1199
+ }
1200
+ async function logTaskTime(taskId, hours) {
1201
+ const planningRoot = getPlanningRoot();
1202
+ return withIndexRegeneration(planningRoot, async () => {
1203
+ const tasksDir = getBucketPathByKind("task", planningRoot);
1204
+ const files = await listMarkdownFiles(tasksDir);
1205
+ const taskFile = files.find((f) => path.basename(f) === `${taskId}.md`);
1206
+ if (!taskFile) {
1207
+ throw new Error(`Task not found: ${taskId}`);
1208
+ }
1209
+ const { frontMatter, body } = await readMarkdownFile(taskFile);
1210
+ const task = coerceTaskYAML(frontMatter);
1211
+ task.timeLoggedHours += hours;
1212
+ task.version = task.version + 1;
1213
+ task.updated_at = (/* @__PURE__ */ new Date()).toISOString();
1214
+ await writeMarkdownFile(
1215
+ taskFile,
1216
+ task,
1217
+ body
1218
+ );
1219
+ return task;
1220
+ });
1221
+ }
1222
+ function deriveTransitionIdentity(input) {
1223
+ if (input.transitionId) {
1224
+ return crypto.createHash("sha256").update(`id\0${input.transitionId}`).digest("hex");
1225
+ }
1226
+ const payload = [
1227
+ "content",
1228
+ input.taskId,
1229
+ input.targetStatus,
1230
+ input.hoursLogged && input.hoursLogged > 0 ? String(input.hoursLogged) : "0",
1231
+ input.resultArtifactPath ?? ""
1232
+ ].join("\0");
1233
+ return crypto.createHash("sha256").update(payload).digest("hex");
1234
+ }
1235
+ async function applyTaskTransitionOutcome(taskId, input) {
1236
+ const planningRoot = getPlanningRoot();
1237
+ const { isArchived } = await getTask(taskId, { includeArchive: true });
1238
+ if (isArchived) {
1239
+ throw new Error(
1240
+ `Cannot update archived task "${taskId}". Reopen or restore the task before changing status.`
1241
+ );
1242
+ }
1243
+ return withIndexRegeneration(planningRoot, async () => {
1244
+ const tasksDir = getBucketPathByKind("task", planningRoot);
1245
+ const files = await listMarkdownFiles(tasksDir);
1246
+ const taskFile = files.find((f) => path.basename(f) === `${taskId}.md`);
1247
+ if (!taskFile) {
1248
+ throw new Error(`Task not found: ${taskId}`);
1249
+ }
1250
+ const { frontMatter, body } = await readMarkdownFile(taskFile);
1251
+ const task = coerceTaskYAML(frontMatter);
1252
+ const constituents = input.constituents && input.constituents.length > 0 ? input.constituents : [
1253
+ {
1254
+ identity: deriveTransitionIdentity({
1255
+ taskId,
1256
+ targetStatus: input.targetStatus,
1257
+ hoursLogged: input.hoursLogged,
1258
+ resultArtifactPath: input.resultArtifactPath
1259
+ }),
1260
+ hoursLogged: input.hoursLogged
1261
+ }
1262
+ ];
1263
+ const recordedSet = new Set(task.appliedTransitions ?? []);
1264
+ const pendingHourIdentities = [];
1265
+ const seenThisCall = /* @__PURE__ */ new Set();
1266
+ let pendingHours = 0;
1267
+ for (const c of constituents) {
1268
+ if (recordedSet.has(c.identity) || seenThisCall.has(c.identity)) continue;
1269
+ seenThisCall.add(c.identity);
1270
+ pendingHourIdentities.push(c.identity);
1271
+ if (c.hoursLogged && c.hoursLogged > 0) {
1272
+ pendingHours += c.hoursLogged;
1273
+ }
1274
+ }
1275
+ const hoursPending = pendingHours > 0;
1276
+ const statusChanged = task.status !== input.targetStatus;
1277
+ const artifactChanged = Boolean(
1278
+ input.resultArtifactPath && task.resultArtifactPath !== input.resultArtifactPath
1279
+ );
1280
+ const reason = input.reason?.trim();
1281
+ const reasonChanged = Boolean(reason && task.lastTransitionReason !== reason);
1282
+ if (!statusChanged && !artifactChanged && !reasonChanged && !hoursPending) {
1283
+ return { task, statusChanged: false, fileUpdated: false, hoursApplied: 0 };
1284
+ }
1285
+ if (statusChanged) {
1286
+ const transition = await validateStateTransition(
1287
+ planningRoot,
1288
+ taskId,
1289
+ task.status,
1290
+ input.targetStatus
1291
+ );
1292
+ if (!transition.success) {
1293
+ const details = transition.errors?.length ? `: ${transition.errors.join("; ")}` : "";
1294
+ throw new Error(`${transition.message}${details}`);
1295
+ }
1296
+ }
1297
+ if (statusChanged && input.targetStatus === "done") {
1298
+ await assertCompletionContractsMet({
1299
+ contracts: task.completionContract
1300
+ });
1301
+ }
1302
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1303
+ const previousStatus = task.status;
1304
+ if (statusChanged) {
1305
+ task.status = input.targetStatus;
1306
+ if (input.targetStatus === "in_progress" && !task.started_at) {
1307
+ task.started_at = now;
1308
+ }
1309
+ if (input.targetStatus === "done") {
1310
+ task.completed_at = now;
1311
+ } else if (previousStatus === "done") {
1312
+ task.completed_at = void 0;
1313
+ }
1314
+ if (input.targetStatus !== "blocked") {
1315
+ task.blockedReason = void 0;
1316
+ }
1317
+ }
1318
+ if (artifactChanged && input.resultArtifactPath) {
1319
+ task.resultArtifactPath = input.resultArtifactPath;
1320
+ }
1321
+ if (reasonChanged && reason) {
1322
+ task.lastTransitionReason = reason;
1323
+ }
1324
+ let hoursApplied = 0;
1325
+ if (hoursPending) {
1326
+ task.timeLoggedHours += pendingHours;
1327
+ hoursApplied = pendingHours;
1328
+ const next = task.appliedTransitions ? [...task.appliedTransitions] : [];
1329
+ for (const id of pendingHourIdentities) {
1330
+ next.push(id);
1331
+ }
1332
+ task.appliedTransitions = next;
1333
+ }
1334
+ task.version = task.version + 1;
1335
+ task.updated_at = now;
1336
+ await writeMarkdownFile(
1337
+ taskFile,
1338
+ task,
1339
+ updateTaskBodyStatusLine(body, task.status)
1340
+ );
1341
+ if (statusChanged && input.targetStatus === "done") {
1342
+ await autoUnblockDependentTasks(task.id, planningRoot).catch((error) => {
1343
+ emitTaskManagerWarning("Failed to auto-unblock dependent tasks after transition", {
1344
+ taskId: task.id,
1345
+ error: error instanceof Error ? error.message : String(error)
1346
+ });
1347
+ });
1348
+ }
1349
+ if (task.sprintId) {
1350
+ try {
1351
+ const { refreshSprintMarkdown } = await import("./sprint-manager-IDQUDNQI.js");
1352
+ await refreshSprintMarkdown(task.sprintId);
1353
+ } catch (refreshError) {
1354
+ const msg = refreshError instanceof Error ? refreshError.message : String(refreshError);
1355
+ emitTaskManagerWarning("Failed to refresh sprint markdown after task transition", {
1356
+ sprintId: task.sprintId,
1357
+ taskId: task.id,
1358
+ error: msg
1359
+ });
1360
+ }
1361
+ }
1362
+ return { task, statusChanged, fileUpdated: true, hoursApplied };
1363
+ });
1364
+ }
1365
+ async function findArchivedDuplicate(taskId, planningRoot) {
1366
+ const archiveDir = getBucketArchivePathByKind("task", planningRoot);
1367
+ return findArchivedTaskFile(archiveDir, taskId);
1368
+ }
1369
+ async function readTaskForCompletionEval(taskId, planningRoot) {
1370
+ const currentDir = getBucketPathByKind("task", planningRoot);
1371
+ const files = await listMarkdownFiles(currentDir);
1372
+ const taskFile = files.find((f) => path.basename(f) === `${taskId}.md`);
1373
+ if (!taskFile) {
1374
+ throw new Error(`Task not found: ${taskId}`);
1375
+ }
1376
+ const { frontMatter } = await readMarkdownFile(taskFile);
1377
+ const task = coerceTaskYAML(frontMatter);
1378
+ return { task };
1379
+ }
1380
+ function completionContractSnapshotKey(contracts) {
1381
+ if (!contracts || contracts.length === 0) return "";
1382
+ return JSON.stringify(contracts);
1383
+ }
1384
+ async function completeTask(taskId, options = {}) {
1385
+ const planningRoot = getPlanningRoot();
1386
+ const forceCompletion = options.force ?? false;
1387
+ const bypass = options.bypassValidation;
1388
+ const bypassReason = bypass?.reason.trim();
1389
+ if (bypass && !bypassReason) {
1390
+ throw new Error("Task status validation bypass requires a reason");
1391
+ }
1392
+ const preEval = await readTaskForCompletionEval(taskId, planningRoot);
1393
+ const preEvalArchivedDuplicate = await findArchivedDuplicate(taskId, planningRoot);
1394
+ if (preEvalArchivedDuplicate) {
1395
+ throw new Error(
1396
+ `Task ${taskId} has both active and archived records. Completion is blocked to avoid overwriting managed state. Run poetic doctor for details; do not edit managed files manually.`
1397
+ );
1398
+ }
1399
+ if (!forceCompletion && (preEval.task.status === "blocked" || preEval.task.status === "cancelled")) {
1400
+ throw new Error(
1401
+ `Cannot complete task ${preEval.task.id} from status "${preEval.task.status}" without --force. Move it to in_progress/review first.`
1402
+ );
1403
+ }
1404
+ const evaluatedVersion = preEval.task.version;
1405
+ const evaluatedContractKey = completionContractSnapshotKey(preEval.task.completionContract);
1406
+ await assertCompletionContractsMet({
1407
+ contracts: preEval.task.completionContract,
1408
+ bypassReason,
1409
+ workingDir: options.completionContractRoot
1410
+ });
1411
+ return withIndexRegeneration(planningRoot, async () => {
1412
+ const bucket = getBucketByName("task", planningRoot);
1413
+ if (!bucket) {
1414
+ throw new Error("Bucket not configured: task");
1415
+ }
1416
+ const currentDir = getBucketPathByKind("task", planningRoot);
1417
+ const files = await listMarkdownFiles(currentDir);
1418
+ const taskFile = files.find((f) => path.basename(f) === `${taskId}.md`);
1419
+ if (!taskFile) {
1420
+ throw new Error(`Task not found: ${taskId}`);
1421
+ }
1422
+ const archivedDuplicate = await findArchivedDuplicate(taskId, planningRoot);
1423
+ if (archivedDuplicate) {
1424
+ throw new Error(
1425
+ `Task ${taskId} has both active and archived records. Completion is blocked to avoid overwriting managed state. Run poetic doctor for details; do not edit managed files manually.`
1426
+ );
1427
+ }
1428
+ const { frontMatter, body } = await readMarkdownFile(taskFile);
1429
+ const task = coerceTaskYAML(frontMatter);
1430
+ if (task.version !== evaluatedVersion || completionContractSnapshotKey(task.completionContract) !== evaluatedContractKey) {
1431
+ throw new StaleVersionError(
1432
+ task.version,
1433
+ evaluatedVersion,
1434
+ taskId,
1435
+ "completionContract",
1436
+ "concurrent task mutation between completion-contract evaluation and archive write"
1437
+ );
1438
+ }
1439
+ if (!forceCompletion && (task.status === "blocked" || task.status === "cancelled")) {
1440
+ throw new Error(
1441
+ `Cannot complete task ${task.id} from status "${task.status}" without --force. Move it to in_progress/review first.`
1442
+ );
1443
+ }
1444
+ if (task.status !== "done" && !(forceCompletion && (task.status === "blocked" || task.status === "cancelled")) && !bypass) {
1445
+ const transition = await validateStateTransition(planningRoot, taskId, task.status, "done");
1446
+ if (!transition.success) {
1447
+ const details = transition.errors?.length ? `: ${transition.errors.join("; ")}` : "";
1448
+ throw new Error(`${transition.message}${details}`);
1449
+ }
1450
+ }
1451
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1452
+ if (forceCompletion && task.status !== "done") {
1453
+ task.forceCompletedFrom = task.status;
1454
+ if (options.preserveBlockedReason && task.status === "blocked" && task.blockedReason) {
1455
+ task.originalBlockedReason = task.blockedReason;
1456
+ }
1457
+ }
1458
+ const previousStatus = task.status;
1459
+ task.status = "done";
1460
+ task.version = task.version + 1;
1461
+ task.completed_at = now;
1462
+ task.updated_at = now;
1463
+ task.archivedAt = now;
1464
+ task.originalSprintId = task.sprintId;
1465
+ if (bypass && bypassReason) {
1466
+ task.statusBypassAudit = [
1467
+ ...task.statusBypassAudit ?? [],
1468
+ {
1469
+ at: now,
1470
+ fromStatus: previousStatus,
1471
+ toStatus: "done",
1472
+ reason: bypassReason,
1473
+ ...bypass.actor ? { actor: bypass.actor } : {}
1474
+ }
1475
+ ];
1476
+ }
1477
+ const archivedPath = getArchivedFilePath(bucket, task.id, now, planningRoot);
1478
+ await ensureDirectoryExists(path.dirname(archivedPath));
1479
+ await writeMarkdownFile(archivedPath, toArchivedTaskFrontMatter(task), body);
1480
+ try {
1481
+ await detachArchivedTaskFromSprintMembership(task, "archiving");
1482
+ } catch (error) {
1483
+ await fs.unlink(archivedPath).catch(() => void 0);
1484
+ throw error;
1485
+ }
1486
+ const archiveDir = getBucketArchivePathByKind("task", planningRoot);
1487
+ const archivedIndex = archivedTaskIndexes.get(archiveDir);
1488
+ if (archivedIndex) {
1489
+ archivedIndex.set(task.id, archivedPath);
1490
+ }
1491
+ await fs.unlink(taskFile);
1492
+ const unblockedTaskIds = await autoUnblockDependentTasks(task.id, planningRoot).catch(
1493
+ (error) => {
1494
+ emitTaskManagerWarning("Failed to auto-unblock dependent tasks after completion", {
1495
+ taskId: task.id,
1496
+ error: error instanceof Error ? error.message : String(error)
1497
+ });
1498
+ return [];
1499
+ }
1500
+ );
1501
+ return { task, archivedPath, unblockedTaskIds };
1502
+ });
1503
+ }
1504
+ function toArchivedTaskFrontMatter(task) {
1505
+ const frontMatter = { ...task };
1506
+ delete frontMatter.sprintId;
1507
+ delete frontMatter.sprint_id;
1508
+ return frontMatter;
1509
+ }
1510
+ function getErrorCode(error) {
1511
+ if (!error || typeof error !== "object" || !("code" in error)) return void 0;
1512
+ const code = error.code;
1513
+ return typeof code === "string" ? code : void 0;
1514
+ }
1515
+ async function detachArchivedTaskFromSprintMembership(task, action) {
1516
+ if (!task.sprintId) return;
1517
+ try {
1518
+ const { detachArchivedTaskFromSprint } = await import("./sprint-manager-IDQUDNQI.js");
1519
+ await detachArchivedTaskFromSprint(task.sprintId, task.id, {
1520
+ completed: action === "archiving"
1521
+ });
1522
+ } catch (removeError) {
1523
+ if (getErrorCode(removeError) === "ENOENT") {
1524
+ return;
1525
+ }
1526
+ const removeMessage = removeError instanceof Error ? removeError.message : String(removeError);
1527
+ try {
1528
+ const { refreshSprintMarkdown } = await import("./sprint-manager-IDQUDNQI.js");
1529
+ await refreshSprintMarkdown(task.sprintId);
1530
+ } catch (refreshError) {
1531
+ emitTaskManagerWarning(`Failed to refresh sprint markdown after ${action} task`, {
1532
+ sprintId: task.sprintId,
1533
+ taskId: task.id,
1534
+ action,
1535
+ error: refreshError instanceof Error ? refreshError.message : String(refreshError)
1536
+ });
1537
+ }
1538
+ throw new Error(
1539
+ `Failed to remove task ${task.id} from sprint ${task.sprintId} after ${action}: ${removeMessage}`
1540
+ );
1541
+ }
1542
+ }
1543
+ function getCancelledTaskArchivePath(taskId, cancelledAt, planningRoot) {
1544
+ const shard = getArchiveShard(cancelledAt);
1545
+ const taskBucket = getBucketPathByKind("task", planningRoot);
1546
+ const archiveRoot = getBucketArchivePathByKind("task", planningRoot);
1547
+ const extraSegments = path.relative(taskBucket, archiveRoot).split(path.sep).filter(Boolean);
1548
+ extraSegments.push("abandoned", shard.year, shard.month);
1549
+ return resolvePlanningItemPath(taskBucket, taskId, {
1550
+ label: "taskId",
1551
+ extraSegments
1552
+ });
1553
+ }
1554
+ async function cancelTask(taskId, options) {
1555
+ const planningRoot = getPlanningRoot();
1556
+ const reason = options.reason.trim();
1557
+ if (!reason) {
1558
+ throw new Error("Cancellation reason is required");
1559
+ }
1560
+ return withIndexRegeneration(planningRoot, async () => {
1561
+ const currentDir = getBucketPathByKind("task", planningRoot);
1562
+ const files = await listMarkdownFiles(currentDir);
1563
+ const taskFile = files.find((f) => path.basename(f) === `${taskId}.md`);
1564
+ if (!taskFile) {
1565
+ throw new Error(`Task not found: ${taskId}`);
1566
+ }
1567
+ const { frontMatter, body } = await readMarkdownFile(taskFile);
1568
+ const task = coerceTaskYAML(frontMatter);
1569
+ if (options.expectedVersion !== void 0 && task.version !== options.expectedVersion) {
1570
+ throw new StaleVersionError(task.version, options.expectedVersion, taskId);
1571
+ }
1572
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1573
+ const bypass = options.bypassValidation;
1574
+ const bypassReason = bypass?.reason.trim();
1575
+ if (bypass && !bypassReason) {
1576
+ throw new Error("Task status validation bypass requires a reason");
1577
+ }
1578
+ if (!bypass) {
1579
+ const transition = await validateStateTransition(
1580
+ planningRoot,
1581
+ taskId,
1582
+ task.status,
1583
+ "cancelled"
1584
+ );
1585
+ if (!transition.success) {
1586
+ const details = transition.errors?.length ? `: ${transition.errors.join("; ")}` : "";
1587
+ throw new Error(`${transition.message}${details}`);
1588
+ }
1589
+ }
1590
+ const previousStatus = task.status;
1591
+ task.status = "cancelled";
1592
+ task.version = task.version + 1;
1593
+ task.cancelledAt = now;
1594
+ task.cancelledReason = reason;
1595
+ task.updated_at = now;
1596
+ task.archivedAt = now;
1597
+ task.completed_at = void 0;
1598
+ task.originalSprintId = task.sprintId;
1599
+ if (bypass && bypassReason) {
1600
+ task.statusBypassAudit = [
1601
+ ...task.statusBypassAudit ?? [],
1602
+ {
1603
+ at: now,
1604
+ fromStatus: previousStatus,
1605
+ toStatus: "cancelled",
1606
+ reason: bypassReason,
1607
+ ...bypass.actor ? { actor: bypass.actor } : {}
1608
+ }
1609
+ ];
1610
+ }
1611
+ const archivedPath = getCancelledTaskArchivePath(task.id, now, planningRoot);
1612
+ await ensureDirectoryExists(path.dirname(archivedPath));
1613
+ await writeMarkdownFile(archivedPath, toArchivedTaskFrontMatter(task), body);
1614
+ try {
1615
+ await detachArchivedTaskFromSprintMembership(task, "cancelling");
1616
+ } catch (error) {
1617
+ await fs.unlink(archivedPath).catch(() => void 0);
1618
+ throw error;
1619
+ }
1620
+ const archiveDir = getBucketArchivePathByKind("task", planningRoot);
1621
+ const archivedIndex = archivedTaskIndexes.get(archiveDir);
1622
+ if (archivedIndex) {
1623
+ archivedIndex.set(task.id, archivedPath);
1624
+ }
1625
+ await fs.unlink(taskFile);
1626
+ return { task, archivedPath };
1627
+ });
1628
+ }
1629
+ async function restoreTask(taskId, options = {}) {
1630
+ const planningRoot = getPlanningRoot();
1631
+ const targetStatus = options.status ?? "in_progress";
1632
+ return withIndexRegeneration(planningRoot, async () => {
1633
+ const { filePath, isArchived } = await getTask(taskId, { includeArchive: true });
1634
+ const { frontMatter, body } = await readMarkdownFile(filePath);
1635
+ const task = coerceTaskYAML(frontMatter);
1636
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1637
+ let restoreIntoSprint = false;
1638
+ let sprintAlreadyMember = false;
1639
+ if (task.sprintId) {
1640
+ const { assertSprintCanAcceptRestoredTask } = await import("./sprint-manager-IDQUDNQI.js");
1641
+ const acceptance = await assertSprintCanAcceptRestoredTask(task.sprintId, task.id);
1642
+ if (acceptance.sprintExists) {
1643
+ restoreIntoSprint = true;
1644
+ sprintAlreadyMember = acceptance.alreadyMember;
1645
+ }
1646
+ }
1647
+ task.status = targetStatus;
1648
+ task.version = task.version + 1;
1649
+ task.updated_at = now;
1650
+ task.completed_at = void 0;
1651
+ delete task.archivedAt;
1652
+ delete task.cancelledAt;
1653
+ delete task.cancelledReason;
1654
+ delete task.originalSprintId;
1655
+ const restoredPath = resolvePlanningItemPath(
1656
+ getBucketPathByKind("task", planningRoot),
1657
+ taskId,
1658
+ { label: "taskId" }
1659
+ );
1660
+ await ensureDirectoryExists(path.dirname(restoredPath));
1661
+ await writeMarkdownFile(
1662
+ restoredPath,
1663
+ task,
1664
+ body
1665
+ );
1666
+ try {
1667
+ if (restoreIntoSprint && task.sprintId) {
1668
+ const { addTaskToSprint, refreshSprintMarkdown, removeTaskFromSprint } = await import("./sprint-manager-IDQUDNQI.js");
1669
+ if (isArchived && !sprintAlreadyMember) {
1670
+ await addTaskToSprint(task.sprintId, task.id, task.estimatedHours);
1671
+ }
1672
+ try {
1673
+ await refreshSprintMarkdown(task.sprintId);
1674
+ } catch (refreshError) {
1675
+ if (isArchived && !sprintAlreadyMember) {
1676
+ await removeTaskFromSprint(task.sprintId, task.id).catch(() => void 0);
1677
+ }
1678
+ throw refreshError;
1679
+ }
1680
+ }
1681
+ } catch (restoreError) {
1682
+ if (isArchived) {
1683
+ await fs.unlink(restoredPath).catch(() => void 0);
1684
+ }
1685
+ throw restoreError;
1686
+ }
1687
+ if (isArchived) {
1688
+ await fs.unlink(filePath);
1689
+ const archiveDir = getBucketArchivePathByKind("task", planningRoot);
1690
+ const archivedIndex = archivedTaskIndexes.get(archiveDir);
1691
+ archivedIndex?.delete(task.id);
1692
+ }
1693
+ return { task, restoredPath };
1694
+ });
1695
+ }
1696
+ var MAX_AMBIGUOUS_MATCH_PREVIEW = 5;
1697
+ function resolveTaskIdFromPrefix(candidateIds, query) {
1698
+ const uniqueIds = [...new Set(candidateIds)];
1699
+ const matches = uniqueIds.filter((id) => id === query || id.startsWith(query));
1700
+ if (matches.length === 0) {
1701
+ return null;
1702
+ }
1703
+ if (matches.length === 1) {
1704
+ return matches[0] ?? null;
1705
+ }
1706
+ const preview = matches.slice(0, MAX_AMBIGUOUS_MATCH_PREVIEW).join(", ");
1707
+ const suffix = matches.length > MAX_AMBIGUOUS_MATCH_PREVIEW ? ", ..." : "";
1708
+ throw new Error(
1709
+ `Ambiguous task ID prefix "${query}": matches ${matches.length} tasks (${preview}${suffix}). Use a longer prefix or the full ID.`
1710
+ );
1711
+ }
1712
+ async function loadTaskLookupFromFile(filePath, isArchived) {
1713
+ const { frontMatter } = await readMarkdownFile(filePath);
1714
+ return {
1715
+ yaml: coerceTaskYAML(frontMatter),
1716
+ filePath,
1717
+ isArchived
1718
+ };
1719
+ }
1720
+ async function collectKnownTaskIds(planningRoot, tasksDir, includeArchive) {
1721
+ const ids = [];
1722
+ const activeFiles = await listMarkdownFiles(tasksDir);
1723
+ for (const filePath of activeFiles) {
1724
+ const id = path.basename(filePath, ".md");
1725
+ if (id) {
1726
+ ids.push(id);
1727
+ }
1728
+ }
1729
+ if (includeArchive) {
1730
+ try {
1731
+ const archiveDir = getBucketArchivePathByKind("task", planningRoot);
1732
+ const index = await getArchivedTaskIndex(archiveDir);
1733
+ ids.push(...index.keys());
1734
+ } catch {
1735
+ }
1736
+ }
1737
+ return ids;
1738
+ }
1739
+ async function getTask(taskId, options = {}) {
1740
+ const { includeArchive = false } = options;
1741
+ const planningRoot = getPlanningRoot();
1742
+ const tasksDir = getBucketPathByKind("task", planningRoot);
1743
+ const activeTaskFile = resolvePlanningItemPath(tasksDir, taskId, { label: "taskId" });
1744
+ try {
1745
+ await fs.access(activeTaskFile);
1746
+ return loadTaskLookupFromFile(activeTaskFile, false);
1747
+ } catch (error) {
1748
+ if (error.code !== "ENOENT") {
1749
+ throw error;
1750
+ }
1751
+ }
1752
+ if (includeArchive) {
1753
+ try {
1754
+ const archiveDir = getBucketArchivePathByKind("task", planningRoot);
1755
+ const archivedTaskFile = await findArchivedTaskFile(archiveDir, taskId);
1756
+ if (archivedTaskFile) {
1757
+ return loadTaskLookupFromFile(archivedTaskFile, true);
1758
+ }
1759
+ } catch (error) {
1760
+ if (getErrorCode(error) !== "ENOENT") {
1761
+ throw error;
1762
+ }
1763
+ }
1764
+ }
1765
+ const resolvedId = resolveTaskIdFromPrefix(
1766
+ await collectKnownTaskIds(planningRoot, tasksDir, includeArchive),
1767
+ taskId
1768
+ );
1769
+ if (resolvedId && resolvedId !== taskId) {
1770
+ return getTask(resolvedId, options);
1771
+ }
1772
+ throw new Error(`Task not found: ${taskId}`);
1773
+ }
1774
+ var archivedTaskIndexes = /* @__PURE__ */ new Map();
1775
+ function clearArchivedTaskIndex() {
1776
+ archivedTaskIndexes.clear();
1777
+ }
1778
+ async function buildArchivedTaskIndex(archiveDir) {
1779
+ const files = await listMarkdownFilesRecursiveStrict(archiveDir);
1780
+ const index = /* @__PURE__ */ new Map();
1781
+ for (const filePath of files) {
1782
+ const base = path.basename(filePath);
1783
+ if (!base.endsWith(".md")) continue;
1784
+ const id = base.slice(0, -3);
1785
+ if (!id) continue;
1786
+ index.set(id, filePath);
1787
+ }
1788
+ return index;
1789
+ }
1790
+ async function getArchivedTaskIndex(archiveDir) {
1791
+ let index = archivedTaskIndexes.get(archiveDir);
1792
+ if (!index) {
1793
+ index = await buildArchivedTaskIndex(archiveDir);
1794
+ archivedTaskIndexes.set(archiveDir, index);
1795
+ }
1796
+ return index;
1797
+ }
1798
+ async function findArchivedTaskFile(archiveDir, taskId) {
1799
+ if (isValidId(taskId)) {
1800
+ const index = await getArchivedTaskIndex(archiveDir);
1801
+ const directMatch = index.get(taskId);
1802
+ if (directMatch) {
1803
+ return directMatch;
1804
+ }
1805
+ const rebuiltIndex = await buildArchivedTaskIndex(archiveDir);
1806
+ archivedTaskIndexes.set(archiveDir, rebuiltIndex);
1807
+ return rebuiltIndex.get(taskId) ?? null;
1808
+ }
1809
+ const files = await listMarkdownFilesRecursiveStrict(archiveDir);
1810
+ return files.find((f) => path.basename(f) === `${taskId}.md`) ?? null;
1811
+ }
1812
+ async function getTaskAny(taskId) {
1813
+ return getTask(taskId, { includeArchive: true });
1814
+ }
1815
+ async function resolveTask(taskId) {
1816
+ return getTask(taskId, { includeArchive: true });
1817
+ }
1818
+ async function getTaskActive(taskId) {
1819
+ return getTask(taskId, { includeArchive: false });
1820
+ }
1821
+ async function getTaskDependency(depId, options = {}) {
1822
+ try {
1823
+ const result = await getTask(depId, { includeArchive: true });
1824
+ const classification = classifyTaskDependency(depId, {
1825
+ task: { status: result.yaml.status, isArchived: result.isArchived }
1826
+ });
1827
+ return {
1828
+ missing: classification.state === "missing",
1829
+ satisfied: classification.satisfied,
1830
+ isArchived: classification.isArchived,
1831
+ task: result.yaml
1832
+ };
1833
+ } catch {
1834
+ let recordedComplete = false;
1835
+ if (options.sprintId) {
1836
+ try {
1837
+ const { isTaskRecordedCompletedInSprint } = await import("./sprint-manager-IDQUDNQI.js");
1838
+ recordedComplete = await isTaskRecordedCompletedInSprint(options.sprintId, depId);
1839
+ } catch {
1840
+ }
1841
+ }
1842
+ const classification = classifyTaskDependency(depId, {
1843
+ task: null,
1844
+ recordedComplete
1845
+ });
1846
+ return {
1847
+ missing: classification.state === "missing",
1848
+ satisfied: classification.satisfied,
1849
+ isArchived: classification.isArchived
1850
+ };
1851
+ }
1852
+ }
1853
+ async function getAllTasks(options = {}) {
1854
+ const { includeArchive = false } = options;
1855
+ const planningRoot = getPlanningRoot();
1856
+ const tasksDir = getBucketPathByKind("task", planningRoot);
1857
+ const results = [];
1858
+ const activeFiles = await listMarkdownFiles(tasksDir);
1859
+ for (const filePath of activeFiles) {
1860
+ try {
1861
+ const { frontMatter } = await readMarkdownFile(filePath);
1862
+ results.push({
1863
+ yaml: coerceTaskYAML(frontMatter),
1864
+ filePath,
1865
+ isArchived: false
1866
+ });
1867
+ } catch {
1868
+ }
1869
+ }
1870
+ if (includeArchive) {
1871
+ try {
1872
+ const archiveDir = getBucketArchivePathByKind("task", planningRoot);
1873
+ const archiveFiles = await listMarkdownFilesRecursive(archiveDir);
1874
+ for (const filePath of archiveFiles) {
1875
+ try {
1876
+ const { frontMatter } = await readMarkdownFile(filePath);
1877
+ results.push({
1878
+ yaml: coerceTaskYAML(frontMatter),
1879
+ filePath,
1880
+ isArchived: true
1881
+ });
1882
+ } catch {
1883
+ }
1884
+ }
1885
+ } catch {
1886
+ }
1887
+ }
1888
+ return results;
1889
+ }
1890
+ async function listTasksLinkedToBacklogItem(backlogItemId, options = {}) {
1891
+ const { includeArchive = false } = options;
1892
+ const allTasks = await getAllTasks({ includeArchive });
1893
+ return allTasks.filter((result) => result.yaml.backlogItemId === backlogItemId).map((result) => ({
1894
+ id: result.yaml.id,
1895
+ title: result.yaml.title,
1896
+ status: result.yaml.status,
1897
+ sprintId: result.yaml.sprintId
1898
+ })).sort((a, b) => a.id.localeCompare(b.id));
1899
+ }
1900
+ async function listTasksInSprint(sprintId, statusFilter) {
1901
+ try {
1902
+ const { listTasksInSprint: listSprintTaskRefs } = await import("./sprint-manager-IDQUDNQI.js");
1903
+ const sprintTasks = await listSprintTaskRefs(sprintId);
1904
+ const tasks2 = [];
1905
+ for (const sprintTask of sprintTasks) {
1906
+ if (sprintTask.missing === true) continue;
1907
+ try {
1908
+ const { yaml: task, isArchived } = await getTask(sprintTask.id, { includeArchive: true });
1909
+ if (isArchived) continue;
1910
+ if (!statusFilter || task.status === statusFilter) {
1911
+ tasks2.push(task);
1912
+ }
1913
+ } catch {
1914
+ }
1915
+ }
1916
+ return tasks2;
1917
+ } catch (error) {
1918
+ const code = error && typeof error === "object" && "code" in error ? error.code : void 0;
1919
+ const message = error instanceof Error ? error.message : String(error);
1920
+ if (code !== "ENOENT" && !message.includes(`Sprint not found: ${sprintId}`)) {
1921
+ throw error;
1922
+ }
1923
+ }
1924
+ const planningRoot = getPlanningRoot();
1925
+ const tasksDir = getBucketPathByKind("task", planningRoot);
1926
+ const files = await listMarkdownFiles(tasksDir);
1927
+ const tasks = [];
1928
+ for (const file of files) {
1929
+ let task;
1930
+ try {
1931
+ const { frontMatter } = await readMarkdownFile(file);
1932
+ task = coerceTaskYAML(frontMatter);
1933
+ } catch {
1934
+ continue;
1935
+ }
1936
+ if (task.sprintId === sprintId) {
1937
+ if (!statusFilter || task.status === statusFilter) {
1938
+ tasks.push(task);
1939
+ }
1940
+ }
1941
+ }
1942
+ return tasks;
1943
+ }
1944
+
1945
+ export {
1946
+ generateTaskId,
1947
+ createTask,
1948
+ createTaskWithGuidance,
1949
+ updateTaskFields,
1950
+ updateTaskStatus,
1951
+ updateTaskStatusWithTransitionValidation,
1952
+ addTaskDependency,
1953
+ removeTaskDependency,
1954
+ validateTaskExecution,
1955
+ logTaskTime,
1956
+ deriveTransitionIdentity,
1957
+ applyTaskTransitionOutcome,
1958
+ completeTask,
1959
+ cancelTask,
1960
+ restoreTask,
1961
+ resolveTaskIdFromPrefix,
1962
+ getTask,
1963
+ clearArchivedTaskIndex,
1964
+ getTaskAny,
1965
+ resolveTask,
1966
+ getTaskActive,
1967
+ getTaskDependency,
1968
+ getAllTasks,
1969
+ listTasksLinkedToBacklogItem,
1970
+ listTasksInSprint
1971
+ };
1972
+ //# sourceMappingURL=chunk-5LTN43AS.js.map