@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,1227 @@
1
+ /**
2
+ * Pure BB presentation for custom task authoring and task relationships.
3
+ *
4
+ * This module is presentation only. It labels the BPAU-02 authoring vocabulary,
5
+ * gates a draft before it may be submitted, builds exactly one typed BPAU-02
6
+ * request from a confirmed draft, and renders the outcome BPAU-02 returned. It
7
+ * holds the same authority boundary as the rest of this plugin:
8
+ *
9
+ * - Poetic is the only mutation and sync authority. Nothing here spawns a
10
+ * process, reads a file, resolves a path, or calls an RPC method.
11
+ * - Custom task creation is labelled as its own product. It is never rendered
12
+ * as adding an existing backlog item to a sprint, and never as a lifecycle
13
+ * transition: no control here can emit `start`, `block`, `unblock`,
14
+ * `review`, `complete`, `cancel`, or `reopen`, and the shipped lifecycle
15
+ * panel is untouched.
16
+ * - Relationship mutations name both endpoints explicitly. A missing,
17
+ * malformed, self-referential, or not-currently-shown endpoint is refused
18
+ * rather than guessed.
19
+ * - A Description replacement is offered only when BB prepopulated the current
20
+ * canonical Description, and the replacement scope is always disclosed.
21
+ * - One confirmed draft emits one request and then waits. While a submission is
22
+ * unresolved every control is refused, and no resulting identity, status,
23
+ * membership, capacity, or push success is predicted: the outcome view
24
+ * reports Poetic's own effect phase, its fresh rereads, and its sync
25
+ * evidence, never the exit code.
26
+ *
27
+ * Nothing from the shared adapter, model, contract, server, app, or route
28
+ * modules is imported here.
29
+ */
30
+
31
+ import {
32
+ TASK_AUTHORING_CONSENT_LABELS,
33
+ TASK_AUTHORING_CREATE_DISTINCTION_NOTICE,
34
+ TASK_AUTHORING_DESCRIPTION_REPLACEMENT_NOTICE,
35
+ TASK_AUTHORING_EFFECTS,
36
+ TASK_AUTHORING_LABELS,
37
+ type TaskAuthoringConsentState,
38
+ type TaskAuthoringPrepopulation,
39
+ taskAuthoringArgv,
40
+ taskAuthoringConsentPayload,
41
+ taskAuthoringDeclaredIdentities,
42
+ taskAuthoringDeniedInputKeys,
43
+ taskAuthoringDescriptionPrepopulation,
44
+ taskAuthoringRequiredConsentKeys,
45
+ } from './task-authoring-model.js';
46
+ import {
47
+ type ApplyTaskAuthoringInput,
48
+ type ApplyTaskAuthoringOutput,
49
+ applyTaskAuthoringInputSchema,
50
+ TASK_AUTHORING_DISCLOSURE,
51
+ TASK_AUTHORING_VOCABULARY,
52
+ type TaskAuthoringAction,
53
+ type TaskAuthoringCommandEvidence,
54
+ type TaskAuthoringEffect,
55
+ type TaskAuthoringRefusal,
56
+ type TaskAuthoringRefusalReason,
57
+ type TaskAuthoringSync,
58
+ taskAuthoringIdentitySchema,
59
+ } from './task-authoring-schema.js';
60
+
61
+ /** Version of the presentation this module publishes. */
62
+ export const TASK_AUTHORING_VIEW_VERSION = '1.0.0' as const;
63
+
64
+ /**
65
+ * Domain every control here carries. It is deliberately not the lifecycle
66
+ * panel's `task-lifecycle` domain, so an authoring control can never be rendered
67
+ * in the lifecycle group or read as a status transition.
68
+ */
69
+ export const TASK_AUTHORING_DOMAIN = 'task-authoring' as const;
70
+
71
+ /** Concise action-first labels for buttons; detailed effects stay adjacent. */
72
+ export const TASK_AUTHORING_BUTTON_LABELS: Readonly<Record<TaskAuthoringAction, string>> = {
73
+ createCustomTask: 'Create Custom Task',
74
+ updateCustomTask: 'Save Task Details',
75
+ addTaskDependency: 'Add Dependency',
76
+ removeTaskDependency: 'Remove Dependency',
77
+ linkTaskToBacklog: 'Link Backlog Item',
78
+ };
79
+
80
+ export const TASK_AUTHORING_LIFECYCLE_SEPARATION_NOTICE =
81
+ 'These are authoring controls. None of them starts, blocks, unblocks, reviews, completes, cancels, reopens, or archives a task; task status stays with the separate task lifecycle controls, which this panel does not change.';
82
+
83
+ export const TASK_AUTHORING_ADD_FROM_BACKLOG_SEPARATION_NOTICE =
84
+ 'Creating a custom task is not "add from backlog". Scheduling an existing backlog item into a sprint is a separate control with its own Poetic command; this panel never schedules a backlog item.';
85
+
86
+ export const TASK_AUTHORING_CONCURRENCY_NOTICE =
87
+ 'This panel submits one authoring action at a time and waits for Poetic to answer. Another BB panel or another process can still submit concurrently; Poetic-side admission, not this panel, is the authority for that.';
88
+
89
+ export const TASK_AUTHORING_AWAITING_REREAD_NOTICE =
90
+ "Poetic is running this command once. BB is waiting for Poetic's own outcome and its fresh canonical reread, and has predicted no task id, status, membership, capacity, or push result.";
91
+
92
+ export const TASK_AUTHORING_REREAD_NOTICE =
93
+ "Everything below is Poetic's own outcome and its fresh reread. BB derived no identity, status, membership, or capacity of its own, and a zero exit never confirmed the managed sync reached the remote.";
94
+
95
+ /** Kinds of relationship endpoint this panel can address. */
96
+ export type TaskAuthoringEndpointKind = 'task' | 'sprint' | 'backlog-item';
97
+
98
+ /**
99
+ * One authoring draft exactly as the operator left it. Every field is raw form
100
+ * text so nothing is coerced before it is validated, and the discriminant is
101
+ * `kind` rather than `action` so a draft object can never carry a key from the
102
+ * refused input surface.
103
+ */
104
+ export type TaskAuthoringDraft =
105
+ | {
106
+ kind: 'createCustomTask';
107
+ sprintId: string;
108
+ title: string;
109
+ /** Required plain decimal hours; never defaulted from a CLI value. */
110
+ estimate: string;
111
+ expectedRuntimeMinutes: string;
112
+ description: string;
113
+ /** `P0`-`P3`, or empty to send none. */
114
+ priority: string;
115
+ dependsOn: readonly string[];
116
+ backlogItemId: string;
117
+ }
118
+ | {
119
+ kind: 'updateCustomTask';
120
+ taskId: string;
121
+ title: string;
122
+ /** Prepopulated from the canonical Description; empty sends none. */
123
+ description: string;
124
+ priority: string;
125
+ estimate: string;
126
+ expectedRuntimeMinutes: string;
127
+ }
128
+ | { kind: 'addTaskDependency'; taskId: string; onTaskId: string }
129
+ | { kind: 'removeTaskDependency'; taskId: string; removeTaskId: string }
130
+ | { kind: 'linkTaskToBacklog'; taskId: string; backlogItemId: string };
131
+
132
+ /** An empty draft per action, so a panel never starts from a partial shape. */
133
+ export function emptyTaskAuthoringDraft(action: TaskAuthoringAction): TaskAuthoringDraft {
134
+ switch (action) {
135
+ case 'createCustomTask':
136
+ return {
137
+ kind: 'createCustomTask',
138
+ sprintId: '',
139
+ title: '',
140
+ estimate: '',
141
+ expectedRuntimeMinutes: '',
142
+ description: '',
143
+ priority: '',
144
+ dependsOn: [],
145
+ backlogItemId: '',
146
+ };
147
+ case 'updateCustomTask':
148
+ return {
149
+ kind: 'updateCustomTask',
150
+ taskId: '',
151
+ title: '',
152
+ description: '',
153
+ priority: '',
154
+ estimate: '',
155
+ expectedRuntimeMinutes: '',
156
+ };
157
+ case 'addTaskDependency':
158
+ return { kind: 'addTaskDependency', taskId: '', onTaskId: '' };
159
+ case 'removeTaskDependency':
160
+ return { kind: 'removeTaskDependency', taskId: '', removeTaskId: '' };
161
+ case 'linkTaskToBacklog':
162
+ return { kind: 'linkTaskToBacklog', taskId: '', backlogItemId: '' };
163
+ }
164
+ }
165
+
166
+ /** The action one draft addresses. */
167
+ export function taskAuthoringDraftAction(draft: TaskAuthoringDraft): TaskAuthoringAction {
168
+ return draft.kind;
169
+ }
170
+
171
+ /** True when this draft asks to replace the task's Description section. */
172
+ export function taskAuthoringDraftReplacesDescription(draft: TaskAuthoringDraft): boolean {
173
+ return draft.kind === 'updateCustomTask' && draft.description.trim().length > 0;
174
+ }
175
+
176
+ /** The canonical read state BB holds for the task a draft addresses. */
177
+ export type TaskAuthoringDetailState = 'available' | 'missing' | 'unavailable' | 'none';
178
+
179
+ /** One unresolved submission this panel owns. */
180
+ export interface TaskAuthoringSubmissionState {
181
+ action: TaskAuthoringAction;
182
+ /** Task id for an edit or relationship, sprint id for a creation. */
183
+ identity: string;
184
+ }
185
+
186
+ /** Why a draft may not be submitted, in BPAU-02's own refusal vocabulary. */
187
+ export interface TaskAuthoringViewRefusal {
188
+ reason: TaskAuthoringRefusalReason;
189
+ message: string;
190
+ }
191
+
192
+ export interface TaskAuthoringGateInput {
193
+ draft: TaskAuthoringDraft;
194
+ consent: TaskAuthoringConsentState;
195
+ /** BB's canonical read state for the addressed task; `none` for a creation. */
196
+ detailState: TaskAuthoringDetailState;
197
+ /** Task id BB currently holds canonical detail for, or null when it holds none. */
198
+ canonicalTaskId: string | null;
199
+ /** Task `updated` timestamp BB built this draft from, or null. */
200
+ observedTaskUpdatedAt: string | null;
201
+ /** Task `updated` timestamp of BB's latest canonical read, or null. */
202
+ canonicalTaskUpdatedAt: string | null;
203
+ /**
204
+ * Canonical Description prepopulation for this task, or null when the panel
205
+ * holds none. Required before a Description replacement may be submitted.
206
+ */
207
+ descriptionPrepopulation: TaskAuthoringPrepopulation | null;
208
+ /** Unresolved submission this panel already owns, or null. */
209
+ inFlight: TaskAuthoringSubmissionState | null;
210
+ }
211
+
212
+ type IdentityCheck = { state: 'valid'; value: string } | { state: 'empty' } | { state: 'invalid' };
213
+
214
+ /** Validate one entered identity without repairing, completing, or guessing it. */
215
+ function checkIdentity(raw: string): IdentityCheck {
216
+ const trimmed = raw.trim();
217
+ if (trimmed.length === 0) return { state: 'empty' };
218
+ return taskAuthoringIdentitySchema.safeParse(trimmed).success
219
+ ? { state: 'valid', value: trimmed }
220
+ : { state: 'invalid' };
221
+ }
222
+
223
+ const ENDPOINT_NOUNS: Readonly<Record<TaskAuthoringEndpointKind, string>> = {
224
+ task: 'task',
225
+ sprint: 'sprint',
226
+ 'backlog-item': 'backlog item',
227
+ };
228
+
229
+ /**
230
+ * Refuse an endpoint that is not exactly one named managed identity. An
231
+ * ambiguous endpoint is never resolved by BB: it is reported, and nothing is
232
+ * submitted.
233
+ */
234
+ function endpointRefusal(
235
+ kind: TaskAuthoringEndpointKind,
236
+ role: string,
237
+ raw: string
238
+ ): TaskAuthoringViewRefusal | null {
239
+ const check = checkIdentity(raw);
240
+ if (check.state === 'empty') {
241
+ return {
242
+ reason: 'missing-identity',
243
+ message: `No ${role} ${ENDPOINT_NOUNS[kind]} is named, so BB will not submit an ambiguous ${ENDPOINT_NOUNS[kind]} endpoint.`,
244
+ };
245
+ }
246
+ if (check.state === 'invalid') {
247
+ return {
248
+ reason: 'invalid-request',
249
+ message: `The ${role} ${ENDPOINT_NOUNS[kind]} "${raw.trim()}" is not a single managed planning id, so BB will not submit it as an endpoint.`,
250
+ };
251
+ }
252
+ return null;
253
+ }
254
+
255
+ type NumberField =
256
+ | { state: 'absent' }
257
+ | { state: 'value'; value: number }
258
+ | { state: 'invalid'; raw: string };
259
+
260
+ /**
261
+ * Read one numeric form field. Only a plain decimal token is accepted, mirroring
262
+ * the wire schema, so an exponent, a sign, a separator, or a non-finite form is
263
+ * refused rather than coerced into a value the operator never typed.
264
+ */
265
+ function readNumberField(raw: string): NumberField {
266
+ const trimmed = raw.trim();
267
+ if (trimmed.length === 0) return { state: 'absent' };
268
+ if (!/^[0-9]+(\.[0-9]+)?$/.test(trimmed)) return { state: 'invalid', raw: trimmed };
269
+ const value = Number(trimmed);
270
+ if (!Number.isFinite(value) || value <= 0) return { state: 'invalid', raw: trimmed };
271
+ return { state: 'value', value };
272
+ }
273
+
274
+ const PRIORITIES = ['P0', 'P1', 'P2', 'P3'] as const;
275
+
276
+ type PriorityField =
277
+ | { state: 'absent' }
278
+ | { state: 'value'; value: (typeof PRIORITIES)[number] }
279
+ | { state: 'invalid'; raw: string };
280
+
281
+ function readPriorityField(raw: string): PriorityField {
282
+ const trimmed = raw.trim();
283
+ if (trimmed.length === 0) return { state: 'absent' };
284
+ const match = PRIORITIES.find((priority) => priority === trimmed);
285
+ if (match === undefined) return { state: 'invalid', raw: trimmed };
286
+ return { state: 'value', value: match };
287
+ }
288
+
289
+ function invalidNumberRefusal(field: string, raw: string): TaskAuthoringViewRefusal {
290
+ return {
291
+ reason: 'invalid-request',
292
+ message: `"${raw}" is not a plain positive number for ${field}, so BB will not submit it.`,
293
+ };
294
+ }
295
+
296
+ /** Refuse a draft whose addressed task is not one BB can currently read. */
297
+ function detailRefusal(
298
+ taskId: string,
299
+ input: TaskAuthoringGateInput
300
+ ): TaskAuthoringViewRefusal | null {
301
+ switch (input.detailState) {
302
+ case 'missing':
303
+ return {
304
+ reason: 'missing-identity',
305
+ message: `Poetic reports no managed task ${taskId}, so no authoring action is submitted for it.`,
306
+ };
307
+ case 'unavailable':
308
+ return {
309
+ reason: 'task-unavailable',
310
+ message: `Poetic could not describe task ${taskId}, so no authoring action is submitted for it.`,
311
+ };
312
+ case 'none':
313
+ return {
314
+ reason: 'task-unavailable',
315
+ message: `BB holds no canonical detail for task ${taskId}, so no authoring action is submitted for it.`,
316
+ };
317
+ default:
318
+ break;
319
+ }
320
+ if (input.canonicalTaskId !== null && input.canonicalTaskId !== taskId) {
321
+ return {
322
+ reason: 'expected-identity-mismatch',
323
+ message: `BB holds canonical detail for task ${input.canonicalTaskId} but this draft addresses ${taskId}, so the endpoint is ambiguous and nothing is submitted.`,
324
+ };
325
+ }
326
+ if (
327
+ input.observedTaskUpdatedAt !== null &&
328
+ input.canonicalTaskUpdatedAt !== null &&
329
+ input.observedTaskUpdatedAt !== input.canonicalTaskUpdatedAt
330
+ ) {
331
+ return {
332
+ reason: 'changed-identity',
333
+ message: `Task ${taskId} changed in Poetic after this draft was prepared (BB read ${input.observedTaskUpdatedAt}, Poetic now reports ${input.canonicalTaskUpdatedAt}). Reload the task before submitting.`,
334
+ };
335
+ }
336
+ return null;
337
+ }
338
+
339
+ /** Identity checks for one draft, before any field is parsed. */
340
+ function identityRefusal(draft: TaskAuthoringDraft): TaskAuthoringViewRefusal | null {
341
+ switch (draft.kind) {
342
+ case 'createCustomTask': {
343
+ const sprint = endpointRefusal('sprint', 'selected', draft.sprintId);
344
+ if (sprint !== null) return sprint;
345
+ for (const dependency of draft.dependsOn) {
346
+ const refusal = endpointRefusal('task', 'dependency', dependency);
347
+ if (refusal !== null) return refusal;
348
+ }
349
+ if (draft.backlogItemId.trim().length > 0) {
350
+ const backlog = endpointRefusal('backlog-item', 'linked', draft.backlogItemId);
351
+ if (backlog !== null) return backlog;
352
+ }
353
+ return null;
354
+ }
355
+ case 'updateCustomTask':
356
+ return endpointRefusal('task', 'edited', draft.taskId);
357
+ case 'addTaskDependency': {
358
+ const source = endpointRefusal('task', 'source', draft.taskId);
359
+ if (source !== null) return source;
360
+ const target = endpointRefusal('task', 'dependency', draft.onTaskId);
361
+ if (target !== null) return target;
362
+ if (draft.taskId.trim() === draft.onTaskId.trim()) {
363
+ return {
364
+ reason: 'invalid-request',
365
+ message: `Task ${draft.taskId.trim()} cannot depend on itself, so BB will not submit this dependency.`,
366
+ };
367
+ }
368
+ return null;
369
+ }
370
+ case 'removeTaskDependency': {
371
+ const source = endpointRefusal('task', 'source', draft.taskId);
372
+ if (source !== null) return source;
373
+ const target = endpointRefusal('task', 'removed dependency', draft.removeTaskId);
374
+ if (target !== null) return target;
375
+ if (draft.taskId.trim() === draft.removeTaskId.trim()) {
376
+ return {
377
+ reason: 'invalid-request',
378
+ message: `Task ${draft.taskId.trim()} cannot depend on itself, so BB will not submit this removal.`,
379
+ };
380
+ }
381
+ return null;
382
+ }
383
+ case 'linkTaskToBacklog': {
384
+ const source = endpointRefusal('task', 'source', draft.taskId);
385
+ if (source !== null) return source;
386
+ return endpointRefusal('backlog-item', 'linked', draft.backlogItemId);
387
+ }
388
+ }
389
+ }
390
+
391
+ /** Field-level checks for one draft, after its identities are known good. */
392
+ function fieldRefusal(draft: TaskAuthoringDraft): TaskAuthoringViewRefusal | null {
393
+ if (draft.kind === 'createCustomTask') {
394
+ if (draft.title.trim().length === 0) {
395
+ return {
396
+ reason: 'invalid-request',
397
+ message: 'Enter a title before creating a custom task.',
398
+ };
399
+ }
400
+ const estimate = readNumberField(draft.estimate);
401
+ if (estimate.state === 'absent') {
402
+ return {
403
+ reason: 'invalid-request',
404
+ message:
405
+ 'Enter an estimate in hours before creating a custom task. BB never inherits an estimate default.',
406
+ };
407
+ }
408
+ if (estimate.state === 'invalid') return invalidNumberRefusal('the estimate', estimate.raw);
409
+ const runtime = readNumberField(draft.expectedRuntimeMinutes);
410
+ if (runtime.state === 'invalid') {
411
+ return invalidNumberRefusal('the expected runtime in minutes', runtime.raw);
412
+ }
413
+ const priority = readPriorityField(draft.priority);
414
+ if (priority.state === 'invalid') {
415
+ return {
416
+ reason: 'invalid-request',
417
+ message: `"${priority.raw}" is not a Poetic priority (P0, P1, P2, or P3), so BB will not submit it.`,
418
+ };
419
+ }
420
+ return null;
421
+ }
422
+ if (draft.kind === 'updateCustomTask') {
423
+ const estimate = readNumberField(draft.estimate);
424
+ if (estimate.state === 'invalid') return invalidNumberRefusal('the estimate', estimate.raw);
425
+ const runtime = readNumberField(draft.expectedRuntimeMinutes);
426
+ if (runtime.state === 'invalid') {
427
+ return invalidNumberRefusal('the expected runtime in minutes', runtime.raw);
428
+ }
429
+ const priority = readPriorityField(draft.priority);
430
+ if (priority.state === 'invalid') {
431
+ return {
432
+ reason: 'invalid-request',
433
+ message: `"${priority.raw}" is not a Poetic priority (P0, P1, P2, or P3), so BB will not submit it.`,
434
+ };
435
+ }
436
+ const changes =
437
+ draft.title.trim().length > 0 ||
438
+ draft.description.trim().length > 0 ||
439
+ priority.state === 'value' ||
440
+ estimate.state === 'value' ||
441
+ runtime.state === 'value';
442
+ if (!changes) {
443
+ return {
444
+ reason: 'invalid-request',
445
+ message: 'Change at least one task field before saving. BB submits no empty edit.',
446
+ };
447
+ }
448
+ }
449
+ return null;
450
+ }
451
+
452
+ /**
453
+ * Refuse a Description replacement BB could not prepopulate from the canonical
454
+ * detail. Submitting an unprepopulated editor would silently discard whatever
455
+ * Poetic currently holds in that section.
456
+ */
457
+ function prepopulationRefusal(
458
+ draft: TaskAuthoringDraft,
459
+ prepopulation: TaskAuthoringPrepopulation | null
460
+ ): TaskAuthoringViewRefusal | null {
461
+ if (!taskAuthoringDraftReplacesDescription(draft)) return null;
462
+ if (prepopulation === null) {
463
+ return {
464
+ reason: 'description-prepopulation-unavailable',
465
+ message:
466
+ 'BB holds no canonical Description for this task, so it will not replace the Description section.',
467
+ };
468
+ }
469
+ if (prepopulation.state === 'unavailable') {
470
+ return { reason: 'description-prepopulation-unavailable', message: prepopulation.reason };
471
+ }
472
+ return null;
473
+ }
474
+
475
+ /**
476
+ * The single refusal gate for an authoring draft, shared by the rendered
477
+ * controls, the confirmation, and request construction, so a disabled control
478
+ * and a refused submission always agree.
479
+ */
480
+ export function taskAuthoringViewRefusal(
481
+ input: TaskAuthoringGateInput
482
+ ): TaskAuthoringViewRefusal | null {
483
+ const draft = input.draft;
484
+
485
+ // A host could hand this panel an object carrying a status, lifecycle,
486
+ // execution, or filesystem field. It is named and refused here rather than
487
+ // silently dropped, and no authoring request is built from it.
488
+ const denied = taskAuthoringDeniedInputKeys(draft);
489
+ if (denied.length > 0) {
490
+ return {
491
+ reason: 'lifecycle-field',
492
+ message: `This draft carries ${denied.join(', ')}, which authoring never sends. Task status stays with the separate lifecycle controls, and nothing was submitted.`,
493
+ };
494
+ }
495
+ if (!(TASK_AUTHORING_VOCABULARY as readonly string[]).includes(draft.kind)) {
496
+ return {
497
+ reason: 'invalid-request',
498
+ message:
499
+ 'This draft is not one of the custom task authoring actions, so nothing was submitted.',
500
+ };
501
+ }
502
+
503
+ const identity = identityRefusal(draft);
504
+ if (identity !== null) return identity;
505
+
506
+ if (draft.kind !== 'createCustomTask') {
507
+ const detail = detailRefusal(draft.taskId.trim(), input);
508
+ if (detail !== null) return detail;
509
+ }
510
+
511
+ const prepopulation = prepopulationRefusal(draft, input.descriptionPrepopulation);
512
+ if (prepopulation !== null) return prepopulation;
513
+
514
+ const inFlight = input.inFlight;
515
+ if (inFlight !== null) {
516
+ return {
517
+ reason: 'already-in-flight',
518
+ message: `This panel already submitted ${TASK_AUTHORING_LABELS[inFlight.action].toLowerCase()} for ${inFlight.identity} and Poetic has not answered yet. Wait for that action before submitting another.`,
519
+ };
520
+ }
521
+
522
+ const fields = fieldRefusal(draft);
523
+ if (fields !== null) return fields;
524
+
525
+ if (
526
+ taskAuthoringConsentPayload(
527
+ draft.kind,
528
+ taskAuthoringDraftReplacesDescription(draft),
529
+ input.consent
530
+ ) === null
531
+ ) {
532
+ return {
533
+ reason: 'invalid-request',
534
+ message: 'Accept every consent line for this action before submitting.',
535
+ };
536
+ }
537
+ return null;
538
+ }
539
+
540
+ /** Evidence BB last read, submitted with the request so drift is refused. */
541
+ export interface TaskAuthoringObservedState {
542
+ repositoryPath: string;
543
+ /** Branch Poetic reported, or null for a detached HEAD. */
544
+ branch: string | null;
545
+ /** Sprint BB was showing this task in, or null when it holds none. */
546
+ observedSprintId: string | null;
547
+ /** Sprint membership BB last read, or null when it holds none. */
548
+ observedSprintTaskIds: readonly string[] | null;
549
+ }
550
+
551
+ export interface TaskAuthoringRequestInput extends TaskAuthoringGateInput {
552
+ projectId: string;
553
+ sourceId: string;
554
+ observed: TaskAuthoringObservedState;
555
+ }
556
+
557
+ export type TaskAuthoringRequestDecision =
558
+ | {
559
+ admitted: true;
560
+ request: ApplyTaskAuthoringInput;
561
+ /** The unresolved submission the panel must hold until Poetic answers. */
562
+ submission: TaskAuthoringSubmissionState;
563
+ }
564
+ | { admitted: false; refusal: TaskAuthoringViewRefusal };
565
+
566
+ /** The draft's whitelisted `input` payload, as raw values for the wire schema. */
567
+ function draftInputPayload(draft: TaskAuthoringDraft): Record<string, unknown> {
568
+ switch (draft.kind) {
569
+ case 'createCustomTask': {
570
+ const estimate = readNumberField(draft.estimate);
571
+ const runtime = readNumberField(draft.expectedRuntimeMinutes);
572
+ const priority = readPriorityField(draft.priority);
573
+ const payload: Record<string, unknown> = {
574
+ sprintId: draft.sprintId.trim(),
575
+ title: draft.title.trim(),
576
+ };
577
+ if (estimate.state === 'value') payload.estimate = estimate.value;
578
+ if (runtime.state === 'value') payload.expectedRuntimeMinutes = runtime.value;
579
+ if (draft.description.trim().length > 0) payload.description = draft.description.trim();
580
+ if (priority.state === 'value') payload.priority = priority.value;
581
+ if (draft.dependsOn.length > 0) {
582
+ payload.dependsOn = draft.dependsOn.map((dependency) => dependency.trim());
583
+ }
584
+ if (draft.backlogItemId.trim().length > 0) {
585
+ payload.backlogItemId = draft.backlogItemId.trim();
586
+ }
587
+ return payload;
588
+ }
589
+ case 'updateCustomTask': {
590
+ const estimate = readNumberField(draft.estimate);
591
+ const runtime = readNumberField(draft.expectedRuntimeMinutes);
592
+ const priority = readPriorityField(draft.priority);
593
+ const payload: Record<string, unknown> = { taskId: draft.taskId.trim() };
594
+ if (draft.title.trim().length > 0) payload.title = draft.title.trim();
595
+ if (draft.description.trim().length > 0) payload.description = draft.description.trim();
596
+ if (priority.state === 'value') payload.priority = priority.value;
597
+ if (estimate.state === 'value') payload.estimate = estimate.value;
598
+ if (runtime.state === 'value') payload.expectedRuntimeMinutes = runtime.value;
599
+ return payload;
600
+ }
601
+ case 'addTaskDependency':
602
+ return { taskId: draft.taskId.trim(), onTaskId: draft.onTaskId.trim() };
603
+ case 'removeTaskDependency':
604
+ return { taskId: draft.taskId.trim(), removeTaskId: draft.removeTaskId.trim() };
605
+ case 'linkTaskToBacklog':
606
+ return { taskId: draft.taskId.trim(), backlogItemId: draft.backlogItemId.trim() };
607
+ }
608
+ }
609
+
610
+ /**
611
+ * Build one typed BPAU-02 request from a confirmed draft, or refuse it.
612
+ *
613
+ * The candidate is validated by the frozen wire schema itself, so anything the
614
+ * legible gate above did not name still fails closed instead of being submitted.
615
+ * It is parsed twice on purpose: `expected.entityIds` must be exactly the
616
+ * identities the request declares, and that set is derived from the already
617
+ * validated request rather than recomputed here.
618
+ */
619
+ export function buildTaskAuthoringRequest(
620
+ input: TaskAuthoringRequestInput
621
+ ): TaskAuthoringRequestDecision {
622
+ const refusal = taskAuthoringViewRefusal(input);
623
+ if (refusal !== null) return { admitted: false, refusal };
624
+
625
+ const draft = input.draft;
626
+ const consent = taskAuthoringConsentPayload(
627
+ draft.kind,
628
+ taskAuthoringDraftReplacesDescription(draft),
629
+ input.consent
630
+ );
631
+ if (consent === null) {
632
+ // Unreachable while the gate above owns consent; kept so a future gate change
633
+ // cannot turn incomplete consent into a submitted request.
634
+ return {
635
+ admitted: false,
636
+ refusal: {
637
+ reason: 'invalid-request',
638
+ message: 'Accept every consent line for this action before submitting.',
639
+ },
640
+ };
641
+ }
642
+
643
+ const candidate = (entityIds: readonly string[]): Record<string, unknown> => ({
644
+ projectId: input.projectId,
645
+ sourceId: input.sourceId,
646
+ action: draft.kind,
647
+ input: draftInputPayload(draft),
648
+ expected: {
649
+ repositoryPath: input.observed.repositoryPath,
650
+ branch: input.observed.branch,
651
+ entityIds: [...entityIds],
652
+ observedSprintId: input.observed.observedSprintId,
653
+ observedTaskUpdatedAt: input.observedTaskUpdatedAt,
654
+ observedSprintTaskIds:
655
+ input.observed.observedSprintTaskIds === null
656
+ ? null
657
+ : [...input.observed.observedSprintTaskIds],
658
+ },
659
+ consent,
660
+ });
661
+
662
+ const provisional = applyTaskAuthoringInputSchema.safeParse(candidate([]));
663
+ if (!provisional.success) {
664
+ return {
665
+ admitted: false,
666
+ refusal: {
667
+ reason: 'invalid-request',
668
+ message:
669
+ 'This draft is not a valid custom task authoring request, so nothing was submitted.',
670
+ },
671
+ };
672
+ }
673
+ const declared = applyTaskAuthoringInputSchema.safeParse(
674
+ candidate(taskAuthoringDeclaredIdentities(provisional.data))
675
+ );
676
+ if (!declared.success) {
677
+ return {
678
+ admitted: false,
679
+ refusal: {
680
+ reason: 'invalid-request',
681
+ message:
682
+ 'This draft is not a valid custom task authoring request, so nothing was submitted.',
683
+ },
684
+ };
685
+ }
686
+
687
+ return {
688
+ admitted: true,
689
+ request: declared.data,
690
+ submission: {
691
+ action: draft.kind,
692
+ identity: draft.kind === 'createCustomTask' ? draft.sprintId.trim() : draft.taskId.trim(),
693
+ },
694
+ };
695
+ }
696
+
697
+ /** One consent line in the confirmation, with its current acknowledgement. */
698
+ export interface TaskAuthoringConsentLineView {
699
+ key: keyof TaskAuthoringConsentState;
700
+ label: string;
701
+ accepted: boolean;
702
+ required: true;
703
+ }
704
+
705
+ /** One rendered authoring control. */
706
+ export interface TaskAuthoringControlView {
707
+ action: TaskAuthoringAction;
708
+ label: string;
709
+ buttonLabel: string;
710
+ effectLabel: string;
711
+ /**
712
+ * Always `task-authoring`: these controls author managed planning content and
713
+ * relationships, never a status transition and never sprint scheduling.
714
+ */
715
+ domain: typeof TASK_AUTHORING_DOMAIN;
716
+ /** Literal false: no authoring control can move a task's status. */
717
+ lifecycleTransition: false;
718
+ /** Literal false: creating a custom task is not adding backlog work. */
719
+ addFromBacklog: false;
720
+ /** True while this panel's unresolved submission is exactly this action. */
721
+ busy: boolean;
722
+ /** True while this panel holds any unresolved authoring submission. */
723
+ panelBusy: boolean;
724
+ submittable: boolean;
725
+ /** Plain reason the control cannot be submitted; null when it can. */
726
+ blockedReason: string | null;
727
+ refusalReason: TaskAuthoringRefusalReason | null;
728
+ }
729
+
730
+ export interface TaskAuthoringControlsView {
731
+ viewVersion: typeof TASK_AUTHORING_VIEW_VERSION;
732
+ domain: typeof TASK_AUTHORING_DOMAIN;
733
+ /** The draft's action, rendered as the selected control. */
734
+ action: TaskAuthoringAction;
735
+ controls: readonly TaskAuthoringControlView[];
736
+ createDistinctionNotice: string;
737
+ addFromBacklogSeparationNotice: string;
738
+ lifecycleSeparationNotice: string;
739
+ concurrencyNotice: string;
740
+ /** Literal false: this panel renders no lifecycle control at all. */
741
+ includesLifecycleControls: false;
742
+ }
743
+
744
+ /**
745
+ * Project the authoring controls for one draft. Pure: the same input always
746
+ * yields the same view. Only the drafted action can be submittable, because a
747
+ * draft carries the fields of exactly one action.
748
+ */
749
+ export function buildTaskAuthoringControlsView(
750
+ input: TaskAuthoringGateInput
751
+ ): TaskAuthoringControlsView {
752
+ const action = taskAuthoringDraftAction(input.draft);
753
+ const panelBusy = input.inFlight !== null;
754
+ const controls = TASK_AUTHORING_VOCABULARY.map((candidate) => {
755
+ const refusal =
756
+ candidate === action
757
+ ? taskAuthoringViewRefusal(input)
758
+ : {
759
+ reason: 'invalid-request' as const,
760
+ message: `Open ${TASK_AUTHORING_LABELS[candidate].toLowerCase()} to enter its own fields; this draft is ${TASK_AUTHORING_LABELS[action].toLowerCase()}.`,
761
+ };
762
+ return {
763
+ action: candidate,
764
+ label: TASK_AUTHORING_LABELS[candidate],
765
+ buttonLabel: TASK_AUTHORING_BUTTON_LABELS[candidate],
766
+ effectLabel: TASK_AUTHORING_EFFECTS[candidate],
767
+ domain: TASK_AUTHORING_DOMAIN,
768
+ lifecycleTransition: false as const,
769
+ addFromBacklog: false as const,
770
+ busy: panelBusy && input.inFlight?.action === candidate,
771
+ panelBusy,
772
+ submittable: refusal === null,
773
+ blockedReason: refusal === null ? null : refusal.message,
774
+ refusalReason: refusal === null ? null : refusal.reason,
775
+ };
776
+ });
777
+
778
+ return {
779
+ viewVersion: TASK_AUTHORING_VIEW_VERSION,
780
+ domain: TASK_AUTHORING_DOMAIN,
781
+ action,
782
+ controls,
783
+ createDistinctionNotice: TASK_AUTHORING_CREATE_DISTINCTION_NOTICE,
784
+ addFromBacklogSeparationNotice: TASK_AUTHORING_ADD_FROM_BACKLOG_SEPARATION_NOTICE,
785
+ lifecycleSeparationNotice: TASK_AUTHORING_LIFECYCLE_SEPARATION_NOTICE,
786
+ concurrencyNotice: TASK_AUTHORING_CONCURRENCY_NOTICE,
787
+ includesLifecycleControls: false,
788
+ };
789
+ }
790
+
791
+ /** The Description editor for one task, and whether it may be submitted. */
792
+ export interface TaskAuthoringDescriptionEditorView {
793
+ taskId: string;
794
+ state: 'prepopulated' | 'unavailable';
795
+ /** The canonical Description to edit; null when it could not be prepopulated. */
796
+ value: string | null;
797
+ editable: boolean;
798
+ submittable: boolean;
799
+ replacementNotice: string;
800
+ /** Poetic's own reason the canonical Description is missing; null otherwise. */
801
+ unavailableReason: string | null;
802
+ }
803
+
804
+ /**
805
+ * Build the Description editor from the canonical `taskDescriptionV1` sibling.
806
+ * An editor BB could not prepopulate is read-only and unsubmittable, so a
807
+ * replacement can never discard a Description BB never read.
808
+ */
809
+ export function buildTaskAuthoringDescriptionEditorView(
810
+ taskId: string,
811
+ sibling:
812
+ | { state: 'available'; value: { taskId: string; description: string } }
813
+ | { state: 'unavailable'; reason: string }
814
+ ): TaskAuthoringDescriptionEditorView {
815
+ const prepopulation = taskAuthoringDescriptionPrepopulation(taskId, sibling);
816
+ if (prepopulation.state === 'unavailable') {
817
+ return {
818
+ taskId,
819
+ state: 'unavailable',
820
+ value: null,
821
+ editable: false,
822
+ submittable: false,
823
+ replacementNotice: TASK_AUTHORING_DESCRIPTION_REPLACEMENT_NOTICE,
824
+ unavailableReason: prepopulation.reason,
825
+ };
826
+ }
827
+ return {
828
+ taskId,
829
+ state: 'prepopulated',
830
+ value: prepopulation.description,
831
+ editable: true,
832
+ submittable: true,
833
+ replacementNotice: TASK_AUTHORING_DESCRIPTION_REPLACEMENT_NOTICE,
834
+ unavailableReason: null,
835
+ };
836
+ }
837
+
838
+ /** The exact endpoints one relationship mutation addresses. */
839
+ export interface TaskAuthoringRelationshipView {
840
+ sourceTaskId: string;
841
+ targetId: string;
842
+ targetKind: TaskAuthoringEndpointKind;
843
+ /** Plain line naming both endpoints, never abbreviated to one of them. */
844
+ identityLine: string;
845
+ }
846
+
847
+ function relationshipView(draft: TaskAuthoringDraft): TaskAuthoringRelationshipView | null {
848
+ switch (draft.kind) {
849
+ case 'addTaskDependency':
850
+ return {
851
+ sourceTaskId: draft.taskId.trim(),
852
+ targetId: draft.onTaskId.trim(),
853
+ targetKind: 'task',
854
+ identityLine: `Task ${draft.taskId.trim()} will be recorded as depending on task ${draft.onTaskId.trim()}.`,
855
+ };
856
+ case 'removeTaskDependency':
857
+ return {
858
+ sourceTaskId: draft.taskId.trim(),
859
+ targetId: draft.removeTaskId.trim(),
860
+ targetKind: 'task',
861
+ identityLine: `The dependency of task ${draft.taskId.trim()} on task ${draft.removeTaskId.trim()} will be removed.`,
862
+ };
863
+ case 'linkTaskToBacklog':
864
+ return {
865
+ sourceTaskId: draft.taskId.trim(),
866
+ targetId: draft.backlogItemId.trim(),
867
+ targetKind: 'backlog-item',
868
+ identityLine: `Task ${draft.taskId.trim()} will record backlog item ${draft.backlogItemId.trim()} as its provenance.`,
869
+ };
870
+ default:
871
+ return null;
872
+ }
873
+ }
874
+
875
+ export interface TaskAuthoringConfirmationView {
876
+ viewVersion: typeof TASK_AUTHORING_VIEW_VERSION;
877
+ action: TaskAuthoringAction;
878
+ headline: string;
879
+ /** Label of the control that actually submits, named for this action. */
880
+ submitLabel: string;
881
+ effectLabel: string;
882
+ repositoryPath: string;
883
+ branchLabel: string;
884
+ targetLine: string;
885
+ /** The exact fixed Poetic command that will run; null while refused. */
886
+ commandLine: string | null;
887
+ /** Endpoints for a relationship mutation; null for create and edit. */
888
+ relationship: TaskAuthoringRelationshipView | null;
889
+ /** Description-replacement disclosure; null when no Description is replaced. */
890
+ descriptionReplacementNotice: string | null;
891
+ disclosureSummary: string;
892
+ consentLines: readonly TaskAuthoringConsentLineView[];
893
+ submittable: boolean;
894
+ blockedReason: string | null;
895
+ refusalReason: TaskAuthoringRefusalReason | null;
896
+ lifecycleSeparationNotice: string;
897
+ }
898
+
899
+ /**
900
+ * The mutation confirmation for one draft: what will run, where, on which
901
+ * branch, against which endpoints, and which consent is still outstanding. The
902
+ * command line is Poetic's own fixed argv and is shown only once the draft is
903
+ * admissible, so a refused draft never displays a command it will not run.
904
+ */
905
+ export function buildTaskAuthoringConfirmationView(
906
+ input: TaskAuthoringRequestInput
907
+ ): TaskAuthoringConfirmationView {
908
+ const draft = input.draft;
909
+ const action = taskAuthoringDraftAction(draft);
910
+ const decision = buildTaskAuthoringRequest(input);
911
+ const branchLabel = input.observed.branch ?? 'detached HEAD (no named branch)';
912
+ const consentKeys = taskAuthoringRequiredConsentKeys(
913
+ action,
914
+ taskAuthoringDraftReplacesDescription(draft)
915
+ );
916
+ const targetLine =
917
+ draft.kind === 'createCustomTask'
918
+ ? `New custom task in sprint ${draft.sprintId.trim()} in ${input.observed.repositoryPath} on ${branchLabel}`
919
+ : `Task ${draft.taskId.trim()} in ${input.observed.repositoryPath} on ${branchLabel}`;
920
+
921
+ return {
922
+ viewVersion: TASK_AUTHORING_VIEW_VERSION,
923
+ action,
924
+ headline: `Confirm ${TASK_AUTHORING_LABELS[action].toLowerCase()}`,
925
+ submitLabel: `Submit ${TASK_AUTHORING_LABELS[action].toLowerCase()}`,
926
+ effectLabel: TASK_AUTHORING_EFFECTS[action],
927
+ repositoryPath: input.observed.repositoryPath,
928
+ branchLabel,
929
+ targetLine,
930
+ commandLine: decision.admitted
931
+ ? `poetic ${taskAuthoringArgv(decision.request).join(' ')}`
932
+ : null,
933
+ relationship: relationshipView(draft),
934
+ descriptionReplacementNotice: taskAuthoringDraftReplacesDescription(draft)
935
+ ? TASK_AUTHORING_DESCRIPTION_REPLACEMENT_NOTICE
936
+ : null,
937
+ disclosureSummary: TASK_AUTHORING_DISCLOSURE.summary,
938
+ consentLines: consentKeys.map((key) => ({
939
+ key,
940
+ label: TASK_AUTHORING_CONSENT_LABELS[key],
941
+ accepted: input.consent[key],
942
+ required: true,
943
+ })),
944
+ submittable: decision.admitted,
945
+ blockedReason: decision.admitted ? null : decision.refusal.message,
946
+ refusalReason: decision.admitted ? null : decision.refusal.reason,
947
+ lifecycleSeparationNotice: TASK_AUTHORING_LIFECYCLE_SEPARATION_NOTICE,
948
+ };
949
+ }
950
+
951
+ /** The panel while one submitted action is unresolved. */
952
+ export interface TaskAuthoringPendingView {
953
+ viewVersion: typeof TASK_AUTHORING_VIEW_VERSION;
954
+ state: 'awaiting-canonical-reread';
955
+ action: TaskAuthoringAction;
956
+ identity: string;
957
+ headline: string;
958
+ attemptsNotice: string;
959
+ awaitingRereadNotice: string;
960
+ /** Literal false: nothing about the result is rendered before Poetic answers. */
961
+ predictsOutcome: false;
962
+ }
963
+
964
+ /**
965
+ * Render the wait between submitting one request and receiving Poetic's outcome.
966
+ * No optimistic identity, status, membership, capacity, or sync result appears
967
+ * here: the panel only reports that it is waiting.
968
+ */
969
+ export function buildTaskAuthoringPendingView(
970
+ submission: TaskAuthoringSubmissionState
971
+ ): TaskAuthoringPendingView {
972
+ return {
973
+ viewVersion: TASK_AUTHORING_VIEW_VERSION,
974
+ state: 'awaiting-canonical-reread',
975
+ action: submission.action,
976
+ identity: submission.identity,
977
+ headline: `Waiting for Poetic: ${TASK_AUTHORING_LABELS[submission.action].toLowerCase()} for ${submission.identity}`,
978
+ attemptsNotice: 'BB submitted this once and never retries it automatically.',
979
+ awaitingRereadNotice: TASK_AUTHORING_AWAITING_REREAD_NOTICE,
980
+ predictsOutcome: false,
981
+ };
982
+ }
983
+
984
+ export interface TaskAuthoringOutcomeRow {
985
+ id: string;
986
+ label: string;
987
+ value: string;
988
+ }
989
+
990
+ /**
991
+ * How the panel presents one completed attempt. It is derived from Poetic's own
992
+ * effect phase, never from the exit code, and `undetermined` is a distinct state
993
+ * from both applied and failed.
994
+ */
995
+ export type TaskAuthoringOutcomeState =
996
+ | 'applied'
997
+ | 'applied-incomplete'
998
+ | 'refused'
999
+ | 'failed'
1000
+ | 'undetermined';
1001
+
1002
+ export interface TaskAuthoringOutcomeView {
1003
+ viewVersion: typeof TASK_AUTHORING_VIEW_VERSION;
1004
+ action: TaskAuthoringAction;
1005
+ state: TaskAuthoringOutcomeState;
1006
+ /** Poetic's own command state, carried verbatim. */
1007
+ commandState: TaskAuthoringCommandEvidence['state'];
1008
+ /** Poetic's own effect phase, carried verbatim. */
1009
+ effectPhase: TaskAuthoringEffect['phase'];
1010
+ headline: string;
1011
+ commandLine: string;
1012
+ attemptsNotice: string;
1013
+ /** Poetic's own diagnostics, verbatim; null when it reported none. */
1014
+ diagnostics: string | null;
1015
+ /** Set whenever the outcome cannot be read as a settled state. */
1016
+ ambiguityNotice: string | null;
1017
+ createdIdentities: readonly string[];
1018
+ affectedIdentities: readonly string[];
1019
+ rows: readonly TaskAuthoringOutcomeRow[];
1020
+ syncState: TaskAuthoringSync['state'];
1021
+ syncWarnings: readonly string[];
1022
+ syncNotice: string;
1023
+ integrityNotes: readonly string[];
1024
+ rereadNotice: string;
1025
+ taskState: 'available' | 'missing' | 'unavailable';
1026
+ taskStateNotice: string;
1027
+ /** Literal false: no status transition is ever reported by this panel. */
1028
+ lifecycleTransition: false;
1029
+ }
1030
+
1031
+ function outcomeState(phase: TaskAuthoringEffect['phase']): TaskAuthoringOutcomeState {
1032
+ switch (phase) {
1033
+ case 'applied':
1034
+ return 'applied';
1035
+ case 'applied-incomplete':
1036
+ return 'applied-incomplete';
1037
+ case 'refused-before-launch':
1038
+ case 'refused-before-effect':
1039
+ return 'refused';
1040
+ case 'failed-after-partial-effect':
1041
+ return 'failed';
1042
+ case 'unknown-after-timeout':
1043
+ return 'undetermined';
1044
+ }
1045
+ }
1046
+
1047
+ function outcomeHeadline(
1048
+ action: TaskAuthoringAction,
1049
+ state: TaskAuthoringOutcomeState,
1050
+ identities: readonly string[]
1051
+ ): string {
1052
+ const label = TASK_AUTHORING_LABELS[action].toLowerCase();
1053
+ const subject = identities.length > 0 ? ` (${identities.join(', ')})` : '';
1054
+ switch (state) {
1055
+ case 'applied':
1056
+ return `Poetic applied ${label}${subject}.`;
1057
+ case 'applied-incomplete':
1058
+ return `Poetic applied ${label}${subject} incompletely; it reported part of the change as not applied.`;
1059
+ case 'refused':
1060
+ return `Poetic refused ${label} before it changed anything.`;
1061
+ case 'failed':
1062
+ return `Poetic reported ${label} failed after a partial effect${subject}.`;
1063
+ case 'undetermined':
1064
+ return `Whether ${label} applied is undetermined; Poetic published no usable outcome for it.`;
1065
+ }
1066
+ }
1067
+
1068
+ function ambiguityNotice(
1069
+ commandState: TaskAuthoringCommandEvidence['state'],
1070
+ state: TaskAuthoringOutcomeState
1071
+ ): string | null {
1072
+ if (commandState === 'timed_out') {
1073
+ return 'Poetic reported this command timed out, so whether it finished is unknown. Nothing was retried, and the canonical reread below is the only authority.';
1074
+ }
1075
+ if (commandState === 'ambiguous' || state === 'undetermined') {
1076
+ return 'Poetic published no usable identity evidence for this attempt, so whether it applied is unknown. Nothing was retried, and BB substituted no task it could see.';
1077
+ }
1078
+ if (state === 'failed') {
1079
+ return 'A failed command may still have applied part of its change. Nothing was retried, and the canonical reread below is the only authority.';
1080
+ }
1081
+ if (state === 'applied-incomplete') {
1082
+ return 'Poetic reported the change as incomplete, so part of it is not recorded. BB completed nothing on its own.';
1083
+ }
1084
+ return null;
1085
+ }
1086
+
1087
+ function rereadLabel(
1088
+ member: { state: 'available'; value: unknown } | { state: 'unavailable'; reason: string } | null
1089
+ ): string {
1090
+ if (member === null) return 'not part of this action';
1091
+ return member.state === 'available' ? 'reread' : `unavailable - ${member.reason}`;
1092
+ }
1093
+
1094
+ function identityRow(value: string | null): string {
1095
+ return value ?? 'none';
1096
+ }
1097
+
1098
+ /**
1099
+ * Plain rendering of one completed authoring attempt.
1100
+ *
1101
+ * Poetic's structured outcome and its fresh rereads are the only authority: the
1102
+ * exit code is not consulted, an unavailable reread is named rather than filled
1103
+ * in, and a zero exit is never rendered as a confirmed push.
1104
+ */
1105
+ export function buildTaskAuthoringOutcomeView(
1106
+ outcome: ApplyTaskAuthoringOutput
1107
+ ): TaskAuthoringOutcomeView {
1108
+ const state = outcomeState(outcome.effect.phase);
1109
+ const reread = outcome.canonicalRereads;
1110
+ const task = reread.task;
1111
+ const taskState = task.state === 'unavailable' ? ('unavailable' as const) : task.value.task.state;
1112
+ const taskStateNotice =
1113
+ task.state === 'unavailable'
1114
+ ? `Poetic could not be reread for this task after the action: ${task.reason}`
1115
+ : task.value.task.state === 'available'
1116
+ ? 'Poetic re-read this task after the action; the canonical detail shown is that reread.'
1117
+ : task.value.task.state === 'missing'
1118
+ ? 'Poetic reports no managed task at this identity after the action. BB inferred no created, completed, cancelled, or archived state.'
1119
+ : `Poetic could not describe this task after the action: ${task.value.task.reason}`;
1120
+
1121
+ const rows: TaskAuthoringOutcomeRow[] = [
1122
+ { id: 'action', label: 'Action', value: TASK_AUTHORING_LABELS[outcome.action] },
1123
+ { id: 'command-state', label: 'Poetic command state', value: outcome.command.state },
1124
+ { id: 'effect-phase', label: 'Poetic effect phase', value: outcome.effect.phase },
1125
+ {
1126
+ id: 'requested-task',
1127
+ label: 'Requested task',
1128
+ value: identityRow(outcome.requestedIdentities.taskId),
1129
+ },
1130
+ {
1131
+ id: 'requested-sprint',
1132
+ label: 'Requested sprint',
1133
+ value: identityRow(outcome.requestedIdentities.sprintId),
1134
+ },
1135
+ {
1136
+ id: 'requested-dependency',
1137
+ label: 'Requested dependency task',
1138
+ value: identityRow(outcome.requestedIdentities.dependencyTaskId),
1139
+ },
1140
+ {
1141
+ id: 'requested-backlog-item',
1142
+ label: 'Requested backlog item',
1143
+ value: identityRow(outcome.requestedIdentities.backlogItemId),
1144
+ },
1145
+ {
1146
+ id: 'created-identities',
1147
+ label: 'Identities Poetic created',
1148
+ value: outcome.effect.createdIdentities.join(', ') || 'none',
1149
+ },
1150
+ {
1151
+ id: 'affected-identities',
1152
+ label: 'Identities Poetic affected',
1153
+ value: outcome.effect.affectedIdentities.join(', ') || 'none',
1154
+ },
1155
+ { id: 'task-reread', label: 'Task reread', value: rereadLabel(task) },
1156
+ { id: 'sprint-reread', label: 'Sprint reread', value: rereadLabel(reread.sprint) },
1157
+ {
1158
+ id: 'description-reread',
1159
+ label: 'Description reread',
1160
+ value: rereadLabel(reread.description),
1161
+ },
1162
+ { id: 'sync-state', label: 'Planning sync', value: outcome.sync.state },
1163
+ { id: 'workspace-reread', label: 'Workspace reread', value: rereadLabel(outcome.workspace) },
1164
+ ];
1165
+
1166
+ return {
1167
+ viewVersion: TASK_AUTHORING_VIEW_VERSION,
1168
+ action: outcome.action,
1169
+ state,
1170
+ commandState: outcome.command.state,
1171
+ effectPhase: outcome.effect.phase,
1172
+ headline: outcomeHeadline(outcome.action, state, [
1173
+ ...outcome.effect.createdIdentities,
1174
+ ...outcome.effect.affectedIdentities,
1175
+ ]),
1176
+ commandLine: `poetic ${outcome.command.argv.join(' ')}`,
1177
+ attemptsNotice: `BB ran this ${outcome.command.attempts} time and never retries it automatically.`,
1178
+ diagnostics: outcome.command.diagnostics,
1179
+ ambiguityNotice: ambiguityNotice(outcome.command.state, state),
1180
+ createdIdentities: [...outcome.effect.createdIdentities],
1181
+ affectedIdentities: [...outcome.effect.affectedIdentities],
1182
+ rows,
1183
+ syncState: outcome.sync.state,
1184
+ syncWarnings: [...outcome.syncWarnings],
1185
+ syncNotice:
1186
+ outcome.syncWarnings.length === 0
1187
+ ? `Poetic reported planning sync as ${outcome.sync.state} on this reread. A zero exit never confirms the managed sync reached the remote.`
1188
+ : "A zero exit never confirms the managed sync reached the remote; the warnings above are Poetic's own fresh evidence.",
1189
+ integrityNotes: [...outcome.integrityNotes],
1190
+ rereadNotice: TASK_AUTHORING_REREAD_NOTICE,
1191
+ taskState,
1192
+ taskStateNotice,
1193
+ lifecycleTransition: false,
1194
+ };
1195
+ }
1196
+
1197
+ /** How the panel presents a BPAU-02 refusal that never reached a process. */
1198
+ export interface TaskAuthoringRefusalView {
1199
+ viewVersion: typeof TASK_AUTHORING_VIEW_VERSION;
1200
+ state: 'refused-before-launch';
1201
+ action: TaskAuthoringAction | null;
1202
+ reason: TaskAuthoringRefusalReason;
1203
+ headline: string;
1204
+ message: string;
1205
+ /** Literal false: a refusal never ran a command, so nothing changed. */
1206
+ commandRan: false;
1207
+ lifecycleSeparationNotice: string;
1208
+ }
1209
+
1210
+ /** Render a pre-launch refusal as a refusal, never as an empty success. */
1211
+ export function buildTaskAuthoringRefusalView(
1212
+ refusal: TaskAuthoringRefusal
1213
+ ): TaskAuthoringRefusalView {
1214
+ return {
1215
+ viewVersion: TASK_AUTHORING_VIEW_VERSION,
1216
+ state: 'refused-before-launch',
1217
+ action: refusal.action,
1218
+ reason: refusal.reason,
1219
+ headline:
1220
+ refusal.action === null
1221
+ ? 'Poetic ran no command: BB refused this authoring request.'
1222
+ : `Poetic ran no command: BB refused ${TASK_AUTHORING_LABELS[refusal.action].toLowerCase()}.`,
1223
+ message: refusal.message,
1224
+ commandRan: false,
1225
+ lifecycleSeparationNotice: TASK_AUTHORING_LIFECYCLE_SEPARATION_NOTICE,
1226
+ };
1227
+ }