@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,2373 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ANCHORED_CHAT_FEATURE_ENV,
|
|
3
|
+
isAnchoredChatEnabled,
|
|
4
|
+
isEnforcedAnchorProvider
|
|
5
|
+
} from "./chunk-RDFRCT64.js";
|
|
6
|
+
import {
|
|
7
|
+
DefaultPricingTable,
|
|
8
|
+
MAX_BUILD_INTENT_LENGTH,
|
|
9
|
+
estimateTaskCost,
|
|
10
|
+
explainBuildRoute,
|
|
11
|
+
resolvePlanExecuteCliBlockerMode
|
|
12
|
+
} from "./chunk-Z2CUQDAR.js";
|
|
13
|
+
import {
|
|
14
|
+
ACTIVE_RUN_STATUSES,
|
|
15
|
+
isActiveRunStatus,
|
|
16
|
+
normalizeRunStatus
|
|
17
|
+
} from "./chunk-44N5WZZH.js";
|
|
18
|
+
import {
|
|
19
|
+
buildCompetitionHealthSnapshot,
|
|
20
|
+
classifyRunHealth,
|
|
21
|
+
summarizeRunHealth
|
|
22
|
+
} from "./chunk-KM3F7SYE.js";
|
|
23
|
+
import {
|
|
24
|
+
extractTitleFromPrompt
|
|
25
|
+
} from "./chunk-F5JO7HAS.js";
|
|
26
|
+
import {
|
|
27
|
+
sanitizeSynthesisArtifactForPersistence
|
|
28
|
+
} from "./chunk-GG6KJYW6.js";
|
|
29
|
+
import {
|
|
30
|
+
resolveConfig
|
|
31
|
+
} from "./chunk-XPU2XADL.js";
|
|
32
|
+
import {
|
|
33
|
+
formatProviderNotReadyMessage,
|
|
34
|
+
formatProviderSetupGuidance,
|
|
35
|
+
selectReadyProvider
|
|
36
|
+
} from "./chunk-AURFMVCD.js";
|
|
37
|
+
import {
|
|
38
|
+
detectSandboxBoundaryAttestation,
|
|
39
|
+
isSandboxBoundaryAccepted,
|
|
40
|
+
resolveSandboxBoundaryPolicy,
|
|
41
|
+
willSandboxBeActive
|
|
42
|
+
} from "./chunk-PCAGC5MR.js";
|
|
43
|
+
import {
|
|
44
|
+
getCurrentBranch,
|
|
45
|
+
isProtectedPipelineBranch
|
|
46
|
+
} from "./chunk-XQD2B6BB.js";
|
|
47
|
+
import {
|
|
48
|
+
POETIC_TUI_TIMING,
|
|
49
|
+
readEnv
|
|
50
|
+
} from "./chunk-5DLKYTQX.js";
|
|
51
|
+
|
|
52
|
+
// src/cli/tui/actions.ts
|
|
53
|
+
import path2 from "path";
|
|
54
|
+
|
|
55
|
+
// package.json
|
|
56
|
+
var package_default = {
|
|
57
|
+
name: "@poetic-ai/poetic",
|
|
58
|
+
version: "1.42.0",
|
|
59
|
+
description: "AI orchestration CLI that runs competing provider variants in parallel and synthesizes the best solution",
|
|
60
|
+
type: "module",
|
|
61
|
+
main: "dist/index.js",
|
|
62
|
+
bin: {
|
|
63
|
+
poetic: "dist/entry.js"
|
|
64
|
+
},
|
|
65
|
+
scripts: {
|
|
66
|
+
preinstall: "node ./scripts/preinstall-node-check.mjs",
|
|
67
|
+
"pretest:native": "tsx scripts/pretest-version-check.ts",
|
|
68
|
+
pretest: "npm run -s pretest:native",
|
|
69
|
+
"pretest:all": "npm run -s pretest:native",
|
|
70
|
+
"pretest:unit": "npm run -s pretest:native",
|
|
71
|
+
"pretest:integration": "npm run -s pretest:native",
|
|
72
|
+
"pretest:integration:hosted": "npm run -s pretest:native",
|
|
73
|
+
"pretest:workflow-contracts": "npm run -s pretest:native",
|
|
74
|
+
"pretest:integration:providers": "npm run -s pretest:native",
|
|
75
|
+
"pretest:integration:orchestrator": "npm run -s pretest:native",
|
|
76
|
+
"pretest:integration:cli": "npm run -s pretest:native",
|
|
77
|
+
"pretest:regression": "npm run -s pretest:native",
|
|
78
|
+
"pretest:core": "npm run -s pretest:native",
|
|
79
|
+
"pretest:config": "npm run -s pretest:native",
|
|
80
|
+
"pretest:smoke": "npm run -s pretest:native",
|
|
81
|
+
"pretest:judge": "npm run -s pretest:native",
|
|
82
|
+
"pretest:installer": "npm run -s pretest:native",
|
|
83
|
+
"pretest:providers": "npm run -s pretest:native",
|
|
84
|
+
"pretest:providers:shared": "npm run -s pretest:native",
|
|
85
|
+
"pretest:provider:claude": "npm run -s pretest:native",
|
|
86
|
+
"pretest:provider:copilot": "npm run -s pretest:native",
|
|
87
|
+
"pretest:provider:cursor": "npm run -s pretest:native",
|
|
88
|
+
"pretest:provider:codex": "npm run -s pretest:native",
|
|
89
|
+
"pretest:provider:gemini": "npm run -s pretest:native",
|
|
90
|
+
"pretest:provider:opencode": "npm run -s pretest:native",
|
|
91
|
+
"pretest:orchestrator": "npm run -s pretest:native",
|
|
92
|
+
"pretest:prompts": "npm run -s pretest:native",
|
|
93
|
+
"pretest:telemetry": "npm run -s pretest:native",
|
|
94
|
+
"pretest:reliability": "npm run -s pretest:native",
|
|
95
|
+
"pretest:automation": "npm run -s pretest:native",
|
|
96
|
+
"pretest:quality": "npm run -s pretest:native",
|
|
97
|
+
"pretest:cli": "npm run -s pretest:native",
|
|
98
|
+
"pretest:cli:unit": "npm run -s pretest:native",
|
|
99
|
+
"pretest:execution": "npm run -s pretest:native",
|
|
100
|
+
"pretest:scripts": "npm run -s pretest:native",
|
|
101
|
+
"pretest:validation": "npm run -s pretest:native",
|
|
102
|
+
"pretest:coverage": "npm run -s pretest:native",
|
|
103
|
+
"pretest:coverage:partial": "npm run -s pretest:native",
|
|
104
|
+
"pretest:coverage:all": "npm run -s pretest:native",
|
|
105
|
+
"pretest:stress": "npm run -s pretest:native",
|
|
106
|
+
"pretest:planning": "npm run -s pretest:native",
|
|
107
|
+
"pretest:planning:unit": "npm run -s pretest:native",
|
|
108
|
+
"pretest:core:testing": "npm run -s pretest:native",
|
|
109
|
+
"preplanning:validate": "npm run -s pretest:native",
|
|
110
|
+
"pretest:e2e": "npm run -s pretest:native && npm run -s build",
|
|
111
|
+
"pretest:stabilized": "npm run -s pretest:native",
|
|
112
|
+
"pretest:extended": "npm run -s pretest:native",
|
|
113
|
+
"pretest:dogfood": "npm run -s pretest:native",
|
|
114
|
+
"pretest:changed": "npm run -s pretest:native",
|
|
115
|
+
"pretest:changed:gate": "npm run -s pretest:native",
|
|
116
|
+
"pretest:changed:inventory": "npm run -s pretest:native",
|
|
117
|
+
"pretest:neutrality:sentinel": "npm run -s pretest:native",
|
|
118
|
+
"preci:stress": "npm run -s pretest:native",
|
|
119
|
+
"check:config-reads": "tsx scripts/check-config-direct-reads.ts",
|
|
120
|
+
"check:architecture-boundaries": "tsx scripts/check-architecture-boundaries.ts",
|
|
121
|
+
"check:no-decorative-glyphs": "tsx scripts/check-no-decorative-glyphs.ts",
|
|
122
|
+
"check:neutrality": "tsx scripts/check-neutrality.ts",
|
|
123
|
+
"check:git-exec": "tsx scripts/check-git-exec.ts",
|
|
124
|
+
"check:hotspot-growth": "node scripts/check-hotspot-growth.mjs",
|
|
125
|
+
"check:recursive-rm": "tsx scripts/check-recursive-rm.ts",
|
|
126
|
+
"check:no-outcome-promotion": "tsx scripts/check-no-outcome-promotion.ts",
|
|
127
|
+
"check:pr-hygiene": "node scripts/check-pr-hygiene.mjs",
|
|
128
|
+
"check:tracked-paths": "node scripts/check-tracked-paths.mjs",
|
|
129
|
+
"check:provider-quirks:blocking": "tsx scripts/check-provider-quirks.ts",
|
|
130
|
+
"check:telemetry-integrity": "tsx scripts/check-telemetry-integrity.ts",
|
|
131
|
+
"check:processes": "node dist/entry.js processes --health --json",
|
|
132
|
+
"check:generated": "node scripts/check-generated.mjs",
|
|
133
|
+
prebuild: "node scripts/generate-provider-json.js && tsx scripts/generate-judge-scoring-schema.ts && tsx scripts/generate-config-schema.ts",
|
|
134
|
+
build: "tsup --config tsup.config.ts",
|
|
135
|
+
postbuild: "node scripts/copy-build-assets.mjs",
|
|
136
|
+
rebuild: "./scripts/build-poetic.sh",
|
|
137
|
+
"add-provider": "tsx scripts/add-provider.ts",
|
|
138
|
+
"providers:generate": "node --import tsx ./src/cli/commands/providers-registry.ts generate",
|
|
139
|
+
"providers:validate": "node --import tsx ./src/cli/commands/providers-registry.ts validate",
|
|
140
|
+
"providers:update-yaml": "tsx scripts/update-providers-yaml.ts",
|
|
141
|
+
"generate:provider-types": "node --import tsx ./scripts/generate-provider-types.ts",
|
|
142
|
+
"generate:config-schema": "node --import tsx ./scripts/generate-config-schema.ts",
|
|
143
|
+
"templates:verify": "node ./scripts/verify-templates.mjs",
|
|
144
|
+
dev: "tsx watch src/cli/entry.ts",
|
|
145
|
+
"dev:once": "node --import tsx src/cli/entry.ts",
|
|
146
|
+
cli: "node --import tsx src/cli/entry.ts",
|
|
147
|
+
test: "bash scripts/test-guard.sh npm run test:unit",
|
|
148
|
+
"test:all": "POETIC_PREFLIGHT_DONE=1 npm run test:unit && POETIC_PREFLIGHT_DONE=1 npm run test:integration && POETIC_PREFLIGHT_DONE=1 npm run test:regression",
|
|
149
|
+
"test:unit": "node scripts/test-unit-inventory.mjs",
|
|
150
|
+
"test:integration": "node scripts/dynamic-node-options.mjs vitest run tests/integration",
|
|
151
|
+
"test:integration:hosted": "node scripts/run-hosted-integration.mjs",
|
|
152
|
+
"test:workflow-contracts": "node scripts/dynamic-node-options.mjs vitest run tests/unit/scripts/automation-workflows-yaml.test.ts tests/unit/scripts/release-gate-contract.test.ts",
|
|
153
|
+
"test:integration:providers": "node scripts/dynamic-node-options.mjs vitest run tests/integration/providers",
|
|
154
|
+
"test:integration:orchestrator": "node scripts/dynamic-node-options.mjs vitest run tests/integration/orchestrator",
|
|
155
|
+
"test:integration:cli": "node scripts/dynamic-node-options.mjs vitest run tests/integration/cli/",
|
|
156
|
+
"test:regression": "node scripts/dynamic-node-options.mjs vitest run tests/regression",
|
|
157
|
+
"test:core": "POETIC_PREFLIGHT_DONE=1 npm run test:telemetry && POETIC_PREFLIGHT_DONE=1 npm run test:automation && POETIC_PREFLIGHT_DONE=1 npm run test:quality && POETIC_PREFLIGHT_DONE=1 npm run test:planning:unit && POETIC_PREFLIGHT_DONE=1 npm run test:core:testing",
|
|
158
|
+
"test:config": "node scripts/dynamic-node-options.mjs vitest run tests/unit/core/config",
|
|
159
|
+
"test:installer": "bash tests/installer/run-all.sh",
|
|
160
|
+
"dogfood:journey": "bash scripts/release/dogfood-real-providers.sh",
|
|
161
|
+
"compete-streak": "tsx scripts/compete-streak/run.ts",
|
|
162
|
+
"release:pack-smoke": "bash scripts/release/pack-and-smoke.sh",
|
|
163
|
+
"release:local-dist-canary": "node scripts/release/local-dist-canary.mjs",
|
|
164
|
+
"release:artifacts": "bash scripts/release/prepare-artifacts.sh",
|
|
165
|
+
"release:dependency-report": "node scripts/release/sbom-license-report.mjs --out-dir .poetic/tmp/release",
|
|
166
|
+
"release:license-report": "npm run -s release:dependency-report",
|
|
167
|
+
"release:secret-scan": "bash scripts/release/secret-scan.sh",
|
|
168
|
+
"release:secret-scan:artifact": "bash scripts/release/secret-scan.sh --artifact",
|
|
169
|
+
"release:gate": "bash scripts/release/run-gate.sh --mode merge",
|
|
170
|
+
"verify:release-gate": "npm run release:gate",
|
|
171
|
+
"release:gate:publish": "bash scripts/release/run-gate.sh --mode publish",
|
|
172
|
+
"release:verify-all": "npm run -s release:gate && npm run -s test:all && npm run -s release:gate:publish && echo '[release:verify-all] CI-only: shrinkwrap generation (release.yml) mutates working tree; POETIC_EXPECT_SHRINKWRAP=1 runs in CI only' && echo '[release:verify-all] Manual extended suites are opt-in: POETIC_RUN_EXTENDED_TESTS=1 npm run -s test:extended'",
|
|
173
|
+
"test:smoke": "node scripts/smoke-tests/run.mjs",
|
|
174
|
+
"smoke-test": "npm run -s test:smoke",
|
|
175
|
+
"test:sprint-smoke": "tsx scripts/sprint-smoke.ts",
|
|
176
|
+
"test:docs:smoke": "bash scripts/test-docs-smoke.sh",
|
|
177
|
+
"test:providers": "node scripts/dynamic-node-options.mjs vitest run tests/unit/core/providers",
|
|
178
|
+
"test:providers:shared": "node scripts/dynamic-node-options.mjs vitest run tests/unit/core/providers/shared",
|
|
179
|
+
"test:provider:claude": "node scripts/dynamic-node-options.mjs vitest run tests/unit/core/providers/claude",
|
|
180
|
+
"test:provider:copilot": "node scripts/dynamic-node-options.mjs vitest run tests/unit/core/providers/copilot",
|
|
181
|
+
"test:provider:cursor": "node scripts/dynamic-node-options.mjs vitest run tests/unit/core/providers/cursor",
|
|
182
|
+
"test:provider:codex": "node scripts/dynamic-node-options.mjs vitest run tests/unit/core/providers/codex",
|
|
183
|
+
"test:provider:gemini": "node scripts/dynamic-node-options.mjs vitest run tests/unit/core/providers/gemini",
|
|
184
|
+
"test:provider:opencode": "node scripts/dynamic-node-options.mjs vitest run tests/unit/core/providers/opencode",
|
|
185
|
+
"test:orchestrator": "node scripts/dynamic-node-options.mjs vitest run tests/unit/orchestrator",
|
|
186
|
+
"test:judge": "node scripts/dynamic-node-options.mjs vitest run tests/unit/orchestrator/judge-verdict-shipping-invariants.test.ts tests/unit/orchestrator/judge-fallback-selector.test.ts tests/unit/orchestrator/matrix-authority.test.ts tests/unit/orchestrator/judge-coordinator.test.ts tests/unit/orchestrator/winner-verification.test.ts tests/unit/core/verification/known-pre-existing-failures.test.ts tests/unit/core/judge/llm-winner-authority.test.ts tests/unit/core/judge/no-post-llm-mutation.test.ts tests/unit/core/judge/winner-from-scores.test.ts tests/unit/core/judge/ai-judge-schema-retry.test.ts",
|
|
187
|
+
"test:telemetry": "node scripts/dynamic-node-options.mjs vitest run tests/unit/telemetry src/telemetry/__tests__ src/telemetry/variants/__tests__",
|
|
188
|
+
"test:reliability": 'node scripts/dynamic-node-options.mjs vitest run tests/unit/cli/commands/telemetry-reliability.test.ts && node scripts/dynamic-node-options.mjs vitest run src/orchestrator/__tests__/basic-competition-master.test.ts -t "provider chaos canary" && node scripts/dynamic-node-options.mjs vitest run src/orchestrator/__tests__/basic-competition-master.test.ts -t "complex multi-file synthesis fallback"',
|
|
189
|
+
"test:automation:preflight": "node scripts/dynamic-node-options.mjs vitest run --silent=passed-only tests/unit/automation/flywheel-preflight.test.ts",
|
|
190
|
+
"test:automation": "node scripts/dynamic-node-options.mjs vitest run --maxWorkers=1 --no-file-parallelism --silent=passed-only tests/unit/automation --exclude tests/unit/automation/flywheel-preflight.test.ts && npm run -s test:automation:preflight",
|
|
191
|
+
"test:quality": "node scripts/dynamic-node-options.mjs vitest run tests/unit/quality",
|
|
192
|
+
"test:planning:unit": "node scripts/dynamic-node-options.mjs vitest run --maxWorkers=1 --no-file-parallelism tests/unit/planning src/planning/__tests__",
|
|
193
|
+
"test:core:testing": "node scripts/dynamic-node-options.mjs vitest run tests/unit/core/memory tests/unit/core/testing",
|
|
194
|
+
"test:prompts": "node scripts/dynamic-node-options.mjs vitest run tests/unit/prompts tests/unit/types tests/unit/utils tests/unit/core/judge/ai-judge-prompt-3bucket-excerpt.test.ts tests/unit/core/judge/criteria-ledger-confidence.test.ts tests/unit/core/judge/winner-from-scores.test.ts tests/unit/core/judge/evidence-proportionality-gate.test.ts tests/unit/core/judge/signal-reliability.test.ts src/prompts src/core/judge/__tests__",
|
|
195
|
+
"test:cli": "node scripts/dynamic-node-options.mjs vitest run tests/integration/providers-registry-cli.test.ts",
|
|
196
|
+
"test:cli:unit": "node scripts/dynamic-node-options.mjs vitest run tests/unit/cli",
|
|
197
|
+
"test:tui-semantic": "node scripts/dynamic-node-options.mjs vitest run tests/unit/cli/tui/e2e/journeys.test.ts tests/unit/cli/tui/ui-state-property.test.ts",
|
|
198
|
+
"test:execution": "node scripts/dynamic-node-options.mjs vitest run tests/unit/core/execution",
|
|
199
|
+
"test:scripts": "node scripts/dynamic-node-options.mjs vitest run tests/unit/scripts",
|
|
200
|
+
"test:validation": "node scripts/dynamic-node-options.mjs vitest run tests/unit/scripts tests/integration/validate-providers-script.test.ts",
|
|
201
|
+
"test:cli:watch": "vitest watch tests/integration/providers-registry-cli.test.ts",
|
|
202
|
+
"test:validation:watch": "vitest watch tests/unit/scripts tests/integration/validate-providers-script.test.ts",
|
|
203
|
+
"test:watch": "vitest watch",
|
|
204
|
+
"test:coverage": "node scripts/dynamic-node-options.mjs vitest run tests/unit/telemetry tests/unit/core tests/unit/orchestrator tests/unit/automation tests/unit/quality tests/unit/types tests/unit/utils --coverage",
|
|
205
|
+
"test:coverage:partial": "node scripts/dynamic-node-options.mjs vitest --config vitest.partial.config.ts run --coverage",
|
|
206
|
+
"test:coverage:all": "node scripts/dynamic-node-options.mjs vitest run --config vitest.partial.config.ts tests/unit/telemetry tests/unit/automation tests/unit/quality tests/unit/planning tests/unit/core/memory/memory-store.test.ts tests/unit/core/providers tests/unit/orchestrator tests/unit/prompts tests/unit/types tests/unit/utils tests/unit/cli tests/unit/core/judge/ai-judge-prompt-3bucket-excerpt.test.ts tests/unit/core/judge/criteria-ledger-confidence.test.ts tests/unit/core/judge/winner-from-scores.test.ts src/prompts src/core/judge/__tests__ tests/integration/providers-registry-cli.test.ts tests/integration/validate-providers-script.test.ts tests/unit/scripts --coverage.enabled",
|
|
207
|
+
"test:stress": "node scripts/dynamic-node-options.mjs node --import tsx tests/stress/memory-stress.js",
|
|
208
|
+
"ci:stress": "NODE_ENV=ci node scripts/dynamic-node-options.mjs node --import tsx tests/stress/memory-stress.js --ci",
|
|
209
|
+
"check:package-docs": "node --import tsx scripts/check-package-docs.mjs",
|
|
210
|
+
postinstall: "node ./scripts/preflight-native.mjs",
|
|
211
|
+
"preflight:native": "node ./scripts/preflight-native.mjs",
|
|
212
|
+
"verify:dist": "tsx scripts/verify-dist.ts",
|
|
213
|
+
"verify:release": "npm run -s verify:dist && node --import tsx ./scripts/verify-release-readiness.ts",
|
|
214
|
+
prepublishOnly: "npm run -s verify:dist",
|
|
215
|
+
"audit:errors": "node --import tsx ./scripts/audit-error-handling.ts --skip-destructive",
|
|
216
|
+
"audit:post-llm-mutations": "node --import tsx ./scripts/audit-post-llm-mutations.ts --strict",
|
|
217
|
+
clean: "rm -rf dist",
|
|
218
|
+
typecheck: "tsc --noEmit -p tsconfig.typecheck-full.json && tsc --noEmit -p tsconfig.tooling.json && tsc --noEmit -p integrations/bb-plugin-poetic/tsconfig.json && tsx scripts/check-test-imports.ts",
|
|
219
|
+
"typecheck:telemetry": "tsc --noEmit -p tsconfig.typecheck.json",
|
|
220
|
+
"typecheck:providers:opencode-glm": "npm run typecheck:providers:opencode",
|
|
221
|
+
"typecheck:providers:opencode": "tsc --noEmit -p tsconfig.providers-opencode.json",
|
|
222
|
+
lint: "biome check --changed --no-errors-on-unmatched",
|
|
223
|
+
"lint:ci": "node scripts/lint-ci.mjs",
|
|
224
|
+
"lint:full": "biome check src/ tests/ scripts/",
|
|
225
|
+
"lint:fix": "biome check --write --changed --no-errors-on-unmatched",
|
|
226
|
+
"lint:fix:full": "biome check --write src/ tests/ scripts/",
|
|
227
|
+
"lint-docs": "node ./scripts/lint-docs-cli.mjs",
|
|
228
|
+
"instructions:lint": "node --import tsx ./scripts/instruction-lint.ts",
|
|
229
|
+
"instructions:surface": "node --import tsx ./scripts/instruction-surface.ts",
|
|
230
|
+
format: "biome format --write src/ tests/ scripts/",
|
|
231
|
+
"format:check": "biome format src/ tests/ scripts/",
|
|
232
|
+
"check:esm": "node scripts/check-esm-compliance.js",
|
|
233
|
+
prepare: "node scripts/setup-git-hooks.mjs",
|
|
234
|
+
"prepare:full": "npm run clean && npm run templates:verify && npm run providers:validate && npm run providers:generate && npm run build && npm run check:esm && npm run -s verify:dist",
|
|
235
|
+
prepack: 'npm run -s check:package-docs && if [ "${POETIC_SKIP_PREPACK:-0}" = "1" ]; then echo "[prepack] POETIC_SKIP_PREPACK=1; skipping prepare:full"; else npm run prepare:full; fi',
|
|
236
|
+
"canary:backlog-execute": "node --import tsx ./scripts/reliability/run-backlog-execute-canary.ts",
|
|
237
|
+
"canary:backlog-execute:validate": "node --import tsx ./scripts/reliability/validate-backlog-execute-canary-artifacts.ts",
|
|
238
|
+
"canary:backlog-execute:scorecard": "node --import tsx ./scripts/reliability/reliability-scorecard.ts",
|
|
239
|
+
"test:planning": "node scripts/dynamic-node-options.mjs vitest run tests/planning",
|
|
240
|
+
"test:planning:watch": "vitest watch tests/planning",
|
|
241
|
+
"planning:validate": "node scripts/dynamic-node-options.mjs vitest run tests/planning/validation.test.ts",
|
|
242
|
+
"backup:telemetry": "node --import tsx scripts/backup-telemetry-db.ts",
|
|
243
|
+
"restore:telemetry": "node --import tsx scripts/restore-telemetry-db.ts",
|
|
244
|
+
"validate:judge-canary": "tsx scripts/validate-judge-canary.ts",
|
|
245
|
+
"judge:calibrate-thresholds": "tsx scripts/replay-judge-threshold-calibration.ts",
|
|
246
|
+
"test:e2e": "POETIC_E2E_USE_DIST=1 node scripts/dynamic-node-options.mjs vitest run tests/e2e --maxWorkers=1 --no-file-parallelism --reporter=verbose",
|
|
247
|
+
"test:e2e:watch": "vitest watch tests/e2e",
|
|
248
|
+
"test:stabilized": "node scripts/dynamic-node-options.mjs vitest run tests/stabilized --reporter=verbose",
|
|
249
|
+
"test:extended": `if [ "\${POETIC_RUN_EXTENDED_TESTS:-0}" = "1" ]; then POETIC_PREFLIGHT_DONE=1 npm run -s test:e2e && POETIC_PREFLIGHT_DONE=1 npm run -s test:stabilized; else echo '[test:extended] SKIP: set POETIC_RUN_EXTENDED_TESTS=1 to run test:e2e and test:stabilized'; fi`,
|
|
250
|
+
"test:dogfood": "bash scripts/release/dogfood-real-providers.sh",
|
|
251
|
+
"stress:autoloop-dogfood": "bash scripts/stress/autoloop-dogfood-streak.sh",
|
|
252
|
+
"stress:builder-dogfood": "bash scripts/stress/builder-dogfood-streak.sh",
|
|
253
|
+
"test:changed": "node ./scripts/test-changed.mjs",
|
|
254
|
+
"test:changed:gate": "node ./scripts/test-changed-gate.mjs",
|
|
255
|
+
"test:changed:inventory": "node ./scripts/test-changed-inventory.mjs",
|
|
256
|
+
"test:neutrality:sentinel": "node --import tsx ./scripts/run-non-node-verification-sentinel.ts",
|
|
257
|
+
"test:fast": "npm run test:changed",
|
|
258
|
+
"test:staged": "npm run test:changed -- --staged",
|
|
259
|
+
"test:related": "node scripts/dynamic-node-options.mjs vitest related",
|
|
260
|
+
"test:watch:orchestrator": "node scripts/dynamic-node-options.mjs vitest watch tests/unit/orchestrator",
|
|
261
|
+
"test:watch:prompts": "node scripts/dynamic-node-options.mjs vitest watch tests/unit/prompts tests/unit/types tests/unit/utils tests/unit/cli tests/unit/core/judge/ai-judge-prompt-3bucket-excerpt.test.ts tests/unit/core/judge/criteria-ledger-confidence.test.ts tests/unit/core/judge/winner-from-scores.test.ts src/prompts src/core/judge/__tests__",
|
|
262
|
+
"ci:gate": "npm run release:gate",
|
|
263
|
+
resources: "node scripts/show-resource-tier.mjs",
|
|
264
|
+
"ci:nightly": "npm run -s check:no-decorative-glyphs && npm run -s test:unit && npm run -s test:integration && npm run -s test:regression"
|
|
265
|
+
},
|
|
266
|
+
keywords: [
|
|
267
|
+
"ai",
|
|
268
|
+
"orchestration",
|
|
269
|
+
"cli",
|
|
270
|
+
"development",
|
|
271
|
+
"automation",
|
|
272
|
+
"variant-competition",
|
|
273
|
+
"quality-gates",
|
|
274
|
+
"telemetry",
|
|
275
|
+
"claude",
|
|
276
|
+
"codex",
|
|
277
|
+
"cursor",
|
|
278
|
+
"multi-provider"
|
|
279
|
+
],
|
|
280
|
+
author: "Ed Brindley <61567470+ebrindley@users.noreply.github.com>",
|
|
281
|
+
license: "MIT",
|
|
282
|
+
homepage: "https://github.com/ebrindley/Poetic#readme",
|
|
283
|
+
repository: {
|
|
284
|
+
type: "git",
|
|
285
|
+
url: "git+https://github.com/ebrindley/Poetic.git"
|
|
286
|
+
},
|
|
287
|
+
bugs: {
|
|
288
|
+
url: "https://github.com/ebrindley/Poetic/issues"
|
|
289
|
+
},
|
|
290
|
+
os: [
|
|
291
|
+
"darwin",
|
|
292
|
+
"linux"
|
|
293
|
+
],
|
|
294
|
+
publishConfig: {
|
|
295
|
+
access: "public",
|
|
296
|
+
provenance: false
|
|
297
|
+
},
|
|
298
|
+
files: [
|
|
299
|
+
"dist/",
|
|
300
|
+
"!dist/**/*.map",
|
|
301
|
+
"!dist/.poetic-build-meta.json",
|
|
302
|
+
".nvmrc",
|
|
303
|
+
"schemas/",
|
|
304
|
+
"scripts/sync.sh",
|
|
305
|
+
"scripts/preinstall-node-check.mjs",
|
|
306
|
+
"scripts/assert-node-runtime.mjs",
|
|
307
|
+
"scripts/preflight-native.mjs",
|
|
308
|
+
"scripts/setup-git-hooks.mjs",
|
|
309
|
+
"scripts/write-node-launcher.sh",
|
|
310
|
+
"src/resources/",
|
|
311
|
+
"templates/",
|
|
312
|
+
"integrations/bb-plugin-poetic/",
|
|
313
|
+
"!integrations/bb-plugin-poetic/node_modules/",
|
|
314
|
+
".poetic/providers/",
|
|
315
|
+
"!.poetic/providers/*.lock",
|
|
316
|
+
"README.md",
|
|
317
|
+
"INSTALL.md",
|
|
318
|
+
"docs/README.md",
|
|
319
|
+
"docs/getting-started/README.md",
|
|
320
|
+
"docs/getting-started/QUICK_START.md",
|
|
321
|
+
"docs/getting-started/SETUP.md",
|
|
322
|
+
"docs/CLI_REFERENCE.md",
|
|
323
|
+
"docs/PROVIDER_SETUP.md",
|
|
324
|
+
"docs/TROUBLESHOOTING.md",
|
|
325
|
+
"docs/reference/AGENT_CONTEXT.md",
|
|
326
|
+
"docs/reference/PROVIDER_RELEASE_TIERS.md",
|
|
327
|
+
"docs/reference/SECURITY.md",
|
|
328
|
+
".github/SECURITY.md",
|
|
329
|
+
"LICENSE",
|
|
330
|
+
"CHANGELOG.md",
|
|
331
|
+
"CONTRIBUTING.md",
|
|
332
|
+
"CODE_OF_CONDUCT.md"
|
|
333
|
+
],
|
|
334
|
+
dependencies: {
|
|
335
|
+
"@anthropic-ai/sdk": "^0.74.0",
|
|
336
|
+
"@inkjs/ui": "^2.0.0",
|
|
337
|
+
ajv: "^8.20.0",
|
|
338
|
+
"ajv-formats": "^3.0.1",
|
|
339
|
+
"async-lock": "^1.4.1",
|
|
340
|
+
"better-sqlite3": "^12.5.0",
|
|
341
|
+
chalk: "^5.3.0",
|
|
342
|
+
"cli-table3": "^0.6.5",
|
|
343
|
+
commander: "^14.0.2",
|
|
344
|
+
"decimal.js": "^10.6.0",
|
|
345
|
+
execa: "^9.0.0",
|
|
346
|
+
"fast-xml-parser": "^5.7.3",
|
|
347
|
+
ink: "^7.0.2",
|
|
348
|
+
"js-yaml": "^4.3.1",
|
|
349
|
+
"jsonc-parser": "^3.3.1",
|
|
350
|
+
minimatch: "^10.2.5",
|
|
351
|
+
"p-limit": "^7.2.0",
|
|
352
|
+
"proper-lockfile": "^4.1.2",
|
|
353
|
+
react: "^19.2.6",
|
|
354
|
+
semver: "^7.7.3",
|
|
355
|
+
"simple-statistics": "^7.8.8",
|
|
356
|
+
"string-width": "^8.2.0",
|
|
357
|
+
yaml: "^2.8.3",
|
|
358
|
+
zod: "^4.1.12"
|
|
359
|
+
},
|
|
360
|
+
devDependencies: {
|
|
361
|
+
"@biomejs/biome": "^2.3.4",
|
|
362
|
+
"@types/async-lock": "^1.4.2",
|
|
363
|
+
"@types/better-sqlite3": "^7.6.11",
|
|
364
|
+
"@types/js-yaml": "^4.0.9",
|
|
365
|
+
"@types/node": "^24.10.0",
|
|
366
|
+
"@types/proper-lockfile": "^4.1.4",
|
|
367
|
+
"@types/react": "^19.2.14",
|
|
368
|
+
"@types/semver": "^7.7.1",
|
|
369
|
+
"@vitest/coverage-v8": "^4.1.8",
|
|
370
|
+
tsup: "^8.5.0",
|
|
371
|
+
tsx: "^4.0.0",
|
|
372
|
+
typescript: "5.4.5",
|
|
373
|
+
vitest: "^4.1.8"
|
|
374
|
+
},
|
|
375
|
+
engines: {
|
|
376
|
+
node: ">=24.0.0 <25.0.0",
|
|
377
|
+
npm: ">=9.0.0"
|
|
378
|
+
},
|
|
379
|
+
overrides: {
|
|
380
|
+
esbuild: "0.28.1",
|
|
381
|
+
picomatch: "4.0.4"
|
|
382
|
+
},
|
|
383
|
+
optionalDependencies: {
|
|
384
|
+
tiktoken: "^1.0.22"
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
// src/cli/tui/command-registry.ts
|
|
389
|
+
var TUI_COMMANDS = [
|
|
390
|
+
{
|
|
391
|
+
name: "tab",
|
|
392
|
+
usage: "/tab <runs|plan|config>",
|
|
393
|
+
description: "Switch the left pane tab."
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
name: "lens",
|
|
397
|
+
usage: "/lens <sprint|tasks|backlog>",
|
|
398
|
+
description: "Switch the Plan tab lens."
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
name: "build",
|
|
402
|
+
usage: "/build <intent>",
|
|
403
|
+
description: "Tell me what you want and I'll build it."
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
name: "plan-run",
|
|
407
|
+
usage: "/plan-run <intent>",
|
|
408
|
+
description: "Plan the work and save it for later.",
|
|
409
|
+
aliases: ["execute-plan"]
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
name: "run",
|
|
413
|
+
usage: "/run <task>",
|
|
414
|
+
description: "Run a single task directly."
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
name: "compete",
|
|
418
|
+
usage: "/compete <task>",
|
|
419
|
+
description: "Implement several approaches and keep the best result."
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
name: "fusion",
|
|
423
|
+
usage: "/fusion <task>",
|
|
424
|
+
description: "Synthesize multiple AI perspectives without a winner."
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
name: "monitor",
|
|
428
|
+
usage: "/monitor <id>",
|
|
429
|
+
description: "Follow progress for an existing run."
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
name: "next",
|
|
433
|
+
usage: "/next",
|
|
434
|
+
description: "Show the next useful Poetic task."
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
name: "quickstart",
|
|
438
|
+
usage: "/quickstart [task...]",
|
|
439
|
+
description: "Open the guided first-run starter."
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
name: "knowledge",
|
|
443
|
+
usage: "/knowledge [status|declare <spec>|clear|resolve <keep|accept>|offer [guidance]|accept <token> <all|ids>|graduate <token>]",
|
|
444
|
+
description: "Inspect and manage the knowledge kit and stack intent contract."
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
name: "model",
|
|
448
|
+
usage: "/model [provider/model|model|provider|reset]",
|
|
449
|
+
description: "Choose the provider and model for this Conversation session."
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
name: "config",
|
|
453
|
+
usage: "/config",
|
|
454
|
+
description: "Open persistent and session configuration (alias: /settings).",
|
|
455
|
+
aliases: ["settings"]
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
name: "status",
|
|
459
|
+
usage: "/status",
|
|
460
|
+
description: "Show configured, requested, and provider-reported model state."
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
name: "context",
|
|
464
|
+
usage: "/context <attach|clear>",
|
|
465
|
+
description: "Attach the selected Work object to Conversation, or clear it."
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
name: "clear",
|
|
469
|
+
usage: "/clear",
|
|
470
|
+
description: "Clear the current TUI output."
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
name: "chat",
|
|
474
|
+
usage: "/chat <message>",
|
|
475
|
+
description: "Send a message to the current chat."
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
name: "help",
|
|
479
|
+
usage: "/help",
|
|
480
|
+
description: "Show available commands."
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
name: "quit",
|
|
484
|
+
usage: "/quit",
|
|
485
|
+
description: "Exit the TUI.",
|
|
486
|
+
aliases: ["exit"]
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
name: "answer",
|
|
490
|
+
usage: "/answer <blockerId>=<answer>",
|
|
491
|
+
description: "Reply to a blocker so work can continue.",
|
|
492
|
+
hidden: true
|
|
493
|
+
}
|
|
494
|
+
];
|
|
495
|
+
function normalizeTuiCommand(command) {
|
|
496
|
+
const normalized = command.trim().toLowerCase();
|
|
497
|
+
for (const definition of TUI_COMMANDS) {
|
|
498
|
+
if (definition.name === normalized || definition.aliases?.includes(normalized)) {
|
|
499
|
+
return definition.name;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
return normalized;
|
|
503
|
+
}
|
|
504
|
+
function getTuiCommandSuggestions(input) {
|
|
505
|
+
const trimmed = input.trimStart();
|
|
506
|
+
if (!trimmed.startsWith("/")) return [];
|
|
507
|
+
const rawCommand = trimmed.slice(1).split(/\s+/, 1)[0]?.toLowerCase() ?? "";
|
|
508
|
+
return TUI_COMMANDS.filter((definition) => {
|
|
509
|
+
if (definition.hidden) return false;
|
|
510
|
+
if (definition.name.startsWith(rawCommand)) return true;
|
|
511
|
+
return definition.aliases?.some((alias) => alias.startsWith(rawCommand)) ?? false;
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// src/cli/tui/chat-formatting.ts
|
|
516
|
+
var SHORT_FOOTER_PROVIDERS = /* @__PURE__ */ new Set(["claude", "codex", "gemini", "grok", "copilot"]);
|
|
517
|
+
var FULL_PATH_FOOTER_PROVIDERS = /* @__PURE__ */ new Set(["opencode", "cursor"]);
|
|
518
|
+
var PROVIDER_DISPLAY_NAMES = {
|
|
519
|
+
claude: "Claude",
|
|
520
|
+
codex: "Codex",
|
|
521
|
+
cursor: "Cursor",
|
|
522
|
+
gemini: "Gemini",
|
|
523
|
+
opencode: "OpenCode",
|
|
524
|
+
grok: "Grok",
|
|
525
|
+
copilot: "Copilot"
|
|
526
|
+
};
|
|
527
|
+
function formatProviderName(provider) {
|
|
528
|
+
return Object.hasOwn(PROVIDER_DISPLAY_NAMES, provider) ? PROVIDER_DISPLAY_NAMES[provider] ?? provider : provider;
|
|
529
|
+
}
|
|
530
|
+
function formatShortModelAlias(model, provider) {
|
|
531
|
+
let trimmed = model.trim();
|
|
532
|
+
const providerKey = provider?.trim().toLowerCase();
|
|
533
|
+
if (!trimmed) return "-";
|
|
534
|
+
if (trimmed === "auto") return providerKey === "claude" ? "-" : "auto";
|
|
535
|
+
if (trimmed.includes("/")) return trimmed;
|
|
536
|
+
let contextSuffix = "";
|
|
537
|
+
if (providerKey === "claude") {
|
|
538
|
+
trimmed = trimmed.replace(/^(?:[a-z0-9-]+\.)?anthropic\./i, "");
|
|
539
|
+
if (trimmed.endsWith("[1m]")) {
|
|
540
|
+
contextSuffix = " [1m]";
|
|
541
|
+
trimmed = trimmed.slice(0, -"[1m]".length);
|
|
542
|
+
}
|
|
543
|
+
trimmed = trimmed.replace(/-\d{8}-v\d+:\d+$/i, "");
|
|
544
|
+
}
|
|
545
|
+
if (providerKey && trimmed.toLowerCase().startsWith(`${providerKey}-`)) {
|
|
546
|
+
const rest = trimmed.slice(providerKey.length + 1);
|
|
547
|
+
if (/^[a-z]/i.test(rest)) {
|
|
548
|
+
trimmed = rest;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
const parts = trimmed.split("-").filter((part) => part.length > 0);
|
|
552
|
+
if (parts.length >= 2) {
|
|
553
|
+
const last = parts[parts.length - 1];
|
|
554
|
+
const secondLast = parts[parts.length - 2];
|
|
555
|
+
if (/^\d+$/.test(last) && /^\d+$/.test(secondLast)) {
|
|
556
|
+
parts.splice(parts.length - 2, 2, `${secondLast}.${last}`);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
return `${parts.join(" ").replace(/\s+/g, " ").trim()}${contextSuffix}`;
|
|
560
|
+
}
|
|
561
|
+
function formatTuiFooterLabel(params) {
|
|
562
|
+
const provider = params.provider.trim().toLowerCase();
|
|
563
|
+
const model = params.model?.trim() ?? (provider === "cursor" ? "auto" : "");
|
|
564
|
+
const providerLabel = formatProviderName(provider);
|
|
565
|
+
if (FULL_PATH_FOOTER_PROVIDERS.has(provider)) {
|
|
566
|
+
return `${providerLabel} | ${model || "-"}`;
|
|
567
|
+
}
|
|
568
|
+
if (SHORT_FOOTER_PROVIDERS.has(provider)) {
|
|
569
|
+
return `${providerLabel} | ${formatShortModelAlias(model, provider)}`;
|
|
570
|
+
}
|
|
571
|
+
if (model.includes("/")) {
|
|
572
|
+
return `${providerLabel} | ${model}`;
|
|
573
|
+
}
|
|
574
|
+
return `${providerLabel} | ${formatShortModelAlias(model, provider)}`;
|
|
575
|
+
}
|
|
576
|
+
function formatElapsed(ms) {
|
|
577
|
+
if (ms === void 0) return void 0;
|
|
578
|
+
if (ms < 6e4) return `${Math.round(ms / 1e3)}s`;
|
|
579
|
+
if (ms < 36e5) return `${Math.round(ms / 6e4)}m`;
|
|
580
|
+
return `${Math.round(ms / 36e5)}h`;
|
|
581
|
+
}
|
|
582
|
+
function formatTuiUserPromptLine(line) {
|
|
583
|
+
return `> ${line}`;
|
|
584
|
+
}
|
|
585
|
+
function formatTuiAssistantMessageContent(content) {
|
|
586
|
+
return content.trim();
|
|
587
|
+
}
|
|
588
|
+
function shouldShowTuiChatWorkingIndicator(message) {
|
|
589
|
+
return message.role === "assistant" && message.status === "streaming";
|
|
590
|
+
}
|
|
591
|
+
function shouldShowTuiChatTurnReceipt(message) {
|
|
592
|
+
return message.role === "assistant" && message.status === "done" && message.durationMs !== void 0;
|
|
593
|
+
}
|
|
594
|
+
function formatWorkingElapsed(elapsedMs) {
|
|
595
|
+
const totalSeconds = Math.max(0, Math.floor(elapsedMs / 1e3));
|
|
596
|
+
if (totalSeconds < 60) return `${totalSeconds}s`;
|
|
597
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
598
|
+
const seconds = totalSeconds % 60;
|
|
599
|
+
return `${minutes}m ${seconds}s`;
|
|
600
|
+
}
|
|
601
|
+
function formatWorkingLine(params) {
|
|
602
|
+
const parts = [formatWorkingElapsed(params.elapsedMs), "c to cancel"];
|
|
603
|
+
if (params.tokensSoFar !== void 0 && params.tokensSoFar > 0) {
|
|
604
|
+
parts.push(`${params.tokensSoFar} tokens`);
|
|
605
|
+
}
|
|
606
|
+
return `Working (${parts.join(" - ")})`;
|
|
607
|
+
}
|
|
608
|
+
function formatTuiChatCostUsd(costUsd) {
|
|
609
|
+
if (costUsd !== 0 && Math.abs(costUsd) < 0.01) {
|
|
610
|
+
return `$${costUsd.toFixed(4)}`;
|
|
611
|
+
}
|
|
612
|
+
return `$${costUsd.toFixed(2)}`;
|
|
613
|
+
}
|
|
614
|
+
function formatTurnReceipt(params) {
|
|
615
|
+
const segments = [];
|
|
616
|
+
if (params.durationMs !== void 0) {
|
|
617
|
+
segments.push(`completed in ${formatReceiptDuration(params.durationMs)}`);
|
|
618
|
+
} else {
|
|
619
|
+
segments.push("completed");
|
|
620
|
+
}
|
|
621
|
+
if (params.costUsd !== void 0) {
|
|
622
|
+
segments.push(formatTuiChatCostUsd(params.costUsd));
|
|
623
|
+
}
|
|
624
|
+
const tokens = receiptTokenTotal(params.tokensIn, params.tokensOut);
|
|
625
|
+
if (tokens !== void 0) {
|
|
626
|
+
segments.push(`${tokens} tokens`);
|
|
627
|
+
}
|
|
628
|
+
if (segments.length <= 1 && params.durationMs === void 0) return void 0;
|
|
629
|
+
return `Turn ${segments.join(" - ")}`;
|
|
630
|
+
}
|
|
631
|
+
function formatReceiptDuration(ms) {
|
|
632
|
+
if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
|
|
633
|
+
const totalSeconds = Math.round(ms / 1e3);
|
|
634
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
635
|
+
const seconds = totalSeconds % 60;
|
|
636
|
+
return `${minutes}m ${seconds}s`;
|
|
637
|
+
}
|
|
638
|
+
function receiptTokenTotal(tokensIn, tokensOut) {
|
|
639
|
+
if (tokensIn === void 0 && tokensOut === void 0) return void 0;
|
|
640
|
+
return (tokensIn ?? 0) + (tokensOut ?? 0);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// src/cli/tui/model-selection.ts
|
|
644
|
+
var EXPLICIT_MODEL_SOURCES = /* @__PURE__ */ new Set([
|
|
645
|
+
"cli",
|
|
646
|
+
"env",
|
|
647
|
+
"env-legacy",
|
|
648
|
+
"profile",
|
|
649
|
+
"project",
|
|
650
|
+
"user-config"
|
|
651
|
+
]);
|
|
652
|
+
function resolveTuiSelectedModel(resolved) {
|
|
653
|
+
if (!resolved || !EXPLICIT_MODEL_SOURCES.has(resolved.source)) return void 0;
|
|
654
|
+
const model = resolved.value.trim();
|
|
655
|
+
return model.length > 0 && model.toLowerCase() !== "auto" ? model : void 0;
|
|
656
|
+
}
|
|
657
|
+
function formatTuiSelectedModel(resolved) {
|
|
658
|
+
return resolveTuiSelectedModel(resolved) ?? "-";
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
// src/cli/tui/dashboard-helpers.ts
|
|
662
|
+
var EXPLICIT_DEFAULT_PROVIDER_SOURCES = /* @__PURE__ */ new Set([
|
|
663
|
+
"cli",
|
|
664
|
+
"env",
|
|
665
|
+
"env-legacy",
|
|
666
|
+
"profile",
|
|
667
|
+
"project",
|
|
668
|
+
"user-config"
|
|
669
|
+
]);
|
|
670
|
+
function isExplicitDefaultProviderSource(source) {
|
|
671
|
+
return EXPLICIT_DEFAULT_PROVIDER_SOURCES.has(source);
|
|
672
|
+
}
|
|
673
|
+
function toEnforcedAnchorProvider(value) {
|
|
674
|
+
if (typeof value === "string" && isEnforcedAnchorProvider(value)) return value;
|
|
675
|
+
return null;
|
|
676
|
+
}
|
|
677
|
+
function resolveTuiChatProvider(params) {
|
|
678
|
+
if (params.anchoredProvider) return params.anchoredProvider;
|
|
679
|
+
const sessionProvider = toEnforcedAnchorProvider(params.sessionDefaultProvider);
|
|
680
|
+
if (sessionProvider) return sessionProvider;
|
|
681
|
+
try {
|
|
682
|
+
return toEnforcedAnchorProvider(
|
|
683
|
+
resolveConfig(void 0, params.repoRoot, { strictSynthesisModel: false }).defaultProvider.value
|
|
684
|
+
);
|
|
685
|
+
} catch {
|
|
686
|
+
return null;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
async function preparePreviewSpawn(preview, repoRoot) {
|
|
690
|
+
const args = [...preview.executable.prefixArgs, ...preview.argv];
|
|
691
|
+
if (preview.sandbox.mode === "none") {
|
|
692
|
+
return { command: preview.executable.command, args, sandboxed: false };
|
|
693
|
+
}
|
|
694
|
+
const { wrapWithSandbox } = await import("./sandbox-RSO7VP6V.js");
|
|
695
|
+
return wrapWithSandbox({
|
|
696
|
+
workingDir: repoRoot,
|
|
697
|
+
command: preview.executable.command,
|
|
698
|
+
args,
|
|
699
|
+
providerName: preview.sandbox.providerName,
|
|
700
|
+
providerId: preview.sandbox.providerId,
|
|
701
|
+
readOnlyWorkingDir: preview.sandbox.mode === "read-only"
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
function resolveTuiImmediateCommandArgError(inputText) {
|
|
705
|
+
const match = /^\/([a-z-]+)\s+(.+)$/i.exec(inputText.trim());
|
|
706
|
+
if (!match) return null;
|
|
707
|
+
const command = normalizeTuiCommand(match[1] ?? "");
|
|
708
|
+
if (!["clear", "quit", "help", "config", "status"].includes(command)) return null;
|
|
709
|
+
return `/${command} does not take arguments.`;
|
|
710
|
+
}
|
|
711
|
+
function resolveTuiImmediateCommand(inputText) {
|
|
712
|
+
const match = /^\/([a-z-]+)$/i.exec(inputText.trim());
|
|
713
|
+
if (!match?.[1]) return null;
|
|
714
|
+
const command = normalizeTuiCommand(match[1]);
|
|
715
|
+
if (command === "help") return "help";
|
|
716
|
+
if (command === "config") return "config-tab";
|
|
717
|
+
if (command === "status") return "status";
|
|
718
|
+
if (command === "clear") return "clear";
|
|
719
|
+
if (command === "quit") return "quit";
|
|
720
|
+
return null;
|
|
721
|
+
}
|
|
722
|
+
function resolveTuiChatAvailable(activeChatProvider) {
|
|
723
|
+
return isAnchoredChatEnabled(process.env) && activeChatProvider !== null;
|
|
724
|
+
}
|
|
725
|
+
function shouldExecuteTuiSuggestionImmediately(command) {
|
|
726
|
+
return !command.usage.includes("<");
|
|
727
|
+
}
|
|
728
|
+
function shouldStartTuiPreviewImmediately(preview) {
|
|
729
|
+
return preview.kind === "chat" && preview.canSubmit;
|
|
730
|
+
}
|
|
731
|
+
function hasProviderSetupAttention(items) {
|
|
732
|
+
return items.some((item) => item.kind === "provider-auth");
|
|
733
|
+
}
|
|
734
|
+
function suggestedTaskLine(plan) {
|
|
735
|
+
const sprintTask = plan.tasks.find((task) => task.meta !== "done") ?? plan.tasks[0];
|
|
736
|
+
if (sprintTask) {
|
|
737
|
+
return `Suggested first task: /quickstart ${sprintTask.title}`;
|
|
738
|
+
}
|
|
739
|
+
const backlogItem = plan.backlog[0];
|
|
740
|
+
if (backlogItem) {
|
|
741
|
+
return `Suggested first task: /quickstart ${backlogItem.title}`;
|
|
742
|
+
}
|
|
743
|
+
return "Suggested first task: /quickstart Describe the change you want.";
|
|
744
|
+
}
|
|
745
|
+
function resolveTuiOnboardingHome(params) {
|
|
746
|
+
if (params.runs.length > 0) return null;
|
|
747
|
+
const providerNeedsSetup = hasProviderSetupAttention(params.attentionItems) || params.providerPromptResolution === "setup" || params.providerPromptResolution === "guidance";
|
|
748
|
+
const providerReady = params.providerPromptResolution === "none";
|
|
749
|
+
return {
|
|
750
|
+
readiness: providerNeedsSetup ? "Readiness: provider setup needed" : providerReady ? `Readiness: ready (${params.backendLabel})` : "Readiness: checking providers",
|
|
751
|
+
providerSetup: providerNeedsSetup ? "Provider setup: use the prompt, or open Config (3)." : providerReady ? "Provider setup: Config (3) changes defaults." : "Provider setup: checking installed provider CLIs.",
|
|
752
|
+
suggestedTask: suggestedTaskLine(params.planState),
|
|
753
|
+
quickstart: "Quickstart: /quickstart opens the guided starter."
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
function resolveTuiFirstRunProviderPrompt(params) {
|
|
757
|
+
const defaultReadiness = params.readiness.find(
|
|
758
|
+
(provider) => provider.provider === params.defaultProvider?.value
|
|
759
|
+
);
|
|
760
|
+
const explicitReadyDefault = params.defaultProvider && EXPLICIT_DEFAULT_PROVIDER_SOURCES.has(params.defaultProvider.source) && defaultReadiness?.ready;
|
|
761
|
+
if (explicitReadyDefault) return { kind: "none" };
|
|
762
|
+
if (params.defaultProvider && EXPLICIT_DEFAULT_PROVIDER_SOURCES.has(params.defaultProvider.source)) {
|
|
763
|
+
return {
|
|
764
|
+
kind: "guidance",
|
|
765
|
+
guidance: defaultReadiness ? formatProviderNotReadyMessage(defaultReadiness) : `Configured provider ${params.defaultProvider.value} is not ready.
|
|
766
|
+
Run poetic provider list after setup completes.`
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
const selection = selectReadyProvider(params.readiness);
|
|
770
|
+
if (selection.kind === "none") {
|
|
771
|
+
return {
|
|
772
|
+
kind: "guidance",
|
|
773
|
+
guidance: formatProviderSetupGuidance(selection.candidates)
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
if (selection.kind === "single") {
|
|
777
|
+
return { kind: "save-scope", provider: selection.provider };
|
|
778
|
+
}
|
|
779
|
+
return { kind: "select-provider", candidates: selection.candidates };
|
|
780
|
+
}
|
|
781
|
+
var PROMPT_SEPARATOR_WIDTH = 120;
|
|
782
|
+
function loadTuiActions() {
|
|
783
|
+
return import("./actions-LUJPINLJ.js");
|
|
784
|
+
}
|
|
785
|
+
function promptSeparator() {
|
|
786
|
+
const columns = process.stdout.columns;
|
|
787
|
+
const width = typeof columns === "number" && Number.isFinite(columns) ? Math.max(24, Math.min(columns, PROMPT_SEPARATOR_WIDTH)) : PROMPT_SEPARATOR_WIDTH;
|
|
788
|
+
return "\u2500".repeat(width);
|
|
789
|
+
}
|
|
790
|
+
function resolveTuiBackendLabel(repoRoot, anchoredProvider) {
|
|
791
|
+
try {
|
|
792
|
+
const config = resolveConfig(void 0, repoRoot, { strictSynthesisModel: false });
|
|
793
|
+
const provider = anchoredProvider ?? config.defaultProvider.value;
|
|
794
|
+
const model = resolveTuiSelectedModel(config.providerModels[provider]);
|
|
795
|
+
return formatTuiFooterLabel({ provider, model });
|
|
796
|
+
} catch {
|
|
797
|
+
return formatTuiFooterLabel({
|
|
798
|
+
provider: anchoredProvider ?? "poetic"
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
function resolveTuiChatModel(repoRoot, provider) {
|
|
803
|
+
try {
|
|
804
|
+
const config = resolveConfig(void 0, repoRoot, { strictSynthesisModel: false });
|
|
805
|
+
return resolveTuiSelectedModel(config.providerModels[provider]);
|
|
806
|
+
} catch {
|
|
807
|
+
return void 0;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
function resolveTuiDisplayedChatModel(messages, provider, selectedModel, activeSessionId) {
|
|
811
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
812
|
+
const message = messages[index];
|
|
813
|
+
if (message?.provider !== provider || message.role !== "assistant" && message.role !== "error") {
|
|
814
|
+
continue;
|
|
815
|
+
}
|
|
816
|
+
if (message.status === "streaming" || activeSessionId !== void 0 && message.sessionId === activeSessionId) {
|
|
817
|
+
return message.model ?? selectedModel;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
return selectedModel;
|
|
821
|
+
}
|
|
822
|
+
function previewNeedsRunBranch(preview) {
|
|
823
|
+
if (!preview || preview.route !== "planned") return false;
|
|
824
|
+
return preview.warnings.some((warning) => warning.startsWith("Protected branch "));
|
|
825
|
+
}
|
|
826
|
+
function countProposalQueueRows(queue) {
|
|
827
|
+
if (!queue) return 0;
|
|
828
|
+
return 1 + 2 + (queue.truncated ? 1 : 0) + queue.rejected.length + queue.actions.length;
|
|
829
|
+
}
|
|
830
|
+
function resolveTuiChatAgentPrompt(readiness) {
|
|
831
|
+
const chatReadiness = readiness.filter((provider) => toEnforcedAnchorProvider(provider.provider));
|
|
832
|
+
const readyCandidates = chatReadiness.filter((provider) => provider.ready);
|
|
833
|
+
if (readyCandidates.length > 0) {
|
|
834
|
+
return {
|
|
835
|
+
kind: "select-provider",
|
|
836
|
+
title: "Choose Chat Agent",
|
|
837
|
+
intro: "Choose an agent to chat with:",
|
|
838
|
+
candidates: readyCandidates
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
return {
|
|
842
|
+
kind: "guidance",
|
|
843
|
+
title: "Choose Chat Agent",
|
|
844
|
+
guidance: chatReadiness.length > 0 ? formatProviderSetupGuidance(chatReadiness) : "No supported chat agent was found. Run poetic provider list after setup completes."
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// src/cli/tui/dashboard-snapshot.ts
|
|
849
|
+
import { execFileSync } from "child_process";
|
|
850
|
+
import fs from "fs";
|
|
851
|
+
import path from "path";
|
|
852
|
+
|
|
853
|
+
// src/cli/tui/competition-view.ts
|
|
854
|
+
import { Box, Text } from "ink";
|
|
855
|
+
import React from "react";
|
|
856
|
+
function isRecord(value) {
|
|
857
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
858
|
+
}
|
|
859
|
+
function readString(record, keys) {
|
|
860
|
+
for (const key of keys) {
|
|
861
|
+
const value = record[key];
|
|
862
|
+
if (typeof value === "string" && value.trim().length > 0) return value;
|
|
863
|
+
}
|
|
864
|
+
return void 0;
|
|
865
|
+
}
|
|
866
|
+
function readNumber(record, keys) {
|
|
867
|
+
for (const key of keys) {
|
|
868
|
+
const value = record[key];
|
|
869
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
870
|
+
}
|
|
871
|
+
return void 0;
|
|
872
|
+
}
|
|
873
|
+
function readNestedString(record, pathParts) {
|
|
874
|
+
let current = record;
|
|
875
|
+
for (const part of pathParts) {
|
|
876
|
+
if (!isRecord(current)) return void 0;
|
|
877
|
+
current = current[part];
|
|
878
|
+
}
|
|
879
|
+
return typeof current === "string" && current.trim().length > 0 ? current : void 0;
|
|
880
|
+
}
|
|
881
|
+
function resolveVariantLabel(candidate) {
|
|
882
|
+
const explicit = readString(candidate, ["variant"]);
|
|
883
|
+
if (explicit) return explicit;
|
|
884
|
+
const provider = readString(candidate, ["provider"]) ?? "unknown";
|
|
885
|
+
const model = readString(candidate, ["model", "resolvedModel"]);
|
|
886
|
+
const strategy = readString(candidate, ["strategy"]);
|
|
887
|
+
const parts = [provider, model, strategy].filter(Boolean);
|
|
888
|
+
return parts.join(":");
|
|
889
|
+
}
|
|
890
|
+
function resolveStatus(candidate) {
|
|
891
|
+
const topLevel = readString(candidate, ["status", "state"]);
|
|
892
|
+
if (topLevel) return topLevel;
|
|
893
|
+
const execStatus = readNestedString(candidate, ["outcome", "execution", "status"]);
|
|
894
|
+
if (execStatus) return execStatus;
|
|
895
|
+
const success = candidate.success;
|
|
896
|
+
if (typeof success === "boolean") return success ? "completed" : "failed";
|
|
897
|
+
return "pending";
|
|
898
|
+
}
|
|
899
|
+
function resolveGates(candidate) {
|
|
900
|
+
const gates = [];
|
|
901
|
+
const verificationStatus = readNestedString(candidate, ["outcome", "verification", "status"]);
|
|
902
|
+
if (verificationStatus) gates.push(`verification=${verificationStatus}`);
|
|
903
|
+
const gatesPassed = candidate.outcome;
|
|
904
|
+
if (isRecord(gatesPassed)) {
|
|
905
|
+
const verification = gatesPassed.verification;
|
|
906
|
+
if (isRecord(verification)) {
|
|
907
|
+
const passed = verification.deterministicGatesPassed;
|
|
908
|
+
if (typeof passed === "boolean") {
|
|
909
|
+
gates.push(`gates=${passed ? "passed" : "failed"}`);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
return [...new Set(gates)];
|
|
914
|
+
}
|
|
915
|
+
function candidateHasResults(candidate) {
|
|
916
|
+
return typeof candidate.success === "boolean" || isRecord(candidate.outcome) || typeof candidate.completeness === "number";
|
|
917
|
+
}
|
|
918
|
+
function extractCompetitionVariants(record) {
|
|
919
|
+
const candidatesRaw = record.candidates;
|
|
920
|
+
if (!Array.isArray(candidatesRaw)) {
|
|
921
|
+
return { variants: [], isComplete: false };
|
|
922
|
+
}
|
|
923
|
+
const winnerRecord = record.winner;
|
|
924
|
+
const winnerVariant = isRecord(winnerRecord) ? readString(winnerRecord, ["variant"]) ?? void 0 : typeof record.winner === "string" ? record.winner : void 0;
|
|
925
|
+
const topStatus = readString(record, ["status", "state"]) ?? "";
|
|
926
|
+
const isComplete = !ACTIVE_RUN_STATUSES.has(topStatus.toLowerCase());
|
|
927
|
+
const rationale = readString(record, ["rationale", "reasoning", "judgeReasoning"]);
|
|
928
|
+
const seenVariants = /* @__PURE__ */ new Set();
|
|
929
|
+
const variants = [];
|
|
930
|
+
for (const raw of candidatesRaw) {
|
|
931
|
+
if (!isRecord(raw)) continue;
|
|
932
|
+
if (!candidateHasResults(raw)) continue;
|
|
933
|
+
const variantLabel = resolveVariantLabel(raw);
|
|
934
|
+
if (seenVariants.has(variantLabel)) continue;
|
|
935
|
+
seenVariants.add(variantLabel);
|
|
936
|
+
const provider = readString(raw, ["provider"]) ?? "unknown";
|
|
937
|
+
const strategy = readString(raw, ["strategy"]);
|
|
938
|
+
const status = resolveStatus(raw);
|
|
939
|
+
const score = readNumber(raw, ["completeness", "judgeScore", "score"]);
|
|
940
|
+
const costUsd = readNumber(raw, ["costUsd", "cost_usd"]);
|
|
941
|
+
const tokenCount = readNumber(raw, ["tokens", "totalTokens", "tokenCount"]);
|
|
942
|
+
const gates = resolveGates(raw);
|
|
943
|
+
const isWinner = winnerVariant !== void 0 && variantLabel === winnerVariant;
|
|
944
|
+
variants.push({
|
|
945
|
+
variant: variantLabel,
|
|
946
|
+
provider,
|
|
947
|
+
strategy,
|
|
948
|
+
status,
|
|
949
|
+
score,
|
|
950
|
+
costUsd,
|
|
951
|
+
tokenCount,
|
|
952
|
+
gates,
|
|
953
|
+
isWinner
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
if (isComplete) {
|
|
957
|
+
variants.sort((a, b) => {
|
|
958
|
+
const scoreA = a.score ?? -1;
|
|
959
|
+
const scoreB = b.score ?? -1;
|
|
960
|
+
return scoreB - scoreA;
|
|
961
|
+
});
|
|
962
|
+
} else {
|
|
963
|
+
variants.sort((a, b) => {
|
|
964
|
+
const aActive = ACTIVE_RUN_STATUSES.has(a.status.toLowerCase()) ? 0 : 1;
|
|
965
|
+
const bActive = ACTIVE_RUN_STATUSES.has(b.status.toLowerCase()) ? 0 : 1;
|
|
966
|
+
return aActive - bActive;
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
return { variants, winner: winnerVariant, rationale, isComplete };
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
// src/cli/tui/dashboard-snapshot.ts
|
|
973
|
+
var MAX_DASHBOARD_RUNS = 16;
|
|
974
|
+
var MAX_DASHBOARD_FILES_PER_DIR = 200;
|
|
975
|
+
var MAX_PENDING_BLOCKERS = 8;
|
|
976
|
+
var MAX_PENDING_BLOCKERS_PER_RUN = 3;
|
|
977
|
+
var MAX_PROMOTED_DECISIONS = 20;
|
|
978
|
+
var STALE_RUN_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
979
|
+
var INACTIVE_BACKGROUND_RUN_AGE_MS = 30 * 60 * 1e3;
|
|
980
|
+
function isRecord2(value) {
|
|
981
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
982
|
+
}
|
|
983
|
+
function readNestedValue(record, pathParts) {
|
|
984
|
+
let current = record;
|
|
985
|
+
for (const part of pathParts) {
|
|
986
|
+
if (!isRecord2(current)) return void 0;
|
|
987
|
+
current = current[part];
|
|
988
|
+
}
|
|
989
|
+
return current;
|
|
990
|
+
}
|
|
991
|
+
function readNestedString2(record, paths) {
|
|
992
|
+
for (const pathParts of paths) {
|
|
993
|
+
const current = readNestedValue(record, pathParts);
|
|
994
|
+
if (typeof current === "string" && current.trim().length > 0) {
|
|
995
|
+
return current;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
return void 0;
|
|
999
|
+
}
|
|
1000
|
+
function readNestedNumber(record, paths) {
|
|
1001
|
+
for (const pathParts of paths) {
|
|
1002
|
+
const value = readNestedValue(record, pathParts);
|
|
1003
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
1004
|
+
}
|
|
1005
|
+
return void 0;
|
|
1006
|
+
}
|
|
1007
|
+
function readNestedStringArray(record, paths) {
|
|
1008
|
+
for (const pathParts of paths) {
|
|
1009
|
+
const value = readNestedValue(record, pathParts);
|
|
1010
|
+
if (Array.isArray(value)) {
|
|
1011
|
+
return value.filter(
|
|
1012
|
+
(entry) => typeof entry === "string" && entry.length > 0
|
|
1013
|
+
);
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
return [];
|
|
1017
|
+
}
|
|
1018
|
+
function readJson(filePath) {
|
|
1019
|
+
try {
|
|
1020
|
+
if (timingFilesReadActive) {
|
|
1021
|
+
timingFilesRead += 1;
|
|
1022
|
+
}
|
|
1023
|
+
const parsed = JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
1024
|
+
const sanitized = sanitizeSynthesisArtifactForPersistence(parsed);
|
|
1025
|
+
return isRecord2(sanitized) ? sanitized : null;
|
|
1026
|
+
} catch {
|
|
1027
|
+
return null;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
function readString2(record, keys) {
|
|
1031
|
+
for (const key of keys) {
|
|
1032
|
+
const value = record[key];
|
|
1033
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
1034
|
+
return value;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
return void 0;
|
|
1038
|
+
}
|
|
1039
|
+
function readNumber2(record, keys) {
|
|
1040
|
+
for (const key of keys) {
|
|
1041
|
+
const value = record[key];
|
|
1042
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
1043
|
+
return value;
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
return void 0;
|
|
1047
|
+
}
|
|
1048
|
+
function readBoolean(record, keys) {
|
|
1049
|
+
for (const key of keys) {
|
|
1050
|
+
const value = record[key];
|
|
1051
|
+
if (typeof value === "boolean") {
|
|
1052
|
+
return value;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
return void 0;
|
|
1056
|
+
}
|
|
1057
|
+
function formatCost(value) {
|
|
1058
|
+
if (value === void 0) return void 0;
|
|
1059
|
+
if (value < 0.01) return `$${value.toFixed(4)}`;
|
|
1060
|
+
return `$${value.toFixed(2)}`;
|
|
1061
|
+
}
|
|
1062
|
+
function formatTokens(value) {
|
|
1063
|
+
if (value === void 0) return void 0;
|
|
1064
|
+
return value >= 1e3 ? `${Math.round(value / 100) / 10}k` : String(value);
|
|
1065
|
+
}
|
|
1066
|
+
function readStringArray(record, keys) {
|
|
1067
|
+
const values = /* @__PURE__ */ new Set();
|
|
1068
|
+
for (const key of keys) {
|
|
1069
|
+
const value = record[key];
|
|
1070
|
+
if (!Array.isArray(value)) continue;
|
|
1071
|
+
for (const item of value) {
|
|
1072
|
+
if (typeof item === "string" && item.trim().length > 0) {
|
|
1073
|
+
values.add(item.trim());
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
return [...values];
|
|
1078
|
+
}
|
|
1079
|
+
function collectFilesChanged(record) {
|
|
1080
|
+
const files = new Set(
|
|
1081
|
+
readStringArray(record, ["filesModified", "modifiedFiles", "changedFiles", "filesChanged"])
|
|
1082
|
+
);
|
|
1083
|
+
const results = Array.isArray(record.results) ? record.results : [];
|
|
1084
|
+
for (const result of results) {
|
|
1085
|
+
if (!isRecord2(result)) continue;
|
|
1086
|
+
for (const file of readStringArray(result, [
|
|
1087
|
+
"filesModified",
|
|
1088
|
+
"modifiedFiles",
|
|
1089
|
+
"changedFiles",
|
|
1090
|
+
"filesChanged"
|
|
1091
|
+
])) {
|
|
1092
|
+
files.add(file);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
return [...files].sort();
|
|
1096
|
+
}
|
|
1097
|
+
function collectGates(record) {
|
|
1098
|
+
const gates = [];
|
|
1099
|
+
const verificationStatus = readNestedString2(record, [
|
|
1100
|
+
["outcome", "verification", "status"],
|
|
1101
|
+
["verification", "status"],
|
|
1102
|
+
["verification", "outcome"]
|
|
1103
|
+
]) ?? void 0;
|
|
1104
|
+
if (verificationStatus) {
|
|
1105
|
+
gates.push(`verification=${verificationStatus}`);
|
|
1106
|
+
}
|
|
1107
|
+
const deterministicGatesPassed = readNestedBoolean(record, [
|
|
1108
|
+
["outcome", "verification", "deterministicGatesPassed"],
|
|
1109
|
+
["verification", "deterministicGatesPassed"],
|
|
1110
|
+
["qualityGates", "passed"]
|
|
1111
|
+
]);
|
|
1112
|
+
if (deterministicGatesPassed !== void 0) {
|
|
1113
|
+
gates.push(`gates=${deterministicGatesPassed ? "passed" : "failed"}`);
|
|
1114
|
+
}
|
|
1115
|
+
const verificationPassed = readNestedBoolean(record, [["verification", "passed"]]);
|
|
1116
|
+
if (!verificationStatus && verificationPassed !== void 0) {
|
|
1117
|
+
gates.push(`verification=${verificationPassed ? "passed" : "failed"}`);
|
|
1118
|
+
}
|
|
1119
|
+
return [...new Set(gates)];
|
|
1120
|
+
}
|
|
1121
|
+
function readNestedBoolean(record, paths) {
|
|
1122
|
+
for (const pathParts of paths) {
|
|
1123
|
+
let current = record;
|
|
1124
|
+
for (const part of pathParts) {
|
|
1125
|
+
if (!isRecord2(current)) {
|
|
1126
|
+
current = void 0;
|
|
1127
|
+
break;
|
|
1128
|
+
}
|
|
1129
|
+
current = current[part];
|
|
1130
|
+
}
|
|
1131
|
+
if (typeof current === "boolean") {
|
|
1132
|
+
return current;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
return void 0;
|
|
1136
|
+
}
|
|
1137
|
+
function parseTimestampMs(value) {
|
|
1138
|
+
if (!value) return void 0;
|
|
1139
|
+
const timestamp = Date.parse(value);
|
|
1140
|
+
return Number.isFinite(timestamp) ? timestamp : void 0;
|
|
1141
|
+
}
|
|
1142
|
+
function listJsonFiles(dir) {
|
|
1143
|
+
try {
|
|
1144
|
+
return fs.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => path.join(dir, entry.name));
|
|
1145
|
+
} catch {
|
|
1146
|
+
return [];
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
function inactiveDashboardRunKey(run) {
|
|
1150
|
+
return [
|
|
1151
|
+
run.kind,
|
|
1152
|
+
normalizeRunStatus(run.status),
|
|
1153
|
+
normalizeDashboardText(run.title ?? run.id),
|
|
1154
|
+
normalizeDashboardText(run.errorReason ?? "")
|
|
1155
|
+
].join("\0");
|
|
1156
|
+
}
|
|
1157
|
+
function extractTitle(prompt, intentOrGoal, fallbackId) {
|
|
1158
|
+
const promptTitle = extractTitleFromPrompt(prompt);
|
|
1159
|
+
if (promptTitle) return promptTitle;
|
|
1160
|
+
const intentTitle = extractTitleFromPrompt(intentOrGoal);
|
|
1161
|
+
if (intentTitle) return intentTitle;
|
|
1162
|
+
return fallbackId.includes("-") ? fallbackId.split("-")[0] || fallbackId.slice(0, 12) : fallbackId.slice(0, 12);
|
|
1163
|
+
}
|
|
1164
|
+
function deriveStatus(record) {
|
|
1165
|
+
const explicitStatus = readString2(record, ["status", "state", "submission_status", "submissionStatus", "phase"]) ?? readNestedString2(record, [
|
|
1166
|
+
["outcome", "execution", "status"],
|
|
1167
|
+
["outcome", "verification", "status"],
|
|
1168
|
+
["verification", "status"]
|
|
1169
|
+
]);
|
|
1170
|
+
if (explicitStatus) return explicitStatus;
|
|
1171
|
+
const success = readBoolean(record, ["success"]);
|
|
1172
|
+
if (success === true) return "completed";
|
|
1173
|
+
if (success === false) return "failed";
|
|
1174
|
+
return "unknown";
|
|
1175
|
+
}
|
|
1176
|
+
function normalizeTerminationReason(reason) {
|
|
1177
|
+
const normalized = reason.trim().toLowerCase();
|
|
1178
|
+
if (normalized === "completed") return void 0;
|
|
1179
|
+
if (normalized === "timeout" || normalized === "timedout" || normalized === "timed_out") {
|
|
1180
|
+
return "timed-out";
|
|
1181
|
+
}
|
|
1182
|
+
if (normalized.startsWith("canceled_") || normalized.startsWith("cancelled_")) {
|
|
1183
|
+
return "canceled";
|
|
1184
|
+
}
|
|
1185
|
+
if (normalized === "failed_crash") return "crashed";
|
|
1186
|
+
if (normalized.startsWith("failed_"))
|
|
1187
|
+
return normalized.slice("failed_".length).replace(/_/g, "-");
|
|
1188
|
+
return normalized.replace(/_/g, "-");
|
|
1189
|
+
}
|
|
1190
|
+
function deriveErrorReason(record) {
|
|
1191
|
+
const explicitReason = readString2(record, [
|
|
1192
|
+
"errorMessage",
|
|
1193
|
+
"error",
|
|
1194
|
+
"failureReason",
|
|
1195
|
+
"terminationSource"
|
|
1196
|
+
]);
|
|
1197
|
+
if (explicitReason) return explicitReason;
|
|
1198
|
+
if (readBoolean(record, ["success"]) !== false) return void 0;
|
|
1199
|
+
if (readBoolean(record, ["timedOut"])) return "timed-out";
|
|
1200
|
+
const terminationReason = readString2(record, ["terminationReason"]);
|
|
1201
|
+
return terminationReason ? normalizeTerminationReason(terminationReason) : void 0;
|
|
1202
|
+
}
|
|
1203
|
+
function isVariantSidecarFile(filePath) {
|
|
1204
|
+
const fileName = path.basename(filePath);
|
|
1205
|
+
return fileName.endsWith(".lifecycle.json") || fileName.endsWith(".adaptive-setup.json");
|
|
1206
|
+
}
|
|
1207
|
+
function computeRunHealth(filePath, stateRecord) {
|
|
1208
|
+
const healthStartMs = timingHealthActive ? Date.now() : 0;
|
|
1209
|
+
try {
|
|
1210
|
+
const snapshot = buildCompetitionHealthSnapshot({ stateFilePath: filePath, stateRecord });
|
|
1211
|
+
const events = classifyRunHealth(snapshot);
|
|
1212
|
+
const summary = summarizeRunHealth(events);
|
|
1213
|
+
const topEvent = events[0];
|
|
1214
|
+
if (!topEvent) return void 0;
|
|
1215
|
+
const isNominal = topEvent.category === "working" || topEvent.category === "idle";
|
|
1216
|
+
const stalledEvent = events.find((event) => event.category === "stalled");
|
|
1217
|
+
const stalledForMs = stalledEvent && typeof stalledEvent.evidence[0]?.data?.staleForMs === "number" ? stalledEvent.evidence[0].data.staleForMs : void 0;
|
|
1218
|
+
return {
|
|
1219
|
+
topCategory: topEvent.category,
|
|
1220
|
+
worstSeverity: summary.worstSeverity,
|
|
1221
|
+
eventCount: isNominal ? 0 : events.length,
|
|
1222
|
+
stalled: stalledEvent !== void 0,
|
|
1223
|
+
stalledForMs
|
|
1224
|
+
};
|
|
1225
|
+
} catch {
|
|
1226
|
+
return void 0;
|
|
1227
|
+
} finally {
|
|
1228
|
+
if (timingHealthActive) {
|
|
1229
|
+
timingHealthMs += Date.now() - healthStartMs;
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
function summarizeFileWithRecord(filePath, kind) {
|
|
1234
|
+
const record = readJson(filePath);
|
|
1235
|
+
if (!record) return null;
|
|
1236
|
+
const id = readString2(record, ["taskId", "task_id", "workflowId", "workflow_id", "runId", "id"]) ?? path.basename(filePath, ".json");
|
|
1237
|
+
const status = deriveStatus(record);
|
|
1238
|
+
const provider = readString2(record, ["provider", "providerId", "selectedProvider"]);
|
|
1239
|
+
const model = readString2(record, ["model", "modelId", "selectedModel"]);
|
|
1240
|
+
const stage = readString2(record, ["stage", "currentStage", "lifecycleState", "step"]);
|
|
1241
|
+
const updatedAt = readString2(record, ["updatedAt", "updated_at", "completedAt", "startedAt"]);
|
|
1242
|
+
const costUsd = readNumber2(record, ["costUsd", "cost_usd", "totalCostUsd"]);
|
|
1243
|
+
const inputTokens = readNestedNumber(record, [
|
|
1244
|
+
["tokenUsage", "inputTokens"],
|
|
1245
|
+
["usage", "inputTokens"]
|
|
1246
|
+
]);
|
|
1247
|
+
const outputTokens = readNestedNumber(record, [
|
|
1248
|
+
["tokenUsage", "outputTokens"],
|
|
1249
|
+
["usage", "outputTokens"]
|
|
1250
|
+
]);
|
|
1251
|
+
const tokenCount = readNumber2(record, ["tokens", "totalTokens", "token_count", "tokensUsed"]) ?? (inputTokens !== void 0 || outputTokens !== void 0 ? (inputTokens ?? 0) + (outputTokens ?? 0) : void 0);
|
|
1252
|
+
const filesChanged = collectFilesChanged(record);
|
|
1253
|
+
const gates = collectGates(record);
|
|
1254
|
+
const promptRaw = readString2(record, ["prompt"]);
|
|
1255
|
+
const title = extractTitle(promptRaw, readString2(record, ["intent", "goal"]), id);
|
|
1256
|
+
const startedAt = readString2(record, ["startedAt", "started_at", "createdAt"]);
|
|
1257
|
+
const startedAtMs = parseTimestampMs(startedAt);
|
|
1258
|
+
const elapsedMs = readNumber2(record, ["elapsedMs", "elapsed_ms", "durationMs", "duration_ms"]);
|
|
1259
|
+
const strategy = readString2(record, ["strategy", "executionStrategy"]);
|
|
1260
|
+
const score = readNestedNumber(record, [
|
|
1261
|
+
["outcome", "score"],
|
|
1262
|
+
["winner", "score"],
|
|
1263
|
+
["judgeSelectedTopPick", "score"]
|
|
1264
|
+
]) ?? readNumber2(record, ["score", "winnerScore"]);
|
|
1265
|
+
const errorReason = deriveErrorReason(record);
|
|
1266
|
+
const initiatedBy = readString2(record, ["initiatedBy", "initiated_by"]);
|
|
1267
|
+
const health = kind === "competition" || kind === "background" ? computeRunHealth(filePath, record) : void 0;
|
|
1268
|
+
const pid = readNumber2(record, ["pid"]);
|
|
1269
|
+
const launcherPid = readNumber2(record, ["launcherPid"]);
|
|
1270
|
+
const processGone = pid !== void 0 && isActiveRunStatus(status) && !isPidAlive(pid) ? true : void 0;
|
|
1271
|
+
return {
|
|
1272
|
+
summary: {
|
|
1273
|
+
id,
|
|
1274
|
+
kind,
|
|
1275
|
+
status,
|
|
1276
|
+
provider,
|
|
1277
|
+
model,
|
|
1278
|
+
stage,
|
|
1279
|
+
cost: formatCost(costUsd),
|
|
1280
|
+
costUsd,
|
|
1281
|
+
tokens: formatTokens(tokenCount),
|
|
1282
|
+
tokenCount,
|
|
1283
|
+
filesChanged,
|
|
1284
|
+
gates,
|
|
1285
|
+
updatedAt,
|
|
1286
|
+
sourcePath: filePath,
|
|
1287
|
+
title,
|
|
1288
|
+
startedAtMs,
|
|
1289
|
+
elapsedMs,
|
|
1290
|
+
strategy,
|
|
1291
|
+
score,
|
|
1292
|
+
errorReason,
|
|
1293
|
+
initiatedBy,
|
|
1294
|
+
health,
|
|
1295
|
+
pid,
|
|
1296
|
+
launcherPid,
|
|
1297
|
+
processGone
|
|
1298
|
+
},
|
|
1299
|
+
record
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
function isPidAlive(pid) {
|
|
1303
|
+
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
1304
|
+
if (pid === process.pid) return true;
|
|
1305
|
+
try {
|
|
1306
|
+
process.kill(pid, 0);
|
|
1307
|
+
return true;
|
|
1308
|
+
} catch (error) {
|
|
1309
|
+
return error.code === "EPERM";
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
function pushDetailLine(lines, label, value) {
|
|
1313
|
+
if (value && value.trim().length > 0) lines.push(`${label}: ${value}`);
|
|
1314
|
+
}
|
|
1315
|
+
function summarizeFilesChanged(record) {
|
|
1316
|
+
const filesChangedArray = readNestedValue(record, ["execution", "filesChanged"]) ?? readNestedValue(record, ["outcome", "execution", "filesChanged"]);
|
|
1317
|
+
const filesChanged = Array.isArray(filesChangedArray) ? filesChangedArray.length : readNestedNumber(record, [
|
|
1318
|
+
["execution", "filesChanged"],
|
|
1319
|
+
["outcome", "execution", "filesChanged"],
|
|
1320
|
+
["filesChanged"],
|
|
1321
|
+
["gitMetrics", "filesChanged"],
|
|
1322
|
+
["worktreeSummary", "filesChanged"]
|
|
1323
|
+
]);
|
|
1324
|
+
const linesAdded = readNestedNumber(record, [
|
|
1325
|
+
["linesAdded"],
|
|
1326
|
+
["gitMetrics", "linesAdded"],
|
|
1327
|
+
["worktreeSummary", "insertions"]
|
|
1328
|
+
]);
|
|
1329
|
+
const linesRemoved = readNestedNumber(record, [
|
|
1330
|
+
["linesRemoved"],
|
|
1331
|
+
["gitMetrics", "linesDeleted"],
|
|
1332
|
+
["worktreeSummary", "deletions"]
|
|
1333
|
+
]);
|
|
1334
|
+
if (filesChanged === void 0 && linesAdded === void 0 && linesRemoved === void 0) {
|
|
1335
|
+
return void 0;
|
|
1336
|
+
}
|
|
1337
|
+
return [
|
|
1338
|
+
filesChanged !== void 0 ? `${filesChanged} files` : void 0,
|
|
1339
|
+
linesAdded !== void 0 ? `+${linesAdded}` : void 0,
|
|
1340
|
+
linesRemoved !== void 0 ? `-${linesRemoved}` : void 0
|
|
1341
|
+
].filter(Boolean).join(", ");
|
|
1342
|
+
}
|
|
1343
|
+
function collectArtifactPaths(record) {
|
|
1344
|
+
return [
|
|
1345
|
+
readNestedString2(record, [
|
|
1346
|
+
["execution", "artifactPath"],
|
|
1347
|
+
["outcome", "execution", "artifactPath"],
|
|
1348
|
+
["artifactPath"],
|
|
1349
|
+
["planArtifactPath"],
|
|
1350
|
+
["manifestPath"],
|
|
1351
|
+
["synthesisArtifactPath"],
|
|
1352
|
+
["workerPacketArtifactPath"]
|
|
1353
|
+
]),
|
|
1354
|
+
...readNestedStringArray(record, [["artifactPaths"], ["artifacts"]])
|
|
1355
|
+
].filter((entry) => Boolean(entry));
|
|
1356
|
+
}
|
|
1357
|
+
function extractGoalSatisfaction(record) {
|
|
1358
|
+
if (readString2(record, ["command"]) !== "build") return void 0;
|
|
1359
|
+
const gateValue = readNestedValue(record, ["goalSatisfactionGate"]) ?? readNestedValue(record, ["outcome", "goalSatisfactionGate"]);
|
|
1360
|
+
if (!isRecord2(gateValue)) return void 0;
|
|
1361
|
+
const status = readString2(gateValue, ["status"]) ?? "unknown";
|
|
1362
|
+
const reason = readString2(gateValue, ["reason"]);
|
|
1363
|
+
const gaps = readNestedStringArray(gateValue, [["gaps"]]);
|
|
1364
|
+
const proposedFollowups = readNestedStringArray(gateValue, [["proposedFollowups"]]);
|
|
1365
|
+
const followupIntent = readString2(gateValue, ["followupIntent", "proposedFollowupIntent"]) ?? (status === "unsatisfied" && (gaps.length > 0 || proposedFollowups.length > 0) ? [
|
|
1366
|
+
"Follow up on goal-satisfaction gaps.",
|
|
1367
|
+
...gaps.map((gap) => `Gap: ${gap}`),
|
|
1368
|
+
...proposedFollowups.map((followup) => `Action: ${followup}`)
|
|
1369
|
+
].join("\n") : void 0);
|
|
1370
|
+
return { status, reason, gaps, followupIntent };
|
|
1371
|
+
}
|
|
1372
|
+
function extractCompetition(record) {
|
|
1373
|
+
const winnerRecord = readNestedValue(record, ["winner"]);
|
|
1374
|
+
const winnerFallbackParts = isRecord2(winnerRecord) ? [readString2(winnerRecord, ["provider"]), readString2(winnerRecord, ["strategy"])].filter(
|
|
1375
|
+
(part) => Boolean(part)
|
|
1376
|
+
) : [];
|
|
1377
|
+
const winnerFromObject = isRecord2(winnerRecord) ? readString2(winnerRecord, ["variant"]) ?? (winnerFallbackParts.length > 0 ? winnerFallbackParts.join(":") : void 0) : void 0;
|
|
1378
|
+
const winner = winnerFromObject ?? readNestedString2(record, [
|
|
1379
|
+
["winner"],
|
|
1380
|
+
["winnerVariant"],
|
|
1381
|
+
["declaredWinner"],
|
|
1382
|
+
["judgeSelectedTopPick", "variant"],
|
|
1383
|
+
["retainedWinner"]
|
|
1384
|
+
]);
|
|
1385
|
+
const scoreNumber = readNestedNumber(record, [
|
|
1386
|
+
["winner", "score"],
|
|
1387
|
+
["winnerScore"],
|
|
1388
|
+
["score"],
|
|
1389
|
+
["outcome", "score"],
|
|
1390
|
+
["judgeSelectedTopPick", "score"]
|
|
1391
|
+
]);
|
|
1392
|
+
const rationale = (isRecord2(winnerRecord) ? readString2(winnerRecord, ["winnerSelectionReason"]) : void 0) ?? readNestedString2(record, [["rationale"], ["reasoning"], ["judgeReasoning"], ["outcome"]]);
|
|
1393
|
+
const competitionView = extractCompetitionVariants(record);
|
|
1394
|
+
const variants = competitionView.variants.length > 0 ? competitionView.variants : void 0;
|
|
1395
|
+
if (!winner && scoreNumber === void 0 && !rationale && !variants) return void 0;
|
|
1396
|
+
return {
|
|
1397
|
+
winner,
|
|
1398
|
+
score: scoreNumber === void 0 ? void 0 : scoreNumber.toFixed(1),
|
|
1399
|
+
rationale,
|
|
1400
|
+
variants
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
function readTuiRunDetail(run) {
|
|
1404
|
+
const lines = [];
|
|
1405
|
+
const limitations = [];
|
|
1406
|
+
let artifacts = [];
|
|
1407
|
+
let filesChanged;
|
|
1408
|
+
let goalSatisfaction;
|
|
1409
|
+
let competition;
|
|
1410
|
+
pushDetailLine(lines, "Kind", run.kind);
|
|
1411
|
+
pushDetailLine(lines, "Run ID", run.id);
|
|
1412
|
+
pushDetailLine(lines, "Status", run.status);
|
|
1413
|
+
pushDetailLine(lines, "Provider", run.provider);
|
|
1414
|
+
pushDetailLine(lines, "Model", run.model);
|
|
1415
|
+
pushDetailLine(lines, "Stage", run.stage);
|
|
1416
|
+
pushDetailLine(lines, "Cost", run.cost);
|
|
1417
|
+
pushDetailLine(lines, "Tokens", run.tokens);
|
|
1418
|
+
pushDetailLine(lines, "Updated", run.updatedAt);
|
|
1419
|
+
if (run.sourcePath) {
|
|
1420
|
+
pushDetailLine(lines, "Source", run.sourcePath);
|
|
1421
|
+
const record = readJson(run.sourcePath);
|
|
1422
|
+
if (record) {
|
|
1423
|
+
pushDetailLine(lines, "Workflow", readString2(record, ["workflowId", "workflow_id"]));
|
|
1424
|
+
pushDetailLine(lines, "Sprint", readNestedString2(record, [["execution", "sprintId"]]));
|
|
1425
|
+
filesChanged = summarizeFilesChanged(record);
|
|
1426
|
+
artifacts = collectArtifactPaths(record);
|
|
1427
|
+
goalSatisfaction = extractGoalSatisfaction(record);
|
|
1428
|
+
competition = run.kind === "competition" || run.kind === "variant" ? extractCompetition(record) : void 0;
|
|
1429
|
+
} else {
|
|
1430
|
+
limitations.push("Detail source could not be read; showing summary fields only.");
|
|
1431
|
+
}
|
|
1432
|
+
} else {
|
|
1433
|
+
limitations.push("No source telemetry path is available for this run.");
|
|
1434
|
+
}
|
|
1435
|
+
limitations.push("Cancel is available only for a command spawned by this TUI session.");
|
|
1436
|
+
limitations.push("Raw logs are available only for the currently spawned command or chat turn.");
|
|
1437
|
+
if (!goalSatisfaction && run.kind !== "background") {
|
|
1438
|
+
limitations.push("Goal-satisfaction follow-up is available only for build outcomes.");
|
|
1439
|
+
}
|
|
1440
|
+
return {
|
|
1441
|
+
summary: run,
|
|
1442
|
+
sourcePath: run.sourcePath,
|
|
1443
|
+
lines,
|
|
1444
|
+
artifacts,
|
|
1445
|
+
filesChanged,
|
|
1446
|
+
goalSatisfaction,
|
|
1447
|
+
competition,
|
|
1448
|
+
limitations
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1451
|
+
var summaryCache = /* @__PURE__ */ new Map();
|
|
1452
|
+
function summarizeFileCached(filePath, mtimeMs, kind) {
|
|
1453
|
+
const cached = summaryCache.get(filePath);
|
|
1454
|
+
if (cached && cached.mtimeMs === mtimeMs) {
|
|
1455
|
+
if (isActiveRunStatus(cached.summary.status)) {
|
|
1456
|
+
const processGone = cached.summary.pid !== void 0 ? !isPidAlive(cached.summary.pid) ? true : void 0 : cached.summary.processGone;
|
|
1457
|
+
const health = (kind === "competition" || kind === "background") && cached.record !== void 0 ? computeRunHealth(filePath, cached.record) : cached.summary.health;
|
|
1458
|
+
const healthChanged = !isSameRunHealth(cached.summary.health, health);
|
|
1459
|
+
const livenessChanged = processGone !== cached.summary.processGone;
|
|
1460
|
+
if (healthChanged || livenessChanged) {
|
|
1461
|
+
const refreshed = { ...cached.summary, processGone, health };
|
|
1462
|
+
summaryCache.set(filePath, { ...cached, mtimeMs, summary: refreshed });
|
|
1463
|
+
return refreshed;
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
return cached.summary;
|
|
1467
|
+
}
|
|
1468
|
+
const summarized = summarizeFileWithRecord(filePath, kind);
|
|
1469
|
+
if (summarized) {
|
|
1470
|
+
const retainRecord = kind === "competition" || kind === "background";
|
|
1471
|
+
summaryCache.set(filePath, {
|
|
1472
|
+
mtimeMs,
|
|
1473
|
+
summary: summarized.summary,
|
|
1474
|
+
record: retainRecord ? summarized.record : void 0,
|
|
1475
|
+
kind
|
|
1476
|
+
});
|
|
1477
|
+
return summarized.summary;
|
|
1478
|
+
}
|
|
1479
|
+
if (cached) {
|
|
1480
|
+
return {
|
|
1481
|
+
...cached.summary,
|
|
1482
|
+
status: `stale (last known: ${cached.summary.status})`
|
|
1483
|
+
};
|
|
1484
|
+
}
|
|
1485
|
+
return null;
|
|
1486
|
+
}
|
|
1487
|
+
function isSameRunHealth(a, b) {
|
|
1488
|
+
if (a === b) return true;
|
|
1489
|
+
if (!a || !b) return false;
|
|
1490
|
+
return a.topCategory === b.topCategory && a.worstSeverity === b.worstSeverity && a.eventCount === b.eventCount && a.stalled === b.stalled && a.stalledForMs === b.stalledForMs;
|
|
1491
|
+
}
|
|
1492
|
+
function pruneSummaryCache(seenPaths) {
|
|
1493
|
+
for (const key of summaryCache.keys()) {
|
|
1494
|
+
if (!seenPaths.has(key)) {
|
|
1495
|
+
summaryCache.delete(key);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
function collectFromDir(repoRoot, relativeDir, kind, seenPaths) {
|
|
1500
|
+
const dir = path.join(repoRoot, relativeDir);
|
|
1501
|
+
return listJsonFiles(dir).filter((filePath) => kind !== "variant" || !isVariantSidecarFile(filePath)).map((filePath) => {
|
|
1502
|
+
try {
|
|
1503
|
+
return { filePath, mtimeMs: fs.statSync(filePath).mtimeMs };
|
|
1504
|
+
} catch {
|
|
1505
|
+
return null;
|
|
1506
|
+
}
|
|
1507
|
+
}).filter((entry) => entry !== null).sort((a, b) => b.mtimeMs - a.mtimeMs).slice(0, MAX_DASHBOARD_FILES_PER_DIR).map(({ filePath, mtimeMs }) => {
|
|
1508
|
+
seenPaths.add(filePath);
|
|
1509
|
+
const summary = summarizeFileCached(filePath, mtimeMs, kind);
|
|
1510
|
+
const observedAtMs = parseTimestampMs(summary?.updatedAt) ?? mtimeMs;
|
|
1511
|
+
return summary ? { summary, observedAtMs, mtimeMs } : null;
|
|
1512
|
+
}).filter((entry) => entry !== null);
|
|
1513
|
+
}
|
|
1514
|
+
function collectFlywheelManifests(repoRoot, seenPaths) {
|
|
1515
|
+
const flywheelDir = path.join(repoRoot, ".poetic/tmp/flywheel");
|
|
1516
|
+
let entries;
|
|
1517
|
+
try {
|
|
1518
|
+
entries = fs.readdirSync(flywheelDir, { withFileTypes: true });
|
|
1519
|
+
} catch {
|
|
1520
|
+
return [];
|
|
1521
|
+
}
|
|
1522
|
+
return entries.filter((entry) => entry.isDirectory()).map((entry) => path.join(flywheelDir, entry.name, "manifest.json")).map((filePath) => {
|
|
1523
|
+
let mtimeMs = 0;
|
|
1524
|
+
try {
|
|
1525
|
+
mtimeMs = fs.statSync(filePath).mtimeMs;
|
|
1526
|
+
} catch {
|
|
1527
|
+
}
|
|
1528
|
+
seenPaths.add(filePath);
|
|
1529
|
+
const summary = summarizeFileCached(filePath, mtimeMs, "workflow");
|
|
1530
|
+
if (!summary) return null;
|
|
1531
|
+
const observedAtMs = parseTimestampMs(summary.updatedAt) ?? mtimeMs;
|
|
1532
|
+
return { summary, observedAtMs, mtimeMs };
|
|
1533
|
+
}).filter((entry) => entry !== null);
|
|
1534
|
+
}
|
|
1535
|
+
function parsePromotedDecision(record) {
|
|
1536
|
+
const id = readString2(record, ["id"]);
|
|
1537
|
+
const title = readString2(record, ["title"]);
|
|
1538
|
+
const severity = readString2(record, ["severity"]);
|
|
1539
|
+
const disposition = readString2(record, ["disposition"]);
|
|
1540
|
+
if (!id || !title || !severity || disposition !== "pending") {
|
|
1541
|
+
return null;
|
|
1542
|
+
}
|
|
1543
|
+
const sourcePr = readNumber2(record, ["sourcePr"]);
|
|
1544
|
+
const detail = readStringArray(record, ["detail"]);
|
|
1545
|
+
return {
|
|
1546
|
+
id,
|
|
1547
|
+
title,
|
|
1548
|
+
severity,
|
|
1549
|
+
...sourcePr !== void 0 ? { sourcePr } : {},
|
|
1550
|
+
disposition,
|
|
1551
|
+
detail
|
|
1552
|
+
};
|
|
1553
|
+
}
|
|
1554
|
+
function collectPromotedDecisions(repoRoot) {
|
|
1555
|
+
const dir = path.join(repoRoot, ".poetic/telemetry/state/decisions");
|
|
1556
|
+
const files = listJsonFiles(dir).map((filePath) => {
|
|
1557
|
+
try {
|
|
1558
|
+
return { filePath, mtimeMs: fs.statSync(filePath).mtimeMs };
|
|
1559
|
+
} catch {
|
|
1560
|
+
return null;
|
|
1561
|
+
}
|
|
1562
|
+
}).filter((entry) => entry !== null).sort((a, b) => b.mtimeMs - a.mtimeMs).slice(0, MAX_PROMOTED_DECISIONS);
|
|
1563
|
+
const decisions = [];
|
|
1564
|
+
for (const { filePath } of files) {
|
|
1565
|
+
const record = readJson(filePath);
|
|
1566
|
+
if (!record) continue;
|
|
1567
|
+
const decision = parsePromotedDecision(record);
|
|
1568
|
+
if (decision) {
|
|
1569
|
+
decisions.push(decision);
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
return decisions;
|
|
1573
|
+
}
|
|
1574
|
+
function collectPendingBlockers(repoRoot, nowMs) {
|
|
1575
|
+
const dir = path.join(repoRoot, ".poetic/blocker-answers");
|
|
1576
|
+
let hiddenPendingBlockerCount = 0;
|
|
1577
|
+
const pendingBlockers = listJsonFiles(dir).filter((filePath) => filePath.endsWith(".pending.json")).map((filePath) => {
|
|
1578
|
+
try {
|
|
1579
|
+
return { filePath, mtimeMs: fs.statSync(filePath).mtimeMs };
|
|
1580
|
+
} catch {
|
|
1581
|
+
return null;
|
|
1582
|
+
}
|
|
1583
|
+
}).filter((entry) => entry !== null).filter((entry) => nowMs - entry.mtimeMs <= STALE_RUN_AGE_MS).sort((a, b) => b.mtimeMs - a.mtimeMs).flatMap(({ filePath }) => {
|
|
1584
|
+
const record = readJson(filePath);
|
|
1585
|
+
if (!record) return [];
|
|
1586
|
+
const runId = readString2(record, ["runId"]) ?? path.basename(filePath, ".pending.json");
|
|
1587
|
+
const intent = readString2(record, ["intent"]);
|
|
1588
|
+
const unanswered = Array.isArray(record.unanswered) ? new Set(
|
|
1589
|
+
record.unanswered.filter(
|
|
1590
|
+
(id) => typeof id === "string" && id.trim().length > 0
|
|
1591
|
+
)
|
|
1592
|
+
) : /* @__PURE__ */ new Set();
|
|
1593
|
+
const blockers = Array.isArray(record.blockers) ? record.blockers : [];
|
|
1594
|
+
const visibleBlockers = blockers.filter(isRecord2).filter((blocker) => {
|
|
1595
|
+
const blockerId = readString2(blocker, ["id"]);
|
|
1596
|
+
return blockerId !== void 0 && unanswered.has(blockerId);
|
|
1597
|
+
}).map((blocker) => ({
|
|
1598
|
+
runId,
|
|
1599
|
+
blockerId: readString2(blocker, ["id"]) ?? "unknown",
|
|
1600
|
+
intent,
|
|
1601
|
+
category: readString2(blocker, ["category"]),
|
|
1602
|
+
severity: readString2(blocker, ["severity"]),
|
|
1603
|
+
question: readString2(blocker, ["question"]) ?? "Unanswered blocker",
|
|
1604
|
+
sourcePath: filePath
|
|
1605
|
+
}));
|
|
1606
|
+
hiddenPendingBlockerCount += Math.max(
|
|
1607
|
+
0,
|
|
1608
|
+
visibleBlockers.length - MAX_PENDING_BLOCKERS_PER_RUN
|
|
1609
|
+
);
|
|
1610
|
+
return visibleBlockers.slice(0, MAX_PENDING_BLOCKERS_PER_RUN);
|
|
1611
|
+
});
|
|
1612
|
+
hiddenPendingBlockerCount += Math.max(0, pendingBlockers.length - MAX_PENDING_BLOCKERS);
|
|
1613
|
+
return {
|
|
1614
|
+
pendingBlockers: pendingBlockers.slice(0, MAX_PENDING_BLOCKERS),
|
|
1615
|
+
hiddenPendingBlockerCount
|
|
1616
|
+
};
|
|
1617
|
+
}
|
|
1618
|
+
function runRecencyKey(run) {
|
|
1619
|
+
const updated = run.updatedAt ? Date.parse(run.updatedAt) : Number.NaN;
|
|
1620
|
+
if (Number.isFinite(updated)) return updated;
|
|
1621
|
+
return run.startedAtMs ?? 0;
|
|
1622
|
+
}
|
|
1623
|
+
function selectActiveRun(runs) {
|
|
1624
|
+
let selected;
|
|
1625
|
+
let selectedKey = Number.NEGATIVE_INFINITY;
|
|
1626
|
+
for (const run of runs) {
|
|
1627
|
+
if (!isActiveRunStatus(run.status) || run.processGone === true) continue;
|
|
1628
|
+
const key = runRecencyKey(run);
|
|
1629
|
+
if (selected === void 0 || key >= selectedKey) {
|
|
1630
|
+
selected = run;
|
|
1631
|
+
selectedKey = key;
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
return selected;
|
|
1635
|
+
}
|
|
1636
|
+
function selectDashboardRuns(collectedRuns, nowMs) {
|
|
1637
|
+
let hiddenStaleRunCount = 0;
|
|
1638
|
+
const visibleRuns = [];
|
|
1639
|
+
for (const run of collectedRuns) {
|
|
1640
|
+
const ageMs = nowMs - run.observedAtMs;
|
|
1641
|
+
const maxAgeMs = run.summary.kind === "background" && !isActiveRunStatus(run.summary.status) ? INACTIVE_BACKGROUND_RUN_AGE_MS : STALE_RUN_AGE_MS;
|
|
1642
|
+
if (ageMs > maxAgeMs) {
|
|
1643
|
+
hiddenStaleRunCount += 1;
|
|
1644
|
+
continue;
|
|
1645
|
+
}
|
|
1646
|
+
visibleRuns.push(run);
|
|
1647
|
+
}
|
|
1648
|
+
const dedupedRuns = dedupeInactiveDashboardRuns(visibleRuns);
|
|
1649
|
+
const runs = dedupedRuns.sort((a, b) => a.observedAtMs - b.observedAtMs || a.mtimeMs - b.mtimeMs).slice(-MAX_DASHBOARD_RUNS).map((entry) => entry.summary);
|
|
1650
|
+
return { runs, hiddenStaleRunCount };
|
|
1651
|
+
}
|
|
1652
|
+
function dedupeInactiveDashboardRuns(runs) {
|
|
1653
|
+
const selected = [];
|
|
1654
|
+
const seenInactiveKeys = /* @__PURE__ */ new Set();
|
|
1655
|
+
for (const run of [...runs].sort(
|
|
1656
|
+
(a, b) => b.observedAtMs - a.observedAtMs || b.mtimeMs - a.mtimeMs
|
|
1657
|
+
)) {
|
|
1658
|
+
if (isActiveRunStatus(run.summary.status)) {
|
|
1659
|
+
selected.push(run);
|
|
1660
|
+
continue;
|
|
1661
|
+
}
|
|
1662
|
+
const key = inactiveDashboardRunKey(run.summary);
|
|
1663
|
+
if (seenInactiveKeys.has(key)) continue;
|
|
1664
|
+
seenInactiveKeys.add(key);
|
|
1665
|
+
selected.push(run);
|
|
1666
|
+
}
|
|
1667
|
+
return selected;
|
|
1668
|
+
}
|
|
1669
|
+
function normalizeDashboardText(value) {
|
|
1670
|
+
return value.trim().replace(/\s+/g, " ").toLowerCase();
|
|
1671
|
+
}
|
|
1672
|
+
var GIT_INFO_CACHE_TTL_MS = 5e3;
|
|
1673
|
+
var gitInfoCache = /* @__PURE__ */ new Map();
|
|
1674
|
+
function readCurrentBranch(repoRoot) {
|
|
1675
|
+
try {
|
|
1676
|
+
return execFileSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
|
|
1677
|
+
cwd: repoRoot,
|
|
1678
|
+
encoding: "utf8",
|
|
1679
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
1680
|
+
timeout: 2e3
|
|
1681
|
+
}).trim();
|
|
1682
|
+
} catch {
|
|
1683
|
+
return "HEAD";
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
function readChangedFiles(repoRoot) {
|
|
1687
|
+
try {
|
|
1688
|
+
return execFileSync("git", ["status", "--short"], {
|
|
1689
|
+
cwd: repoRoot,
|
|
1690
|
+
encoding: "utf8",
|
|
1691
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
1692
|
+
timeout: 2e3
|
|
1693
|
+
}).split(/\r?\n/).filter((line) => line.trim().length > 0).map((line) => {
|
|
1694
|
+
const normalized = line.trim();
|
|
1695
|
+
const renamed = normalized.match(/^R\S*\s+(.+?)\s+->\s+(.+)$/);
|
|
1696
|
+
if (renamed?.[2]) return renamed[2];
|
|
1697
|
+
return line.slice(3).trim();
|
|
1698
|
+
}).filter(Boolean).slice(0, 8);
|
|
1699
|
+
} catch {
|
|
1700
|
+
return [];
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
function readGitInfo(repoRoot) {
|
|
1704
|
+
const nowMs = Date.now();
|
|
1705
|
+
const cached = gitInfoCache.get(repoRoot);
|
|
1706
|
+
if (cached && nowMs - cached.cachedAtMs < GIT_INFO_CACHE_TTL_MS) {
|
|
1707
|
+
return { branch: cached.branch, changedFiles: cached.changedFiles };
|
|
1708
|
+
}
|
|
1709
|
+
const branch = readCurrentBranch(repoRoot);
|
|
1710
|
+
const changedFiles = readChangedFiles(repoRoot);
|
|
1711
|
+
gitInfoCache.set(repoRoot, { branch, changedFiles, cachedAtMs: nowMs });
|
|
1712
|
+
return { branch, changedFiles };
|
|
1713
|
+
}
|
|
1714
|
+
var timingHealthMs = 0;
|
|
1715
|
+
var timingHealthActive = false;
|
|
1716
|
+
var timingFilesRead = 0;
|
|
1717
|
+
var timingFilesReadActive = false;
|
|
1718
|
+
function appendTuiTimingLine(repoRoot, startedAtMs, gitMs, healthMs, filesRead) {
|
|
1719
|
+
try {
|
|
1720
|
+
const timingPath = path.join(repoRoot, ".poetic/tmp/tui-timing.jsonl");
|
|
1721
|
+
const line = JSON.stringify({
|
|
1722
|
+
ts: new Date(startedAtMs).toISOString(),
|
|
1723
|
+
totalMs: Date.now() - startedAtMs,
|
|
1724
|
+
gitMs,
|
|
1725
|
+
healthMs,
|
|
1726
|
+
filesRead
|
|
1727
|
+
});
|
|
1728
|
+
fs.mkdirSync(path.dirname(timingPath), { recursive: true });
|
|
1729
|
+
fs.appendFileSync(timingPath, `${line}
|
|
1730
|
+
`);
|
|
1731
|
+
} catch {
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
function summarizeGateState(runs) {
|
|
1735
|
+
return [...new Set(runs.flatMap((run) => run.gates ?? []))].slice(0, 4);
|
|
1736
|
+
}
|
|
1737
|
+
function sumCosts(runs) {
|
|
1738
|
+
const total = runs.reduce((sum, run) => sum + (run.costUsd ?? 0), 0);
|
|
1739
|
+
return total > 0 ? formatCost(total) : void 0;
|
|
1740
|
+
}
|
|
1741
|
+
function sumTokens(runs) {
|
|
1742
|
+
const total = runs.reduce((sum, run) => sum + (run.tokenCount ?? 0), 0);
|
|
1743
|
+
return total > 0 ? formatTokens(total) : void 0;
|
|
1744
|
+
}
|
|
1745
|
+
function readTuiDashboardState(repoRoot) {
|
|
1746
|
+
const timingEnabled = readEnv(POETIC_TUI_TIMING).value === true;
|
|
1747
|
+
const startedAtMs = timingEnabled ? Date.now() : 0;
|
|
1748
|
+
if (timingEnabled) {
|
|
1749
|
+
timingHealthMs = 0;
|
|
1750
|
+
timingFilesRead = 0;
|
|
1751
|
+
timingHealthActive = true;
|
|
1752
|
+
timingFilesReadActive = true;
|
|
1753
|
+
}
|
|
1754
|
+
const nowMs = Date.now();
|
|
1755
|
+
const seenPaths = /* @__PURE__ */ new Set();
|
|
1756
|
+
const { runs, hiddenStaleRunCount } = selectDashboardRuns(
|
|
1757
|
+
[
|
|
1758
|
+
...collectFromDir(repoRoot, ".poetic/telemetry/state/background", "background", seenPaths),
|
|
1759
|
+
...collectFromDir(repoRoot, ".poetic/telemetry/state/competitions", "competition", seenPaths),
|
|
1760
|
+
...collectFromDir(repoRoot, ".poetic/telemetry/state/variants", "variant", seenPaths),
|
|
1761
|
+
...collectFlywheelManifests(repoRoot, seenPaths)
|
|
1762
|
+
],
|
|
1763
|
+
nowMs
|
|
1764
|
+
);
|
|
1765
|
+
pruneSummaryCache(seenPaths);
|
|
1766
|
+
const { pendingBlockers, hiddenPendingBlockerCount } = collectPendingBlockers(repoRoot, nowMs);
|
|
1767
|
+
const promotedDecisions = collectPromotedDecisions(repoRoot);
|
|
1768
|
+
const activeRun = selectActiveRun(runs);
|
|
1769
|
+
const gitStartMs = timingEnabled ? Date.now() : 0;
|
|
1770
|
+
const { branch, changedFiles } = readGitInfo(repoRoot);
|
|
1771
|
+
const gitMs = timingEnabled ? Date.now() - gitStartMs : 0;
|
|
1772
|
+
if (timingEnabled) {
|
|
1773
|
+
timingHealthActive = false;
|
|
1774
|
+
timingFilesReadActive = false;
|
|
1775
|
+
appendTuiTimingLine(repoRoot, startedAtMs, gitMs, timingHealthMs, timingFilesRead);
|
|
1776
|
+
}
|
|
1777
|
+
return {
|
|
1778
|
+
repoRoot,
|
|
1779
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1780
|
+
branch,
|
|
1781
|
+
changedFiles,
|
|
1782
|
+
activeRun,
|
|
1783
|
+
totalCost: sumCosts(runs),
|
|
1784
|
+
totalTokens: sumTokens(runs),
|
|
1785
|
+
gateSummary: summarizeGateState(runs),
|
|
1786
|
+
runs,
|
|
1787
|
+
pendingBlockers,
|
|
1788
|
+
promotedDecisions,
|
|
1789
|
+
hiddenPendingBlockerCount,
|
|
1790
|
+
hiddenStaleRunCount
|
|
1791
|
+
};
|
|
1792
|
+
}
|
|
1793
|
+
function createInitialTuiDashboardState(repoRoot) {
|
|
1794
|
+
return {
|
|
1795
|
+
repoRoot,
|
|
1796
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1797
|
+
branch: "...",
|
|
1798
|
+
changedFiles: [],
|
|
1799
|
+
gateSummary: [],
|
|
1800
|
+
runs: [],
|
|
1801
|
+
pendingBlockers: [],
|
|
1802
|
+
promotedDecisions: [],
|
|
1803
|
+
hiddenPendingBlockerCount: 0,
|
|
1804
|
+
hiddenStaleRunCount: 0
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
// src/cli/tui/actions.ts
|
|
1809
|
+
var WARN_INTENT_LENGTH = 4e3;
|
|
1810
|
+
var KNOWN_ESTIMATE_PROVIDERS = /* @__PURE__ */ new Set([
|
|
1811
|
+
"claude",
|
|
1812
|
+
"cursor",
|
|
1813
|
+
"codex",
|
|
1814
|
+
"gemini",
|
|
1815
|
+
"copilot",
|
|
1816
|
+
"opencode"
|
|
1817
|
+
]);
|
|
1818
|
+
var pricingTable = new DefaultPricingTable();
|
|
1819
|
+
var POETIC_PACKAGE_VERSION = typeof package_default.version === "string" && package_default.version.trim() ? package_default.version.trim() : "0.0.0";
|
|
1820
|
+
function quoteArg(arg) {
|
|
1821
|
+
if (/^[A-Za-z0-9_./:=@+-]+$/.test(arg)) return arg;
|
|
1822
|
+
return JSON.stringify(arg);
|
|
1823
|
+
}
|
|
1824
|
+
function commandDisplay(executable, argv) {
|
|
1825
|
+
return [executable.display, ...argv.map(quoteArg)].join(" ");
|
|
1826
|
+
}
|
|
1827
|
+
function createSandboxPosture(options) {
|
|
1828
|
+
if (options.mode === "none") {
|
|
1829
|
+
return {
|
|
1830
|
+
...options,
|
|
1831
|
+
active: false,
|
|
1832
|
+
boundaryAccepted: false,
|
|
1833
|
+
provenance: "none",
|
|
1834
|
+
display: "none"
|
|
1835
|
+
};
|
|
1836
|
+
}
|
|
1837
|
+
const attestation = detectSandboxBoundaryAttestation(options.providerName, options.providerId);
|
|
1838
|
+
const boundaryPolicy = resolveSandboxBoundaryPolicy(process.env.POETIC_SANDBOX_BOUNDARY_POLICY);
|
|
1839
|
+
const boundaryAccepted = isSandboxBoundaryAccepted(attestation, boundaryPolicy);
|
|
1840
|
+
const active = willSandboxBeActive(options.providerName, options.providerId);
|
|
1841
|
+
const status = active ? "active" : "inactive";
|
|
1842
|
+
return {
|
|
1843
|
+
...options,
|
|
1844
|
+
active,
|
|
1845
|
+
boundaryAccepted,
|
|
1846
|
+
provenance: attestation.provenance,
|
|
1847
|
+
display: `${options.mode} ${status} (${attestation.provenance})`
|
|
1848
|
+
};
|
|
1849
|
+
}
|
|
1850
|
+
function createCommandSandboxPosture() {
|
|
1851
|
+
return createSandboxPosture({
|
|
1852
|
+
mode: "workspace-write",
|
|
1853
|
+
providerName: "poetic-tui",
|
|
1854
|
+
providerId: "poetic-tui"
|
|
1855
|
+
});
|
|
1856
|
+
}
|
|
1857
|
+
function createReadOnlyChatSandboxPosture(provider) {
|
|
1858
|
+
return createSandboxPosture({
|
|
1859
|
+
mode: "read-only",
|
|
1860
|
+
providerName: provider ?? "anchored-chat",
|
|
1861
|
+
providerId: provider ?? "anchored-chat"
|
|
1862
|
+
});
|
|
1863
|
+
}
|
|
1864
|
+
function resolvePoeticExecutable(argv = process.argv) {
|
|
1865
|
+
const node = process.execPath;
|
|
1866
|
+
const entryPath = argv[1];
|
|
1867
|
+
const version = POETIC_PACKAGE_VERSION;
|
|
1868
|
+
if (entryPath && (entryPath.endsWith(".js") || entryPath.endsWith(".ts"))) {
|
|
1869
|
+
return {
|
|
1870
|
+
command: node,
|
|
1871
|
+
prefixArgs: [entryPath],
|
|
1872
|
+
display: `${quoteArg(node)} ${quoteArg(entryPath)}`,
|
|
1873
|
+
version
|
|
1874
|
+
};
|
|
1875
|
+
}
|
|
1876
|
+
return {
|
|
1877
|
+
command: "poetic",
|
|
1878
|
+
prefixArgs: [],
|
|
1879
|
+
display: "poetic",
|
|
1880
|
+
version
|
|
1881
|
+
};
|
|
1882
|
+
}
|
|
1883
|
+
function parseInput(input) {
|
|
1884
|
+
const trimmed = input.trim();
|
|
1885
|
+
if (!trimmed.startsWith("/")) {
|
|
1886
|
+
return { command: "chat", value: trimmed };
|
|
1887
|
+
}
|
|
1888
|
+
const match = /^\/([A-Za-z-]+)(?:\s+(.*))?$/.exec(trimmed);
|
|
1889
|
+
const command = normalizeTuiCommand(match?.[1]?.toLowerCase() ?? "help");
|
|
1890
|
+
const value = match?.[2]?.trim() ?? "";
|
|
1891
|
+
switch (command) {
|
|
1892
|
+
case "build":
|
|
1893
|
+
case "plan-run":
|
|
1894
|
+
case "next":
|
|
1895
|
+
case "quickstart":
|
|
1896
|
+
case "knowledge":
|
|
1897
|
+
case "run":
|
|
1898
|
+
case "compete":
|
|
1899
|
+
case "fusion":
|
|
1900
|
+
case "monitor":
|
|
1901
|
+
case "answer":
|
|
1902
|
+
case "clear":
|
|
1903
|
+
case "chat":
|
|
1904
|
+
case "help":
|
|
1905
|
+
case "quit":
|
|
1906
|
+
return { command, value };
|
|
1907
|
+
default:
|
|
1908
|
+
return { command: "help", value: command };
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
function buildKnowledgeArgv(value) {
|
|
1912
|
+
const parts = value.split(/\s+/).filter((part) => part.length > 0);
|
|
1913
|
+
const sub = parts[0]?.toLowerCase() ?? "status";
|
|
1914
|
+
const rest = parts.slice(1);
|
|
1915
|
+
switch (sub) {
|
|
1916
|
+
case "status":
|
|
1917
|
+
return ["knowledge", "status"];
|
|
1918
|
+
case "clear":
|
|
1919
|
+
return ["knowledge", "clear"];
|
|
1920
|
+
case "declare":
|
|
1921
|
+
return ["knowledge", "declare", rest.join(" ")];
|
|
1922
|
+
case "resolve":
|
|
1923
|
+
return ["knowledge", "resolve", rest[0] ?? ""];
|
|
1924
|
+
case "offer": {
|
|
1925
|
+
const refresh = rest.some((part) => part === "--refresh" || part === "refresh");
|
|
1926
|
+
const guidanceWords = rest.filter((part) => part !== "--refresh" && part !== "refresh");
|
|
1927
|
+
return [
|
|
1928
|
+
"knowledge",
|
|
1929
|
+
"offer",
|
|
1930
|
+
...refresh ? ["--refresh"] : [],
|
|
1931
|
+
...guidanceWords.length > 0 ? ["--guidance", guidanceWords.join(" ")] : []
|
|
1932
|
+
];
|
|
1933
|
+
}
|
|
1934
|
+
case "accept":
|
|
1935
|
+
return ["knowledge", "accept", rest[0] ?? "", rest[1] ?? ""];
|
|
1936
|
+
case "graduate":
|
|
1937
|
+
return ["knowledge", "graduate", rest[0] ?? ""];
|
|
1938
|
+
default:
|
|
1939
|
+
return ["knowledge", "status"];
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
function buildArgv(command) {
|
|
1943
|
+
switch (command.command) {
|
|
1944
|
+
case "plan-run":
|
|
1945
|
+
return ["plan", "create", "--decompose", command.value];
|
|
1946
|
+
case "build":
|
|
1947
|
+
return ["build", command.value];
|
|
1948
|
+
case "next":
|
|
1949
|
+
return ["next"];
|
|
1950
|
+
case "quickstart":
|
|
1951
|
+
return command.value ? ["quickstart", ...command.value.split(/\s+/).filter((part) => part.length > 0)] : ["quickstart"];
|
|
1952
|
+
case "knowledge":
|
|
1953
|
+
return buildKnowledgeArgv(command.value);
|
|
1954
|
+
case "run":
|
|
1955
|
+
return ["run", command.value];
|
|
1956
|
+
case "compete":
|
|
1957
|
+
return ["compete", command.value];
|
|
1958
|
+
case "fusion":
|
|
1959
|
+
return ["fusion", command.value];
|
|
1960
|
+
case "monitor":
|
|
1961
|
+
return command.value ? ["monitor", command.value, "--follow"] : ["monitor"];
|
|
1962
|
+
case "answer":
|
|
1963
|
+
return ["build"];
|
|
1964
|
+
case "clear":
|
|
1965
|
+
return [];
|
|
1966
|
+
case "chat":
|
|
1967
|
+
return [];
|
|
1968
|
+
case "help":
|
|
1969
|
+
return ["--help"];
|
|
1970
|
+
case "quit":
|
|
1971
|
+
return [];
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
function parseAnswerValue(value) {
|
|
1975
|
+
const separator = value.indexOf("=");
|
|
1976
|
+
if (separator <= 0) return {};
|
|
1977
|
+
const lhs = value.slice(0, separator).trim();
|
|
1978
|
+
const answer = value.slice(separator + 1).trim();
|
|
1979
|
+
if (!lhs || !answer) return { answer: answer || void 0 };
|
|
1980
|
+
const scopeSeparator = lhs.indexOf(":");
|
|
1981
|
+
if (scopeSeparator > 0) {
|
|
1982
|
+
const runId = lhs.slice(0, scopeSeparator).trim();
|
|
1983
|
+
const blockerId = lhs.slice(scopeSeparator + 1).trim();
|
|
1984
|
+
return {
|
|
1985
|
+
runId: runId || void 0,
|
|
1986
|
+
blockerId: blockerId || void 0,
|
|
1987
|
+
answer
|
|
1988
|
+
};
|
|
1989
|
+
}
|
|
1990
|
+
return { blockerId: lhs, answer };
|
|
1991
|
+
}
|
|
1992
|
+
function resolveBranch(repoRoot) {
|
|
1993
|
+
return getCurrentBranch(repoRoot);
|
|
1994
|
+
}
|
|
1995
|
+
function costUnknown(reason) {
|
|
1996
|
+
return {
|
|
1997
|
+
status: "unknown",
|
|
1998
|
+
label: "unknown",
|
|
1999
|
+
reason
|
|
2000
|
+
};
|
|
2001
|
+
}
|
|
2002
|
+
function costNotApplicable(reason) {
|
|
2003
|
+
return {
|
|
2004
|
+
status: "not_applicable",
|
|
2005
|
+
label: "not applicable",
|
|
2006
|
+
reason
|
|
2007
|
+
};
|
|
2008
|
+
}
|
|
2009
|
+
function formatUsd(amount) {
|
|
2010
|
+
if (amount < 0.01) return "<$0.01";
|
|
2011
|
+
return `$${amount.toFixed(2)}`;
|
|
2012
|
+
}
|
|
2013
|
+
function estimatePreviewCost(params) {
|
|
2014
|
+
const provider = params.provider.toLowerCase();
|
|
2015
|
+
if (!params.taskPrompt.trim()) {
|
|
2016
|
+
return costUnknown("No prompt text is available for a cost estimate.");
|
|
2017
|
+
}
|
|
2018
|
+
if (!KNOWN_ESTIMATE_PROVIDERS.has(provider)) {
|
|
2019
|
+
return costUnknown(`No local pricing estimate is available for provider ${params.provider}.`);
|
|
2020
|
+
}
|
|
2021
|
+
try {
|
|
2022
|
+
const estimate = estimateTaskCost(
|
|
2023
|
+
{
|
|
2024
|
+
taskPrompt: params.taskPrompt,
|
|
2025
|
+
provider,
|
|
2026
|
+
model: params.model,
|
|
2027
|
+
strategy: params.strategy
|
|
2028
|
+
},
|
|
2029
|
+
pricingTable
|
|
2030
|
+
);
|
|
2031
|
+
const theoretical = estimate.isTheoreticalCost ? " theoretical" : "";
|
|
2032
|
+
const modelSuffix = estimate.model ? `:${estimate.model}` : "";
|
|
2033
|
+
if (estimate.estimatedCostUsd === null) {
|
|
2034
|
+
return costUnknown(`No local pricing estimate is available for provider ${params.provider}.`);
|
|
2035
|
+
}
|
|
2036
|
+
return {
|
|
2037
|
+
status: "estimated",
|
|
2038
|
+
label: `${formatUsd(estimate.estimatedCostUsd)}${theoretical} (${estimate.confidence}, ${provider}${modelSuffix})`,
|
|
2039
|
+
reason: params.reason,
|
|
2040
|
+
estimatedUsd: estimate.estimatedCostUsd,
|
|
2041
|
+
provider,
|
|
2042
|
+
model: estimate.model,
|
|
2043
|
+
confidence: estimate.confidence,
|
|
2044
|
+
isTheoreticalCost: estimate.isTheoreticalCost,
|
|
2045
|
+
assumptions: estimate.assumptions
|
|
2046
|
+
};
|
|
2047
|
+
} catch (error) {
|
|
2048
|
+
return costUnknown(
|
|
2049
|
+
`Local cost estimator failed: ${error instanceof Error ? error.message : String(error)}`
|
|
2050
|
+
);
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
function estimateDefaultProviderCost(params) {
|
|
2054
|
+
try {
|
|
2055
|
+
const resolved = resolveConfig(void 0, params.repoRoot, { strictSynthesisModel: false });
|
|
2056
|
+
const provider = params.defaultProviderOverride ?? resolved.defaultProvider.value;
|
|
2057
|
+
return estimatePreviewCost({
|
|
2058
|
+
taskPrompt: params.taskPrompt,
|
|
2059
|
+
provider,
|
|
2060
|
+
model: params.defaultProviderOverride ? resolved.providerModels[provider]?.value ?? "auto" : resolved.defaultModel.value,
|
|
2061
|
+
strategy: params.strategy ?? resolved.defaultStrategy.value,
|
|
2062
|
+
reason: params.reason
|
|
2063
|
+
});
|
|
2064
|
+
} catch (error) {
|
|
2065
|
+
return costUnknown(
|
|
2066
|
+
`Could not resolve the default provider/model: ${error instanceof Error ? error.message : String(error)}`
|
|
2067
|
+
);
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
function chatActionDisplay(provider) {
|
|
2071
|
+
return provider ? `TUI action: send read-only chat turn to ${provider}` : "TUI action: send read-only chat turn";
|
|
2072
|
+
}
|
|
2073
|
+
function createCommandPreview(options) {
|
|
2074
|
+
const executable = options.executable ?? resolvePoeticExecutable();
|
|
2075
|
+
const parsed = parseInput(options.input);
|
|
2076
|
+
let argv = buildArgv(parsed);
|
|
2077
|
+
const warnings = [];
|
|
2078
|
+
const errors = [];
|
|
2079
|
+
const branch = resolveBranch(options.repoRoot);
|
|
2080
|
+
if (parsed.command === "help") {
|
|
2081
|
+
const title = parsed.value ? `Unknown command: /${parsed.value}` : "Help";
|
|
2082
|
+
if (parsed.value) {
|
|
2083
|
+
errors.push(`Unknown command: /${parsed.value}`);
|
|
2084
|
+
}
|
|
2085
|
+
return {
|
|
2086
|
+
kind: "help",
|
|
2087
|
+
title,
|
|
2088
|
+
argv,
|
|
2089
|
+
argvDisplay: parsed.value ? commandDisplay(executable, argv) : "TUI action: show help",
|
|
2090
|
+
executable,
|
|
2091
|
+
canSubmit: false,
|
|
2092
|
+
warnings,
|
|
2093
|
+
errors,
|
|
2094
|
+
branch,
|
|
2095
|
+
sandbox: createSandboxPosture({
|
|
2096
|
+
mode: "none",
|
|
2097
|
+
providerName: "poetic-tui",
|
|
2098
|
+
providerId: "poetic-tui"
|
|
2099
|
+
}),
|
|
2100
|
+
cost: costNotApplicable("Help preview does not run a provider.")
|
|
2101
|
+
};
|
|
2102
|
+
}
|
|
2103
|
+
if (parsed.command === "chat") {
|
|
2104
|
+
const provider = options.anchoredProvider;
|
|
2105
|
+
if (!parsed.value) {
|
|
2106
|
+
errors.push("Enter a message to chat.");
|
|
2107
|
+
}
|
|
2108
|
+
if (!provider) {
|
|
2109
|
+
errors.push("No chat provider selected. Choose one with /model.");
|
|
2110
|
+
}
|
|
2111
|
+
if (!isAnchoredChatEnabled(process.env)) {
|
|
2112
|
+
errors.push(`TUI chat is disabled by ${ANCHORED_CHAT_FEATURE_ENV}.`);
|
|
2113
|
+
}
|
|
2114
|
+
return {
|
|
2115
|
+
kind: "chat",
|
|
2116
|
+
title: "Chat preview",
|
|
2117
|
+
argv,
|
|
2118
|
+
argvDisplay: chatActionDisplay(provider),
|
|
2119
|
+
executable,
|
|
2120
|
+
canSubmit: errors.length === 0,
|
|
2121
|
+
warnings,
|
|
2122
|
+
errors,
|
|
2123
|
+
branch,
|
|
2124
|
+
anchorProvider: provider,
|
|
2125
|
+
chatMessage: parsed.value,
|
|
2126
|
+
sandbox: createReadOnlyChatSandboxPosture(provider),
|
|
2127
|
+
cost: provider ? estimatePreviewCost({
|
|
2128
|
+
taskPrompt: parsed.value,
|
|
2129
|
+
provider,
|
|
2130
|
+
// Mirror the model actually threaded into the chat turn: explicit
|
|
2131
|
+
// user config only; undefined lets the estimator (like the provider
|
|
2132
|
+
// CLI) fall back to its own default.
|
|
2133
|
+
model: resolveTuiChatModel(options.repoRoot, provider),
|
|
2134
|
+
reason: "Estimated from the anchored chat message and selected provider."
|
|
2135
|
+
}) : costUnknown("No anchored provider is selected.")
|
|
2136
|
+
};
|
|
2137
|
+
}
|
|
2138
|
+
let answerBlockerId;
|
|
2139
|
+
let buildIntent = parsed.value;
|
|
2140
|
+
if (parsed.command === "answer") {
|
|
2141
|
+
const parsedAnswer = parseAnswerValue(parsed.value);
|
|
2142
|
+
answerBlockerId = parsedAnswer.blockerId;
|
|
2143
|
+
if (!parsedAnswer.blockerId || !parsedAnswer.answer) {
|
|
2144
|
+
errors.push("/answer requires blockerId=value (or runId:blockerId=value).");
|
|
2145
|
+
} else {
|
|
2146
|
+
const pendingBlockers = readTuiDashboardState(options.repoRoot).pendingBlockers;
|
|
2147
|
+
const matches = pendingBlockers.filter(
|
|
2148
|
+
(blocker) => blocker.blockerId === parsedAnswer.blockerId && (parsedAnswer.runId === void 0 || blocker.runId === parsedAnswer.runId)
|
|
2149
|
+
);
|
|
2150
|
+
const pending = matches[0];
|
|
2151
|
+
if (!pending) {
|
|
2152
|
+
const scope = parsedAnswer.runId ? ` in run ${parsedAnswer.runId}` : "";
|
|
2153
|
+
errors.push(`No pending blocker found for ${parsedAnswer.blockerId}${scope}.`);
|
|
2154
|
+
} else if (matches.length > 1) {
|
|
2155
|
+
const runIds = matches.map((match) => match.runId).join(", ");
|
|
2156
|
+
errors.push(
|
|
2157
|
+
`Blocker ${parsedAnswer.blockerId} appears in multiple runs (${runIds}); scope with runId:blockerId=value.`
|
|
2158
|
+
);
|
|
2159
|
+
} else if (!pending.intent) {
|
|
2160
|
+
errors.push(
|
|
2161
|
+
`Pending blocker ${parsedAnswer.blockerId} (run ${pending.runId}) does not include an intent; re-run planned build to regenerate.`
|
|
2162
|
+
);
|
|
2163
|
+
} else {
|
|
2164
|
+
buildIntent = pending.intent;
|
|
2165
|
+
argv = [
|
|
2166
|
+
"build",
|
|
2167
|
+
"--planned",
|
|
2168
|
+
"--answer",
|
|
2169
|
+
`${pending.runId}:${parsedAnswer.blockerId}=${parsedAnswer.answer}`,
|
|
2170
|
+
pending.intent
|
|
2171
|
+
];
|
|
2172
|
+
warnings.push(`Answers pending blocker ${parsedAnswer.blockerId} in run ${pending.runId}.`);
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2176
|
+
if (["build", "plan-run", "run", "compete", "fusion"].includes(parsed.command) && !parsed.value) {
|
|
2177
|
+
errors.push(`/${parsed.command} requires an intent or task text.`);
|
|
2178
|
+
}
|
|
2179
|
+
if (parsed.command === "knowledge") {
|
|
2180
|
+
const knowledgeParts = parsed.value.split(/\s+/).filter((part) => part.length > 0);
|
|
2181
|
+
const knowledgeSub = knowledgeParts[0]?.toLowerCase() ?? "status";
|
|
2182
|
+
const knowledgeRest = knowledgeParts.slice(1);
|
|
2183
|
+
if (knowledgeSub === "declare" && knowledgeRest.length === 0) {
|
|
2184
|
+
errors.push("/knowledge declare requires a stack spec (e.g. swift,swiftui,macos-26).");
|
|
2185
|
+
} else if (knowledgeSub === "resolve" && knowledgeRest[0] !== "keep" && knowledgeRest[0] !== "accept") {
|
|
2186
|
+
errors.push("/knowledge resolve requires keep or accept.");
|
|
2187
|
+
} else if (knowledgeSub === "accept" && knowledgeRest.length < 2) {
|
|
2188
|
+
errors.push("/knowledge accept requires <token> <all|id,id,...>.");
|
|
2189
|
+
} else if (knowledgeSub === "graduate" && knowledgeRest.length === 0) {
|
|
2190
|
+
errors.push("/knowledge graduate requires a review token from /knowledge offer.");
|
|
2191
|
+
} else if (!["status", "declare", "clear", "resolve", "offer", "accept", "graduate"].includes(
|
|
2192
|
+
knowledgeSub
|
|
2193
|
+
)) {
|
|
2194
|
+
errors.push(
|
|
2195
|
+
`Unknown /knowledge subcommand '${knowledgeSub}' \u2014 use status, declare, clear, resolve, offer, accept, or graduate.`
|
|
2196
|
+
);
|
|
2197
|
+
}
|
|
2198
|
+
if (["declare", "clear", "resolve", "accept", "graduate"].includes(knowledgeSub)) {
|
|
2199
|
+
warnings.push("This writes knowledge/intent files in the repo (committed).");
|
|
2200
|
+
}
|
|
2201
|
+
if (knowledgeSub === "offer") {
|
|
2202
|
+
warnings.push("Offer runs a resource search via the default ask provider.");
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
const isBuild = parsed.command === "build" || parsed.command === "answer";
|
|
2206
|
+
let route;
|
|
2207
|
+
let routeReason;
|
|
2208
|
+
let blockerMode;
|
|
2209
|
+
if (isBuild) {
|
|
2210
|
+
if (buildIntent.length > WARN_INTENT_LENGTH && buildIntent.length <= MAX_BUILD_INTENT_LENGTH) {
|
|
2211
|
+
warnings.push(
|
|
2212
|
+
`Intent is ${buildIntent.length} characters; consider moving detail into a file.`
|
|
2213
|
+
);
|
|
2214
|
+
}
|
|
2215
|
+
if (buildIntent.length > MAX_BUILD_INTENT_LENGTH) {
|
|
2216
|
+
errors.push(`Intent exceeds the ${MAX_BUILD_INTENT_LENGTH}-character limit.`);
|
|
2217
|
+
}
|
|
2218
|
+
const routeExplanation = explainBuildRoute(
|
|
2219
|
+
{
|
|
2220
|
+
planned: parsed.command === "answer" || options.buildRouteOverride === "planned"
|
|
2221
|
+
},
|
|
2222
|
+
buildIntent
|
|
2223
|
+
);
|
|
2224
|
+
route = routeExplanation.route;
|
|
2225
|
+
routeReason = routeExplanation.reason;
|
|
2226
|
+
if (route === "planned") {
|
|
2227
|
+
blockerMode = resolvePlanExecuteCliBlockerMode({});
|
|
2228
|
+
if (branch === "HEAD") {
|
|
2229
|
+
warnings.push("Detached HEAD: planned execution requires an active branch.");
|
|
2230
|
+
} else if (isProtectedPipelineBranch(branch)) {
|
|
2231
|
+
warnings.push(
|
|
2232
|
+
`Protected branch '${branch}': create a run branch before planned execution.`
|
|
2233
|
+
);
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
if (parsed.command === "compete") {
|
|
2238
|
+
warnings.push("Competition can run multiple providers and may cost more than a build.");
|
|
2239
|
+
}
|
|
2240
|
+
if (parsed.command === "monitor" && !parsed.value) {
|
|
2241
|
+
errors.push("/monitor requires a task ID.");
|
|
2242
|
+
}
|
|
2243
|
+
let cost;
|
|
2244
|
+
if (isBuild) {
|
|
2245
|
+
if (route === "planned") {
|
|
2246
|
+
cost = costUnknown(
|
|
2247
|
+
"Planned builds may decompose into multiple provider calls; providers are selected during execution."
|
|
2248
|
+
);
|
|
2249
|
+
} else {
|
|
2250
|
+
cost = estimateDefaultProviderCost({
|
|
2251
|
+
taskPrompt: buildIntent,
|
|
2252
|
+
repoRoot: options.repoRoot,
|
|
2253
|
+
reason: "Estimated from the build intent and resolved default provider/model.",
|
|
2254
|
+
defaultProviderOverride: options.defaultProviderOverride
|
|
2255
|
+
});
|
|
2256
|
+
}
|
|
2257
|
+
} else if (parsed.command === "run") {
|
|
2258
|
+
cost = estimateDefaultProviderCost({
|
|
2259
|
+
taskPrompt: parsed.value,
|
|
2260
|
+
repoRoot: options.repoRoot,
|
|
2261
|
+
reason: "Estimated from the run prompt and resolved default provider/model.",
|
|
2262
|
+
defaultProviderOverride: options.defaultProviderOverride
|
|
2263
|
+
});
|
|
2264
|
+
} else if (parsed.command === "compete") {
|
|
2265
|
+
cost = costUnknown(
|
|
2266
|
+
"Competition provider/model selection and variant count are resolved at execution time."
|
|
2267
|
+
);
|
|
2268
|
+
} else if (parsed.command === "fusion") {
|
|
2269
|
+
cost = costUnknown("Fusion panel providers and synthesis cost are resolved at execution time.");
|
|
2270
|
+
} else if (parsed.command === "plan-run") {
|
|
2271
|
+
cost = costUnknown(
|
|
2272
|
+
"Planning uses the configured planning provider; final cost is known after the plan is created."
|
|
2273
|
+
);
|
|
2274
|
+
} else if (parsed.command === "quickstart") {
|
|
2275
|
+
cost = costUnknown("Quickstart decides provider usage during execution.");
|
|
2276
|
+
} else if (parsed.command === "knowledge" && (parsed.value.split(/\s+/)[0]?.toLowerCase() ?? "status") === "offer") {
|
|
2277
|
+
cost = costUnknown("The knowledge offer runs a bounded resource search via the ask provider.");
|
|
2278
|
+
} else {
|
|
2279
|
+
cost = costNotApplicable("This preview does not start provider execution.");
|
|
2280
|
+
}
|
|
2281
|
+
return {
|
|
2282
|
+
kind: isBuild ? "build" : "command",
|
|
2283
|
+
title: parsed.command === "answer" ? `Answer ${answerBlockerId ?? "blocker"}` : isBuild ? "Build preview" : `${parsed.command} preview`,
|
|
2284
|
+
argv,
|
|
2285
|
+
argvDisplay: commandDisplay(executable, argv),
|
|
2286
|
+
executable,
|
|
2287
|
+
canSubmit: errors.length === 0,
|
|
2288
|
+
warnings,
|
|
2289
|
+
errors,
|
|
2290
|
+
route,
|
|
2291
|
+
routeReason,
|
|
2292
|
+
branch,
|
|
2293
|
+
blockerMode,
|
|
2294
|
+
sandbox: createCommandSandboxPosture(),
|
|
2295
|
+
cost
|
|
2296
|
+
};
|
|
2297
|
+
}
|
|
2298
|
+
function createCommandPreviewFromAgentAction(options) {
|
|
2299
|
+
const executable = options.executable ?? resolvePoeticExecutable();
|
|
2300
|
+
const directInput = ["build", "run", "compete", "fusion"].includes(options.action.command) ? `/${options.action.command} ${options.action.command === "build" ? options.action.argv.at(-1) ?? "" : options.action.args.join(" ")}` : "/next";
|
|
2301
|
+
const directPreview = createCommandPreview({
|
|
2302
|
+
input: directInput,
|
|
2303
|
+
repoRoot: options.repoRoot,
|
|
2304
|
+
executable,
|
|
2305
|
+
buildRouteOverride: options.action.command === "build" ? "planned" : void 0
|
|
2306
|
+
});
|
|
2307
|
+
const sandbox = options.action.risk === "read" ? createSandboxPosture({
|
|
2308
|
+
mode: "none",
|
|
2309
|
+
providerName: "poetic-tui",
|
|
2310
|
+
providerId: "poetic-tui"
|
|
2311
|
+
}) : directPreview.sandbox;
|
|
2312
|
+
const warnings = options.action.risk === "managed-write" ? ["This suggested command writes Poetic-managed state after approval."] : directPreview.warnings;
|
|
2313
|
+
return {
|
|
2314
|
+
...directPreview,
|
|
2315
|
+
kind: options.action.command === "build" ? "build" : "command",
|
|
2316
|
+
title: `Suggested: ${options.action.command}`,
|
|
2317
|
+
argv: options.action.argv,
|
|
2318
|
+
argvDisplay: commandDisplay(executable, options.action.argv),
|
|
2319
|
+
executable,
|
|
2320
|
+
canSubmit: true,
|
|
2321
|
+
warnings,
|
|
2322
|
+
errors: [],
|
|
2323
|
+
sandbox,
|
|
2324
|
+
cost: options.action.command === "build" ? costNotApplicable("Dry-run preview does not start provider execution.") : directPreview.cost,
|
|
2325
|
+
suggestedAction: options.action
|
|
2326
|
+
};
|
|
2327
|
+
}
|
|
2328
|
+
function createRunBranchName(intent) {
|
|
2329
|
+
const slug = intent.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48) || "poetic-build";
|
|
2330
|
+
return path2.posix.join("run", slug);
|
|
2331
|
+
}
|
|
2332
|
+
|
|
2333
|
+
export {
|
|
2334
|
+
formatProviderName,
|
|
2335
|
+
formatTuiFooterLabel,
|
|
2336
|
+
formatElapsed,
|
|
2337
|
+
formatTuiUserPromptLine,
|
|
2338
|
+
formatTuiAssistantMessageContent,
|
|
2339
|
+
shouldShowTuiChatWorkingIndicator,
|
|
2340
|
+
shouldShowTuiChatTurnReceipt,
|
|
2341
|
+
formatWorkingLine,
|
|
2342
|
+
formatTuiChatCostUsd,
|
|
2343
|
+
formatTurnReceipt,
|
|
2344
|
+
readTuiRunDetail,
|
|
2345
|
+
readTuiDashboardState,
|
|
2346
|
+
createInitialTuiDashboardState,
|
|
2347
|
+
formatTuiSelectedModel,
|
|
2348
|
+
TUI_COMMANDS,
|
|
2349
|
+
getTuiCommandSuggestions,
|
|
2350
|
+
resolvePoeticExecutable,
|
|
2351
|
+
createCommandPreview,
|
|
2352
|
+
createCommandPreviewFromAgentAction,
|
|
2353
|
+
createRunBranchName,
|
|
2354
|
+
isExplicitDefaultProviderSource,
|
|
2355
|
+
resolveTuiChatProvider,
|
|
2356
|
+
preparePreviewSpawn,
|
|
2357
|
+
resolveTuiImmediateCommandArgError,
|
|
2358
|
+
resolveTuiImmediateCommand,
|
|
2359
|
+
resolveTuiChatAvailable,
|
|
2360
|
+
shouldExecuteTuiSuggestionImmediately,
|
|
2361
|
+
shouldStartTuiPreviewImmediately,
|
|
2362
|
+
resolveTuiOnboardingHome,
|
|
2363
|
+
resolveTuiFirstRunProviderPrompt,
|
|
2364
|
+
loadTuiActions,
|
|
2365
|
+
promptSeparator,
|
|
2366
|
+
resolveTuiBackendLabel,
|
|
2367
|
+
resolveTuiChatModel,
|
|
2368
|
+
resolveTuiDisplayedChatModel,
|
|
2369
|
+
previewNeedsRunBranch,
|
|
2370
|
+
countProposalQueueRows,
|
|
2371
|
+
resolveTuiChatAgentPrompt
|
|
2372
|
+
};
|
|
2373
|
+
//# sourceMappingURL=chunk-TGQZHDY2.js.map
|