@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.
- package/.github/SECURITY.md +47 -0
- package/.nvmrc +1 -0
- package/.poetic/README.md +37 -0
- package/.poetic/providers/catalog.json +12051 -0
- package/.poetic/providers/pricing.json +1272 -0
- package/.poetic/providers/registry.json +3369 -0
- package/CHANGELOG.md +552 -0
- package/CODE_OF_CONDUCT.md +40 -0
- package/CONTRIBUTING.md +23 -0
- package/INSTALL.md +454 -0
- package/LICENSE +21 -0
- package/README.md +474 -0
- package/dist/BasicOptimizationCompetitionRunner-5H5TBYO4.js +153 -0
- package/dist/ExecutionTracker-UVONC4C6.js +16 -0
- package/dist/OptimizationConfig-7DFY2TST.js +17 -0
- package/dist/OptimizationEngine-JIMGP3LY.js +1597 -0
- package/dist/PromptStore-U6ZD3ZMQ.js +18 -0
- package/dist/actions-LUJPINLJ.js +322 -0
- package/dist/agent-ingest-3DJUJ7FU.js +53 -0
- package/dist/aggregator-DNCBINFO.js +12 -0
- package/dist/ai-judge-5QT5QJVU.js +156 -0
- package/dist/allowlist-grounding-RO6HKUFI.js +16 -0
- package/dist/allowlist-utils-23V7TJ3G.js +28 -0
- package/dist/anchored-turn-service-JULUCUIK.js +489 -0
- package/dist/api-transport-4TYTNLTJ.js +1087 -0
- package/dist/apply-completion-mode-AW2MOS3R.js +89 -0
- package/dist/artifact-migrator-23L45ISD.js +267 -0
- package/dist/ask-HWVV6QFR.js +135 -0
- package/dist/auth-5KEDKAPP.js +67 -0
- package/dist/auth-7TT3JINV.js +78 -0
- package/dist/auth-E6XUNZ5M.js +68 -0
- package/dist/auth-H3XDZE22.js +134 -0
- package/dist/auth-OC4E6633.js +71 -0
- package/dist/auth-S4CTX4GQ.js +44 -0
- package/dist/auth-YLH3S7EY.js +69 -0
- package/dist/auth-liveness-TDDEZY3T.js +46 -0
- package/dist/auto-optimizer-VPRWOWGU.js +80 -0
- package/dist/autoloop-cleanup-JOGKTLWA.js +109 -0
- package/dist/autoloop-evidence-gates-PCDALGVJ.js +38 -0
- package/dist/autoloop-gate-policy-Z7FVJVXV.js +175 -0
- package/dist/autoloop-helpers-2KTK43GL.js +22 -0
- package/dist/autoloop-ledger-W7QO62PX.js +96 -0
- package/dist/autoloop-ledger-subscriber-Z5RW5EIE.js +162 -0
- package/dist/autoloop-run-defaults-FERGRZGP.js +19 -0
- package/dist/autoloop-run-lock-CT2NWSV3.js +197 -0
- package/dist/autoloop-success-J2VKKBXQ.js +85 -0
- package/dist/autoloop-termination-summary-RN75F422.js +58 -0
- package/dist/autoloop-trajectory-XFIEXP5Z.js +282 -0
- package/dist/autoloop-wall-clock-T7ZVIQOC.js +12 -0
- package/dist/autonomous-loop-controller-PW4XVFGQ.js +4120 -0
- package/dist/backend-P3DAYRP7.js +29 -0
- package/dist/background-executor-CBN552V4.js +257 -0
- package/dist/backlog-execution-intent-U4XYPTV6.js +15 -0
- package/dist/backup-active-store-5WXG6SXT.js +17 -0
- package/dist/backup-telemetry-db-XGLXAA3N.js +254 -0
- package/dist/basic-competition-master-VCSBJVRN.js +344 -0
- package/dist/branch-archive-manager-RP6FP3ZC.js +254 -0
- package/dist/branch-cleanup-manager-RSHAI7YR.js +20 -0
- package/dist/build-gate-YHGRB4QB.js +71 -0
- package/dist/change-summary-WY7J5TOX.js +33 -0
- package/dist/chunk-23A26CSN.js +123 -0
- package/dist/chunk-27UTJD3M.js +265 -0
- package/dist/chunk-2A5CILN3.js +310 -0
- package/dist/chunk-2AQUWJPW.js +225 -0
- package/dist/chunk-2BZ53J6J.js +2344 -0
- package/dist/chunk-2DY5KNVM.js +276 -0
- package/dist/chunk-2EIA4RBE.js +659 -0
- package/dist/chunk-2IUXIGQD.js +1064 -0
- package/dist/chunk-2N42MS2Z.js +2193 -0
- package/dist/chunk-2QJ3H3L7.js +42 -0
- package/dist/chunk-2QLYTVYX.js +791 -0
- package/dist/chunk-2VSQMRCB.js +18 -0
- package/dist/chunk-2XQXYBM2.js +130 -0
- package/dist/chunk-2YFUIER7.js +426 -0
- package/dist/chunk-34CNP2HB.js +148 -0
- package/dist/chunk-35P3W3JX.js +456 -0
- package/dist/chunk-36PEBZAF.js +18 -0
- package/dist/chunk-3AOKYKA7.js +22 -0
- package/dist/chunk-3BCUNHKF.js +475 -0
- package/dist/chunk-3FLXLLB7.js +26 -0
- package/dist/chunk-3FOZ2VHV.js +100 -0
- package/dist/chunk-3G6FZCRF.js +106 -0
- package/dist/chunk-3M57DADF.js +44 -0
- package/dist/chunk-3S62LLWJ.js +543 -0
- package/dist/chunk-3ZPQLGV7.js +2904 -0
- package/dist/chunk-44N5WZZH.js +45 -0
- package/dist/chunk-45FPSA3B.js +125 -0
- package/dist/chunk-4BJ3O4RQ.js +929 -0
- package/dist/chunk-4BOP7T6L.js +2321 -0
- package/dist/chunk-4BTDUT2S.js +42 -0
- package/dist/chunk-4CSS7WVI.js +143 -0
- package/dist/chunk-4CUY7AFY.js +247 -0
- package/dist/chunk-4GSN5O5J.js +62 -0
- package/dist/chunk-4HN6DF7V.js +1027 -0
- package/dist/chunk-4IAPOG5V.js +415 -0
- package/dist/chunk-4IYIZQWV.js +48 -0
- package/dist/chunk-4NXPXE62.js +84 -0
- package/dist/chunk-4RCCF5BR.js +712 -0
- package/dist/chunk-4V7NAQ4R.js +19527 -0
- package/dist/chunk-4VJITV4P.js +445 -0
- package/dist/chunk-4YX7J6QL.js +1859 -0
- package/dist/chunk-527OBWQB.js +338 -0
- package/dist/chunk-5D4A7E3D.js +448 -0
- package/dist/chunk-5DLKYTQX.js +4003 -0
- package/dist/chunk-5EERLVZB.js +139 -0
- package/dist/chunk-5H72XE4H.js +256 -0
- package/dist/chunk-5HDP7XZG.js +91 -0
- package/dist/chunk-5LAMRH4X.js +969 -0
- package/dist/chunk-5LTN43AS.js +1972 -0
- package/dist/chunk-5RBHQYDB.js +2206 -0
- package/dist/chunk-5WCQRDRB.js +588 -0
- package/dist/chunk-5WRLK5KW.js +700 -0
- package/dist/chunk-5ZCXC23G.js +595 -0
- package/dist/chunk-6BM72ZMG.js +31 -0
- package/dist/chunk-6EDAJH2I.js +68 -0
- package/dist/chunk-6EQKFDBH.js +457 -0
- package/dist/chunk-6MFRHTRI.js +115 -0
- package/dist/chunk-6TZJRKNW.js +321 -0
- package/dist/chunk-6V7HGQFZ.js +20 -0
- package/dist/chunk-6VWVO2TU.js +3746 -0
- package/dist/chunk-6Y5TWI7H.js +146 -0
- package/dist/chunk-6Y5U7UFY.js +91 -0
- package/dist/chunk-6ZLAK3XG.js +14 -0
- package/dist/chunk-72XCRQED.js +34 -0
- package/dist/chunk-72YTZMAM.js +589 -0
- package/dist/chunk-73BBJOKA.js +263 -0
- package/dist/chunk-73NCTWKL.js +188 -0
- package/dist/chunk-77I6G4CO.js +1 -0
- package/dist/chunk-7DHRDWFS.js +3104 -0
- package/dist/chunk-7DNSNKJV.js +78 -0
- package/dist/chunk-7FMJVYBS.js +307 -0
- package/dist/chunk-7GDRQBQC.js +419 -0
- package/dist/chunk-7GPCEFUV.js +270 -0
- package/dist/chunk-7IL4A2PP.js +948 -0
- package/dist/chunk-7MMLMXO6.js +3679 -0
- package/dist/chunk-7QCZSLBH.js +1 -0
- package/dist/chunk-7R2WLDOS.js +62 -0
- package/dist/chunk-7T7RUJI7.js +949 -0
- package/dist/chunk-A2WKSVX7.js +43 -0
- package/dist/chunk-A3YGID55.js +133 -0
- package/dist/chunk-A722DEVA.js +14 -0
- package/dist/chunk-ACDIT7OP.js +1376 -0
- package/dist/chunk-ACKIPAOJ.js +302 -0
- package/dist/chunk-APPNGGN7.js +365 -0
- package/dist/chunk-APV6MK5E.js +137 -0
- package/dist/chunk-ASEP3M2W.js +968 -0
- package/dist/chunk-AT4TNPWW.js +2931 -0
- package/dist/chunk-ATVKCSGT.js +250 -0
- package/dist/chunk-AURFMVCD.js +899 -0
- package/dist/chunk-AX6GWE7V.js +47 -0
- package/dist/chunk-AY5EWJPF.js +385 -0
- package/dist/chunk-BAV2HJXS.js +194 -0
- package/dist/chunk-BBHRN366.js +89 -0
- package/dist/chunk-BBPSTTPA.js +1004 -0
- package/dist/chunk-BDATUDDJ.js +992 -0
- package/dist/chunk-BKE5PG5L.js +20414 -0
- package/dist/chunk-BLPHWMDK.js +797 -0
- package/dist/chunk-BSE4R6XD.js +322 -0
- package/dist/chunk-BXGMAU4A.js +396 -0
- package/dist/chunk-BXI4NXL3.js +507 -0
- package/dist/chunk-BZU2O43F.js +1125 -0
- package/dist/chunk-C3L6YQ7P.js +147 -0
- package/dist/chunk-C57KJOUQ.js +121 -0
- package/dist/chunk-CCV7BPSY.js +118 -0
- package/dist/chunk-CD7ISXA4.js +826 -0
- package/dist/chunk-CE5OZBYY.js +21 -0
- package/dist/chunk-CFBIG37O.js +154 -0
- package/dist/chunk-CJC6GZ46.js +457 -0
- package/dist/chunk-CKCDGXIV.js +408 -0
- package/dist/chunk-CKNX3TTP.js +10338 -0
- package/dist/chunk-CLKSETWE.js +10 -0
- package/dist/chunk-CP7H3HSP.js +1552 -0
- package/dist/chunk-CPLEWXNZ.js +66 -0
- package/dist/chunk-CQM3A35X.js +844 -0
- package/dist/chunk-CS6P76D3.js +103 -0
- package/dist/chunk-CTLUBNCW.js +622 -0
- package/dist/chunk-CUSRN6RJ.js +632 -0
- package/dist/chunk-D5EP5D2W.js +26 -0
- package/dist/chunk-D5RYINO7.js +412 -0
- package/dist/chunk-DBFS4HMH.js +751 -0
- package/dist/chunk-DC4ZYMXJ.js +115 -0
- package/dist/chunk-DCBZP442.js +9243 -0
- package/dist/chunk-DCYF7EKG.js +26 -0
- package/dist/chunk-DDMAFNUK.js +5351 -0
- package/dist/chunk-DF5SLDE4.js +966 -0
- package/dist/chunk-DJFW7SMX.js +348 -0
- package/dist/chunk-DQFLLBJW.js +121 -0
- package/dist/chunk-DSFM56OA.js +1203 -0
- package/dist/chunk-DTY4APYV.js +218 -0
- package/dist/chunk-DXH5JBRS.js +437 -0
- package/dist/chunk-E3NTPHEO.js +194 -0
- package/dist/chunk-E74LUIID.js +302 -0
- package/dist/chunk-EI57M5BI.js +194 -0
- package/dist/chunk-EJ4ZAWLV.js +305 -0
- package/dist/chunk-EJGCZGUF.js +1483 -0
- package/dist/chunk-EK2U3YEG.js +486 -0
- package/dist/chunk-ELMFYNV7.js +109 -0
- package/dist/chunk-ENRGKNR5.js +25 -0
- package/dist/chunk-ETYDXCK7.js +679 -0
- package/dist/chunk-EYRH3W74.js +239 -0
- package/dist/chunk-F23DIWNN.js +1024 -0
- package/dist/chunk-F5JO7HAS.js +94 -0
- package/dist/chunk-F7ER6ANO.js +174 -0
- package/dist/chunk-FATUVIIN.js +374 -0
- package/dist/chunk-FC23CTXV.js +322 -0
- package/dist/chunk-FD4ERYEG.js +22 -0
- package/dist/chunk-FH7WOJAE.js +79 -0
- package/dist/chunk-FHOWVDF5.js +1342 -0
- package/dist/chunk-FKAUPHMR.js +96 -0
- package/dist/chunk-FONNFJXA.js +137 -0
- package/dist/chunk-FQ7FSZRW.js +75 -0
- package/dist/chunk-FRG57FPM.js +240 -0
- package/dist/chunk-FUVP64ER.js +31 -0
- package/dist/chunk-FYOILAN5.js +6818 -0
- package/dist/chunk-G35UYQ6Z.js +69 -0
- package/dist/chunk-G36W2T2S.js +1143 -0
- package/dist/chunk-G3L2L5XZ.js +49 -0
- package/dist/chunk-G4THLFV3.js +148 -0
- package/dist/chunk-GAFJEYLK.js +29 -0
- package/dist/chunk-GFGYB2ZU.js +1689 -0
- package/dist/chunk-GG6KJYW6.js +85 -0
- package/dist/chunk-GHHFDU2U.js +55 -0
- package/dist/chunk-GHTZSQB7.js +57 -0
- package/dist/chunk-GK37ILCX.js +1231 -0
- package/dist/chunk-GKN3HMN4.js +2809 -0
- package/dist/chunk-GNVDBVJP.js +156 -0
- package/dist/chunk-GPEL3FBM.js +924 -0
- package/dist/chunk-GPSNGPZS.js +1604 -0
- package/dist/chunk-GSGD5E4C.js +30 -0
- package/dist/chunk-GSUQJJXQ.js +331 -0
- package/dist/chunk-GSV226X6.js +110 -0
- package/dist/chunk-H2AYQIHW.js +224 -0
- package/dist/chunk-H66DXFS5.js +1374 -0
- package/dist/chunk-H6G7QRMQ.js +35 -0
- package/dist/chunk-H7JAGHZT.js +59 -0
- package/dist/chunk-H7ZEFECA.js +316 -0
- package/dist/chunk-HAC6EHZZ.js +79 -0
- package/dist/chunk-HIO33P3G.js +19 -0
- package/dist/chunk-HMVQIPH3.js +547 -0
- package/dist/chunk-HOYBYAOA.js +257 -0
- package/dist/chunk-HX5P3CSP.js +1784 -0
- package/dist/chunk-I46EG2XQ.js +65 -0
- package/dist/chunk-I4NPDSCB.js +279 -0
- package/dist/chunk-I5WRT7ZR.js +514 -0
- package/dist/chunk-IC7I6YIJ.js +301 -0
- package/dist/chunk-IDCSOZVN.js +78 -0
- package/dist/chunk-IFCBYECK.js +112 -0
- package/dist/chunk-IFZCPEY2.js +66 -0
- package/dist/chunk-IKFP2KUR.js +48 -0
- package/dist/chunk-IRFBN336.js +878 -0
- package/dist/chunk-IUXNGKA6.js +152 -0
- package/dist/chunk-IV2RVAN7.js +1356 -0
- package/dist/chunk-IZYIQQ7X.js +53 -0
- package/dist/chunk-J3UUR7DE.js +210 -0
- package/dist/chunk-J54VUAY2.js +566 -0
- package/dist/chunk-J62KPGII.js +464 -0
- package/dist/chunk-J6P3FWWW.js +130 -0
- package/dist/chunk-JKBHJQMT.js +434 -0
- package/dist/chunk-JLS65NUQ.js +14 -0
- package/dist/chunk-JOSYEJKY.js +141 -0
- package/dist/chunk-JPKSXKNB.js +94 -0
- package/dist/chunk-JQNJB2BB.js +2440 -0
- package/dist/chunk-JRVNSWSQ.js +2626 -0
- package/dist/chunk-JSWMRQYG.js +28 -0
- package/dist/chunk-JZKNBBIB.js +152 -0
- package/dist/chunk-K54Y7MLK.js +160 -0
- package/dist/chunk-K65546RE.js +183 -0
- package/dist/chunk-KM3F7SYE.js +702 -0
- package/dist/chunk-KNDYMVWN.js +102 -0
- package/dist/chunk-KNT72VR6.js +132 -0
- package/dist/chunk-KP6YILMU.js +482 -0
- package/dist/chunk-KQEBSK3T.js +274 -0
- package/dist/chunk-KT6VHSPF.js +84 -0
- package/dist/chunk-KTMW65UX.js +14 -0
- package/dist/chunk-KZ5CJVBP.js +1813 -0
- package/dist/chunk-L4427KOE.js +26 -0
- package/dist/chunk-L6OM4A22.js +189 -0
- package/dist/chunk-L7E6XCRA.js +1042 -0
- package/dist/chunk-L7JZLXQL.js +173 -0
- package/dist/chunk-LAMKBTXX.js +40 -0
- package/dist/chunk-LDCF2MKN.js +132 -0
- package/dist/chunk-LEIIWPWQ.js +78 -0
- package/dist/chunk-LFTQVYBB.js +31 -0
- package/dist/chunk-LG3PDRTR.js +2872 -0
- package/dist/chunk-LGHII5ET.js +23 -0
- package/dist/chunk-LH5QY22X.js +1205 -0
- package/dist/chunk-LIVJ6266.js +438 -0
- package/dist/chunk-LKRAR3IH.js +276 -0
- package/dist/chunk-LO23NABI.js +3063 -0
- package/dist/chunk-LO3X5NLS.js +326 -0
- package/dist/chunk-LPITVM7M.js +339 -0
- package/dist/chunk-LR5IJIGV.js +810 -0
- package/dist/chunk-LRGMHROI.js +79 -0
- package/dist/chunk-LUVKFFWR.js +315 -0
- package/dist/chunk-LWCBNGH6.js +35 -0
- package/dist/chunk-LWTN3WRV.js +260 -0
- package/dist/chunk-M3HQYKQX.js +308 -0
- package/dist/chunk-M6GVSPEH.js +1016 -0
- package/dist/chunk-MF5HP6XV.js +221 -0
- package/dist/chunk-MHLCBZJB.js +328 -0
- package/dist/chunk-MN6PL4AN.js +120 -0
- package/dist/chunk-MOEY65Z6.js +5678 -0
- package/dist/chunk-MQ4WA34C.js +206 -0
- package/dist/chunk-MWHF5V7U.js +223 -0
- package/dist/chunk-MWHLBPNU.js +211 -0
- package/dist/chunk-MWK5UZQ3.js +1068 -0
- package/dist/chunk-MYLH2S4G.js +64 -0
- package/dist/chunk-MZ5WYKNA.js +28 -0
- package/dist/chunk-N4VTRA7K.js +131 -0
- package/dist/chunk-N5DX4JAK.js +12 -0
- package/dist/chunk-N65O4XTH.js +5011 -0
- package/dist/chunk-NEQUQHOX.js +223 -0
- package/dist/chunk-NGK6PEOG.js +25 -0
- package/dist/chunk-NJVD4PWE.js +1033 -0
- package/dist/chunk-NM6PMYY4.js +768 -0
- package/dist/chunk-NN4PJDHP.js +708 -0
- package/dist/chunk-NP2V3L7K.js +226 -0
- package/dist/chunk-NRLY536M.js +260 -0
- package/dist/chunk-NRNE225N.js +1270 -0
- package/dist/chunk-NS2K2GTP.js +605 -0
- package/dist/chunk-NS33V3IM.js +51 -0
- package/dist/chunk-NSHASMZZ.js +71 -0
- package/dist/chunk-NWOYOA6H.js +378 -0
- package/dist/chunk-NWRUSEXG.js +322 -0
- package/dist/chunk-NZGDAWIP.js +1905 -0
- package/dist/chunk-O47UOKU3.js +395 -0
- package/dist/chunk-O4G2W3ST.js +9831 -0
- package/dist/chunk-O6V4PNLO.js +63 -0
- package/dist/chunk-OA4GPILI.js +624 -0
- package/dist/chunk-OGMSYL6J.js +227 -0
- package/dist/chunk-OIS7J26S.js +319 -0
- package/dist/chunk-OMX5VL43.js +79 -0
- package/dist/chunk-ON3G73BU.js +264 -0
- package/dist/chunk-OPYFYTWQ.js +220 -0
- package/dist/chunk-OQ6K46CK.js +1734 -0
- package/dist/chunk-OYZYO7TV.js +47 -0
- package/dist/chunk-OZ4REHIN.js +4386 -0
- package/dist/chunk-P47VN5F4.js +282 -0
- package/dist/chunk-P5I4X7A7.js +353 -0
- package/dist/chunk-P6VQROCO.js +594 -0
- package/dist/chunk-P7CQGPLS.js +30 -0
- package/dist/chunk-PCAGC5MR.js +1763 -0
- package/dist/chunk-PFTQBXS6.js +5181 -0
- package/dist/chunk-PGSPX4SU.js +15 -0
- package/dist/chunk-PIKLF7BM.js +432 -0
- package/dist/chunk-PJWJ3SAV.js +22 -0
- package/dist/chunk-PKIFMV72.js +100 -0
- package/dist/chunk-PL37JDNA.js +189 -0
- package/dist/chunk-PTH5E5XO.js +195 -0
- package/dist/chunk-PW6AXLQC.js +4128 -0
- package/dist/chunk-PYITM4N2.js +79 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-Q3RO7N35.js +45 -0
- package/dist/chunk-Q3WIC6GQ.js +2670 -0
- package/dist/chunk-Q5XIXSHX.js +271 -0
- package/dist/chunk-QGJDMEOV.js +34 -0
- package/dist/chunk-QNOB37UH.js +58 -0
- package/dist/chunk-QOCOVLUH.js +462 -0
- package/dist/chunk-QTCJ5CC5.js +172 -0
- package/dist/chunk-QVFV5IP2.js +232 -0
- package/dist/chunk-QVZMFDYG.js +29 -0
- package/dist/chunk-R35PEUKH.js +511 -0
- package/dist/chunk-R4UWBC35.js +200 -0
- package/dist/chunk-R6MLCREW.js +44 -0
- package/dist/chunk-R6W23LKN.js +254 -0
- package/dist/chunk-R7XDDX2A.js +4007 -0
- package/dist/chunk-RDFRCT64.js +168 -0
- package/dist/chunk-RE5VZDFQ.js +58 -0
- package/dist/chunk-RGROYC2G.js +638 -0
- package/dist/chunk-RGWHUI5E.js +68 -0
- package/dist/chunk-RHVG6UNL.js +205 -0
- package/dist/chunk-RI4EX2QE.js +18 -0
- package/dist/chunk-RJAAKDRX.js +17 -0
- package/dist/chunk-ROMHOSMQ.js +185 -0
- package/dist/chunk-RWREC3KJ.js +517 -0
- package/dist/chunk-RYNETRDJ.js +118 -0
- package/dist/chunk-RZY7RKM5.js +500 -0
- package/dist/chunk-S2MNWFAG.js +52 -0
- package/dist/chunk-S2VQCZO4.js +22 -0
- package/dist/chunk-S54MKU6V.js +117 -0
- package/dist/chunk-S5OIDFRM.js +302 -0
- package/dist/chunk-SCW4ZF6R.js +150 -0
- package/dist/chunk-SLS2N4PH.js +2213 -0
- package/dist/chunk-SNLBO4BF.js +247 -0
- package/dist/chunk-SP3LFU6B.js +60 -0
- package/dist/chunk-SQQTDDQA.js +537 -0
- package/dist/chunk-STV6LYYE.js +45 -0
- package/dist/chunk-SURZ2WFE.js +326 -0
- package/dist/chunk-SZ7DL357.js +1047 -0
- package/dist/chunk-T5E4NQCM.js +5742 -0
- package/dist/chunk-TAJPCXSB.js +13 -0
- package/dist/chunk-TAOOYK3P.js +358 -0
- package/dist/chunk-TDSEX5CF.js +24 -0
- package/dist/chunk-TFTGP7Z7.js +174 -0
- package/dist/chunk-TGON4N4O.js +197 -0
- package/dist/chunk-TGQZHDY2.js +2373 -0
- package/dist/chunk-TJJZ2OKV.js +6783 -0
- package/dist/chunk-TRSVUPCX.js +25 -0
- package/dist/chunk-TSXGRLPR.js +107 -0
- package/dist/chunk-U2S3YEX3.js +224 -0
- package/dist/chunk-U45RTRGY.js +818 -0
- package/dist/chunk-U6C3VVWS.js +13 -0
- package/dist/chunk-UDMS5AD3.js +307 -0
- package/dist/chunk-UGX7GI37.js +94 -0
- package/dist/chunk-UH3JJSHK.js +1 -0
- package/dist/chunk-UHRBTZYY.js +208 -0
- package/dist/chunk-UHT2KRG5.js +193 -0
- package/dist/chunk-UI2F6DJ5.js +118 -0
- package/dist/chunk-UMAKSB4Z.js +284 -0
- package/dist/chunk-UR2IBGIM.js +521 -0
- package/dist/chunk-UUH2RVKS.js +585 -0
- package/dist/chunk-UVJ4PJDK.js +4533 -0
- package/dist/chunk-V53UG2OT.js +9924 -0
- package/dist/chunk-V72RMBM4.js +48 -0
- package/dist/chunk-VBNCKCCI.js +16 -0
- package/dist/chunk-VNSYKC25.js +24 -0
- package/dist/chunk-VPHVFK4A.js +1984 -0
- package/dist/chunk-VTLNJQ44.js +133 -0
- package/dist/chunk-VTW7HP3R.js +100 -0
- package/dist/chunk-VVGEPBPS.js +218 -0
- package/dist/chunk-VVLLL7I4.js +166 -0
- package/dist/chunk-VX3UMWB7.js +483 -0
- package/dist/chunk-VXF4Q3FW.js +20 -0
- package/dist/chunk-W3JMT2YY.js +712 -0
- package/dist/chunk-WDUORIHF.js +877 -0
- package/dist/chunk-WDVTY4U6.js +148 -0
- package/dist/chunk-WIFZCHEG.js +12566 -0
- package/dist/chunk-WIRN3F75.js +736 -0
- package/dist/chunk-WMPU2UOV.js +82 -0
- package/dist/chunk-WTOKKE2V.js +784 -0
- package/dist/chunk-WX5IRLF6.js +740 -0
- package/dist/chunk-WZ6U3O7I.js +1581 -0
- package/dist/chunk-XAONGNST.js +57 -0
- package/dist/chunk-XB5YLCLB.js +13 -0
- package/dist/chunk-XEP5NQ5Y.js +688 -0
- package/dist/chunk-XGYF2QMZ.js +351 -0
- package/dist/chunk-XHEKQENB.js +255 -0
- package/dist/chunk-XNO4FM6X.js +1124 -0
- package/dist/chunk-XPHKYHO4.js +878 -0
- package/dist/chunk-XPK2I4NC.js +405 -0
- package/dist/chunk-XPU2XADL.js +2175 -0
- package/dist/chunk-XQD2B6BB.js +507 -0
- package/dist/chunk-XT2ZQVTC.js +558 -0
- package/dist/chunk-XTXJGGUV.js +351 -0
- package/dist/chunk-XUXVDPSZ.js +50 -0
- package/dist/chunk-XV7NZL4B.js +57 -0
- package/dist/chunk-XZE4XARH.js +563 -0
- package/dist/chunk-XZYR5EDO.js +152 -0
- package/dist/chunk-Y3J4JMTU.js +61 -0
- package/dist/chunk-Y55LZN5U.js +52 -0
- package/dist/chunk-Y5VN7DMP.js +112 -0
- package/dist/chunk-Y67VAHN4.js +459 -0
- package/dist/chunk-YAXSKEUH.js +3544 -0
- package/dist/chunk-YB3JD4E6.js +975 -0
- package/dist/chunk-YESZJFK6.js +220 -0
- package/dist/chunk-YGXKOBQQ.js +292 -0
- package/dist/chunk-YMX76IOS.js +31 -0
- package/dist/chunk-YOTXESEH.js +257 -0
- package/dist/chunk-YTYIEZQY.js +119 -0
- package/dist/chunk-YVORHQ2S.js +579 -0
- package/dist/chunk-Z2CUQDAR.js +3429 -0
- package/dist/chunk-Z2KYOFHS.js +7000 -0
- package/dist/chunk-Z6PC7QX6.js +161 -0
- package/dist/chunk-ZDTGECTN.js +235 -0
- package/dist/chunk-ZIPWI2LY.js +151 -0
- package/dist/chunk-ZSKKMTQJ.js +554 -0
- package/dist/chunk-ZTT5IVPY.js +1160 -0
- package/dist/chunk-ZX65UI5W.js +78 -0
- package/dist/chunk-ZYG7GGKO.js +218 -0
- package/dist/chunk-ZZZUL4OF.js +38 -0
- package/dist/cli-utils-IXL26KJT.js +40 -0
- package/dist/cli-validation-WLXWLUJL.js +111 -0
- package/dist/commit-utils-P7CRJF5N.js +202 -0
- package/dist/compete-config-resolver-R5ULXMYH.js +76 -0
- package/dist/compete-request-62JESVET.js +364 -0
- package/dist/compete-results-QEPG6FZX.js +208 -0
- package/dist/competition-outcome-tracker-R32OOZ43.js +38 -0
- package/dist/config-JCOKXOQT.js +166 -0
- package/dist/config-audit-EL3GHXS7.js +360 -0
- package/dist/config-explain-TNILDEVJ.js +12 -0
- package/dist/config-loader-VPFPFO4B.js +38 -0
- package/dist/config-manager-7T4E2BQO.js +67 -0
- package/dist/config-validator-KKOHOW7O.js +72 -0
- package/dist/cost-YC42XUF3.js +53 -0
- package/dist/coverage-orchestrator-CISNKJC2.js +772 -0
- package/dist/coverage-scanner-YVD62MLH.js +12 -0
- package/dist/createCompetitionRunner-LJG6ZQSO.js +46 -0
- package/dist/data-migration-state-VJK64DLT.js +31 -0
- package/dist/db-migrator-XSEIOGWY.js +34 -0
- package/dist/discovery-JGYGDD25.js +25 -0
- package/dist/doctor-GJOYE7AE.js +186 -0
- package/dist/domain-analyzer-AWF3RP6E.js +29 -0
- package/dist/ensure-initialized-744DIZEZ.js +52 -0
- package/dist/entry.js +940 -0
- package/dist/environment-YS45U5ZI.js +81 -0
- package/dist/error-parser-core-PPZ36A4S.js +50 -0
- package/dist/escalation-ladder-MKTCEGSA.js +130 -0
- package/dist/evaluation-context-KV4GZNN7.js +35 -0
- package/dist/evidence-plan-resolver-GBSYSAPX.js +85 -0
- package/dist/execution-data-writer-3ODTBDLH.js +53 -0
- package/dist/execution-policy-applier-ZHD3DCF3.js +31 -0
- package/dist/execution-preflight-Z4Y64V3I.js +209 -0
- package/dist/execution-roles-R3DPPMD3.js +66 -0
- package/dist/exit-code-error-Z4SW2DVK.js +14 -0
- package/dist/external-temp-cleanup-N2RZH4QP.js +311 -0
- package/dist/factory-XBN7DFIM.js +149 -0
- package/dist/file-utils-XIVR2ZMA.js +47 -0
- package/dist/flywheel-autoloop-executor-UILGOFFK.js +249 -0
- package/dist/flywheel-competition-executor-JOBEXTRB.js +259 -0
- package/dist/flywheel-executor-6JFLA6J5.js +369 -0
- package/dist/flywheel-git-isolation-UC5NIEVU.js +48 -0
- package/dist/flywheel-manifest-5UC4VBMA.js +108 -0
- package/dist/flywheel-model-defaults-7CVKP53V.js +27 -0
- package/dist/flywheel-preflight-XEY5SHM6.js +104 -0
- package/dist/flywheel-resume-7HELH7QS.js +23 -0
- package/dist/flywheel-safety-7U7DPOAP.js +28 -0
- package/dist/flywheel-scope-decision-ZHKF6ZIN.js +11 -0
- package/dist/get-telemetry-logger-DPVWWIYY.js +73 -0
- package/dist/git-worktree-IY6V6DUO.js +18 -0
- package/dist/github-pr-manager-4LXEKJTA.js +211 -0
- package/dist/guidance-profile-config-E7XJL2VP.js +117 -0
- package/dist/guidance-profile-renderer-QK2YMAAP.js +21 -0
- package/dist/index-query-4JEUKA44.js +31 -0
- package/dist/index.js +108661 -0
- package/dist/instructions-6BURLQJC.js +64 -0
- package/dist/invoke-provider-auth-GRUYP44M.js +223 -0
- package/dist/judge-scoring.json +80 -0
- package/dist/judge-test.js +555 -0
- package/dist/lab-mode-OTWVHN63.js +39 -0
- package/dist/lab-utils-BJRFLGK4.js +23 -0
- package/dist/linux-host-class-UY4KVLFD.js +29 -0
- package/dist/llm-judge-executor-F7Z3HO77.js +133 -0
- package/dist/local-executor-CEHWE2PL.js +223 -0
- package/dist/logger-33TR6EE5.js +72 -0
- package/dist/loop-spec-XTLQAVZ7.js +191 -0
- package/dist/manager-2HJG5CLT.js +25 -0
- package/dist/matrix-prompt-builder-6UDN5X3F.js +497 -0
- package/dist/matrix-result-parser-7W35EUOV.js +15 -0
- package/dist/metadata-HQ43NDEK.js +22 -0
- package/dist/model-invocations-db-QBO4Y7WZ.js +38 -0
- package/dist/monitor-XGYBG2DW.js +72 -0
- package/dist/next-PB5ZXZKB.js +90 -0
- package/dist/next-ZBDK725T.js +69 -0
- package/dist/optimization-config-resolver-O6WKR47U.js +75 -0
- package/dist/package-3YCWIQQ5.js +10 -0
- package/dist/parallel-orchestrator-NL7YJJU2.js +297 -0
- package/dist/parallel-worker.js +279 -0
- package/dist/parse-git-status-PIAF3OTP.js +10 -0
- package/dist/path-security-ETTH6TZL.js +39 -0
- package/dist/pattern-bank-UNJR5ADV.js +15 -0
- package/dist/plan-backlog-list-fast-VAGYBV3J.js +270 -0
- package/dist/plan-backlog-show-fast-SG2CZPW3.js +406 -0
- package/dist/plan-sprint-list-fast-LURAX47V.js +162 -0
- package/dist/plan-sprint-status-fast-FJAODCHD.js +208 -0
- package/dist/plan-task-status-fast-HNYBMQI4.js +349 -0
- package/dist/plan-to-flywheel-Z4U3GWPN.js +456 -0
- package/dist/planning-backlog-3CQ5QQBQ.js +319 -0
- package/dist/poetic-root-V5DNXEAE.js +17 -0
- package/dist/preflight-OPANWMME.js +12 -0
- package/dist/process-registry-PDZJPTAS.js +27 -0
- package/dist/process-scanner-C22SYXYD.js +22 -0
- package/dist/processes-KMQUD7HY.js +29 -0
- package/dist/processes-json-fast-IBDXZ6WW.js +135 -0
- package/dist/profile-SE5EVXAP.js +149 -0
- package/dist/prompts-WZZPGWBX.js +168 -0
- package/dist/protected-branches-RNTEX7ET.js +57 -0
- package/dist/provider-aware-resource-manager-QBTZJMNP.js +18 -0
- package/dist/provider-matrix-N5X57V3Y.js +154 -0
- package/dist/provider-matrix-renderer-MZDWKKID.js +139 -0
- package/dist/provider-output-forwarding-DERID3TP.js +30 -0
- package/dist/provider-registry-J5NRBJKI.js +128 -0
- package/dist/provider-temp-cleanup-KYGLF6YU.js +14 -0
- package/dist/prune-engine-Q6E2DXBN.js +451 -0
- package/dist/quality-gate-YRHMQAEI.js +70 -0
- package/dist/quickstart-FIRLKGJI.js +62 -0
- package/dist/readiness-VZTMSG6J.js +96 -0
- package/dist/registry-YODFY77A.js +153 -0
- package/dist/repair-helpers-TTV5FEF4.js +117 -0
- package/dist/repo-root-2IGD4H7X.js +22 -0
- package/dist/resolution-engine-D6TX6FRG.js +127 -0
- package/dist/resolve-provider-cli-O2P6XZBZ.js +35 -0
- package/dist/restore-telemetry-db-BQL6DTQF.js +360 -0
- package/dist/result-streamer-WEHW476R.js +19 -0
- package/dist/routing-events-DHPUZDDF.js +27 -0
- package/dist/routing-history-store-UWCEXAP3.js +46 -0
- package/dist/routing-planner-F5WQEUOM.js +160 -0
- package/dist/run-poetic-tui-J6LWRJUP.js +13517 -0
- package/dist/run-simulation.js +376 -0
- package/dist/runner-CS2TNGHA.js +1092 -0
- package/dist/runner-HHH7ZN2Z.js +1571 -0
- package/dist/safety-OCC4KJJR.js +64 -0
- package/dist/safety-stanza-7SV3HGG3.js +60 -0
- package/dist/sandbox-32QXJEMV.js +81 -0
- package/dist/sandbox-RSO7VP6V.js +94 -0
- package/dist/schema-extensions.sql +234 -0
- package/dist/security-2KI5XNDG.js +17 -0
- package/dist/setup-bb-plugin-QAQWZCV5.js +738 -0
- package/dist/setup-claude-code-P7BTTSPO.js +317 -0
- package/dist/setup-temp-cleanup-GASCWZ2I.js +20 -0
- package/dist/shared-utils-D6U6UREP.js +37 -0
- package/dist/simple-artifact-goal-OTXNGZY6.js +25 -0
- package/dist/sprint-UIXPYOXQ.js +338 -0
- package/dist/sprint-bridge-4BHMSC3M.js +68 -0
- package/dist/sprint-execution-service-2B7WHL5L.js +311 -0
- package/dist/sprint-manager-IDQUDNQI.js +91 -0
- package/dist/sqlite-wrapper-UDWCTNLJ.js +17 -0
- package/dist/stale-cleanup-orchestrator-XWXV7KCZ.js +62 -0
- package/dist/storage-access-F6ALDN4S.js +22 -0
- package/dist/synthesis-XD6EDVHF.js +185 -0
- package/dist/task-classifier-LNLXSHOM.js +494 -0
- package/dist/task-list-fast-PTMA4LUC.js +147 -0
- package/dist/task-manager-XAT7GOWB.js +93 -0
- package/dist/task-splitter-U7DJ7W6A.js +79 -0
- package/dist/task-type-detector-OLVOMXZO.js +21 -0
- package/dist/task-type-resolver-KKNQYSB4.js +42 -0
- package/dist/telemetry-5HWBBXLX.js +131 -0
- package/dist/telemetry-health-tracker-DMSSGBZ2.js +11 -0
- package/dist/telemetry-path-resolver-7ICSG276.js +28 -0
- package/dist/telemetry-reliability-XUOZNZZ6.js +125 -0
- package/dist/token-estimator-MEQUL3EJ.js +37 -0
- package/dist/transports-KNSSV2V4.js +255 -0
- package/dist/unified-cost-tracker-4TFRBVPR.js +35 -0
- package/dist/unified-state-cleanup-LJPF2BOW.js +276 -0
- package/dist/universal-cost-calculator-BAJV35GA.js +42 -0
- package/dist/user-agents-GHUGCSKN.js +22 -0
- package/dist/variant-delivery-state-KLRNG6XA.js +33 -0
- package/dist/variant-state-cleanup-MZGGLQAJ.js +280 -0
- package/dist/variant-success-PJXWE3ZV.js +12 -0
- package/dist/variant-worker-KUWKBLAH.js +4196 -0
- package/dist/variant-worker.js +24 -0
- package/dist/variants-JE2FSAQS.js +233 -0
- package/dist/verification-toolchains-V24UHW6Q.js +28 -0
- package/dist/verify-commands-H3DTCSGI.js +37 -0
- package/dist/warning-EGQGUUIO.js +12 -0
- package/dist/work-edge-RWEDWJZF.js +49 -0
- package/dist/work-item-writer-WHAVZXAY.js +19 -0
- package/dist/worker-7SA2VS2Y.js +1435 -0
- package/dist/worker.js +19 -0
- package/dist/worktree-metrics-3DFUYVYE.js +26 -0
- package/dist/writeback-VZKHYHSN.js +44 -0
- package/docs/CLI_REFERENCE.md +7042 -0
- package/docs/PROVIDER_SETUP.md +1570 -0
- package/docs/README.md +96 -0
- package/docs/TROUBLESHOOTING.md +2232 -0
- package/docs/getting-started/QUICK_START.md +294 -0
- package/docs/getting-started/README.md +188 -0
- package/docs/getting-started/SETUP.md +52 -0
- package/docs/reference/AGENT_CONTEXT.md +38 -0
- package/docs/reference/PROVIDER_RELEASE_TIERS.md +34 -0
- package/docs/reference/README.md +381 -0
- package/docs/reference/SECURITY.md +262 -0
- package/integrations/bb-plugin-poetic/README.md +362 -0
- package/integrations/bb-plugin-poetic/app.css +341 -0
- package/integrations/bb-plugin-poetic/app.tsx +5059 -0
- package/integrations/bb-plugin-poetic/package.json +45 -0
- package/integrations/bb-plugin-poetic/server.ts +444 -0
- package/integrations/bb-plugin-poetic/src/adapter.ts +3312 -0
- package/integrations/bb-plugin-poetic/src/backlog-authoring-model.ts +150 -0
- package/integrations/bb-plugin-poetic/src/backlog-authoring-schema.ts +355 -0
- package/integrations/bb-plugin-poetic/src/backlog-authoring-service.ts +419 -0
- package/integrations/bb-plugin-poetic/src/backlog-authoring-view.ts +1026 -0
- package/integrations/bb-plugin-poetic/src/competition-defaults-schema.ts +122 -0
- package/integrations/bb-plugin-poetic/src/competition-defaults-service.ts +105 -0
- package/integrations/bb-plugin-poetic/src/competition-defaults-view.ts +138 -0
- package/integrations/bb-plugin-poetic/src/contract.ts +615 -0
- package/integrations/bb-plugin-poetic/src/finalize-model.ts +205 -0
- package/integrations/bb-plugin-poetic/src/finalize-schema.ts +158 -0
- package/integrations/bb-plugin-poetic/src/finalize-service.ts +382 -0
- package/integrations/bb-plugin-poetic/src/finalize-view.ts +159 -0
- package/integrations/bb-plugin-poetic/src/judge-operations-readback.ts +303 -0
- package/integrations/bb-plugin-poetic/src/judge-operations-schema.ts +33 -0
- package/integrations/bb-plugin-poetic/src/judge-operations-view.ts +459 -0
- package/integrations/bb-plugin-poetic/src/model.ts +1302 -0
- package/integrations/bb-plugin-poetic/src/monitor-service.ts +233 -0
- package/integrations/bb-plugin-poetic/src/panel-read-ux.ts +97 -0
- package/integrations/bb-plugin-poetic/src/patch-preview-schema.ts +166 -0
- package/integrations/bb-plugin-poetic/src/patch-preview-service.ts +480 -0
- package/integrations/bb-plugin-poetic/src/patch-preview-view.ts +109 -0
- package/integrations/bb-plugin-poetic/src/planning-readback.ts +204 -0
- package/integrations/bb-plugin-poetic/src/planning-service.ts +594 -0
- package/integrations/bb-plugin-poetic/src/planning-workspace-schema.ts +95 -0
- package/integrations/bb-plugin-poetic/src/planning-workspace.ts +323 -0
- package/integrations/bb-plugin-poetic/src/poll-handoff.ts +136 -0
- package/integrations/bb-plugin-poetic/src/project-target-server.ts +21 -0
- package/integrations/bb-plugin-poetic/src/project-target.ts +45 -0
- package/integrations/bb-plugin-poetic/src/reference-index.ts +192 -0
- package/integrations/bb-plugin-poetic/src/repository-schema.ts +30 -0
- package/integrations/bb-plugin-poetic/src/result-explorer-view.ts +597 -0
- package/integrations/bb-plugin-poetic/src/result-readback-model.ts +163 -0
- package/integrations/bb-plugin-poetic/src/result-readback-schema.ts +319 -0
- package/integrations/bb-plugin-poetic/src/result-readback-service.ts +333 -0
- package/integrations/bb-plugin-poetic/src/run-page-view.ts +177 -0
- package/integrations/bb-plugin-poetic/src/setup-config-schema.ts +291 -0
- package/integrations/bb-plugin-poetic/src/setup-config-service.ts +590 -0
- package/integrations/bb-plugin-poetic/src/setup-config-view.ts +413 -0
- package/integrations/bb-plugin-poetic/src/sprint-close-model.ts +150 -0
- package/integrations/bb-plugin-poetic/src/sprint-close-schema.ts +136 -0
- package/integrations/bb-plugin-poetic/src/sprint-close-service.ts +341 -0
- package/integrations/bb-plugin-poetic/src/sprint-close-view.ts +116 -0
- package/integrations/bb-plugin-poetic/src/sprint-composition-model.ts +714 -0
- package/integrations/bb-plugin-poetic/src/sprint-composition-readback.ts +231 -0
- package/integrations/bb-plugin-poetic/src/sprint-composition-schema.ts +601 -0
- package/integrations/bb-plugin-poetic/src/sprint-composition-service.ts +775 -0
- package/integrations/bb-plugin-poetic/src/sprint-composition-view.ts +1221 -0
- package/integrations/bb-plugin-poetic/src/task-authoring-model.ts +567 -0
- package/integrations/bb-plugin-poetic/src/task-authoring-schema.ts +635 -0
- package/integrations/bb-plugin-poetic/src/task-authoring-service.ts +842 -0
- package/integrations/bb-plugin-poetic/src/task-authoring-view.ts +1227 -0
- package/integrations/bb-plugin-poetic/src/task-detail-readback.ts +56 -0
- package/integrations/bb-plugin-poetic/src/task-detail-schema.ts +144 -0
- package/integrations/bb-plugin-poetic/src/task-navigation.ts +446 -0
- package/integrations/bb-plugin-poetic/src/workbench-route.ts +74 -0
- package/integrations/bb-plugin-poetic/tests/host-contract.test.ts +773 -0
- package/integrations/bb-plugin-poetic/tsconfig.json +18 -0
- package/integrations/bb-plugin-poetic/types/PROVENANCE.json +52 -0
- package/integrations/bb-plugin-poetic/types/bb-plugin-sdk-app.d.ts +1444 -0
- package/integrations/bb-plugin-poetic/types/bb-plugin-sdk.d.ts +13030 -0
- package/integrations/bb-plugin-poetic/vitest.host.config.ts +71 -0
- package/npm-shrinkwrap.json +4950 -0
- package/package.json +331 -0
- package/schemas/README.md +80 -0
- package/schemas/config-v1.schema.json +136 -0
- package/schemas/execution-config.schema.json +47 -0
- package/schemas/judge-scoring.schema.json +370 -0
- package/schemas/poetic.config.schema.json +2214 -0
- package/schemas/provider-config.schema.json +203 -0
- package/schemas/telemetry-config.schema.json +79 -0
- package/schemas/user-preferences.schema.json +141 -0
- package/scripts/assert-node-runtime.mjs +140 -0
- package/scripts/preflight-native.mjs +49 -0
- package/scripts/preinstall-node-check.mjs +78 -0
- package/scripts/setup-git-hooks.mjs +24 -0
- package/scripts/sync.sh +2722 -0
- package/scripts/write-node-launcher.sh +108 -0
- package/src/resources/gemini/slash-packs/default/plan.toml +15 -0
- package/src/resources/gemini/slash-packs/default/summary.toml +16 -0
- package/src/resources/gemini/slash-packs/default/tests.toml +16 -0
- package/templates/.poetic/README.md +37 -0
- package/templates/.poetic/agents/README.md +296 -0
- package/templates/.poetic/agents/api-documenter.md +147 -0
- package/templates/.poetic/agents/backend-architect.md +31 -0
- package/templates/.poetic/agents/code-reviewer.md +157 -0
- package/templates/.poetic/agents/data-scientist.md +179 -0
- package/templates/.poetic/agents/database-optimizer.md +145 -0
- package/templates/.poetic/agents/debugger.md +31 -0
- package/templates/.poetic/agents/deployment-engineer.md +164 -0
- package/templates/.poetic/agents/devops-troubleshooter.md +139 -0
- package/templates/.poetic/agents/frontend-developer.md +150 -0
- package/templates/.poetic/agents/javascript-pro.md +36 -0
- package/templates/.poetic/agents/performance-engineer.md +151 -0
- package/templates/.poetic/agents/python-pro.md +137 -0
- package/templates/.poetic/agents/test-automator.md +147 -0
- package/templates/.poetic/agents/typescript-pro.md +34 -0
- package/templates/.poetic/config/poetic.config.jsonc +69 -0
- package/templates/.poetic/config/project-context.template.json +6 -0
- package/templates/.poetic/config/task-type-aliases.presets/kanban.yaml +14 -0
- package/templates/.poetic/config/task-type-aliases.presets/scrum.yaml +17 -0
- package/templates/.poetic/config/task-type-aliases.presets/xp.yaml +12 -0
- package/templates/.poetic/config/task-type-aliases.yaml +28 -0
- package/templates/.poetic/gitignore.template +55 -0
- package/templates/.poetic/task-types/analysis.yaml +40 -0
- package/templates/.poetic/task-types/architecture.yaml +38 -0
- package/templates/.poetic/task-types/doc.yaml +35 -0
- package/templates/.poetic/task-types/feature.yaml +23 -0
- package/templates/.poetic/task-types/general.yaml +6 -0
- package/templates/.poetic/task-types/security.yaml +39 -0
- package/templates/AGENTS.template.md +99 -0
- package/templates/CLAUDE.template.md +1 -0
- package/templates/GEMINI.template.md +1 -0
- package/templates/builtin-workflows/code-review.yaml +73 -0
- package/templates/builtin-workflows/compete-streak.yaml +78 -0
- package/templates/builtin-workflows/hello-verify.yaml +10 -0
- package/templates/builtin-workflows/judge-regression.yaml +114 -0
- package/templates/builtin-workflows/skills/code-review/SKILL.md +60 -0
- package/templates/builtin-workflows/skills/hello-verify/SKILL.md +6 -0
- package/templates/guard-kit/GUARD_SETUP.md.template +255 -0
- package/templates/guard-kit/check.mjs.template +777 -0
- package/templates/guard-kit/config.json.template +6 -0
- package/templates/guard-kit/poetic-guard.yml.template +189 -0
- package/templates/profiles/README.md +56 -0
- package/templates/profiles/frontier-claude.json +27 -0
- 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
|
+
}
|