@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,1689 @@
|
|
|
1
|
+
import {
|
|
2
|
+
classifyTask,
|
|
3
|
+
stripPromptInjections
|
|
4
|
+
} from "./chunk-FQ7FSZRW.js";
|
|
5
|
+
import {
|
|
6
|
+
TaskTypeAliasMap,
|
|
7
|
+
TaskTypeRegistry
|
|
8
|
+
} from "./chunk-LO3X5NLS.js";
|
|
9
|
+
import {
|
|
10
|
+
getP1SemanticChecks
|
|
11
|
+
} from "./chunk-XPK2I4NC.js";
|
|
12
|
+
import {
|
|
13
|
+
hasUnfilledMarkers
|
|
14
|
+
} from "./chunk-P6VQROCO.js";
|
|
15
|
+
import {
|
|
16
|
+
getTask
|
|
17
|
+
} from "./chunk-5LTN43AS.js";
|
|
18
|
+
import {
|
|
19
|
+
buildPromptFromTask,
|
|
20
|
+
parseTaskBody
|
|
21
|
+
} from "./chunk-LIVJ6266.js";
|
|
22
|
+
import {
|
|
23
|
+
classifyIntent
|
|
24
|
+
} from "./chunk-4RCCF5BR.js";
|
|
25
|
+
import {
|
|
26
|
+
applyExecutionPolicy,
|
|
27
|
+
describeExecutionPolicyStampMismatch,
|
|
28
|
+
isCurrentExecutionPolicyWorkflow,
|
|
29
|
+
isExecutionPolicyEngaged
|
|
30
|
+
} from "./chunk-PIKLF7BM.js";
|
|
31
|
+
import {
|
|
32
|
+
resolveExecutionRoles
|
|
33
|
+
} from "./chunk-YB3JD4E6.js";
|
|
34
|
+
import {
|
|
35
|
+
classifyTaskDependency
|
|
36
|
+
} from "./chunk-3BCUNHKF.js";
|
|
37
|
+
import {
|
|
38
|
+
getPlanningRoot
|
|
39
|
+
} from "./chunk-OPYFYTWQ.js";
|
|
40
|
+
import {
|
|
41
|
+
getBucketArchivePathByKind,
|
|
42
|
+
getBucketPathByKind
|
|
43
|
+
} from "./chunk-HOYBYAOA.js";
|
|
44
|
+
import {
|
|
45
|
+
getWorkflowYamlPath
|
|
46
|
+
} from "./chunk-CQM3A35X.js";
|
|
47
|
+
import {
|
|
48
|
+
expectsCodeEdits,
|
|
49
|
+
extractTaskContract
|
|
50
|
+
} from "./chunk-ACDIT7OP.js";
|
|
51
|
+
import {
|
|
52
|
+
parsePromptSpec
|
|
53
|
+
} from "./chunk-7T7RUJI7.js";
|
|
54
|
+
import {
|
|
55
|
+
detectExplicitNoEditDirective
|
|
56
|
+
} from "./chunk-JOSYEJKY.js";
|
|
57
|
+
import {
|
|
58
|
+
listMarkdownFilesRecursive,
|
|
59
|
+
readMarkdownFile
|
|
60
|
+
} from "./chunk-OIS7J26S.js";
|
|
61
|
+
import {
|
|
62
|
+
resolveDefaultProvider,
|
|
63
|
+
resolveJudgeType
|
|
64
|
+
} from "./chunk-XPU2XADL.js";
|
|
65
|
+
import {
|
|
66
|
+
checkVerifyCommandSafety
|
|
67
|
+
} from "./chunk-LO23NABI.js";
|
|
68
|
+
import {
|
|
69
|
+
resolveExecutionBoundary
|
|
70
|
+
} from "./chunk-7R2WLDOS.js";
|
|
71
|
+
import {
|
|
72
|
+
getProjectReferencePathExtensions
|
|
73
|
+
} from "./chunk-UDMS5AD3.js";
|
|
74
|
+
|
|
75
|
+
// src/planning/stage-contract-adapter.ts
|
|
76
|
+
function resolveStageContract({
|
|
77
|
+
text,
|
|
78
|
+
title,
|
|
79
|
+
metadataExecutionIntent,
|
|
80
|
+
policyExecutionIntent
|
|
81
|
+
}) {
|
|
82
|
+
if (metadataExecutionIntent) {
|
|
83
|
+
return fromIntent(metadataExecutionIntent, "metadata", metadataExecutionIntent === "analysis");
|
|
84
|
+
}
|
|
85
|
+
if (policyExecutionIntent === "analysis") {
|
|
86
|
+
return fromIntent("analysis", "task-type-policy", true);
|
|
87
|
+
}
|
|
88
|
+
const stageText = [title, text].filter(Boolean).join("\n\n");
|
|
89
|
+
if (detectExplicitNoEditDirective(stageText)) {
|
|
90
|
+
return fromIntent("analysis", "explicit-no-edit", true);
|
|
91
|
+
}
|
|
92
|
+
if (policyExecutionIntent === "edit") {
|
|
93
|
+
return fromIntent("edit", "task-type-policy", false);
|
|
94
|
+
}
|
|
95
|
+
if (detectExplicitEdit(stageText)) {
|
|
96
|
+
return fromIntent("edit", "explicit-edit", false);
|
|
97
|
+
}
|
|
98
|
+
const promptSpec = parsePromptSpec(stageText);
|
|
99
|
+
if (promptSpec.isAnalysisIntent || promptSpec.editsRequired === false) {
|
|
100
|
+
return fromIntent("analysis", "prompt-spec", true);
|
|
101
|
+
}
|
|
102
|
+
if (promptSpec.fileConstraint.mode !== "none") {
|
|
103
|
+
return fromIntent("edit", "file-marker", false);
|
|
104
|
+
}
|
|
105
|
+
const contract = extractTaskContract(stageText, { validateQuotes: false });
|
|
106
|
+
if (expectsCodeEdits(contract.deliverableType)) {
|
|
107
|
+
return fromIntent("edit", "task-contract", false);
|
|
108
|
+
}
|
|
109
|
+
if (isAnalysisStageSemantics(stageText)) {
|
|
110
|
+
return fromIntent("analysis", "stage-semantics", true);
|
|
111
|
+
}
|
|
112
|
+
return fromIntent("edit", "stage-semantics", false);
|
|
113
|
+
}
|
|
114
|
+
function fromIntent(intent, source, authoritativeAnalysis) {
|
|
115
|
+
return {
|
|
116
|
+
capabilities: intent === "analysis" ? {
|
|
117
|
+
modifiesFiles: false,
|
|
118
|
+
producesText: true,
|
|
119
|
+
executionIntent: intent
|
|
120
|
+
} : {
|
|
121
|
+
modifiesFiles: true,
|
|
122
|
+
executionIntent: intent
|
|
123
|
+
},
|
|
124
|
+
source,
|
|
125
|
+
authoritativeAnalysis
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function detectExplicitEdit(text) {
|
|
129
|
+
return /\b(implement|fix|repair|patch|add|create|write|update|modify|refactor|rewrite)\b/i.test(
|
|
130
|
+
text
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
function isAnalysisStageSemantics(text) {
|
|
134
|
+
return /\b(plan|design|analy[sz]e|inspect|investigate|review|audit|assess|evaluate|verify|validate|diagnose|research)\b/i.test(
|
|
135
|
+
text
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/planning/sprint-to-workflow.ts
|
|
140
|
+
import * as fs from "fs/promises";
|
|
141
|
+
import * as path from "path";
|
|
142
|
+
import * as yaml from "js-yaml";
|
|
143
|
+
|
|
144
|
+
// src/core/routing/fusion-default-activities.ts
|
|
145
|
+
var FUSION_DEFAULT_ACTIVITIES = /* @__PURE__ */ new Set([
|
|
146
|
+
"architecture",
|
|
147
|
+
"design",
|
|
148
|
+
"research",
|
|
149
|
+
"planning"
|
|
150
|
+
]);
|
|
151
|
+
|
|
152
|
+
// src/core/routing/select-execution-strategy.ts
|
|
153
|
+
var COMPETE_ACTIVITIES = /* @__PURE__ */ new Set([
|
|
154
|
+
...FUSION_DEFAULT_ACTIVITIES,
|
|
155
|
+
"development",
|
|
156
|
+
"debugging"
|
|
157
|
+
]);
|
|
158
|
+
var SINGLE_PASS_CATEGORIES = /* @__PURE__ */ new Set(["analyze", "review", "document"]);
|
|
159
|
+
function hasExplicitFlywheelConfig(task) {
|
|
160
|
+
return Boolean(task.flywheel?.type || task.flywheel?.competition || task.flywheel?.autoloop);
|
|
161
|
+
}
|
|
162
|
+
function selectExecutionStrategy(task) {
|
|
163
|
+
const reasons = [];
|
|
164
|
+
const alternatives = [];
|
|
165
|
+
let strategy;
|
|
166
|
+
let confidence;
|
|
167
|
+
const hasExplicitConfig = hasExplicitFlywheelConfig(task);
|
|
168
|
+
if (hasExplicitConfig) {
|
|
169
|
+
const explicitType = task.flywheel?.type;
|
|
170
|
+
const hasCompetition = Boolean(task.flywheel?.competition);
|
|
171
|
+
if (explicitType === "competition" || hasCompetition) {
|
|
172
|
+
strategy = "compete";
|
|
173
|
+
reasons.push("Explicit flywheel.competition or type=competition configured");
|
|
174
|
+
} else if (explicitType === "standard") {
|
|
175
|
+
strategy = "single-pass";
|
|
176
|
+
reasons.push("Explicit flywheel.type=standard configured");
|
|
177
|
+
} else if (explicitType === "verify") {
|
|
178
|
+
strategy = "single-pass";
|
|
179
|
+
reasons.push("Explicit flywheel.type=verify configured (local verification)");
|
|
180
|
+
} else {
|
|
181
|
+
strategy = "compete";
|
|
182
|
+
reasons.push("Explicit flywheel config present");
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
strategy,
|
|
186
|
+
reasons,
|
|
187
|
+
confidence: 100,
|
|
188
|
+
hasExplicitConfig: true
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
const activity = task.taskClassification?.activity;
|
|
192
|
+
if (activity && COMPETE_ACTIVITIES.has(activity)) {
|
|
193
|
+
strategy = "compete";
|
|
194
|
+
reasons.push(`activity=${activity}: Benefits from multi-perspective Fusion/competition`);
|
|
195
|
+
confidence = 90;
|
|
196
|
+
if (FUSION_DEFAULT_ACTIVITIES.has(activity)) {
|
|
197
|
+
alternatives.push({
|
|
198
|
+
strategy: "single-pass",
|
|
199
|
+
reason: "Could use single-pass if time/cost constrained"
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
if (activity === "debugging") {
|
|
203
|
+
alternatives.push({
|
|
204
|
+
strategy: "autoloop",
|
|
205
|
+
reason: "Iterative debugging could be more effective for complex bugs"
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
return { strategy, reasons, confidence, alternatives, hasExplicitConfig: false };
|
|
209
|
+
}
|
|
210
|
+
const executionIntent = task.metadata?.executionIntent;
|
|
211
|
+
if (executionIntent === "analysis") {
|
|
212
|
+
strategy = "single-pass";
|
|
213
|
+
reasons.push("executionIntent=analysis: Single provider sufficient for generic analysis");
|
|
214
|
+
confidence = 90;
|
|
215
|
+
alternatives.push({
|
|
216
|
+
strategy: "compete",
|
|
217
|
+
reason: "Use Fusion/competition when the task is architecture, design, research, or planning"
|
|
218
|
+
});
|
|
219
|
+
return { strategy, reasons, confidence, alternatives, hasExplicitConfig: false };
|
|
220
|
+
}
|
|
221
|
+
if (executionIntent === "edit") {
|
|
222
|
+
reasons.push("executionIntent=edit: Code changes benefit from multi-variant competition");
|
|
223
|
+
}
|
|
224
|
+
const category = task.taskClassification?.category;
|
|
225
|
+
if (!executionIntent && category && SINGLE_PASS_CATEGORIES.has(category)) {
|
|
226
|
+
strategy = "single-pass";
|
|
227
|
+
reasons.push(`category=${category}: Single provider sufficient for non-edit oriented work`);
|
|
228
|
+
confidence = 75;
|
|
229
|
+
alternatives.push({
|
|
230
|
+
strategy: "compete",
|
|
231
|
+
reason: "Competition could provide higher confidence at higher cost"
|
|
232
|
+
});
|
|
233
|
+
return { strategy, reasons, confidence, alternatives, hasExplicitConfig: false };
|
|
234
|
+
}
|
|
235
|
+
if (executionIntent === "edit") {
|
|
236
|
+
strategy = "compete";
|
|
237
|
+
confidence = 75;
|
|
238
|
+
reasons.push("Default for edit tasks: Competition for quality assurance");
|
|
239
|
+
} else {
|
|
240
|
+
strategy = "compete";
|
|
241
|
+
confidence = 60;
|
|
242
|
+
reasons.push("No classification signals: Defaulting to competition for quality assurance");
|
|
243
|
+
}
|
|
244
|
+
alternatives.push(
|
|
245
|
+
{ strategy: "single-pass", reason: "For simple, well-defined tasks with low risk" },
|
|
246
|
+
{ strategy: "autoloop", reason: "For complex tasks requiring iterative refinement" },
|
|
247
|
+
{ strategy: "parallel", reason: "For independent subtasks that can run concurrently" }
|
|
248
|
+
);
|
|
249
|
+
return { strategy, reasons, confidence, alternatives, hasExplicitConfig: false };
|
|
250
|
+
}
|
|
251
|
+
function getDefaultCompetitionVariantsForProvider(provider) {
|
|
252
|
+
const resolvedProvider = typeof provider === "string" && provider.trim().length > 0 && provider !== "multi" ? provider.trim() : resolveDefaultProvider().value;
|
|
253
|
+
return [
|
|
254
|
+
{ provider: resolvedProvider, strategy: "conservative" },
|
|
255
|
+
{ provider: resolvedProvider, strategy: "innovative" }
|
|
256
|
+
];
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// src/core/task-types/resolver.ts
|
|
260
|
+
function normalizeText(text) {
|
|
261
|
+
return text.toLowerCase();
|
|
262
|
+
}
|
|
263
|
+
function isNegatedDocConstraint(text) {
|
|
264
|
+
const normalized = normalizeText(text);
|
|
265
|
+
return /\b(?:do not|don't|no)\s+(?:edit|touch|change|modify|update|write|create|add)?\s*docs?\b/.test(
|
|
266
|
+
normalized
|
|
267
|
+
) || /\bdocs?\s+(?:should|must)\s+not\s+be\s+(?:edited|changed|modified|updated|touched)\b/.test(
|
|
268
|
+
normalized
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
function hasStrongCodeOnlySignals(text) {
|
|
272
|
+
const normalized = normalizeText(text);
|
|
273
|
+
return normalized.includes("code-only") || normalized.includes("src/") || normalized.includes("tests/") || /\b(?:test|tests|cli|command|commands|handler|warning|error|validation)\b/.test(normalized);
|
|
274
|
+
}
|
|
275
|
+
function hasDirectDocumentationDeliverableIntent(text) {
|
|
276
|
+
return /\b(?:fix|create|update|add|write|generate|improve)\b.{0,40}\b(?:doc|docs|documentation|readme|guideline|guide|instructions|specification)\b/i.test(
|
|
277
|
+
text
|
|
278
|
+
) || /\b(?:doc|docs|documentation|readme|guideline|guide|instructions|specification)\b.{0,40}\b(?:file|page|section|content|reference)\b/i.test(
|
|
279
|
+
text
|
|
280
|
+
) || /(?:^|[\s`'"])(?:docs\/[^\s`'"]+|(?:readme|changelog|claude|agents|gemini)\.md)\b/i.test(text);
|
|
281
|
+
}
|
|
282
|
+
function countKeywordMatches(text, keywords) {
|
|
283
|
+
const normalized = normalizeText(text);
|
|
284
|
+
const matched = [];
|
|
285
|
+
for (const keyword of keywords) {
|
|
286
|
+
const k = keyword.trim().toLowerCase();
|
|
287
|
+
if (!k) continue;
|
|
288
|
+
if (normalized.includes(k)) {
|
|
289
|
+
matched.push(keyword);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return { count: matched.length, matched };
|
|
293
|
+
}
|
|
294
|
+
function countRegexMatches(text, regexStrings) {
|
|
295
|
+
const matched = [];
|
|
296
|
+
for (const raw of regexStrings) {
|
|
297
|
+
try {
|
|
298
|
+
const re = new RegExp(raw, "i");
|
|
299
|
+
if (re.test(text)) {
|
|
300
|
+
matched.push(raw);
|
|
301
|
+
}
|
|
302
|
+
} catch {
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return { count: matched.length, matched };
|
|
306
|
+
}
|
|
307
|
+
function canonicalMatches(classification, match) {
|
|
308
|
+
if (!classification || !match?.canonical) return { ok: true, reasons: [], matched: false };
|
|
309
|
+
const reasons = [];
|
|
310
|
+
let matchedAny = false;
|
|
311
|
+
if (Array.isArray(match.canonical.category) && match.canonical.category.length > 0) {
|
|
312
|
+
const ok = match.canonical.category.includes(classification.category);
|
|
313
|
+
if (!ok) {
|
|
314
|
+
return {
|
|
315
|
+
ok: false,
|
|
316
|
+
reasons: [`canonical.category mismatch (${classification.category})`],
|
|
317
|
+
matched: false
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
matchedAny = true;
|
|
321
|
+
reasons.push(`canonical.category=${classification.category}`);
|
|
322
|
+
}
|
|
323
|
+
if (Array.isArray(match.canonical.judgeTaskKind) && match.canonical.judgeTaskKind.length > 0) {
|
|
324
|
+
const ok = match.canonical.judgeTaskKind.includes(classification.judgeTaskKind);
|
|
325
|
+
if (!ok) {
|
|
326
|
+
return {
|
|
327
|
+
ok: false,
|
|
328
|
+
reasons: [`canonical.judgeTaskKind mismatch (${classification.judgeTaskKind})`],
|
|
329
|
+
matched: false
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
matchedAny = true;
|
|
333
|
+
reasons.push(`canonical.judgeTaskKind=${classification.judgeTaskKind}`);
|
|
334
|
+
}
|
|
335
|
+
return { ok: true, reasons, matched: matchedAny };
|
|
336
|
+
}
|
|
337
|
+
function getPriority(typeDef) {
|
|
338
|
+
const raw = typeDef.match?.priority;
|
|
339
|
+
return typeof raw === "number" && Number.isFinite(raw) ? raw : 0;
|
|
340
|
+
}
|
|
341
|
+
function resolveTaskTypeFromCandidates(options) {
|
|
342
|
+
const { taskText, candidates, classification, fallbackId = "general" } = options;
|
|
343
|
+
const scored = [];
|
|
344
|
+
for (const candidate of candidates) {
|
|
345
|
+
const match = candidate.match;
|
|
346
|
+
if (!match) {
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
if (match.suppressWhenCodeOnly === true && hasStrongCodeOnlySignals(taskText)) {
|
|
350
|
+
if (isNegatedDocConstraint(taskText) || !hasDirectDocumentationDeliverableIntent(taskText)) {
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
const {
|
|
355
|
+
ok: canonicalOk,
|
|
356
|
+
reasons: canonicalReasons,
|
|
357
|
+
matched: canonicalMatched
|
|
358
|
+
} = canonicalMatches(classification, match);
|
|
359
|
+
if (!canonicalOk) {
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
const keywords = Array.isArray(match.keywords) ? match.keywords : [];
|
|
363
|
+
const regex = Array.isArray(match.regex) ? match.regex : [];
|
|
364
|
+
const keywordMatches = countKeywordMatches(taskText, keywords);
|
|
365
|
+
const regexMatches = countRegexMatches(taskText, regex);
|
|
366
|
+
const hasAnySignal = keywordMatches.count > 0 || regexMatches.count > 0;
|
|
367
|
+
if (!hasAnySignal) {
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
const reasons = [];
|
|
371
|
+
reasons.push(...canonicalReasons);
|
|
372
|
+
for (const k of keywordMatches.matched) reasons.push(`keyword:${k}`);
|
|
373
|
+
for (const r of regexMatches.matched) reasons.push(`regex:${r}`);
|
|
374
|
+
const priority = getPriority(candidate);
|
|
375
|
+
const confidence = Math.min(
|
|
376
|
+
1,
|
|
377
|
+
(canonicalMatched ? 0.3 : 0) + Math.min(0.5, keywordMatches.count * 0.1) + Math.min(0.3, regexMatches.count * 0.1)
|
|
378
|
+
);
|
|
379
|
+
scored.push({ id: candidate.id, priority, confidence, reasons });
|
|
380
|
+
}
|
|
381
|
+
if (scored.length === 0) {
|
|
382
|
+
return { id: fallbackId, resolvedBy: "fallback", reasons: ["no matcher candidates"] };
|
|
383
|
+
}
|
|
384
|
+
scored.sort((a, b) => {
|
|
385
|
+
if (b.priority !== a.priority) return b.priority - a.priority;
|
|
386
|
+
if (b.confidence !== a.confidence) return b.confidence - a.confidence;
|
|
387
|
+
return a.id.localeCompare(b.id);
|
|
388
|
+
});
|
|
389
|
+
const best = scored[0];
|
|
390
|
+
if (!best) {
|
|
391
|
+
return { id: fallbackId, resolvedBy: "fallback", reasons: ["no matcher candidates"] };
|
|
392
|
+
}
|
|
393
|
+
return {
|
|
394
|
+
id: best.id,
|
|
395
|
+
resolvedBy: "matcher",
|
|
396
|
+
confidence: best.confidence,
|
|
397
|
+
reasons: best.reasons
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
function hasInvestigationSignals(text) {
|
|
401
|
+
return /\b(investigat|analy[sz]e|audit|assess|review|root\s*cause)\b/i.test(text);
|
|
402
|
+
}
|
|
403
|
+
function classificationForTaskTypeMatching(taskText, classification) {
|
|
404
|
+
let category = classification.category;
|
|
405
|
+
let judgeTaskKind = classification.judgeTaskKind;
|
|
406
|
+
if (isNegatedDocConstraint(taskText) && hasStrongCodeOnlySignals(taskText)) {
|
|
407
|
+
if (category === "document") {
|
|
408
|
+
category = "execute";
|
|
409
|
+
}
|
|
410
|
+
if ((category === "execute" || category === "test") && !["implementation", "bugfix", "refactor"].includes(judgeTaskKind)) {
|
|
411
|
+
judgeTaskKind = "implementation";
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
if (category === "document" && hasInvestigationSignals(taskText)) {
|
|
415
|
+
category = "analyze";
|
|
416
|
+
judgeTaskKind = "analysis";
|
|
417
|
+
}
|
|
418
|
+
return { category, judgeTaskKind };
|
|
419
|
+
}
|
|
420
|
+
function resolveTaskTypeWithDeclaration(options) {
|
|
421
|
+
const hasId = options.hasId ?? (() => true);
|
|
422
|
+
const explicitId = options.explicitId?.trim();
|
|
423
|
+
if (explicitId && hasId(explicitId)) {
|
|
424
|
+
const resolvedBy = options.explicitResolvedBy ?? "frontmatter";
|
|
425
|
+
return { id: explicitId, resolvedBy, reasons: [`${resolvedBy} override`] };
|
|
426
|
+
}
|
|
427
|
+
const declaredType = typeof options.declaredType === "string" && options.declaredType.length > 0 ? options.declaredType : void 0;
|
|
428
|
+
if (declaredType && options.resolveDeclared) {
|
|
429
|
+
const mappedId = options.resolveDeclared(declaredType);
|
|
430
|
+
if (typeof mappedId === "string" && mappedId.length > 0 && hasId(mappedId)) {
|
|
431
|
+
return {
|
|
432
|
+
id: mappedId,
|
|
433
|
+
resolvedBy: "declared",
|
|
434
|
+
reasons: [`declared:${declaredType}`]
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
const infer = options.inferFallback ?? resolveTaskTypeForText;
|
|
439
|
+
return infer({
|
|
440
|
+
taskText: options.taskText,
|
|
441
|
+
candidates: options.candidates,
|
|
442
|
+
fallbackId: options.fallbackId,
|
|
443
|
+
stripInjections: options.stripInjections
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
function resolveTaskTypeForText(options) {
|
|
447
|
+
const stripInjections = options.stripInjections ?? true;
|
|
448
|
+
const matcherText = stripInjections ? stripPromptInjections(options.taskText) : options.taskText;
|
|
449
|
+
const classification = classifyTask(matcherText, {
|
|
450
|
+
stripInjections: false
|
|
451
|
+
});
|
|
452
|
+
const matcherClassification = classificationForTaskTypeMatching(matcherText, classification);
|
|
453
|
+
return resolveTaskTypeFromCandidates({
|
|
454
|
+
taskText: matcherText,
|
|
455
|
+
candidates: options.candidates,
|
|
456
|
+
classification: matcherClassification,
|
|
457
|
+
fallbackId: options.fallbackId
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// src/planning/sprint-to-workflow.ts
|
|
462
|
+
var DEFAULT_SPRINT_WORKFLOW_DENYLIST = [
|
|
463
|
+
// Node
|
|
464
|
+
"package.json",
|
|
465
|
+
"package-lock.json",
|
|
466
|
+
"pnpm-lock.yaml",
|
|
467
|
+
"yarn.lock",
|
|
468
|
+
"bun.lockb",
|
|
469
|
+
// Rust
|
|
470
|
+
"Cargo.toml",
|
|
471
|
+
"Cargo.lock",
|
|
472
|
+
// Go
|
|
473
|
+
"go.mod",
|
|
474
|
+
"go.sum",
|
|
475
|
+
// Python
|
|
476
|
+
"pyproject.toml",
|
|
477
|
+
"poetry.lock",
|
|
478
|
+
"uv.lock",
|
|
479
|
+
"requirements.txt",
|
|
480
|
+
// Ruby
|
|
481
|
+
"Gemfile",
|
|
482
|
+
"Gemfile.lock",
|
|
483
|
+
// PHP
|
|
484
|
+
"composer.json",
|
|
485
|
+
"composer.lock",
|
|
486
|
+
// .NET (glob-less matcher: *.csproj cannot be expressed; root MSBuild props can)
|
|
487
|
+
"Directory.Build.props",
|
|
488
|
+
// CI
|
|
489
|
+
".github/workflows/"
|
|
490
|
+
];
|
|
491
|
+
var IGNORED_TARGET_PREFIXES = [
|
|
492
|
+
".poetic/planning/",
|
|
493
|
+
".poetic/tmp/",
|
|
494
|
+
".poetic/cache/",
|
|
495
|
+
".poetic/state/",
|
|
496
|
+
".poetic/telemetry/",
|
|
497
|
+
".poetic/runs/",
|
|
498
|
+
".poetic/artifacts/",
|
|
499
|
+
".poetic/workflows/",
|
|
500
|
+
"node_modules/",
|
|
501
|
+
"dist/",
|
|
502
|
+
"build/",
|
|
503
|
+
"coverage/"
|
|
504
|
+
];
|
|
505
|
+
var PATH_REFERENCE_EXTENSION_ALTERNATION = getProjectReferencePathExtensions().map((ext) => ext.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
|
|
506
|
+
var PATH_TOKEN_PATTERN = new RegExp(
|
|
507
|
+
String.raw`(?:^|[\s\u0060'"])((?:\.?\.\/)?(?:[A-Za-z0-9_.-]+\/)+[A-Za-z0-9_.-]*\.(?:${PATH_REFERENCE_EXTENSION_ALTERNATION}))(?:$|[\s\u0060'",.;:)])`,
|
|
508
|
+
"gi"
|
|
509
|
+
);
|
|
510
|
+
function extractLikelyPathReferences(text) {
|
|
511
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
512
|
+
for (const match of text.matchAll(PATH_TOKEN_PATTERN)) {
|
|
513
|
+
const raw = match[1]?.trim();
|
|
514
|
+
if (!raw) continue;
|
|
515
|
+
candidates.add(raw.replace(/^\.\//, ""));
|
|
516
|
+
}
|
|
517
|
+
return Array.from(candidates);
|
|
518
|
+
}
|
|
519
|
+
function quoteVerifyArg(value) {
|
|
520
|
+
if (/^[A-Za-z0-9_./:@%+=,-]+$/.test(value)) return value;
|
|
521
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
522
|
+
}
|
|
523
|
+
function extractExactOneLineContent(text) {
|
|
524
|
+
const match = text.match(/\bexactly\s+one\s+line\s*:\s*([^\n]+)/i);
|
|
525
|
+
let content = match?.[1]?.trim();
|
|
526
|
+
if (!content) return void 0;
|
|
527
|
+
const openingQuote = content[0];
|
|
528
|
+
if (openingQuote === '"' || openingQuote === "'" || openingQuote === "`") {
|
|
529
|
+
let escaped = false;
|
|
530
|
+
let decoded = "";
|
|
531
|
+
for (let i = 1; i < content.length; i++) {
|
|
532
|
+
const ch = content[i];
|
|
533
|
+
if (escaped) {
|
|
534
|
+
decoded += ch;
|
|
535
|
+
escaped = false;
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
if (ch === "\\") {
|
|
539
|
+
escaped = true;
|
|
540
|
+
continue;
|
|
541
|
+
}
|
|
542
|
+
if (ch === openingQuote) {
|
|
543
|
+
content = decoded;
|
|
544
|
+
return content && content.length > 0 ? content : void 0;
|
|
545
|
+
}
|
|
546
|
+
decoded += ch;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
content = content.replace(/\.\s+(?:(?:Do not|Verify|Validation)\b|Acceptance:).*$/i, "").trim();
|
|
550
|
+
content = content.replace(/\.$/, "").trim();
|
|
551
|
+
return content && content.length > 0 ? content : void 0;
|
|
552
|
+
}
|
|
553
|
+
function buildExactLineVerifyCommand(pathValue, content) {
|
|
554
|
+
const encodedContent = Buffer.from(content, "utf8").toString("base64");
|
|
555
|
+
return `poetic assert exact-line ${quoteVerifyArg(pathValue)} --content-base64 ${encodedContent}`;
|
|
556
|
+
}
|
|
557
|
+
function normalizeBodyVerifyLine(line) {
|
|
558
|
+
let value = line.trim().replace(/^\s*(?:[-*+]|\d+[.)])\s+/, "").trim();
|
|
559
|
+
if (!value) return void 0;
|
|
560
|
+
const codeSpan = value.match(/`([^`]+)`/);
|
|
561
|
+
if (codeSpan?.[1]) {
|
|
562
|
+
value = codeSpan[1].trim().replace(/^["']|["']$/g, "").trim();
|
|
563
|
+
return value.length > 0 ? value : void 0;
|
|
564
|
+
}
|
|
565
|
+
value = value.replace(/^run\s+/i, "").trim().replace(/^["']|["']$/g, "").replace(/(?<![./]);$/g, "").replace(/(?<![./])\.$/g, "").trim();
|
|
566
|
+
return value.length > 0 ? value : void 0;
|
|
567
|
+
}
|
|
568
|
+
function extractBodyVerifyCommands(text) {
|
|
569
|
+
const lines = text.split(/\r?\n/);
|
|
570
|
+
const commands = [];
|
|
571
|
+
let inVerifySection = false;
|
|
572
|
+
let inFence = false;
|
|
573
|
+
for (const line of lines) {
|
|
574
|
+
const trimmed = line.trim();
|
|
575
|
+
if (/^```/.test(trimmed)) {
|
|
576
|
+
if (inVerifySection) {
|
|
577
|
+
inFence = !inFence;
|
|
578
|
+
}
|
|
579
|
+
continue;
|
|
580
|
+
}
|
|
581
|
+
if (!inFence && /^#{1,6}\s+/.test(trimmed)) {
|
|
582
|
+
if (/^#{1,6}\s+how\s+to\s+verify\b/i.test(trimmed)) {
|
|
583
|
+
inVerifySection = true;
|
|
584
|
+
continue;
|
|
585
|
+
}
|
|
586
|
+
if (inVerifySection) {
|
|
587
|
+
break;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
if (!inVerifySection) continue;
|
|
591
|
+
const command = normalizeBodyVerifyLine(line);
|
|
592
|
+
if (!command) continue;
|
|
593
|
+
const safety = checkVerifyCommandSafety(command);
|
|
594
|
+
if (safety.safe && !commands.includes(command)) {
|
|
595
|
+
commands.push(command);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
return commands;
|
|
599
|
+
}
|
|
600
|
+
function isIgnoredTargetPath(targetPath) {
|
|
601
|
+
const normalized = targetPath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
602
|
+
return IGNORED_TARGET_PREFIXES.some(
|
|
603
|
+
(prefix) => normalized === prefix.slice(0, -1) || normalized.startsWith(prefix)
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
function normalizeTargetPath(value) {
|
|
607
|
+
return value.trim().replace(/^`|`$/g, "").replace(/^\.\//, "").replace(/#L\d+(?:-L?\d+)?$/i, "").replace(/\s+\(\s*(?:new|create|modify)\s*\)$/i, "").replace(/[),.;:]+$/g, "");
|
|
608
|
+
}
|
|
609
|
+
function extractCreateAnnotatedFileTargets(text) {
|
|
610
|
+
const targets = /* @__PURE__ */ new Set();
|
|
611
|
+
for (const line of text.split("\n")) {
|
|
612
|
+
const match = line.match(/^\s*FILE:\s*(.+)$/i);
|
|
613
|
+
if (!match) continue;
|
|
614
|
+
if (!/\(\s*(?:new|create)\s*\)\s*$/i.test(match[1] ?? "")) continue;
|
|
615
|
+
const target = normalizeTargetPath(match[1] ?? "");
|
|
616
|
+
if (target) targets.add(target);
|
|
617
|
+
}
|
|
618
|
+
return Array.from(targets);
|
|
619
|
+
}
|
|
620
|
+
function hasCreateFileIntent(text) {
|
|
621
|
+
return /\b(?:create|scaffold|generate|introduce)\b[\s\S]{0,120}\b(?:file|module|component|template|fixture|script|document|doc)\b/i.test(
|
|
622
|
+
text
|
|
623
|
+
) || /\bnew\s+(?:file|module|component|template|fixture|script|document|doc)\b/i.test(text);
|
|
624
|
+
}
|
|
625
|
+
function inferCreateIntentTargets(options) {
|
|
626
|
+
const { task, body, stage } = options;
|
|
627
|
+
const text = `${task.title ?? ""}
|
|
628
|
+
${body.rawBody || body.description || ""}`;
|
|
629
|
+
const annotatedTargets = extractCreateAnnotatedFileTargets(text);
|
|
630
|
+
if (annotatedTargets.length > 0) return annotatedTargets;
|
|
631
|
+
if (!hasCreateFileIntent(text)) return [];
|
|
632
|
+
return Array.from(
|
|
633
|
+
new Set(
|
|
634
|
+
[
|
|
635
|
+
...body.fileMarkers,
|
|
636
|
+
...stage.allowlist ?? [],
|
|
637
|
+
...stage.validation?.requiredFiles ?? [],
|
|
638
|
+
...extractLikelyPathReferences(text)
|
|
639
|
+
].map(normalizeTargetPath).filter((target) => target.length > 0 && !target.endsWith("/"))
|
|
640
|
+
)
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
function annotatePromptWithCreateTargets(prompt, createTargets) {
|
|
644
|
+
if (createTargets.length === 0) return prompt;
|
|
645
|
+
const remaining = new Set(createTargets);
|
|
646
|
+
const lines = prompt.split("\n").map((line) => {
|
|
647
|
+
const match = line.match(/^(\s*)FILE:\s*(.+)$/i);
|
|
648
|
+
if (!match) return line;
|
|
649
|
+
const indent = match[1] ?? "";
|
|
650
|
+
const target = normalizeTargetPath(match[2] ?? "");
|
|
651
|
+
if (!remaining.has(target)) return line;
|
|
652
|
+
remaining.delete(target);
|
|
653
|
+
return `${indent}FILE: ${target} (create)`;
|
|
654
|
+
});
|
|
655
|
+
if (remaining.size === 0) return lines.join("\n");
|
|
656
|
+
const insertion = Array.from(remaining, (target) => `FILE: ${target} (create)`).join("\n");
|
|
657
|
+
const checklistIndex = lines.findIndex((line) => /^##\s+Checklist\b/i.test(line));
|
|
658
|
+
if (checklistIndex >= 0) {
|
|
659
|
+
lines.splice(checklistIndex, 0, "", insertion, "");
|
|
660
|
+
return lines.join("\n");
|
|
661
|
+
}
|
|
662
|
+
return `${lines.join("\n").trimEnd()}
|
|
663
|
+
|
|
664
|
+
${insertion}
|
|
665
|
+
`;
|
|
666
|
+
}
|
|
667
|
+
function addCreateIntentValidation(stage, createTargets) {
|
|
668
|
+
if (createTargets.length === 0) return;
|
|
669
|
+
stage.validation = stage.validation ?? { enabled: false };
|
|
670
|
+
const requiredFiles = new Set(stage.validation.requiredFiles ?? []);
|
|
671
|
+
const checks = [...stage.validation.checks ?? []];
|
|
672
|
+
const existingFileExistsChecks = new Set(
|
|
673
|
+
checks.filter((check) => check.type === "file-exists").map((check) => normalizeTargetPath(check.path))
|
|
674
|
+
);
|
|
675
|
+
for (const target of createTargets) {
|
|
676
|
+
requiredFiles.add(target);
|
|
677
|
+
if (!existingFileExistsChecks.has(target)) {
|
|
678
|
+
checks.push({ type: "file-exists", path: target });
|
|
679
|
+
existingFileExistsChecks.add(target);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
stage.validation.requiredFiles = Array.from(requiredFiles);
|
|
683
|
+
stage.validation.checks = checks;
|
|
684
|
+
}
|
|
685
|
+
function taskTypeFrameworkToJudgeType(framework, defaultJudgeType) {
|
|
686
|
+
if (framework === "multi-lens") return "multi-lens";
|
|
687
|
+
if (framework === "ai-judge") return "ai";
|
|
688
|
+
if (framework === "auto") return defaultJudgeType;
|
|
689
|
+
return defaultJudgeType;
|
|
690
|
+
}
|
|
691
|
+
function getPolicyAwareDefaultCompetitionVariants(provider, policy) {
|
|
692
|
+
const base = getDefaultCompetitionVariantsForProvider(provider);
|
|
693
|
+
const preferred = policy?.routing?.defaultStrategy;
|
|
694
|
+
if (!preferred) return base;
|
|
695
|
+
const providerId = base[0]?.provider ?? provider ?? resolveDefaultProvider(void 0, process.cwd()).value;
|
|
696
|
+
if (preferred === "hybrid") {
|
|
697
|
+
return [
|
|
698
|
+
{ provider: providerId, strategy: "hybrid" },
|
|
699
|
+
{ provider: providerId, strategy: "conservative" }
|
|
700
|
+
];
|
|
701
|
+
}
|
|
702
|
+
const first = base.find((v) => v.strategy === preferred);
|
|
703
|
+
const rest = base.filter((v) => v !== first);
|
|
704
|
+
return first ? [first, ...rest] : base;
|
|
705
|
+
}
|
|
706
|
+
function createDefaultCompetitionConfig(provider, overrides, policy, defaultJudgeType = "ai") {
|
|
707
|
+
const policyDefaultScore = policy?.judging?.defaultScore;
|
|
708
|
+
const policyMinimumScore = policy?.judging?.minimumScore;
|
|
709
|
+
const defaultThresholdRaw = policyDefaultScore ?? 70;
|
|
710
|
+
const minimumThresholdRaw = policyMinimumScore ?? -Infinity;
|
|
711
|
+
const defaultThreshold = Math.max(defaultThresholdRaw, minimumThresholdRaw);
|
|
712
|
+
const config = {
|
|
713
|
+
variants: getPolicyAwareDefaultCompetitionVariants(provider, policy),
|
|
714
|
+
judgeConfig: {
|
|
715
|
+
type: overrides?.judgeType ?? taskTypeFrameworkToJudgeType(policy?.judging?.framework, defaultJudgeType),
|
|
716
|
+
threshold: defaultThreshold
|
|
717
|
+
},
|
|
718
|
+
preserveCandidates: false,
|
|
719
|
+
applyWinner: true,
|
|
720
|
+
// Delivery-safe default: verification failures disqualify candidates.
|
|
721
|
+
verificationPolicy: "blocking",
|
|
722
|
+
// Enable automatic repair for winners with verification findings
|
|
723
|
+
repairOnFindings: {
|
|
724
|
+
enabled: true,
|
|
725
|
+
maxIterations: 3,
|
|
726
|
+
timeboxMs: resolveExecutionBoundary("bounded-loop").hardCeilingMs
|
|
727
|
+
},
|
|
728
|
+
// Default to 'inconclusive': refuse to break score ties without an LLM verdict.
|
|
729
|
+
// Users can opt back into deterministic tie-breaking by setting the stage's
|
|
730
|
+
// tieBreaker explicitly (e.g. 'prefer-first-ranked').
|
|
731
|
+
tieBreaker: {
|
|
732
|
+
mode: "inconclusive"
|
|
733
|
+
}
|
|
734
|
+
};
|
|
735
|
+
if (overrides) {
|
|
736
|
+
if (overrides.verificationPolicy) {
|
|
737
|
+
config.verificationPolicy = overrides.verificationPolicy;
|
|
738
|
+
}
|
|
739
|
+
if (overrides.repairOnFindings !== void 0) {
|
|
740
|
+
if (!overrides.repairOnFindings.enabled) {
|
|
741
|
+
config.repairOnFindings = { enabled: false };
|
|
742
|
+
} else {
|
|
743
|
+
config.repairOnFindings = {
|
|
744
|
+
enabled: true,
|
|
745
|
+
maxIterations: overrides.repairOnFindings.maxIterations ?? 3,
|
|
746
|
+
timeboxMs: overrides.repairOnFindings.timeboxMs ?? resolveExecutionBoundary("bounded-loop").hardCeilingMs
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
if (overrides.judgeType) {
|
|
751
|
+
config.judgeConfig = {
|
|
752
|
+
...config.judgeConfig ?? { threshold: defaultThreshold },
|
|
753
|
+
type: overrides.judgeType
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
if (overrides.disableAiJudge) {
|
|
757
|
+
config.judgeConfig = {
|
|
758
|
+
...config.judgeConfig ?? { type: defaultJudgeType, threshold: defaultThreshold },
|
|
759
|
+
disableAiJudge: true
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
if (overrides.aiJudgeRun !== void 0 && overrides.aiJudgeRun !== false) {
|
|
763
|
+
config.judgeConfig = {
|
|
764
|
+
...config.judgeConfig ?? { type: defaultJudgeType, threshold: defaultThreshold },
|
|
765
|
+
runComparison: true
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
return config;
|
|
770
|
+
}
|
|
771
|
+
async function validateAndFilterDependencies(task, sprintTaskIds, completedTaskIds) {
|
|
772
|
+
const validDeps = [];
|
|
773
|
+
const satisfiedArchivedDeps = [];
|
|
774
|
+
const crossSprintDeps = [];
|
|
775
|
+
const missingDeps = [];
|
|
776
|
+
const dependencies = Array.isArray(task.dependencies) ? task.dependencies : [];
|
|
777
|
+
for (const dep of dependencies) {
|
|
778
|
+
if (sprintTaskIds.has(dep)) {
|
|
779
|
+
try {
|
|
780
|
+
const { yaml: depTask } = await getTask(dep, { includeArchive: false });
|
|
781
|
+
if (depTask.status === "blocked" || depTask.status === "cancelled") {
|
|
782
|
+
crossSprintDeps.push(`${dep} (status: ${depTask.status})`);
|
|
783
|
+
continue;
|
|
784
|
+
}
|
|
785
|
+
} catch {
|
|
786
|
+
}
|
|
787
|
+
validDeps.push(dep);
|
|
788
|
+
} else {
|
|
789
|
+
try {
|
|
790
|
+
const { yaml: depTask, isArchived } = await getTask(dep, { includeArchive: true });
|
|
791
|
+
const classification = classifyTaskDependency(dep, {
|
|
792
|
+
task: { status: depTask.status, isArchived }
|
|
793
|
+
});
|
|
794
|
+
if (classification.satisfied) {
|
|
795
|
+
satisfiedArchivedDeps.push(dep);
|
|
796
|
+
} else {
|
|
797
|
+
crossSprintDeps.push(isArchived ? `${dep} (archived status: ${depTask.status})` : dep);
|
|
798
|
+
}
|
|
799
|
+
} catch {
|
|
800
|
+
const classification = classifyTaskDependency(dep, {
|
|
801
|
+
task: null,
|
|
802
|
+
recordedComplete: completedTaskIds.has(dep)
|
|
803
|
+
});
|
|
804
|
+
if (classification.satisfied) {
|
|
805
|
+
satisfiedArchivedDeps.push(dep);
|
|
806
|
+
} else {
|
|
807
|
+
missingDeps.push(dep);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
const canExecute = crossSprintDeps.length === 0 && missingDeps.length === 0;
|
|
813
|
+
return { validDeps, satisfiedArchivedDeps, crossSprintDeps, missingDeps, canExecute };
|
|
814
|
+
}
|
|
815
|
+
async function buildTaskTypeContext(registry) {
|
|
816
|
+
const candidates = registry.listIds().map((id) => registry.get(id)).filter((v) => v !== null);
|
|
817
|
+
let aliasMap = TaskTypeAliasMap.empty();
|
|
818
|
+
try {
|
|
819
|
+
aliasMap = await TaskTypeAliasMap.load({ cwd: process.cwd() });
|
|
820
|
+
} catch {
|
|
821
|
+
}
|
|
822
|
+
return { registry, candidates, aliasMap };
|
|
823
|
+
}
|
|
824
|
+
function resolveTaskTypePolicy(options) {
|
|
825
|
+
const { task, taskText, ctx } = options;
|
|
826
|
+
if (!ctx) return null;
|
|
827
|
+
const explicitId = task.taskType?.trim() || task.resolvedTaskTypeId?.trim() || void 0;
|
|
828
|
+
const resolution = resolveTaskTypeWithDeclaration({
|
|
829
|
+
taskText: stripPromptInjections(taskText),
|
|
830
|
+
candidates: ctx.candidates,
|
|
831
|
+
explicitId,
|
|
832
|
+
explicitResolvedBy: "frontmatter",
|
|
833
|
+
declaredType: task.declaredType,
|
|
834
|
+
resolveDeclared: (declared) => ctx.aliasMap.resolve(declared),
|
|
835
|
+
hasId: (id) => ctx.registry.get(id) !== null,
|
|
836
|
+
fallbackId: "general",
|
|
837
|
+
// Preserve the original matcher behavior here: the pure candidate matcher
|
|
838
|
+
// over already-stripped text (NOT the classification-aware variant), so the
|
|
839
|
+
// declared-term gate adds a step in front without changing matcher scoring.
|
|
840
|
+
inferFallback: ({ taskText: text, candidates, fallbackId }) => resolveTaskTypeFromCandidates({ taskText: text, candidates, fallbackId })
|
|
841
|
+
});
|
|
842
|
+
const def = ctx.registry.get(resolution.id);
|
|
843
|
+
return { resolution, policy: def?.policy ?? {} };
|
|
844
|
+
}
|
|
845
|
+
function inferStageContract(task, description, policyExecutionIntent) {
|
|
846
|
+
const contract = resolveStageContract({
|
|
847
|
+
title: task.title,
|
|
848
|
+
text: description,
|
|
849
|
+
metadataExecutionIntent: task.metadata?.executionIntent,
|
|
850
|
+
policyExecutionIntent
|
|
851
|
+
});
|
|
852
|
+
if (contract.source === "stage-semantics") {
|
|
853
|
+
const intent = classifyIntent(description);
|
|
854
|
+
const isHighConfidenceAnalysis = intent.category === "analyze" && intent.confidence > 0.8;
|
|
855
|
+
return {
|
|
856
|
+
capabilities: {
|
|
857
|
+
modifiesFiles: !isHighConfidenceAnalysis,
|
|
858
|
+
executionIntent: isHighConfidenceAnalysis ? "analysis" : "edit"
|
|
859
|
+
},
|
|
860
|
+
source: "intent-classifier",
|
|
861
|
+
authoritativeAnalysis: false
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
return contract;
|
|
865
|
+
}
|
|
866
|
+
async function readTaskBody(taskId) {
|
|
867
|
+
try {
|
|
868
|
+
const { filePath } = await getTask(taskId, { includeArchive: true });
|
|
869
|
+
const { body } = await readMarkdownFile(filePath);
|
|
870
|
+
return parseTaskBody(body);
|
|
871
|
+
} catch {
|
|
872
|
+
return {
|
|
873
|
+
description: "",
|
|
874
|
+
subtasks: [],
|
|
875
|
+
notes: "",
|
|
876
|
+
fileMarkers: [],
|
|
877
|
+
rawBody: ""
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
async function mapTaskToStage(task, body, sprintTaskIds, completedTaskIds, strict, defaultProvider, competitionOverrides, taskTypeContext, defaultJudgeType = "ai") {
|
|
882
|
+
const warnings = [];
|
|
883
|
+
const errors = [];
|
|
884
|
+
const depValidation = await validateAndFilterDependencies(task, sprintTaskIds, completedTaskIds);
|
|
885
|
+
if (task.status === "blocked") {
|
|
886
|
+
const msg = `Task ${task.id} is blocked and cannot be executed until unblocked.`;
|
|
887
|
+
if (strict) {
|
|
888
|
+
errors.push(msg);
|
|
889
|
+
} else {
|
|
890
|
+
warnings.push(`SKIPPING: ${msg}`);
|
|
891
|
+
return {
|
|
892
|
+
stage: null,
|
|
893
|
+
skipped: true,
|
|
894
|
+
warnings,
|
|
895
|
+
errors,
|
|
896
|
+
skipMeta: { taskId: task.id, reason: "blocked", message: msg }
|
|
897
|
+
};
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
if (depValidation.satisfiedArchivedDeps.length > 0) {
|
|
901
|
+
warnings.push(
|
|
902
|
+
`Task ${task.id} has archived/completed deps (satisfied): ${depValidation.satisfiedArchivedDeps.join(", ")}`
|
|
903
|
+
);
|
|
904
|
+
}
|
|
905
|
+
if (depValidation.crossSprintDeps.length > 0) {
|
|
906
|
+
const msg = `Task ${task.id} has cross-sprint deps that are not yet done: ${depValidation.crossSprintDeps.join(", ")}`;
|
|
907
|
+
if (strict) {
|
|
908
|
+
errors.push(msg);
|
|
909
|
+
} else {
|
|
910
|
+
warnings.push(`SKIPPING: ${msg}`);
|
|
911
|
+
return {
|
|
912
|
+
stage: null,
|
|
913
|
+
skipped: true,
|
|
914
|
+
warnings,
|
|
915
|
+
errors,
|
|
916
|
+
skipMeta: { taskId: task.id, reason: "crossSprintDep", message: msg }
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
if (depValidation.missingDeps.length > 0) {
|
|
921
|
+
const msg = `Task ${task.id} has missing deps: ${depValidation.missingDeps.join(", ")}`;
|
|
922
|
+
if (strict) {
|
|
923
|
+
errors.push(msg);
|
|
924
|
+
} else {
|
|
925
|
+
warnings.push(`SKIPPING: ${msg}`);
|
|
926
|
+
return {
|
|
927
|
+
stage: null,
|
|
928
|
+
skipped: true,
|
|
929
|
+
warnings,
|
|
930
|
+
errors,
|
|
931
|
+
skipMeta: { taskId: task.id, reason: "missing", message: msg }
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
const taskText = `${task.title}
|
|
936
|
+
|
|
937
|
+
${body.rawBody || body.description || ""}`;
|
|
938
|
+
const taskTypePolicy = resolveTaskTypePolicy({ task, taskText, ctx: taskTypeContext });
|
|
939
|
+
if (task.taskType && taskTypeContext && taskTypePolicy?.resolution.resolvedBy !== "frontmatter") {
|
|
940
|
+
warnings.push(`Task ${task.id}: unknown taskType override '${task.taskType}' (falling back)`);
|
|
941
|
+
}
|
|
942
|
+
if (taskTypePolicy && (taskTypePolicy.resolution.id !== "general" || task.taskType)) {
|
|
943
|
+
warnings.push(
|
|
944
|
+
`Task ${task.id}: taskType=${taskTypePolicy.resolution.id} (${taskTypePolicy.resolution.resolvedBy})`
|
|
945
|
+
);
|
|
946
|
+
}
|
|
947
|
+
const stagePolicyExecutionIntent = taskTypePolicy?.resolution.resolvedBy === "fallback" ? void 0 : taskTypePolicy?.policy.executionIntent;
|
|
948
|
+
const stageContract = inferStageContract(task, taskText, stagePolicyExecutionIntent);
|
|
949
|
+
const capabilities = stageContract.capabilities;
|
|
950
|
+
const validation = capabilities.executionIntent === "analysis" ? { enabled: false } : { enabled: true, threshold: 60 };
|
|
951
|
+
void (capabilities.executionIntent === "analysis");
|
|
952
|
+
const stage = {
|
|
953
|
+
id: task.id,
|
|
954
|
+
name: task.title,
|
|
955
|
+
deps: depValidation.validDeps.length > 0 ? depValidation.validDeps : void 0,
|
|
956
|
+
prompt: buildPromptFromTask(task, body),
|
|
957
|
+
capabilities,
|
|
958
|
+
validation
|
|
959
|
+
};
|
|
960
|
+
const inferredAllowlistTargets = Array.from(
|
|
961
|
+
/* @__PURE__ */ new Set([
|
|
962
|
+
...body.fileMarkers,
|
|
963
|
+
...extractLikelyPathReferences(taskText),
|
|
964
|
+
...task.flywheel?.validation?.requiredFiles ?? []
|
|
965
|
+
])
|
|
966
|
+
);
|
|
967
|
+
const groundedInferredAllowlistTargets = inferredAllowlistTargets.filter(
|
|
968
|
+
(target) => !isIgnoredTargetPath(target)
|
|
969
|
+
);
|
|
970
|
+
if (taskTypePolicy) {
|
|
971
|
+
stage.templateVariables = {
|
|
972
|
+
...stage.templateVariables,
|
|
973
|
+
taskTypeId: taskTypePolicy.resolution.id,
|
|
974
|
+
taskTypeResolvedBy: taskTypePolicy.resolution.resolvedBy
|
|
975
|
+
};
|
|
976
|
+
const taskTypeAllowlistMode = taskTypePolicy.policy.allowlist?.mode;
|
|
977
|
+
const hasAllowlistScope = (stage.allowlist?.length ?? 0) > 0 || (task.flywheel?.allowlist?.length ?? 0) > 0 || groundedInferredAllowlistTargets.length > 0;
|
|
978
|
+
const requiresNonEmptyAllowlist = taskTypePolicy.policy.allowlist?.requireNonEmpty === true;
|
|
979
|
+
if (!task.flywheel?.allowlistMode && taskTypeAllowlistMode && !stage.allowlistMode) {
|
|
980
|
+
if (taskTypeAllowlistMode === "strict" && requiresNonEmptyAllowlist && !hasAllowlistScope && capabilities.executionIntent !== "analysis") {
|
|
981
|
+
const msg = `Task ${task.id}: taskType policy requires a non-empty allowlist; refine the task scope before execution`;
|
|
982
|
+
if (strict) {
|
|
983
|
+
errors.push(msg);
|
|
984
|
+
} else {
|
|
985
|
+
warnings.push(`SKIPPING: ${msg}`);
|
|
986
|
+
return {
|
|
987
|
+
stage: null,
|
|
988
|
+
skipped: true,
|
|
989
|
+
warnings,
|
|
990
|
+
errors,
|
|
991
|
+
skipMeta: { taskId: task.id, reason: "refinement", message: msg }
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
} else {
|
|
995
|
+
stage.allowlistMode = taskTypeAllowlistMode;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
if (requiresNonEmptyAllowlist && stage.allowlistMode === "strict" && !hasAllowlistScope) {
|
|
999
|
+
warnings.push(`Task ${task.id}: taskType policy requires a non-empty allowlist (strict)`);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
if (task.routing) {
|
|
1003
|
+
if (task.routing.provider) {
|
|
1004
|
+
stage.provider = task.routing.provider;
|
|
1005
|
+
}
|
|
1006
|
+
if (task.routing.model) {
|
|
1007
|
+
stage.model = task.routing.model;
|
|
1008
|
+
}
|
|
1009
|
+
if (task.routing.strategy || task.routing.reasoning || task.routing.profile) {
|
|
1010
|
+
stage.templateVariables = {
|
|
1011
|
+
...stage.templateVariables,
|
|
1012
|
+
routingStrategy: task.routing.strategy,
|
|
1013
|
+
routingReasoning: task.routing.reasoning,
|
|
1014
|
+
routingProfile: task.routing.profile
|
|
1015
|
+
};
|
|
1016
|
+
}
|
|
1017
|
+
const pins = [
|
|
1018
|
+
task.routing.provider && `provider=${task.routing.provider}`,
|
|
1019
|
+
task.routing.model && `model=${task.routing.model}`,
|
|
1020
|
+
task.routing.strategy && `strategy=${task.routing.strategy}`
|
|
1021
|
+
].filter(Boolean).join(", ");
|
|
1022
|
+
if (pins) {
|
|
1023
|
+
warnings.push(`Task ${task.id} has routing pins: ${pins}`);
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
if (task.flywheel) {
|
|
1027
|
+
if (task.flywheel.type) {
|
|
1028
|
+
stage.type = task.flywheel.type;
|
|
1029
|
+
}
|
|
1030
|
+
if (task.flywheel.inputs && task.flywheel.inputs.length > 0) {
|
|
1031
|
+
stage.inputs = task.flywheel.inputs;
|
|
1032
|
+
}
|
|
1033
|
+
if (task.flywheel.outputs) {
|
|
1034
|
+
stage.outputs = task.flywheel.outputs;
|
|
1035
|
+
}
|
|
1036
|
+
if (task.flywheel.validation) {
|
|
1037
|
+
stage.validation = {
|
|
1038
|
+
...stage.validation ?? { enabled: false },
|
|
1039
|
+
...task.flywheel.validation
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1042
|
+
if (task.flywheel.competition) {
|
|
1043
|
+
stage.type = "competition";
|
|
1044
|
+
stage.competition = task.flywheel.competition;
|
|
1045
|
+
}
|
|
1046
|
+
if (task.flywheel.allowEmptyResults !== void 0) {
|
|
1047
|
+
stage.allowEmptyResults = task.flywheel.allowEmptyResults;
|
|
1048
|
+
}
|
|
1049
|
+
if (task.flywheel.allowlist && task.flywheel.allowlist.length > 0) {
|
|
1050
|
+
stage.allowlist = task.flywheel.allowlist;
|
|
1051
|
+
}
|
|
1052
|
+
if (task.flywheel.allowlistMode) {
|
|
1053
|
+
stage.allowlistMode = task.flywheel.allowlistMode;
|
|
1054
|
+
}
|
|
1055
|
+
if (task.flywheel.allowDenylist && task.flywheel.allowDenylist.length > 0) {
|
|
1056
|
+
stage.allowDenylist = task.flywheel.allowDenylist;
|
|
1057
|
+
}
|
|
1058
|
+
if (task.flywheel.verify && task.flywheel.verify.commands.length > 0) {
|
|
1059
|
+
stage.verify = task.flywheel.verify;
|
|
1060
|
+
}
|
|
1061
|
+
if (task.flywheel.type === "autoloop" || task.flywheel.autoloop) {
|
|
1062
|
+
stage.type = "autoloop";
|
|
1063
|
+
stage.autoloop = task.flywheel.autoloop ?? {};
|
|
1064
|
+
warnings.push(
|
|
1065
|
+
`Task ${task.id}: Explicit autoloop configuration applied (maxIterations: ${stage.autoloop.maxIterations ?? 3})`
|
|
1066
|
+
);
|
|
1067
|
+
}
|
|
1068
|
+
if (stage.type === "verify" && stage.verify?.commands && stage.verify.commands.length > 0) {
|
|
1069
|
+
if (stage.validation?.semanticChecks) {
|
|
1070
|
+
delete stage.validation.semanticChecks;
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
if (!hasExplicitFlywheelConfig(task)) {
|
|
1075
|
+
const isExplicitAnalysisIntent = capabilities.executionIntent === "analysis" && stageContract.authoritativeAnalysis;
|
|
1076
|
+
const isFusionDefaultActivity = task.taskClassification?.activity !== void 0 && FUSION_DEFAULT_ACTIVITIES.has(task.taskClassification.activity);
|
|
1077
|
+
const useMatchedAnalysisIntent = !task.taskClassification && taskTypePolicy?.resolution.id === "analysis" && taskTypePolicy.policy.executionIntent === "analysis";
|
|
1078
|
+
const policyExecutionIntent = taskTypePolicy?.policy.executionIntent;
|
|
1079
|
+
const strategyExecutionIntent = task.metadata?.executionIntent ?? (policyExecutionIntent === "analysis" && (task.taskType || useMatchedAnalysisIntent) ? policyExecutionIntent : void 0);
|
|
1080
|
+
const strategyTask = strategyExecutionIntent && strategyExecutionIntent !== task.metadata?.executionIntent ? {
|
|
1081
|
+
...task,
|
|
1082
|
+
metadata: {
|
|
1083
|
+
...task.metadata,
|
|
1084
|
+
executionIntent: strategyExecutionIntent
|
|
1085
|
+
}
|
|
1086
|
+
} : task;
|
|
1087
|
+
const preferCompetition = isFusionDefaultActivity || taskTypePolicy?.policy.routing?.preferCompetition === true && !isExplicitAnalysisIntent;
|
|
1088
|
+
const strategySelection = competitionOverrides?.forceSinglePass ? {
|
|
1089
|
+
strategy: "single-pass",
|
|
1090
|
+
reasons: ["--single-pass requested"],
|
|
1091
|
+
confidence: 100,
|
|
1092
|
+
hasExplicitConfig: false
|
|
1093
|
+
} : isExplicitAnalysisIntent && !isFusionDefaultActivity ? {
|
|
1094
|
+
strategy: "single-pass",
|
|
1095
|
+
reasons: ["analysis intent avoids competition fan-in"],
|
|
1096
|
+
confidence: 100,
|
|
1097
|
+
hasExplicitConfig: false
|
|
1098
|
+
} : preferCompetition ? {
|
|
1099
|
+
strategy: "compete",
|
|
1100
|
+
reasons: [
|
|
1101
|
+
isFusionDefaultActivity ? "activity defaults to Fusion-style competition" : "taskType policy prefers competition"
|
|
1102
|
+
],
|
|
1103
|
+
confidence: 100,
|
|
1104
|
+
hasExplicitConfig: false
|
|
1105
|
+
} : selectExecutionStrategy(strategyTask);
|
|
1106
|
+
const preferredProvider = task.routing?.provider ?? defaultProvider;
|
|
1107
|
+
if (strategySelection.strategy === "compete") {
|
|
1108
|
+
stage.type = "competition";
|
|
1109
|
+
stage.competition = createDefaultCompetitionConfig(
|
|
1110
|
+
preferredProvider,
|
|
1111
|
+
competitionOverrides,
|
|
1112
|
+
taskTypePolicy?.policy,
|
|
1113
|
+
defaultJudgeType
|
|
1114
|
+
);
|
|
1115
|
+
warnings.push(
|
|
1116
|
+
`Task ${task.id}: Strategy selection \u2192 competition (${strategySelection.reasons.join("; ")})`
|
|
1117
|
+
);
|
|
1118
|
+
} else if (strategySelection.strategy === "single-pass") {
|
|
1119
|
+
stage.type = "standard";
|
|
1120
|
+
warnings.push(
|
|
1121
|
+
`Task ${task.id}: Strategy selection \u2192 single-pass (${strategySelection.reasons.join("; ")})`
|
|
1122
|
+
);
|
|
1123
|
+
} else if (strategySelection.strategy === "autoloop" || strategySelection.strategy === "parallel") {
|
|
1124
|
+
stage.type = "standard";
|
|
1125
|
+
warnings.push(
|
|
1126
|
+
`Task ${task.id}: Strategy selection \u2192 ${strategySelection.strategy} (mapped to standard; full support pending) (${strategySelection.reasons.join("; ")})`
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
if (stage.type === "competition" && task.flywheel?.validation?.enabled === void 0) {
|
|
1131
|
+
stage.validation = { ...stage.validation ?? { enabled: false }, enabled: false };
|
|
1132
|
+
}
|
|
1133
|
+
if (stage.type === "competition" && stage.competition && competitionOverrides?.judgeType) {
|
|
1134
|
+
stage.competition.judgeConfig = {
|
|
1135
|
+
...stage.competition.judgeConfig ?? { threshold: 70 },
|
|
1136
|
+
type: competitionOverrides.judgeType
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
if (stage.type === "competition" && stage.competition && taskTypePolicy) {
|
|
1140
|
+
if (!stage.competition.judgeConfig) {
|
|
1141
|
+
stage.competition.judgeConfig = {
|
|
1142
|
+
type: defaultJudgeType,
|
|
1143
|
+
threshold: 70
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
const judgeConfig = stage.competition.judgeConfig;
|
|
1147
|
+
const defaultScore = taskTypePolicy.policy.judging?.defaultScore;
|
|
1148
|
+
if (judgeConfig.threshold === void 0 && typeof defaultScore === "number") {
|
|
1149
|
+
judgeConfig.threshold = defaultScore;
|
|
1150
|
+
}
|
|
1151
|
+
const minimumScore = taskTypePolicy.policy.judging?.minimumScore;
|
|
1152
|
+
if (typeof minimumScore === "number") {
|
|
1153
|
+
const current = judgeConfig.threshold ?? 0;
|
|
1154
|
+
if (current < minimumScore) {
|
|
1155
|
+
judgeConfig.threshold = minimumScore;
|
|
1156
|
+
warnings.push(
|
|
1157
|
+
`Task ${task.id}: clamped judge threshold to ${minimumScore} (taskType minimumScore)`
|
|
1158
|
+
);
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
if (stage.allowEmptyResults === void 0) {
|
|
1163
|
+
const descriptionText = `${task.title ?? ""}
|
|
1164
|
+
${body.rawBody ?? body.description ?? ""}`.toLowerCase();
|
|
1165
|
+
const idempotentPatterns = /\b(idempotent|make no (?:repository |file )?changes|no changes (?:needed|required|expected)|already (?:correct|satisfied|present)|succeed with (?:no|zero) (?:changes|edits|file changes))\b/;
|
|
1166
|
+
if (idempotentPatterns.test(descriptionText)) {
|
|
1167
|
+
stage.allowEmptyResults = true;
|
|
1168
|
+
warnings.push(
|
|
1169
|
+
`Task ${task.id}: auto-detected idempotent intent from description \u2192 allowEmptyResults=true`
|
|
1170
|
+
);
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
if (stage.capabilities?.executionIntent === "analysis" && stage.allowEmptyResults === void 0) {
|
|
1174
|
+
stage.allowEmptyResults = true;
|
|
1175
|
+
}
|
|
1176
|
+
if (stage.validation?.requireChanges === void 0) {
|
|
1177
|
+
const isEditIntent = stage.capabilities?.executionIntent === "edit";
|
|
1178
|
+
const isApplyWinnerCompetition = stage.type === "competition" && stage.competition?.applyWinner === true;
|
|
1179
|
+
if (stage.allowEmptyResults === true) {
|
|
1180
|
+
stage.validation = stage.validation ?? { enabled: false };
|
|
1181
|
+
stage.validation.requireChanges = false;
|
|
1182
|
+
} else if (isEditIntent || isApplyWinnerCompetition) {
|
|
1183
|
+
stage.validation = stage.validation ?? { enabled: false };
|
|
1184
|
+
stage.validation.requireChanges = true;
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
if (stage.capabilities?.executionIntent === "analysis" && !stage.outputs) {
|
|
1188
|
+
stage.outputs = { report: "text" };
|
|
1189
|
+
}
|
|
1190
|
+
const taskTargetPaths = Array.from(
|
|
1191
|
+
/* @__PURE__ */ new Set([
|
|
1192
|
+
...inferredAllowlistTargets,
|
|
1193
|
+
...stage.allowlist ?? [],
|
|
1194
|
+
...stage.validation?.requiredFiles ?? []
|
|
1195
|
+
])
|
|
1196
|
+
);
|
|
1197
|
+
if ((stage.allowlist?.length ?? 0) === 0 && groundedInferredAllowlistTargets.length > 0) {
|
|
1198
|
+
stage.allowlist = groundedInferredAllowlistTargets;
|
|
1199
|
+
}
|
|
1200
|
+
const exactLineContent = extractExactOneLineContent(body.rawBody ?? body.description ?? "");
|
|
1201
|
+
const exactLineTargets = (stage.allowlist ?? []).filter((target) => !isIgnoredTargetPath(target));
|
|
1202
|
+
if (exactLineContent && exactLineTargets.length === 1) {
|
|
1203
|
+
const command = buildExactLineVerifyCommand(exactLineTargets[0], exactLineContent);
|
|
1204
|
+
const existingCommands = stage.verify?.commands ?? [];
|
|
1205
|
+
if (!existingCommands.includes(command)) {
|
|
1206
|
+
stage.verify = { commands: [...existingCommands, command] };
|
|
1207
|
+
warnings.push(`Task ${task.id}: added exact-line verify command for ${exactLineTargets[0]}`);
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
if ((stage.verify?.commands?.length ?? 0) === 0) {
|
|
1211
|
+
const bodyVerifyCommands = extractBodyVerifyCommands(body.rawBody ?? body.description ?? "");
|
|
1212
|
+
if (bodyVerifyCommands.length > 0) {
|
|
1213
|
+
stage.verify = { commands: bodyVerifyCommands };
|
|
1214
|
+
warnings.push(
|
|
1215
|
+
`Task ${task.id}: added ${bodyVerifyCommands.length} verify command(s) from How to Verify`
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
const ignoredTargets = taskTargetPaths.filter(isIgnoredTargetPath);
|
|
1220
|
+
if (ignoredTargets.length > 0) {
|
|
1221
|
+
const message = `Task ${task.id}: target path(s) are gitignored/runtime-scoped and may produce no fan-in material: ` + ignoredTargets.join(", ");
|
|
1222
|
+
if (strict) {
|
|
1223
|
+
errors.push(message);
|
|
1224
|
+
} else {
|
|
1225
|
+
warnings.push(`${message}. Use tracked paths for change-producing sprint validation tasks.`);
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
const createIntentTargets = inferCreateIntentTargets({ task, body, stage });
|
|
1229
|
+
if (createIntentTargets.length > 0) {
|
|
1230
|
+
stage.prompt = annotatePromptWithCreateTargets(stage.prompt ?? "", createIntentTargets);
|
|
1231
|
+
const validationTargets = createIntentTargets.filter((target) => !isIgnoredTargetPath(target));
|
|
1232
|
+
addCreateIntentValidation(stage, validationTargets);
|
|
1233
|
+
}
|
|
1234
|
+
if (stage.validation?.enabled && stage.outputs && Object.keys(stage.outputs).length > 1) {
|
|
1235
|
+
if (!stage.validation.target) {
|
|
1236
|
+
if (Object.hasOwn(stage.outputs, "bundle")) {
|
|
1237
|
+
stage.validation.target = "bundle";
|
|
1238
|
+
} else {
|
|
1239
|
+
const entries = Object.entries(stage.outputs);
|
|
1240
|
+
const diffEntry = entries.find(([, type]) => type === "diff");
|
|
1241
|
+
const filesEntry = entries.find(([, type]) => type === "files");
|
|
1242
|
+
stage.validation.target = diffEntry?.[0] ?? filesEntry?.[0] ?? Object.keys(stage.outputs)[0] ?? void 0;
|
|
1243
|
+
}
|
|
1244
|
+
if (stage.validation.target) {
|
|
1245
|
+
warnings.push(
|
|
1246
|
+
`Stage ${task.id}: defaulted validation.target to '${stage.validation.target}' for multi-output stage`
|
|
1247
|
+
);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
const hasAssignmentOutput = stage.type !== "competition" && Boolean(stage.outputs && Object.hasOwn(stage.outputs, "assignment"));
|
|
1252
|
+
if (hasAssignmentOutput && stage.capabilities?.executionIntent === "analysis") {
|
|
1253
|
+
stage.validation = stage.validation ?? { enabled: false };
|
|
1254
|
+
stage.validation.semanticChecks = stage.validation.semanticChecks ?? getP1SemanticChecks();
|
|
1255
|
+
stage.validation.onFailure = stage.validation.onFailure ?? "retry-with-feedback";
|
|
1256
|
+
stage.validation.maxRetries = stage.validation.maxRetries ?? 2;
|
|
1257
|
+
warnings.push(
|
|
1258
|
+
`Stage ${task.id}: applied default semantic assignment gates + retry-with-feedback (${stage.validation.maxRetries} retries)`
|
|
1259
|
+
);
|
|
1260
|
+
}
|
|
1261
|
+
return {
|
|
1262
|
+
stage,
|
|
1263
|
+
skipped: false,
|
|
1264
|
+
warnings,
|
|
1265
|
+
errors
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
async function buildWorkflowStages(tasks, sprintTaskIds, completedTaskIds, strict, initialSkippedTaskIds, defaultProvider, competitionOverrides, taskTypeContext, defaultJudgeType = "ai") {
|
|
1269
|
+
const stages = [];
|
|
1270
|
+
const skippedTaskIds = new Set(initialSkippedTaskIds);
|
|
1271
|
+
const skippedTasks = [];
|
|
1272
|
+
const allWarnings = [];
|
|
1273
|
+
const allErrors = [];
|
|
1274
|
+
const mappingResults = /* @__PURE__ */ new Map();
|
|
1275
|
+
for (const task of tasks) {
|
|
1276
|
+
const body = await readTaskBody(task.id);
|
|
1277
|
+
const result = await mapTaskToStage(
|
|
1278
|
+
task,
|
|
1279
|
+
body,
|
|
1280
|
+
sprintTaskIds,
|
|
1281
|
+
completedTaskIds,
|
|
1282
|
+
strict,
|
|
1283
|
+
defaultProvider,
|
|
1284
|
+
competitionOverrides,
|
|
1285
|
+
taskTypeContext,
|
|
1286
|
+
defaultJudgeType
|
|
1287
|
+
);
|
|
1288
|
+
mappingResults.set(task.id, result);
|
|
1289
|
+
if (result.skipped) {
|
|
1290
|
+
skippedTaskIds.add(task.id);
|
|
1291
|
+
if (result.skipMeta) {
|
|
1292
|
+
skippedTasks.push(result.skipMeta);
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
allWarnings.push(...result.warnings);
|
|
1296
|
+
allErrors.push(...result.errors);
|
|
1297
|
+
}
|
|
1298
|
+
let changed = true;
|
|
1299
|
+
while (changed) {
|
|
1300
|
+
changed = false;
|
|
1301
|
+
for (const [taskId, result] of mappingResults) {
|
|
1302
|
+
if (result.skipped) continue;
|
|
1303
|
+
if (!result.stage) continue;
|
|
1304
|
+
const hasSkippedDep = result.stage.deps?.some((dep) => skippedTaskIds.has(dep)) ?? false;
|
|
1305
|
+
if (hasSkippedDep) {
|
|
1306
|
+
const skippedDeps = result.stage.deps?.filter((dep) => skippedTaskIds.has(dep)) ?? [];
|
|
1307
|
+
const msg = `Task ${taskId} depends on skipped tasks: ${skippedDeps.join(", ")}`;
|
|
1308
|
+
allWarnings.push(`SKIPPING: ${msg}`);
|
|
1309
|
+
skippedTaskIds.add(taskId);
|
|
1310
|
+
skippedTasks.push({ taskId, reason: "dependsOnSkipped", message: msg });
|
|
1311
|
+
result.skipped = true;
|
|
1312
|
+
result.stage = null;
|
|
1313
|
+
changed = true;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
for (const [_taskId, result] of mappingResults) {
|
|
1318
|
+
if (result.stage && !result.skipped) {
|
|
1319
|
+
if (result.stage.deps) {
|
|
1320
|
+
result.stage.deps = result.stage.deps.filter((dep) => !skippedTaskIds.has(dep));
|
|
1321
|
+
}
|
|
1322
|
+
stages.push(result.stage);
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
return { stages, skippedTaskIds, skippedTasks, warnings: allWarnings, errors: allErrors };
|
|
1326
|
+
}
|
|
1327
|
+
async function collectTasksWithUnfilledSpecMarkers(tasks) {
|
|
1328
|
+
const taskIds = [];
|
|
1329
|
+
for (const task of tasks) {
|
|
1330
|
+
const body = await readTaskBody(task.id);
|
|
1331
|
+
if (hasUnfilledMarkers(body.rawBody || body.description || "")) {
|
|
1332
|
+
taskIds.push(task.id);
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
return taskIds;
|
|
1336
|
+
}
|
|
1337
|
+
async function loadSprintData(sprintId) {
|
|
1338
|
+
const planningRoot = getPlanningRoot();
|
|
1339
|
+
const sprintPath = path.join(getBucketPathByKind("sprint", planningRoot), `${sprintId}.md`);
|
|
1340
|
+
try {
|
|
1341
|
+
const { frontMatter } = await readMarkdownFile(sprintPath);
|
|
1342
|
+
return {
|
|
1343
|
+
taskIds: frontMatter.taskIds || [],
|
|
1344
|
+
completedTaskIds: frontMatter.completedTaskIds || []
|
|
1345
|
+
};
|
|
1346
|
+
} catch (_error) {
|
|
1347
|
+
try {
|
|
1348
|
+
const archivedRoot = getBucketArchivePathByKind("sprint", planningRoot);
|
|
1349
|
+
const files = await listMarkdownFilesRecursive(archivedRoot);
|
|
1350
|
+
const file = files.find((p) => path.basename(p) === `${sprintId}.md`);
|
|
1351
|
+
if (!file) {
|
|
1352
|
+
throw new Error("not found");
|
|
1353
|
+
}
|
|
1354
|
+
const { frontMatter } = await readMarkdownFile(file);
|
|
1355
|
+
return {
|
|
1356
|
+
taskIds: frontMatter.taskIds || [],
|
|
1357
|
+
completedTaskIds: frontMatter.completedTaskIds || []
|
|
1358
|
+
};
|
|
1359
|
+
} catch {
|
|
1360
|
+
throw new Error(`Sprint not found: ${sprintId}`);
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
async function validateAndLoadTasks(taskIds, strict) {
|
|
1365
|
+
const tasks = [];
|
|
1366
|
+
const warnings = [];
|
|
1367
|
+
const errors = [];
|
|
1368
|
+
const skippedIds = [];
|
|
1369
|
+
const archivedIds = [];
|
|
1370
|
+
const doneIds = [];
|
|
1371
|
+
const skippedTasks = [];
|
|
1372
|
+
for (const taskId of taskIds) {
|
|
1373
|
+
try {
|
|
1374
|
+
const { yaml: task, isArchived } = await getTask(taskId, { includeArchive: true });
|
|
1375
|
+
if (isArchived) {
|
|
1376
|
+
const msg = `Task ${taskId} is archived (already completed).`;
|
|
1377
|
+
if (strict) {
|
|
1378
|
+
errors.push(msg);
|
|
1379
|
+
} else {
|
|
1380
|
+
warnings.push(`SKIPPING: ${msg}`);
|
|
1381
|
+
skippedIds.push(taskId);
|
|
1382
|
+
archivedIds.push(taskId);
|
|
1383
|
+
skippedTasks.push({ taskId, reason: "archived", message: msg });
|
|
1384
|
+
}
|
|
1385
|
+
continue;
|
|
1386
|
+
}
|
|
1387
|
+
if (task.status === "done") {
|
|
1388
|
+
const msg = `Task ${taskId} is already done (status: done).`;
|
|
1389
|
+
if (strict) {
|
|
1390
|
+
errors.push(msg);
|
|
1391
|
+
} else {
|
|
1392
|
+
warnings.push(`SKIPPING: ${msg}`);
|
|
1393
|
+
skippedIds.push(taskId);
|
|
1394
|
+
doneIds.push(taskId);
|
|
1395
|
+
skippedTasks.push({ taskId, reason: "done", message: msg });
|
|
1396
|
+
}
|
|
1397
|
+
continue;
|
|
1398
|
+
}
|
|
1399
|
+
tasks.push(task);
|
|
1400
|
+
} catch {
|
|
1401
|
+
const isBacklogId = taskId.startsWith("backlog-") || taskId.includes("backlog");
|
|
1402
|
+
if (isBacklogId) {
|
|
1403
|
+
const msg = `Task ${taskId} looks like a backlog ID without a task file. Use 'sprint add-task --split' to create task files.`;
|
|
1404
|
+
if (strict) {
|
|
1405
|
+
errors.push(msg);
|
|
1406
|
+
} else {
|
|
1407
|
+
warnings.push(`SKIPPING: ${msg}`);
|
|
1408
|
+
skippedIds.push(taskId);
|
|
1409
|
+
skippedTasks.push({ taskId, reason: "backlogId", message: msg });
|
|
1410
|
+
}
|
|
1411
|
+
} else {
|
|
1412
|
+
const msg = `Task file not found: ${taskId}`;
|
|
1413
|
+
if (strict) {
|
|
1414
|
+
errors.push(msg);
|
|
1415
|
+
} else {
|
|
1416
|
+
warnings.push(`SKIPPING: ${msg}`);
|
|
1417
|
+
skippedIds.push(taskId);
|
|
1418
|
+
skippedTasks.push({ taskId, reason: "missing", message: msg });
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
return { tasks, warnings, errors, skippedIds, archivedIds, doneIds, skippedTasks };
|
|
1424
|
+
}
|
|
1425
|
+
async function writeWorkflowYaml(workflow, sprintId, workflowId) {
|
|
1426
|
+
let filePath;
|
|
1427
|
+
if (workflowId) {
|
|
1428
|
+
filePath = getWorkflowYamlPath(workflowId);
|
|
1429
|
+
const artifactDir = path.dirname(filePath);
|
|
1430
|
+
await fs.mkdir(artifactDir, { recursive: true });
|
|
1431
|
+
} else {
|
|
1432
|
+
const planningRoot = getPlanningRoot();
|
|
1433
|
+
const workflowsDir = path.join(planningRoot, ".poetic", "workflows");
|
|
1434
|
+
await fs.mkdir(workflowsDir, { recursive: true });
|
|
1435
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
1436
|
+
const filename = `sprint-${sprintId}-${timestamp}.yaml`;
|
|
1437
|
+
filePath = path.join(workflowsDir, filename);
|
|
1438
|
+
}
|
|
1439
|
+
const yamlContent = yaml.dump(workflow, {
|
|
1440
|
+
indent: 2,
|
|
1441
|
+
lineWidth: 120,
|
|
1442
|
+
noRefs: true
|
|
1443
|
+
});
|
|
1444
|
+
await fs.writeFile(filePath, yamlContent, "utf-8");
|
|
1445
|
+
return filePath;
|
|
1446
|
+
}
|
|
1447
|
+
async function generateSprintWorkflow(options) {
|
|
1448
|
+
const {
|
|
1449
|
+
sprintId,
|
|
1450
|
+
taskIds: specificTaskIds,
|
|
1451
|
+
provider,
|
|
1452
|
+
strict = false,
|
|
1453
|
+
competitionOverrides,
|
|
1454
|
+
acceptIncompleteSpec = false
|
|
1455
|
+
} = options;
|
|
1456
|
+
const warnings = [];
|
|
1457
|
+
const errors = [];
|
|
1458
|
+
const skippedTaskIds = [];
|
|
1459
|
+
const skippedTasks = [];
|
|
1460
|
+
let sprintTaskIds;
|
|
1461
|
+
let sprintCompletedTaskIds;
|
|
1462
|
+
try {
|
|
1463
|
+
const sprint = await loadSprintData(sprintId);
|
|
1464
|
+
sprintTaskIds = specificTaskIds ?? sprint.taskIds;
|
|
1465
|
+
sprintCompletedTaskIds = sprint.completedTaskIds;
|
|
1466
|
+
} catch (error) {
|
|
1467
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
1468
|
+
return {
|
|
1469
|
+
workflow: null,
|
|
1470
|
+
yamlPath: "",
|
|
1471
|
+
warnings: [],
|
|
1472
|
+
errors: [msg],
|
|
1473
|
+
skippedTaskIds: [],
|
|
1474
|
+
skippedTasks: []
|
|
1475
|
+
};
|
|
1476
|
+
}
|
|
1477
|
+
if (sprintTaskIds.length === 0) {
|
|
1478
|
+
const msg = "Sprint has no tasks. Add tasks with `sprint add-task` first.";
|
|
1479
|
+
return {
|
|
1480
|
+
workflow: null,
|
|
1481
|
+
yamlPath: "",
|
|
1482
|
+
warnings: [],
|
|
1483
|
+
errors: [msg],
|
|
1484
|
+
skippedTaskIds: [],
|
|
1485
|
+
skippedTasks: []
|
|
1486
|
+
};
|
|
1487
|
+
}
|
|
1488
|
+
const loadResult = await validateAndLoadTasks(sprintTaskIds, strict);
|
|
1489
|
+
warnings.push(...loadResult.warnings);
|
|
1490
|
+
errors.push(...loadResult.errors);
|
|
1491
|
+
skippedTaskIds.push(...loadResult.skippedIds);
|
|
1492
|
+
skippedTasks.push(...loadResult.skippedTasks);
|
|
1493
|
+
for (const id of loadResult.archivedIds) {
|
|
1494
|
+
if (!skippedTaskIds.includes(id)) {
|
|
1495
|
+
skippedTaskIds.push(id);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
if (strict && errors.length > 0) {
|
|
1499
|
+
return { workflow: null, yamlPath: "", warnings, errors, skippedTaskIds, skippedTasks };
|
|
1500
|
+
}
|
|
1501
|
+
const incompleteSpecTaskIds = await collectTasksWithUnfilledSpecMarkers(loadResult.tasks);
|
|
1502
|
+
if (incompleteSpecTaskIds.length > 0) {
|
|
1503
|
+
const message = `Task spec(s) contain unfilled <<<FILL>>> placeholders: ${incompleteSpecTaskIds.join(", ")}`;
|
|
1504
|
+
if (!acceptIncompleteSpec) {
|
|
1505
|
+
return {
|
|
1506
|
+
workflow: null,
|
|
1507
|
+
yamlPath: "",
|
|
1508
|
+
warnings,
|
|
1509
|
+
errors: [
|
|
1510
|
+
`${message}. Complete the task specs or rerun with --accept-incomplete-spec to proceed anyway.`
|
|
1511
|
+
],
|
|
1512
|
+
skippedTaskIds,
|
|
1513
|
+
skippedTasks
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1516
|
+
warnings.push(`${message}; continuing because --accept-incomplete-spec was provided.`);
|
|
1517
|
+
}
|
|
1518
|
+
let taskTypeContext = null;
|
|
1519
|
+
try {
|
|
1520
|
+
taskTypeContext = await buildTaskTypeContext(
|
|
1521
|
+
await TaskTypeRegistry.load({ cwd: process.cwd() })
|
|
1522
|
+
);
|
|
1523
|
+
} catch (error) {
|
|
1524
|
+
warnings.push(
|
|
1525
|
+
`Task types disabled (failed to load registry): ${error instanceof Error ? error.message : String(error)}`
|
|
1526
|
+
);
|
|
1527
|
+
}
|
|
1528
|
+
const defaultJudgeType = resolveJudgeType(void 0, process.cwd()).value;
|
|
1529
|
+
const completedTaskIds = /* @__PURE__ */ new Set([...loadResult.archivedIds, ...loadResult.doneIds]);
|
|
1530
|
+
for (const id of sprintCompletedTaskIds) completedTaskIds.add(id);
|
|
1531
|
+
const sprintTaskSet = new Set(sprintTaskIds.filter((id) => !completedTaskIds.has(id)));
|
|
1532
|
+
const buildResult = await buildWorkflowStages(
|
|
1533
|
+
loadResult.tasks,
|
|
1534
|
+
sprintTaskSet,
|
|
1535
|
+
completedTaskIds,
|
|
1536
|
+
strict,
|
|
1537
|
+
new Set(loadResult.skippedIds),
|
|
1538
|
+
provider,
|
|
1539
|
+
competitionOverrides,
|
|
1540
|
+
taskTypeContext,
|
|
1541
|
+
defaultJudgeType
|
|
1542
|
+
);
|
|
1543
|
+
warnings.push(...buildResult.warnings);
|
|
1544
|
+
errors.push(...buildResult.errors);
|
|
1545
|
+
for (const id of buildResult.skippedTaskIds) {
|
|
1546
|
+
if (!skippedTaskIds.includes(id)) {
|
|
1547
|
+
skippedTaskIds.push(id);
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
for (const s of buildResult.skippedTasks) {
|
|
1551
|
+
if (!skippedTasks.some((existing) => existing.taskId === s.taskId)) {
|
|
1552
|
+
skippedTasks.push(s);
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
if (strict && errors.length > 0) {
|
|
1556
|
+
return { workflow: null, yamlPath: "", warnings, errors, skippedTaskIds, skippedTasks };
|
|
1557
|
+
}
|
|
1558
|
+
if (buildResult.stages.length === 0) {
|
|
1559
|
+
const allSkippedMsg = `All ${skippedTaskIds.length} task(s) were skipped. Nothing to execute.`;
|
|
1560
|
+
if (strict) {
|
|
1561
|
+
return {
|
|
1562
|
+
workflow: null,
|
|
1563
|
+
yamlPath: "",
|
|
1564
|
+
warnings,
|
|
1565
|
+
errors: [...errors, allSkippedMsg],
|
|
1566
|
+
skippedTaskIds,
|
|
1567
|
+
skippedTasks
|
|
1568
|
+
};
|
|
1569
|
+
}
|
|
1570
|
+
return {
|
|
1571
|
+
workflow: null,
|
|
1572
|
+
yamlPath: "",
|
|
1573
|
+
warnings: [...warnings, allSkippedMsg],
|
|
1574
|
+
errors: [],
|
|
1575
|
+
skippedTaskIds,
|
|
1576
|
+
skippedTasks
|
|
1577
|
+
};
|
|
1578
|
+
}
|
|
1579
|
+
const workflow = {
|
|
1580
|
+
name: `Sprint: ${sprintId}`,
|
|
1581
|
+
stages: buildResult.stages,
|
|
1582
|
+
strict: {
|
|
1583
|
+
// Warn-first by default: allow stages to make ripple edits without hard-failing.
|
|
1584
|
+
allowlistMode: "warn",
|
|
1585
|
+
// Hard safety rail: prevent accidental high-impact edits unless explicitly allowlisted.
|
|
1586
|
+
denylist: DEFAULT_SPRINT_WORKFLOW_DENYLIST
|
|
1587
|
+
},
|
|
1588
|
+
git: {
|
|
1589
|
+
commitStrategy: "pass-only",
|
|
1590
|
+
// Default to Run → Review → Integrate: preserve the integration branch/worktree.
|
|
1591
|
+
historyCleanup: "keep-all",
|
|
1592
|
+
skipHooksOnIntermediate: true
|
|
1593
|
+
}
|
|
1594
|
+
};
|
|
1595
|
+
if (provider) {
|
|
1596
|
+
for (const stage of workflow.stages) {
|
|
1597
|
+
if (!stage.provider) {
|
|
1598
|
+
stage.provider = provider;
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
const stampedWorkflow = applyExecutionPolicyToGeneratedWorkflow(workflow, {
|
|
1603
|
+
cliProviderOverride: provider,
|
|
1604
|
+
warnings
|
|
1605
|
+
});
|
|
1606
|
+
let yamlPath = "";
|
|
1607
|
+
if (!options.dryRun) {
|
|
1608
|
+
yamlPath = await writeWorkflowYaml(stampedWorkflow, sprintId, options.workflowId);
|
|
1609
|
+
}
|
|
1610
|
+
return {
|
|
1611
|
+
workflow: stampedWorkflow,
|
|
1612
|
+
yamlPath,
|
|
1613
|
+
warnings,
|
|
1614
|
+
errors,
|
|
1615
|
+
skippedTaskIds,
|
|
1616
|
+
skippedTasks
|
|
1617
|
+
};
|
|
1618
|
+
}
|
|
1619
|
+
function applyExecutionPolicyToGeneratedWorkflow(workflow, options) {
|
|
1620
|
+
const existingStamp = workflow.metadata?.executionPolicy;
|
|
1621
|
+
if (existingStamp !== void 0) {
|
|
1622
|
+
if (isCurrentExecutionPolicyWorkflow(workflow)) return workflow;
|
|
1623
|
+
throw new Error(
|
|
1624
|
+
`Generated workflow has a stale or malformed execution-policy stamp (${describeExecutionPolicyStampMismatch(existingStamp)}); regenerate the workflow.`
|
|
1625
|
+
);
|
|
1626
|
+
}
|
|
1627
|
+
const cliOverrides = {
|
|
1628
|
+
executorProvider: options.cliProviderOverride,
|
|
1629
|
+
orchestratorProvider: options.orchestratorOverrideIsExplicit ? options.orchestratorProviderOverride : void 0,
|
|
1630
|
+
orchestratorModel: options.orchestratorOverrideIsExplicit ? options.orchestratorModelOverride : void 0
|
|
1631
|
+
};
|
|
1632
|
+
const roles = resolveExecutionRoles({
|
|
1633
|
+
cwd: process.cwd(),
|
|
1634
|
+
cli: Object.values(cliOverrides).some(Boolean) ? cliOverrides : void 0,
|
|
1635
|
+
additionalReviewerExcludes: collectCompetitionExecutorProviders(workflow),
|
|
1636
|
+
effectiveOrchestrator: options.orchestratorProviderOverride && !options.orchestratorOverrideIsExplicit ? {
|
|
1637
|
+
provider: options.orchestratorProviderOverride,
|
|
1638
|
+
model: options.orchestratorModelOverride,
|
|
1639
|
+
sourcePath: "artifact:executionDefaults"
|
|
1640
|
+
} : void 0
|
|
1641
|
+
});
|
|
1642
|
+
const hasTaskExecutionStage = workflow.stages.some((stage) => {
|
|
1643
|
+
const stageType = stage.type ?? "standard";
|
|
1644
|
+
if (stageType === "standard" || stageType === "competition") return true;
|
|
1645
|
+
return stage.seededPlan?.subStages.some((subStage) => {
|
|
1646
|
+
const subStageType = subStage.type ?? "standard";
|
|
1647
|
+
return subStageType === "standard" || subStageType === "competition";
|
|
1648
|
+
});
|
|
1649
|
+
});
|
|
1650
|
+
const sameAsExecutor = roles.reviewAssurance?.executorSeparation === "same-as-executor" || roles.sameVendorReview;
|
|
1651
|
+
if (isExecutionPolicyEngaged(roles) && sameAsExecutor && hasTaskExecutionStage) {
|
|
1652
|
+
throw new Error(
|
|
1653
|
+
`Execution policy requires executor separation (reviewer provider != executor provider(s)), but reviewer resolved to executor provider '${roles.executor.provider.value}'. Configure another reviewer provider (reviewer may match the orchestrator), or set the reviewer gate to off.`
|
|
1654
|
+
);
|
|
1655
|
+
}
|
|
1656
|
+
return applyExecutionPolicy(workflow, roles, {
|
|
1657
|
+
cliProviderOverride: options.cliProviderOverride,
|
|
1658
|
+
onNotice: (message) => options.warnings.push(message)
|
|
1659
|
+
});
|
|
1660
|
+
}
|
|
1661
|
+
function collectCompetitionExecutorProviders(workflow) {
|
|
1662
|
+
const providers = /* @__PURE__ */ new Set();
|
|
1663
|
+
const visit = (stage) => {
|
|
1664
|
+
if (stage.type === "competition") {
|
|
1665
|
+
for (const variant of stage.competition?.variants ?? []) {
|
|
1666
|
+
const provider = variant.provider?.trim();
|
|
1667
|
+
if (provider) providers.add(provider);
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
if (stage.type === "orchestrator" && stage.seededPlan) {
|
|
1671
|
+
for (const subStage of stage.seededPlan.subStages) visit(subStage);
|
|
1672
|
+
}
|
|
1673
|
+
};
|
|
1674
|
+
for (const stage of workflow.stages) visit(stage);
|
|
1675
|
+
return [...providers];
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
export {
|
|
1679
|
+
FUSION_DEFAULT_ACTIVITIES,
|
|
1680
|
+
getDefaultCompetitionVariantsForProvider,
|
|
1681
|
+
resolveTaskTypeFromCandidates,
|
|
1682
|
+
resolveTaskTypeWithDeclaration,
|
|
1683
|
+
resolveTaskTypeForText,
|
|
1684
|
+
resolveStageContract,
|
|
1685
|
+
createDefaultCompetitionConfig,
|
|
1686
|
+
generateSprintWorkflow,
|
|
1687
|
+
applyExecutionPolicyToGeneratedWorkflow
|
|
1688
|
+
};
|
|
1689
|
+
//# sourceMappingURL=chunk-GFGYB2ZU.js.map
|