@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,1734 @@
|
|
|
1
|
+
import {
|
|
2
|
+
performActivation
|
|
3
|
+
} from "./chunk-6BM72ZMG.js";
|
|
4
|
+
import {
|
|
5
|
+
parseJsonWithContext
|
|
6
|
+
} from "./chunk-QVZMFDYG.js";
|
|
7
|
+
import {
|
|
8
|
+
sqlite_wrapper_default
|
|
9
|
+
} from "./chunk-45FPSA3B.js";
|
|
10
|
+
import {
|
|
11
|
+
resolvePoeticDirFromContext
|
|
12
|
+
} from "./chunk-UI2F6DJ5.js";
|
|
13
|
+
|
|
14
|
+
// src/prompts/store.ts
|
|
15
|
+
import crypto from "crypto";
|
|
16
|
+
import fs from "fs";
|
|
17
|
+
import path from "path";
|
|
18
|
+
var PROMPT_ID_PATTERN = /^[a-z0-9-]+$/;
|
|
19
|
+
var LEGACY_PROMPT_ID_PATTERN = /^[a-z0-9][a-z0-9_-]*$/;
|
|
20
|
+
var VERSION_ID_PATTERN = /^[a-z0-9][a-z0-9._-]*$/i;
|
|
21
|
+
var LIKE_WILDCARD_CHARACTERS = /[%_]/g;
|
|
22
|
+
function escapeLikePattern(value) {
|
|
23
|
+
return value.replace(LIKE_WILDCARD_CHARACTERS, "\\$&");
|
|
24
|
+
}
|
|
25
|
+
function atomicWriteTextSync(filePath, content) {
|
|
26
|
+
const dir = path.dirname(filePath);
|
|
27
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
28
|
+
const tempPath = path.join(
|
|
29
|
+
dir,
|
|
30
|
+
`.tmp.${process.pid}.${Date.now()}.${crypto.randomBytes(8).toString("hex")}`
|
|
31
|
+
);
|
|
32
|
+
let fd;
|
|
33
|
+
try {
|
|
34
|
+
fd = fs.openSync(tempPath, "wx");
|
|
35
|
+
fs.writeFileSync(fd, content, "utf8");
|
|
36
|
+
fs.fsyncSync(fd);
|
|
37
|
+
fs.closeSync(fd);
|
|
38
|
+
fd = void 0;
|
|
39
|
+
fs.renameSync(tempPath, filePath);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (fd !== void 0) {
|
|
42
|
+
try {
|
|
43
|
+
fs.closeSync(fd);
|
|
44
|
+
} catch {
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
fs.unlinkSync(tempPath);
|
|
49
|
+
} catch {
|
|
50
|
+
}
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
var PromptStore = class {
|
|
55
|
+
poeticDir;
|
|
56
|
+
promptsDir;
|
|
57
|
+
dbDir;
|
|
58
|
+
activeDir;
|
|
59
|
+
archivedDir;
|
|
60
|
+
templatesDir;
|
|
61
|
+
db;
|
|
62
|
+
constructor(options = {}) {
|
|
63
|
+
this.poeticDir = resolvePoeticDirFromContext(options.poeticDir);
|
|
64
|
+
this.promptsDir = path.join(this.poeticDir, "prompts");
|
|
65
|
+
this.dbDir = path.join(this.promptsDir, "db");
|
|
66
|
+
this.activeDir = path.join(this.promptsDir, "active");
|
|
67
|
+
this.archivedDir = path.join(this.promptsDir, "archived");
|
|
68
|
+
this.templatesDir = path.join(this.promptsDir, "templates");
|
|
69
|
+
this.ensureDirectories();
|
|
70
|
+
if (!sqlite_wrapper_default) {
|
|
71
|
+
throw new Error("Database constructor not available");
|
|
72
|
+
}
|
|
73
|
+
const DatabaseConstructor = sqlite_wrapper_default;
|
|
74
|
+
this.db = new DatabaseConstructor(path.join(this.dbDir, "prompts.db"));
|
|
75
|
+
if (this.db.defaultSafeIntegers) {
|
|
76
|
+
this.db.defaultSafeIntegers(false);
|
|
77
|
+
}
|
|
78
|
+
this.db.pragma("foreign_keys = ON");
|
|
79
|
+
this.db.pragma("journal_mode = WAL");
|
|
80
|
+
this.initSchema();
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Ensure all required directories exist
|
|
84
|
+
*/
|
|
85
|
+
ensureDirectories() {
|
|
86
|
+
[this.promptsDir, this.dbDir, this.activeDir, this.archivedDir, this.templatesDir].forEach(
|
|
87
|
+
(dir) => {
|
|
88
|
+
if (!fs.existsSync(dir)) {
|
|
89
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Initialize database schema
|
|
96
|
+
*/
|
|
97
|
+
initSchema() {
|
|
98
|
+
this.db.exec(`
|
|
99
|
+
CREATE TABLE IF NOT EXISTS prompts (
|
|
100
|
+
id TEXT PRIMARY KEY,
|
|
101
|
+
name TEXT NOT NULL,
|
|
102
|
+
description TEXT NOT NULL,
|
|
103
|
+
category TEXT NOT NULL,
|
|
104
|
+
status TEXT NOT NULL,
|
|
105
|
+
variant TEXT,
|
|
106
|
+
tags TEXT NOT NULL,
|
|
107
|
+
auto_opt_in INTEGER DEFAULT 0,
|
|
108
|
+
current_version TEXT NOT NULL,
|
|
109
|
+
active_version_id TEXT,
|
|
110
|
+
created_at TEXT NOT NULL,
|
|
111
|
+
updated_at TEXT NOT NULL,
|
|
112
|
+
archived_at TEXT,
|
|
113
|
+
usage_count INTEGER DEFAULT 0,
|
|
114
|
+
last_used_at TEXT,
|
|
115
|
+
UNIQUE(name, category)
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
CREATE INDEX IF NOT EXISTS idx_prompts_category ON prompts(category);
|
|
119
|
+
CREATE INDEX IF NOT EXISTS idx_prompts_updated ON prompts(updated_at DESC);
|
|
120
|
+
`);
|
|
121
|
+
const promptColumns = this.db.prepare("PRAGMA table_info(prompts)").all();
|
|
122
|
+
const promptColumnNames = promptColumns.map((col) => col.name);
|
|
123
|
+
if (!promptColumnNames.includes("auto_opt_in")) {
|
|
124
|
+
this.db.exec("ALTER TABLE prompts ADD COLUMN auto_opt_in INTEGER DEFAULT 0");
|
|
125
|
+
}
|
|
126
|
+
if (!promptColumnNames.includes("active_version_id")) {
|
|
127
|
+
this.db.exec("ALTER TABLE prompts ADD COLUMN active_version_id TEXT");
|
|
128
|
+
}
|
|
129
|
+
if (!promptColumnNames.includes("current_version")) {
|
|
130
|
+
this.db.exec("ALTER TABLE prompts ADD COLUMN current_version TEXT");
|
|
131
|
+
this.db.exec(
|
|
132
|
+
"UPDATE prompts SET current_version = active_version_id WHERE current_version IS NULL"
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
if (!promptColumnNames.includes("status")) {
|
|
136
|
+
this.db.exec("ALTER TABLE prompts ADD COLUMN status TEXT NOT NULL DEFAULT 'active'");
|
|
137
|
+
}
|
|
138
|
+
if (!promptColumnNames.includes("variant")) {
|
|
139
|
+
this.db.exec("ALTER TABLE prompts ADD COLUMN variant TEXT");
|
|
140
|
+
}
|
|
141
|
+
if (!promptColumnNames.includes("tags")) {
|
|
142
|
+
this.db.exec("ALTER TABLE prompts ADD COLUMN tags TEXT NOT NULL DEFAULT '[]'");
|
|
143
|
+
}
|
|
144
|
+
if (!promptColumnNames.includes("archived_at")) {
|
|
145
|
+
this.db.exec("ALTER TABLE prompts ADD COLUMN archived_at TEXT");
|
|
146
|
+
}
|
|
147
|
+
if (!promptColumnNames.includes("usage_count")) {
|
|
148
|
+
this.db.exec("ALTER TABLE prompts ADD COLUMN usage_count INTEGER DEFAULT 0");
|
|
149
|
+
}
|
|
150
|
+
if (!promptColumnNames.includes("last_used_at")) {
|
|
151
|
+
this.db.exec("ALTER TABLE prompts ADD COLUMN last_used_at TEXT");
|
|
152
|
+
}
|
|
153
|
+
this.db.exec("CREATE INDEX IF NOT EXISTS idx_prompts_status ON prompts(status)");
|
|
154
|
+
this.db.exec("CREATE INDEX IF NOT EXISTS idx_prompts_variant ON prompts(variant)");
|
|
155
|
+
this.db.exec(
|
|
156
|
+
"CREATE INDEX IF NOT EXISTS idx_prompts_active_version ON prompts(active_version_id)"
|
|
157
|
+
);
|
|
158
|
+
this.db.exec(`
|
|
159
|
+
CREATE TABLE IF NOT EXISTS prompt_versions (
|
|
160
|
+
id TEXT NOT NULL,
|
|
161
|
+
prompt_id TEXT NOT NULL,
|
|
162
|
+
content_hash TEXT NOT NULL,
|
|
163
|
+
changelog TEXT,
|
|
164
|
+
author TEXT,
|
|
165
|
+
is_active INTEGER DEFAULT 0,
|
|
166
|
+
is_generated INTEGER DEFAULT 0,
|
|
167
|
+
generation_model TEXT,
|
|
168
|
+
generation_prompt TEXT,
|
|
169
|
+
created_at TEXT NOT NULL,
|
|
170
|
+
activated_at TEXT,
|
|
171
|
+
deactivated_at TEXT,
|
|
172
|
+
parent_version_id TEXT,
|
|
173
|
+
mutation_type TEXT,
|
|
174
|
+
optimization_metadata TEXT,
|
|
175
|
+
generated_by TEXT,
|
|
176
|
+
activated_by TEXT,
|
|
177
|
+
performance_score REAL,
|
|
178
|
+
PRIMARY KEY (prompt_id, id),
|
|
179
|
+
FOREIGN KEY (prompt_id) REFERENCES prompts(id) ON DELETE CASCADE
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
CREATE INDEX IF NOT EXISTS idx_versions_prompt ON prompt_versions(prompt_id);
|
|
183
|
+
CREATE INDEX IF NOT EXISTS idx_versions_active ON prompt_versions(prompt_id, is_active);
|
|
184
|
+
`);
|
|
185
|
+
const versionColumns = this.db.prepare("PRAGMA table_info(prompt_versions)").all();
|
|
186
|
+
const versionColumnNames = versionColumns.map((col) => col.name);
|
|
187
|
+
if (!versionColumnNames.includes("content_hash")) {
|
|
188
|
+
this.db.exec("ALTER TABLE prompt_versions ADD COLUMN content_hash TEXT NOT NULL DEFAULT ''");
|
|
189
|
+
}
|
|
190
|
+
if (versionColumnNames.includes("content")) {
|
|
191
|
+
const legacyRows = this.db.prepare("SELECT prompt_id, id, content, content_hash FROM prompt_versions").all();
|
|
192
|
+
const invalidHash = /^(?:sha256:)?[a-f0-9]{64}$/i;
|
|
193
|
+
const updateHash = this.db.prepare(
|
|
194
|
+
"UPDATE prompt_versions SET content_hash = ? WHERE prompt_id = ? AND id = ?"
|
|
195
|
+
);
|
|
196
|
+
const applyBackfill = () => {
|
|
197
|
+
for (const row of legacyRows) {
|
|
198
|
+
if (typeof row.content !== "string" || invalidHash.test(row.content_hash.trim()))
|
|
199
|
+
continue;
|
|
200
|
+
updateHash.run(this.hashContent(row.content), row.prompt_id, row.id);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
if (this.db.transaction) {
|
|
204
|
+
this.db.transaction(applyBackfill)();
|
|
205
|
+
} else {
|
|
206
|
+
applyBackfill();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (!versionColumnNames.includes("changelog")) {
|
|
210
|
+
this.db.exec("ALTER TABLE prompt_versions ADD COLUMN changelog TEXT");
|
|
211
|
+
}
|
|
212
|
+
if (!versionColumnNames.includes("author")) {
|
|
213
|
+
this.db.exec("ALTER TABLE prompt_versions ADD COLUMN author TEXT");
|
|
214
|
+
}
|
|
215
|
+
if (!versionColumnNames.includes("is_generated")) {
|
|
216
|
+
this.db.exec("ALTER TABLE prompt_versions ADD COLUMN is_generated INTEGER DEFAULT 0");
|
|
217
|
+
}
|
|
218
|
+
if (!versionColumnNames.includes("generation_model")) {
|
|
219
|
+
this.db.exec("ALTER TABLE prompt_versions ADD COLUMN generation_model TEXT");
|
|
220
|
+
}
|
|
221
|
+
if (!versionColumnNames.includes("generation_prompt")) {
|
|
222
|
+
this.db.exec("ALTER TABLE prompt_versions ADD COLUMN generation_prompt TEXT");
|
|
223
|
+
}
|
|
224
|
+
if (!versionColumnNames.includes("activated_at")) {
|
|
225
|
+
this.db.exec("ALTER TABLE prompt_versions ADD COLUMN activated_at TEXT");
|
|
226
|
+
}
|
|
227
|
+
if (!versionColumnNames.includes("deactivated_at")) {
|
|
228
|
+
this.db.exec("ALTER TABLE prompt_versions ADD COLUMN deactivated_at TEXT");
|
|
229
|
+
}
|
|
230
|
+
if (!versionColumnNames.includes("parent_version_id")) {
|
|
231
|
+
this.db.exec("ALTER TABLE prompt_versions ADD COLUMN parent_version_id TEXT");
|
|
232
|
+
}
|
|
233
|
+
if (!versionColumnNames.includes("mutation_type")) {
|
|
234
|
+
this.db.exec("ALTER TABLE prompt_versions ADD COLUMN mutation_type TEXT");
|
|
235
|
+
}
|
|
236
|
+
if (!versionColumnNames.includes("optimization_metadata")) {
|
|
237
|
+
this.db.exec("ALTER TABLE prompt_versions ADD COLUMN optimization_metadata TEXT");
|
|
238
|
+
}
|
|
239
|
+
if (!versionColumnNames.includes("generated_by")) {
|
|
240
|
+
this.db.exec("ALTER TABLE prompt_versions ADD COLUMN generated_by TEXT");
|
|
241
|
+
}
|
|
242
|
+
if (!versionColumnNames.includes("activated_by")) {
|
|
243
|
+
this.db.exec("ALTER TABLE prompt_versions ADD COLUMN activated_by TEXT");
|
|
244
|
+
}
|
|
245
|
+
if (!versionColumnNames.includes("performance_score")) {
|
|
246
|
+
this.db.exec("ALTER TABLE prompt_versions ADD COLUMN performance_score REAL");
|
|
247
|
+
}
|
|
248
|
+
this.db.exec("CREATE INDEX IF NOT EXISTS idx_versions_hash ON prompt_versions(content_hash)");
|
|
249
|
+
this.db.exec(`
|
|
250
|
+
CREATE INDEX IF NOT EXISTS idx_versions_parent ON prompt_versions(parent_version_id);
|
|
251
|
+
CREATE INDEX IF NOT EXISTS idx_versions_lineage ON prompt_versions(prompt_id, parent_version_id);
|
|
252
|
+
CREATE INDEX IF NOT EXISTS idx_versions_mutation_type ON prompt_versions(mutation_type);
|
|
253
|
+
CREATE INDEX IF NOT EXISTS idx_versions_performance ON prompt_versions(performance_score DESC);
|
|
254
|
+
`);
|
|
255
|
+
this.db.exec(`
|
|
256
|
+
CREATE TABLE IF NOT EXISTS prompt_performance (
|
|
257
|
+
prompt_id TEXT NOT NULL,
|
|
258
|
+
version_id TEXT NOT NULL,
|
|
259
|
+
variant TEXT,
|
|
260
|
+
total_executions INTEGER DEFAULT 0,
|
|
261
|
+
successful_executions INTEGER DEFAULT 0,
|
|
262
|
+
failed_executions INTEGER DEFAULT 0,
|
|
263
|
+
success_rate REAL DEFAULT 0,
|
|
264
|
+
avg_completeness REAL DEFAULT 0,
|
|
265
|
+
avg_code_delivery_rate REAL DEFAULT 0,
|
|
266
|
+
avg_duration REAL DEFAULT 0,
|
|
267
|
+
min_completeness REAL DEFAULT 0,
|
|
268
|
+
max_completeness REAL DEFAULT 0,
|
|
269
|
+
std_dev_completeness REAL DEFAULT 0,
|
|
270
|
+
sample_size INTEGER DEFAULT 0,
|
|
271
|
+
first_execution_at TEXT,
|
|
272
|
+
last_execution_at TEXT,
|
|
273
|
+
calculated_at TEXT NOT NULL,
|
|
274
|
+
PRIMARY KEY (prompt_id, version_id, variant),
|
|
275
|
+
FOREIGN KEY (prompt_id, version_id) REFERENCES prompt_versions(prompt_id, id) ON DELETE CASCADE
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
CREATE INDEX IF NOT EXISTS idx_performance_version ON prompt_performance(version_id);
|
|
279
|
+
CREATE INDEX IF NOT EXISTS idx_performance_variant ON prompt_performance(variant);
|
|
280
|
+
CREATE INDEX IF NOT EXISTS idx_performance_success_rate ON prompt_performance(success_rate DESC);
|
|
281
|
+
`);
|
|
282
|
+
this.db.exec(`
|
|
283
|
+
CREATE TABLE IF NOT EXISTS prompt_variants (
|
|
284
|
+
id TEXT PRIMARY KEY,
|
|
285
|
+
prompt_id TEXT NOT NULL,
|
|
286
|
+
base_version_id TEXT NOT NULL,
|
|
287
|
+
mutation_strategies TEXT NOT NULL,
|
|
288
|
+
success_rate REAL,
|
|
289
|
+
completeness REAL,
|
|
290
|
+
duration_ms INTEGER,
|
|
291
|
+
confidence REAL,
|
|
292
|
+
expected_improvement REAL,
|
|
293
|
+
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
294
|
+
FOREIGN KEY (prompt_id) REFERENCES prompts(id) ON DELETE CASCADE,
|
|
295
|
+
FOREIGN KEY (prompt_id, base_version_id) REFERENCES prompt_versions(prompt_id, id) ON DELETE CASCADE
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
CREATE INDEX IF NOT EXISTS idx_variants_prompt ON prompt_variants(prompt_id, created_at DESC);
|
|
299
|
+
CREATE INDEX IF NOT EXISTS idx_variants_base_version ON prompt_variants(base_version_id);
|
|
300
|
+
CREATE INDEX IF NOT EXISTS idx_variants_performance ON prompt_variants(success_rate DESC, completeness DESC);
|
|
301
|
+
CREATE INDEX IF NOT EXISTS idx_variants_strategies ON prompt_variants(mutation_strategies);
|
|
302
|
+
CREATE INDEX IF NOT EXISTS idx_variants_confidence ON prompt_variants(confidence DESC);
|
|
303
|
+
`);
|
|
304
|
+
this.db.exec(`
|
|
305
|
+
CREATE TABLE IF NOT EXISTS activation_history (
|
|
306
|
+
id TEXT PRIMARY KEY,
|
|
307
|
+
prompt_id TEXT NOT NULL,
|
|
308
|
+
version_id TEXT NOT NULL,
|
|
309
|
+
activated_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
310
|
+
activated_by TEXT,
|
|
311
|
+
reason TEXT,
|
|
312
|
+
FOREIGN KEY (prompt_id) REFERENCES prompts(id) ON DELETE CASCADE
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
CREATE INDEX IF NOT EXISTS idx_activation_prompt_timeline ON activation_history(prompt_id, activated_at DESC);
|
|
316
|
+
CREATE INDEX IF NOT EXISTS idx_activation_version ON activation_history(version_id, activated_at DESC);
|
|
317
|
+
CREATE INDEX IF NOT EXISTS idx_activation_by ON activation_history(activated_by, activated_at DESC);
|
|
318
|
+
CREATE INDEX IF NOT EXISTS idx_activation_recent ON activation_history(activated_at DESC);
|
|
319
|
+
`);
|
|
320
|
+
}
|
|
321
|
+
promptVersionsHasColumn(columnName) {
|
|
322
|
+
const columns = this.db.prepare("PRAGMA table_info(prompt_versions)").all();
|
|
323
|
+
return columns.some((column) => column.name === columnName);
|
|
324
|
+
}
|
|
325
|
+
nextLegacyVersionNumber(promptId) {
|
|
326
|
+
const row = this.db.prepare("SELECT MAX(version_number) as maxVersion FROM prompt_versions WHERE prompt_id = ?").get(promptId);
|
|
327
|
+
return (row?.maxVersion ?? 0) + 1;
|
|
328
|
+
}
|
|
329
|
+
createPrompt(inputOrId, name, description, category, variant, tags = []) {
|
|
330
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
331
|
+
const data = typeof inputOrId === "object" ? {
|
|
332
|
+
id: inputOrId.id,
|
|
333
|
+
name: inputOrId.name,
|
|
334
|
+
description: inputOrId.description,
|
|
335
|
+
category: inputOrId.category,
|
|
336
|
+
status: inputOrId.status ?? "active",
|
|
337
|
+
variant: inputOrId.variant,
|
|
338
|
+
tags: inputOrId.tags ?? [],
|
|
339
|
+
currentVersion: inputOrId.currentVersion ?? "",
|
|
340
|
+
autoOptimize: inputOrId.autoOptimize ?? false
|
|
341
|
+
} : {
|
|
342
|
+
id: inputOrId,
|
|
343
|
+
name: name ?? "",
|
|
344
|
+
description: description ?? "",
|
|
345
|
+
category,
|
|
346
|
+
status: "active",
|
|
347
|
+
variant,
|
|
348
|
+
tags,
|
|
349
|
+
currentVersion: "",
|
|
350
|
+
autoOptimize: false
|
|
351
|
+
};
|
|
352
|
+
if (!data.id || !data.name || !data.description || !data.category) {
|
|
353
|
+
throw new Error("createPrompt requires id, name, description, and category");
|
|
354
|
+
}
|
|
355
|
+
if (!PROMPT_ID_PATTERN.test(data.id)) {
|
|
356
|
+
throw new Error("Prompt ID must be a valid slug (lowercase, numbers, hyphens only)");
|
|
357
|
+
}
|
|
358
|
+
const existing = this.getPrompt(data.id);
|
|
359
|
+
if (existing) {
|
|
360
|
+
throw new Error(`Prompt with ID "${data.id}" already exists`);
|
|
361
|
+
}
|
|
362
|
+
const promptDirBase = data.status === "archived" ? this.archivedDir : this.activeDir;
|
|
363
|
+
const promptDir = path.join(promptDirBase, data.id);
|
|
364
|
+
if (!fs.existsSync(promptDir)) {
|
|
365
|
+
fs.mkdirSync(promptDir, { recursive: true });
|
|
366
|
+
}
|
|
367
|
+
const stmt = this.db.prepare(`
|
|
368
|
+
INSERT INTO prompts (
|
|
369
|
+
id, name, description, category, status, variant, tags,
|
|
370
|
+
auto_opt_in, current_version, created_at, updated_at, archived_at
|
|
371
|
+
)
|
|
372
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
373
|
+
`);
|
|
374
|
+
stmt.run(
|
|
375
|
+
data.id,
|
|
376
|
+
data.name,
|
|
377
|
+
data.description,
|
|
378
|
+
data.category,
|
|
379
|
+
data.status,
|
|
380
|
+
data.variant || null,
|
|
381
|
+
JSON.stringify(data.tags),
|
|
382
|
+
data.autoOptimize ? 1 : 0,
|
|
383
|
+
data.currentVersion,
|
|
384
|
+
now,
|
|
385
|
+
now,
|
|
386
|
+
data.status === "archived" ? now : null
|
|
387
|
+
);
|
|
388
|
+
return this.getPrompt(data.id);
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Get a prompt by ID
|
|
392
|
+
*/
|
|
393
|
+
getPrompt(id) {
|
|
394
|
+
const stmt = this.db.prepare("SELECT * FROM prompts WHERE id = ?");
|
|
395
|
+
const row = stmt.get(id);
|
|
396
|
+
if (!row) {
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
return this.rowToPrompt(row);
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Update a prompt
|
|
403
|
+
*/
|
|
404
|
+
updatePrompt(id, updates) {
|
|
405
|
+
const existing = this.getPrompt(id);
|
|
406
|
+
if (!existing) {
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
410
|
+
const setClauses = [];
|
|
411
|
+
const values = [];
|
|
412
|
+
if (updates.name !== void 0) {
|
|
413
|
+
setClauses.push("name = ?");
|
|
414
|
+
values.push(updates.name);
|
|
415
|
+
}
|
|
416
|
+
if (updates.description !== void 0) {
|
|
417
|
+
setClauses.push("description = ?");
|
|
418
|
+
values.push(updates.description);
|
|
419
|
+
}
|
|
420
|
+
if (updates.status !== void 0) {
|
|
421
|
+
setClauses.push("status = ?");
|
|
422
|
+
values.push(updates.status);
|
|
423
|
+
if (updates.status !== void 0 && updates.status !== "archived" && updates.status !== "active") {
|
|
424
|
+
}
|
|
425
|
+
if (updates.status === "archived" && existing.status !== "archived") {
|
|
426
|
+
setClauses.push("archived_at = ?");
|
|
427
|
+
values.push(now);
|
|
428
|
+
} else if (updates.status !== "archived" && existing.status === "archived") {
|
|
429
|
+
setClauses.push("archived_at = ?");
|
|
430
|
+
values.push(null);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
if (updates.variant !== void 0) {
|
|
434
|
+
setClauses.push("variant = ?");
|
|
435
|
+
values.push(updates.variant || null);
|
|
436
|
+
}
|
|
437
|
+
if (updates.category !== void 0) {
|
|
438
|
+
setClauses.push("category = ?");
|
|
439
|
+
values.push(updates.category);
|
|
440
|
+
}
|
|
441
|
+
if (updates.tags !== void 0) {
|
|
442
|
+
setClauses.push("tags = ?");
|
|
443
|
+
values.push(JSON.stringify(updates.tags));
|
|
444
|
+
}
|
|
445
|
+
if (updates.autoOptimize !== void 0) {
|
|
446
|
+
setClauses.push("auto_opt_in = ?");
|
|
447
|
+
values.push(updates.autoOptimize ? 1 : 0);
|
|
448
|
+
}
|
|
449
|
+
setClauses.push("updated_at = ?");
|
|
450
|
+
values.push(now);
|
|
451
|
+
values.push(id);
|
|
452
|
+
const stmt = this.db.prepare(`
|
|
453
|
+
UPDATE prompts
|
|
454
|
+
SET ${setClauses.join(", ")}
|
|
455
|
+
WHERE id = ?
|
|
456
|
+
`);
|
|
457
|
+
stmt.run(...values);
|
|
458
|
+
if (updates.status !== void 0) {
|
|
459
|
+
try {
|
|
460
|
+
if (updates.status === "archived" && existing.status !== "archived") {
|
|
461
|
+
this.movePromptFiles(id, "active", "archived");
|
|
462
|
+
} else if (updates.status !== "archived" && existing.status === "archived") {
|
|
463
|
+
this.movePromptFiles(id, "archived", "active");
|
|
464
|
+
}
|
|
465
|
+
} catch (moveErr) {
|
|
466
|
+
try {
|
|
467
|
+
const revertStmt = this.db.prepare(
|
|
468
|
+
"UPDATE prompts SET status = ?, archived_at = ?, updated_at = ? WHERE id = ?"
|
|
469
|
+
);
|
|
470
|
+
revertStmt.run(
|
|
471
|
+
existing.status,
|
|
472
|
+
existing.status === "archived" ? existing.archivedAt ?? now : null,
|
|
473
|
+
now,
|
|
474
|
+
id
|
|
475
|
+
);
|
|
476
|
+
} catch {
|
|
477
|
+
}
|
|
478
|
+
throw moveErr;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return this.getPrompt(id);
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Delete a prompt and all its versions
|
|
485
|
+
*/
|
|
486
|
+
deletePrompt(id) {
|
|
487
|
+
const prompt = this.getPrompt(id);
|
|
488
|
+
if (!prompt) {
|
|
489
|
+
return false;
|
|
490
|
+
}
|
|
491
|
+
try {
|
|
492
|
+
const versions = this.listVersions(id);
|
|
493
|
+
const stmt = this.db.prepare("DELETE FROM prompts WHERE id = ?");
|
|
494
|
+
const result = stmt.run(id);
|
|
495
|
+
for (const version of versions) {
|
|
496
|
+
const contentPath = this.getVersionContentPath(id, version.id, prompt.status);
|
|
497
|
+
if (fs.existsSync(contentPath)) {
|
|
498
|
+
fs.unlinkSync(contentPath);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return result.changes > 0;
|
|
502
|
+
} catch (error) {
|
|
503
|
+
console.error(`Error deleting prompt ${id}:`, error);
|
|
504
|
+
throw error;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Archive a prompt
|
|
509
|
+
*/
|
|
510
|
+
archivePrompt(id) {
|
|
511
|
+
return this.updatePrompt(id, { status: "archived" });
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Restore an archived prompt
|
|
515
|
+
*/
|
|
516
|
+
restorePrompt(id) {
|
|
517
|
+
return this.updatePrompt(id, { status: "active" });
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* List prompts with optional filtering and pagination
|
|
521
|
+
*/
|
|
522
|
+
listPrompts(criteria = {}) {
|
|
523
|
+
let query = "SELECT * FROM prompts WHERE 1=1";
|
|
524
|
+
const params = [];
|
|
525
|
+
if (criteria.category) {
|
|
526
|
+
query += " AND category = ?";
|
|
527
|
+
params.push(criteria.category);
|
|
528
|
+
}
|
|
529
|
+
if (criteria.status) {
|
|
530
|
+
query += " AND status = ?";
|
|
531
|
+
params.push(criteria.status);
|
|
532
|
+
}
|
|
533
|
+
if (criteria.variant) {
|
|
534
|
+
query += " AND variant = ?";
|
|
535
|
+
params.push(criteria.variant);
|
|
536
|
+
}
|
|
537
|
+
if (criteria.minUsageCount !== void 0) {
|
|
538
|
+
query += " AND usage_count >= ?";
|
|
539
|
+
params.push(criteria.minUsageCount);
|
|
540
|
+
}
|
|
541
|
+
if (criteria.tags && criteria.tags.length > 0) {
|
|
542
|
+
const normalizedTags = criteria.tags.map((tag) => typeof tag === "string" ? tag.trim() : "").filter((tag) => tag.length > 0);
|
|
543
|
+
normalizedTags.forEach((tag) => {
|
|
544
|
+
query += " AND tags LIKE ? ESCAPE '\\'";
|
|
545
|
+
params.push(`%"${escapeLikePattern(tag)}"%`);
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
if (criteria.autoOptimize !== void 0) {
|
|
549
|
+
query += " AND auto_opt_in = ?";
|
|
550
|
+
params.push(criteria.autoOptimize ? 1 : 0);
|
|
551
|
+
}
|
|
552
|
+
if (criteria.query) {
|
|
553
|
+
query += " AND (name LIKE ? ESCAPE '\\' OR description LIKE ? ESCAPE '\\')";
|
|
554
|
+
const searchPattern = `%${escapeLikePattern(criteria.query)}%`;
|
|
555
|
+
params.push(searchPattern, searchPattern);
|
|
556
|
+
}
|
|
557
|
+
const sortBy = criteria.sortBy || "updatedAt";
|
|
558
|
+
const sortOrder = (criteria.sortOrder || "desc").toLowerCase();
|
|
559
|
+
const sortColumn = {
|
|
560
|
+
name: "name",
|
|
561
|
+
createdAt: "created_at",
|
|
562
|
+
updatedAt: "updated_at",
|
|
563
|
+
usageCount: "usage_count",
|
|
564
|
+
successRate: "usage_count",
|
|
565
|
+
avgCompleteness: "usage_count"
|
|
566
|
+
}[sortBy] || "updated_at";
|
|
567
|
+
const sortDirection = sortOrder === "asc" ? "ASC" : "DESC";
|
|
568
|
+
query += ` ORDER BY ${sortColumn} ${sortDirection}`;
|
|
569
|
+
if (sortColumn !== "updated_at") {
|
|
570
|
+
query += ", updated_at DESC";
|
|
571
|
+
}
|
|
572
|
+
query += `, id ${sortDirection}`;
|
|
573
|
+
const hasLimit = typeof criteria.limit === "number";
|
|
574
|
+
const hasOffset = typeof criteria.offset === "number";
|
|
575
|
+
if (hasLimit) {
|
|
576
|
+
query += " LIMIT ?";
|
|
577
|
+
params.push(criteria.limit);
|
|
578
|
+
}
|
|
579
|
+
if (!hasLimit && hasOffset) {
|
|
580
|
+
query += " LIMIT -1";
|
|
581
|
+
}
|
|
582
|
+
if (hasOffset) {
|
|
583
|
+
query += " OFFSET ?";
|
|
584
|
+
params.push(criteria.offset);
|
|
585
|
+
}
|
|
586
|
+
const stmt = this.db.prepare(query);
|
|
587
|
+
const rows = stmt.all(...params);
|
|
588
|
+
return rows.map((row) => this.rowToPrompt(row));
|
|
589
|
+
}
|
|
590
|
+
createVersion(inputOrPromptId, versionId, content, options = {}) {
|
|
591
|
+
const data = typeof inputOrPromptId === "object" ? {
|
|
592
|
+
promptId: inputOrPromptId.promptId,
|
|
593
|
+
versionId: inputOrPromptId.id,
|
|
594
|
+
content: inputOrPromptId.content,
|
|
595
|
+
changelog: inputOrPromptId.changelog,
|
|
596
|
+
author: inputOrPromptId.author,
|
|
597
|
+
isGenerated: inputOrPromptId.isGenerated,
|
|
598
|
+
generationModel: inputOrPromptId.generationModel,
|
|
599
|
+
generationPrompt: inputOrPromptId.generationPrompt,
|
|
600
|
+
activate: inputOrPromptId.activate ?? inputOrPromptId.isActive ?? false
|
|
601
|
+
} : {
|
|
602
|
+
promptId: inputOrPromptId,
|
|
603
|
+
versionId: versionId ?? "",
|
|
604
|
+
content: content ?? "",
|
|
605
|
+
changelog: options.changelog,
|
|
606
|
+
author: options.author,
|
|
607
|
+
isGenerated: options.isGenerated,
|
|
608
|
+
generationModel: options.generationModel,
|
|
609
|
+
generationPrompt: options.generationPrompt,
|
|
610
|
+
activate: options.activate ?? false
|
|
611
|
+
};
|
|
612
|
+
if (!data.promptId || !data.versionId || data.content === void 0) {
|
|
613
|
+
throw new Error("createVersion requires promptId, versionId, and content");
|
|
614
|
+
}
|
|
615
|
+
const prompt = this.getPrompt(data.promptId);
|
|
616
|
+
if (!prompt) {
|
|
617
|
+
throw new Error(`Prompt with ID "${data.promptId}" not found`);
|
|
618
|
+
}
|
|
619
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
620
|
+
const contentHash = this.hashContent(data.content);
|
|
621
|
+
const duplicateStmt = this.db.prepare(
|
|
622
|
+
"SELECT id FROM prompt_versions WHERE prompt_id = ? AND content_hash = ?"
|
|
623
|
+
);
|
|
624
|
+
const duplicate = duplicateStmt.get(data.promptId, contentHash);
|
|
625
|
+
if (duplicate) {
|
|
626
|
+
throw new Error("A version with identical content already exists");
|
|
627
|
+
}
|
|
628
|
+
this.saveVersionContent(data.promptId, data.versionId, data.content, prompt.status);
|
|
629
|
+
if (!this.db.transaction) {
|
|
630
|
+
try {
|
|
631
|
+
this.deleteVersionContent(data.promptId, data.versionId, prompt.status);
|
|
632
|
+
} catch {
|
|
633
|
+
}
|
|
634
|
+
throw new Error("Database transaction not available");
|
|
635
|
+
}
|
|
636
|
+
const transaction = this.db.transaction(() => {
|
|
637
|
+
const versionColumns = [
|
|
638
|
+
"id",
|
|
639
|
+
"prompt_id",
|
|
640
|
+
"content_hash",
|
|
641
|
+
"changelog",
|
|
642
|
+
"author",
|
|
643
|
+
"is_active",
|
|
644
|
+
"is_generated",
|
|
645
|
+
"generation_model",
|
|
646
|
+
"generation_prompt",
|
|
647
|
+
"created_at",
|
|
648
|
+
"activated_at"
|
|
649
|
+
];
|
|
650
|
+
const versionValues = [
|
|
651
|
+
data.versionId,
|
|
652
|
+
data.promptId,
|
|
653
|
+
contentHash,
|
|
654
|
+
data.changelog || null,
|
|
655
|
+
data.author || null,
|
|
656
|
+
0,
|
|
657
|
+
data.isGenerated ? 1 : 0,
|
|
658
|
+
data.generationModel || null,
|
|
659
|
+
data.generationPrompt || null,
|
|
660
|
+
now,
|
|
661
|
+
null
|
|
662
|
+
];
|
|
663
|
+
if (this.promptVersionsHasColumn("version_number")) {
|
|
664
|
+
versionColumns.splice(2, 0, "version_number");
|
|
665
|
+
versionValues.splice(2, 0, this.nextLegacyVersionNumber(data.promptId));
|
|
666
|
+
}
|
|
667
|
+
if (this.promptVersionsHasColumn("content")) {
|
|
668
|
+
versionColumns.push("content");
|
|
669
|
+
versionValues.push(data.content);
|
|
670
|
+
}
|
|
671
|
+
if (this.promptVersionsHasColumn("created_by")) {
|
|
672
|
+
versionColumns.push("created_by");
|
|
673
|
+
versionValues.push(data.author || "unknown");
|
|
674
|
+
}
|
|
675
|
+
const placeholders = versionColumns.map(() => "?").join(", ");
|
|
676
|
+
const stmt = this.db.prepare(`
|
|
677
|
+
INSERT INTO prompt_versions (${versionColumns.join(", ")})
|
|
678
|
+
VALUES (${placeholders})
|
|
679
|
+
`);
|
|
680
|
+
stmt.run(...versionValues);
|
|
681
|
+
if (data.activate) {
|
|
682
|
+
performActivation(this.db, {
|
|
683
|
+
promptId: data.promptId,
|
|
684
|
+
versionId: data.versionId,
|
|
685
|
+
now
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
try {
|
|
690
|
+
transaction();
|
|
691
|
+
} catch (txErr) {
|
|
692
|
+
try {
|
|
693
|
+
this.deleteVersionContent(data.promptId, data.versionId, prompt.status);
|
|
694
|
+
} catch {
|
|
695
|
+
}
|
|
696
|
+
throw txErr;
|
|
697
|
+
}
|
|
698
|
+
return this.getVersion(data.promptId, data.versionId);
|
|
699
|
+
}
|
|
700
|
+
getVersion(idOrPromptId, versionId) {
|
|
701
|
+
if (typeof versionId === "string") {
|
|
702
|
+
const stmt2 = this.db.prepare("SELECT * FROM prompt_versions WHERE prompt_id = ? AND id = ?");
|
|
703
|
+
const row = stmt2.get(idOrPromptId, versionId);
|
|
704
|
+
if (!row) return null;
|
|
705
|
+
return this.rowToVersion(row);
|
|
706
|
+
}
|
|
707
|
+
const stmt = this.db.prepare("SELECT * FROM prompt_versions WHERE id = ?");
|
|
708
|
+
const rows = stmt.all(idOrPromptId);
|
|
709
|
+
if (rows.length === 0) return null;
|
|
710
|
+
if (rows.length > 1) {
|
|
711
|
+
throw new Error(
|
|
712
|
+
`Version ID "${idOrPromptId}" is ambiguous (matches ${rows.length} prompts); pass promptId explicitly`
|
|
713
|
+
);
|
|
714
|
+
}
|
|
715
|
+
return this.rowToVersion(rows[0]);
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Get active version for a prompt
|
|
719
|
+
*/
|
|
720
|
+
getActiveVersion(promptId) {
|
|
721
|
+
const stmt = this.db.prepare(
|
|
722
|
+
"SELECT * FROM prompt_versions WHERE prompt_id = ? AND is_active = 1"
|
|
723
|
+
);
|
|
724
|
+
const row = stmt.get(promptId);
|
|
725
|
+
if (!row) {
|
|
726
|
+
return null;
|
|
727
|
+
}
|
|
728
|
+
return this.rowToVersion(row);
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* List all versions for a prompt
|
|
732
|
+
*/
|
|
733
|
+
listVersions(promptId) {
|
|
734
|
+
const stmt = this.db.prepare(
|
|
735
|
+
"SELECT * FROM prompt_versions WHERE prompt_id = ? ORDER BY created_at DESC"
|
|
736
|
+
);
|
|
737
|
+
const rows = stmt.all(promptId);
|
|
738
|
+
return rows.map((row) => this.rowToVersion(row));
|
|
739
|
+
}
|
|
740
|
+
/** List version metadata without hydrating prompt content side-files. */
|
|
741
|
+
listVersionMetadata(promptId) {
|
|
742
|
+
const stmt = this.db.prepare(
|
|
743
|
+
"SELECT * FROM prompt_versions WHERE prompt_id = ? ORDER BY created_at DESC"
|
|
744
|
+
);
|
|
745
|
+
const rows = stmt.all(promptId);
|
|
746
|
+
return rows.map((row) => ({
|
|
747
|
+
id: row.id,
|
|
748
|
+
promptId: row.prompt_id,
|
|
749
|
+
contentHash: row.content_hash,
|
|
750
|
+
isActive: row.is_active === 1,
|
|
751
|
+
isGenerated: row.is_generated === 1,
|
|
752
|
+
createdAt: row.created_at
|
|
753
|
+
}));
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Alias for listVersions to maintain backward compatibility
|
|
757
|
+
*/
|
|
758
|
+
getVersions(promptId) {
|
|
759
|
+
return this.listVersions(promptId);
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* Activate a version
|
|
763
|
+
*/
|
|
764
|
+
activateVersion(promptId, versionId, reason) {
|
|
765
|
+
const version = this.getVersion(promptId, versionId);
|
|
766
|
+
if (!version) {
|
|
767
|
+
throw new Error(`Version "${versionId}" not found for prompt "${promptId}"`);
|
|
768
|
+
}
|
|
769
|
+
if (!this.db.transaction) {
|
|
770
|
+
throw new Error("Database transaction not available");
|
|
771
|
+
}
|
|
772
|
+
performActivation(this.db, { promptId, versionId });
|
|
773
|
+
this.recordActivationHistory(promptId, versionId, reason || "manual:activate");
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Sync helper that writes one row into activation_history. Best-effort:
|
|
777
|
+
* the primary activation has already been performed by the caller, so a
|
|
778
|
+
* history-write failure must not abort it. Failures are surfaced via a
|
|
779
|
+
* console warning so test runs and ops surfaces still see them.
|
|
780
|
+
*/
|
|
781
|
+
recordActivationHistory(promptId, versionId, reason) {
|
|
782
|
+
try {
|
|
783
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
784
|
+
const recordId = `activation-${promptId}-${versionId}-${Date.now()}`;
|
|
785
|
+
const stmt = this.db.prepare(`
|
|
786
|
+
INSERT INTO activation_history (
|
|
787
|
+
id, prompt_id, version_id, activated_at, activated_by, reason
|
|
788
|
+
)
|
|
789
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
790
|
+
`);
|
|
791
|
+
stmt.run(recordId, promptId, versionId, now, "system:version-activation", reason);
|
|
792
|
+
} catch (error) {
|
|
793
|
+
console.warn(
|
|
794
|
+
`[prompts] activation_history insert failed for ${promptId}/${versionId}: ${error.message}`
|
|
795
|
+
);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
deactivateVersion(idOrPromptId, versionId) {
|
|
799
|
+
let resolvedPromptId;
|
|
800
|
+
let resolvedVersionId;
|
|
801
|
+
if (typeof versionId === "string") {
|
|
802
|
+
resolvedPromptId = idOrPromptId;
|
|
803
|
+
resolvedVersionId = versionId;
|
|
804
|
+
const version = this.getVersion(resolvedPromptId, resolvedVersionId);
|
|
805
|
+
if (!version) {
|
|
806
|
+
throw new Error(
|
|
807
|
+
`Version "${resolvedVersionId}" not found for prompt "${resolvedPromptId}"`
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
} else {
|
|
811
|
+
resolvedVersionId = idOrPromptId;
|
|
812
|
+
const lookupStmt = this.db.prepare("SELECT prompt_id FROM prompt_versions WHERE id = ?");
|
|
813
|
+
const rows = lookupStmt.all(resolvedVersionId);
|
|
814
|
+
if (rows.length === 0) {
|
|
815
|
+
throw new Error(`Version with ID "${resolvedVersionId}" not found`);
|
|
816
|
+
}
|
|
817
|
+
if (rows.length > 1) {
|
|
818
|
+
throw new Error(
|
|
819
|
+
`Version ID "${resolvedVersionId}" is ambiguous (matches ${rows.length} prompts); pass promptId explicitly`
|
|
820
|
+
);
|
|
821
|
+
}
|
|
822
|
+
resolvedPromptId = rows[0].prompt_id;
|
|
823
|
+
}
|
|
824
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
825
|
+
const stmt = this.db.prepare(`
|
|
826
|
+
UPDATE prompt_versions
|
|
827
|
+
SET is_active = 0, deactivated_at = ?
|
|
828
|
+
WHERE prompt_id = ? AND id = ?
|
|
829
|
+
`);
|
|
830
|
+
stmt.run(now, resolvedPromptId, resolvedVersionId);
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Increment usage count for a prompt
|
|
834
|
+
* Uses transaction and lock to prevent race conditions
|
|
835
|
+
*/
|
|
836
|
+
incrementUsage(promptId) {
|
|
837
|
+
if (!this.db.transaction) {
|
|
838
|
+
throw new Error("Database transaction not available");
|
|
839
|
+
}
|
|
840
|
+
const transaction = this.db.transaction(() => {
|
|
841
|
+
const checkStmt = this.db.prepare("SELECT last_used_at FROM prompts WHERE id = ?");
|
|
842
|
+
const row = checkStmt.get(promptId);
|
|
843
|
+
if (!row) {
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
let nowDate = /* @__PURE__ */ new Date();
|
|
847
|
+
if (row.last_used_at) {
|
|
848
|
+
const previous = new Date(row.last_used_at);
|
|
849
|
+
if (!Number.isNaN(previous.getTime()) && nowDate <= previous) {
|
|
850
|
+
nowDate = new Date(previous.getTime() + 1);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
const now = nowDate.toISOString();
|
|
854
|
+
const updateStmt = this.db.prepare(`
|
|
855
|
+
UPDATE prompts
|
|
856
|
+
SET usage_count = usage_count + 1, last_used_at = ?, updated_at = ?
|
|
857
|
+
WHERE id = ?
|
|
858
|
+
`);
|
|
859
|
+
updateStmt.run(now, now, promptId);
|
|
860
|
+
});
|
|
861
|
+
transaction();
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* Batch increment usage counts for multiple prompts
|
|
865
|
+
* More efficient than calling incrementUsage multiple times (prevents N+1 queries)
|
|
866
|
+
*/
|
|
867
|
+
incrementUsageBatch(promptIds) {
|
|
868
|
+
if (promptIds.length === 0) {
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
if (!this.db.transaction) {
|
|
872
|
+
throw new Error("Database transaction not available");
|
|
873
|
+
}
|
|
874
|
+
const transaction = this.db.transaction(() => {
|
|
875
|
+
const placeholders = promptIds.map(() => "?").join(",");
|
|
876
|
+
const batchLoadStmt = this.db.prepare(`
|
|
877
|
+
SELECT id, last_used_at FROM prompts WHERE id IN (${placeholders})
|
|
878
|
+
`);
|
|
879
|
+
const rows = batchLoadStmt.all(...promptIds);
|
|
880
|
+
const promptMap = /* @__PURE__ */ new Map();
|
|
881
|
+
for (const row of rows) {
|
|
882
|
+
promptMap.set(row.id, row.last_used_at);
|
|
883
|
+
}
|
|
884
|
+
const updateStmt = this.db.prepare(`
|
|
885
|
+
UPDATE prompts
|
|
886
|
+
SET usage_count = usage_count + 1, last_used_at = ?, updated_at = ?
|
|
887
|
+
WHERE id = ?
|
|
888
|
+
`);
|
|
889
|
+
const now = Date.now();
|
|
890
|
+
for (const promptId of promptIds) {
|
|
891
|
+
const lastUsedAt = promptMap.get(promptId);
|
|
892
|
+
if (lastUsedAt === void 0) {
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
895
|
+
let nowDate = new Date(now);
|
|
896
|
+
if (lastUsedAt !== null) {
|
|
897
|
+
const previous = new Date(lastUsedAt);
|
|
898
|
+
if (!Number.isNaN(previous.getTime()) && nowDate <= previous) {
|
|
899
|
+
nowDate = new Date(previous.getTime() + 1);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
const nowIso = nowDate.toISOString();
|
|
903
|
+
updateStmt.run(nowIso, nowIso, promptId);
|
|
904
|
+
}
|
|
905
|
+
});
|
|
906
|
+
transaction();
|
|
907
|
+
}
|
|
908
|
+
/**
|
|
909
|
+
* Get performance metrics for a version
|
|
910
|
+
*/
|
|
911
|
+
getPerformanceMetrics(versionId, variant) {
|
|
912
|
+
let query = "SELECT * FROM prompt_performance WHERE version_id = ?";
|
|
913
|
+
const params = [versionId];
|
|
914
|
+
if (variant) {
|
|
915
|
+
query += " AND variant = ?";
|
|
916
|
+
params.push(variant);
|
|
917
|
+
}
|
|
918
|
+
const stmt = this.db.prepare(query);
|
|
919
|
+
const row = stmt.get(...params);
|
|
920
|
+
if (!row) {
|
|
921
|
+
return null;
|
|
922
|
+
}
|
|
923
|
+
return this.rowToPerformance(row);
|
|
924
|
+
}
|
|
925
|
+
/**
|
|
926
|
+
* Update performance metrics for a version
|
|
927
|
+
*/
|
|
928
|
+
updatePerformanceMetrics(metrics) {
|
|
929
|
+
const stmt = this.db.prepare(`
|
|
930
|
+
INSERT OR REPLACE INTO prompt_performance (
|
|
931
|
+
prompt_id, version_id, variant,
|
|
932
|
+
total_executions, successful_executions, failed_executions,
|
|
933
|
+
success_rate, avg_completeness, avg_code_delivery_rate, avg_duration,
|
|
934
|
+
min_completeness, max_completeness, std_dev_completeness,
|
|
935
|
+
sample_size, first_execution_at, last_execution_at, calculated_at
|
|
936
|
+
)
|
|
937
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
938
|
+
`);
|
|
939
|
+
stmt.run(
|
|
940
|
+
metrics.promptId,
|
|
941
|
+
metrics.versionId,
|
|
942
|
+
metrics.variant || null,
|
|
943
|
+
metrics.totalExecutions,
|
|
944
|
+
metrics.successfulExecutions,
|
|
945
|
+
metrics.failedExecutions,
|
|
946
|
+
metrics.successRate,
|
|
947
|
+
metrics.avgCompleteness,
|
|
948
|
+
metrics.avgCodeDeliveryRate,
|
|
949
|
+
metrics.avgDuration,
|
|
950
|
+
metrics.minCompleteness,
|
|
951
|
+
metrics.maxCompleteness,
|
|
952
|
+
metrics.stdDevCompleteness,
|
|
953
|
+
metrics.sampleSize,
|
|
954
|
+
metrics.firstExecutionAt,
|
|
955
|
+
metrics.lastExecutionAt,
|
|
956
|
+
metrics.calculatedAt
|
|
957
|
+
);
|
|
958
|
+
}
|
|
959
|
+
/**
|
|
960
|
+
* Store performance metrics for a version (alias for updatePerformanceMetrics)
|
|
961
|
+
*/
|
|
962
|
+
storeMetrics(metrics) {
|
|
963
|
+
this.updatePerformanceMetrics(metrics);
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Get metrics for a prompt and version (alias for getPerformanceMetrics)
|
|
967
|
+
*/
|
|
968
|
+
getMetrics(promptId, versionId, variant) {
|
|
969
|
+
let query = "SELECT * FROM prompt_performance WHERE prompt_id = ? AND version_id = ?";
|
|
970
|
+
const params = [promptId, versionId];
|
|
971
|
+
if (variant) {
|
|
972
|
+
query += " AND variant = ?";
|
|
973
|
+
params.push(variant);
|
|
974
|
+
}
|
|
975
|
+
const stmt = this.db.prepare(query);
|
|
976
|
+
const row = stmt.get(...params);
|
|
977
|
+
if (!row) {
|
|
978
|
+
return null;
|
|
979
|
+
}
|
|
980
|
+
return this.rowToPerformance(row);
|
|
981
|
+
}
|
|
982
|
+
/**
|
|
983
|
+
* Get version content from file
|
|
984
|
+
*/
|
|
985
|
+
getVersionContent(promptId, versionId, status = "active") {
|
|
986
|
+
const contentPath = this.getVersionContentPath(promptId, versionId, status);
|
|
987
|
+
if (!fs.existsSync(contentPath)) {
|
|
988
|
+
throw new Error(`Content file not found for version ${versionId}`);
|
|
989
|
+
}
|
|
990
|
+
return fs.readFileSync(contentPath, "utf8");
|
|
991
|
+
}
|
|
992
|
+
/**
|
|
993
|
+
* Creates a new version of an existing prompt with content
|
|
994
|
+
*
|
|
995
|
+
* Tracks parent version for lineage and validates prompt exists.
|
|
996
|
+
*
|
|
997
|
+
* @param promptId - ID of the prompt to version
|
|
998
|
+
* @param content - New version content
|
|
999
|
+
* @param options - Optional metadata (changelog, author, activation reason)
|
|
1000
|
+
* @returns New version ID
|
|
1001
|
+
* @throws Error if prompt not found
|
|
1002
|
+
*
|
|
1003
|
+
* @example
|
|
1004
|
+
* const versionId = await store.createVersionAsync('user-auth', 'New prompt text', {
|
|
1005
|
+
* changelog: 'Improved clarity',
|
|
1006
|
+
* author: 'user:alice',
|
|
1007
|
+
* reason: 'Manual refinement'
|
|
1008
|
+
* });
|
|
1009
|
+
*/
|
|
1010
|
+
createVersionAsync(promptId, content, options) {
|
|
1011
|
+
return new Promise((resolve, reject) => {
|
|
1012
|
+
try {
|
|
1013
|
+
const prompt = this.getPrompt(promptId);
|
|
1014
|
+
if (!prompt) {
|
|
1015
|
+
reject(new Error(`Prompt with ID "${promptId}" not found`));
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
1018
|
+
const versionId = crypto.randomBytes(8).toString("hex");
|
|
1019
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1020
|
+
const contentHash = this.hashContent(content);
|
|
1021
|
+
const duplicateStmt = this.db.prepare(
|
|
1022
|
+
"SELECT id FROM prompt_versions WHERE prompt_id = ? AND content_hash = ?"
|
|
1023
|
+
);
|
|
1024
|
+
const duplicate = duplicateStmt.get(promptId, contentHash);
|
|
1025
|
+
if (duplicate) {
|
|
1026
|
+
reject(new Error("A version with identical content already exists"));
|
|
1027
|
+
return;
|
|
1028
|
+
}
|
|
1029
|
+
const currentActiveStmt = this.db.prepare(
|
|
1030
|
+
"SELECT id FROM prompt_versions WHERE prompt_id = ? AND is_active = 1"
|
|
1031
|
+
);
|
|
1032
|
+
const currentActive = currentActiveStmt.get(promptId);
|
|
1033
|
+
const parentVersionId = currentActive?.id || null;
|
|
1034
|
+
this.saveVersionContent(promptId, versionId, content, prompt.status);
|
|
1035
|
+
const versionColumns = [
|
|
1036
|
+
"id",
|
|
1037
|
+
"prompt_id",
|
|
1038
|
+
"content_hash",
|
|
1039
|
+
"changelog",
|
|
1040
|
+
"author",
|
|
1041
|
+
"is_active",
|
|
1042
|
+
"is_generated",
|
|
1043
|
+
"generation_model",
|
|
1044
|
+
"generation_prompt",
|
|
1045
|
+
"created_at",
|
|
1046
|
+
"parent_version_id"
|
|
1047
|
+
];
|
|
1048
|
+
const versionValues = [
|
|
1049
|
+
versionId,
|
|
1050
|
+
promptId,
|
|
1051
|
+
contentHash,
|
|
1052
|
+
options?.changelog || null,
|
|
1053
|
+
options?.author || null,
|
|
1054
|
+
0,
|
|
1055
|
+
// not active by default
|
|
1056
|
+
options?.isGenerated ? 1 : 0,
|
|
1057
|
+
options?.generationModel || null,
|
|
1058
|
+
options?.generationPrompt || null,
|
|
1059
|
+
now,
|
|
1060
|
+
parentVersionId
|
|
1061
|
+
];
|
|
1062
|
+
if (this.promptVersionsHasColumn("version_number")) {
|
|
1063
|
+
versionColumns.splice(2, 0, "version_number");
|
|
1064
|
+
versionValues.splice(2, 0, this.nextLegacyVersionNumber(promptId));
|
|
1065
|
+
}
|
|
1066
|
+
if (this.promptVersionsHasColumn("content")) {
|
|
1067
|
+
versionColumns.push("content");
|
|
1068
|
+
versionValues.push(content);
|
|
1069
|
+
}
|
|
1070
|
+
if (this.promptVersionsHasColumn("created_by")) {
|
|
1071
|
+
versionColumns.push("created_by");
|
|
1072
|
+
versionValues.push(options?.author || "unknown");
|
|
1073
|
+
}
|
|
1074
|
+
const placeholders = versionColumns.map(() => "?").join(", ");
|
|
1075
|
+
const stmt = this.db.prepare(`
|
|
1076
|
+
INSERT INTO prompt_versions (${versionColumns.join(", ")})
|
|
1077
|
+
VALUES (${placeholders})
|
|
1078
|
+
`);
|
|
1079
|
+
stmt.run(...versionValues);
|
|
1080
|
+
resolve(versionId);
|
|
1081
|
+
} catch (error) {
|
|
1082
|
+
reject(error);
|
|
1083
|
+
}
|
|
1084
|
+
});
|
|
1085
|
+
}
|
|
1086
|
+
/**
|
|
1087
|
+
* Returns all versions of a prompt in chronological order with lineage
|
|
1088
|
+
*
|
|
1089
|
+
* Includes parent-child relationships for lineage visualization.
|
|
1090
|
+
*
|
|
1091
|
+
* @param promptId - ID of the prompt
|
|
1092
|
+
* @returns Array of versions sorted by creation date (oldest first)
|
|
1093
|
+
* @throws Error if prompt not found
|
|
1094
|
+
*
|
|
1095
|
+
* @example
|
|
1096
|
+
* const history = await store.getVersionHistory('user-auth');
|
|
1097
|
+
* history.forEach(v => console.log(`${v.id}: ${v.changelog}`));
|
|
1098
|
+
*/
|
|
1099
|
+
getVersionHistory(promptId) {
|
|
1100
|
+
return new Promise((resolve, reject) => {
|
|
1101
|
+
try {
|
|
1102
|
+
const prompt = this.getPrompt(promptId);
|
|
1103
|
+
if (!prompt) {
|
|
1104
|
+
reject(new Error(`Prompt with ID "${promptId}" not found`));
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1107
|
+
const stmt = this.db.prepare(`
|
|
1108
|
+
SELECT * FROM prompt_versions
|
|
1109
|
+
WHERE prompt_id = ?
|
|
1110
|
+
ORDER BY created_at ASC
|
|
1111
|
+
`);
|
|
1112
|
+
const rows = stmt.all(promptId);
|
|
1113
|
+
const versions = rows.map((row) => this.rowToVersion(row));
|
|
1114
|
+
resolve(versions);
|
|
1115
|
+
} catch (error) {
|
|
1116
|
+
reject(error);
|
|
1117
|
+
}
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1120
|
+
/**
|
|
1121
|
+
* Activates a specific version of a prompt
|
|
1122
|
+
*
|
|
1123
|
+
* Updates the active version and records activation history. Validates
|
|
1124
|
+
* version exists for the prompt before activation.
|
|
1125
|
+
*
|
|
1126
|
+
* @param promptId - ID of the prompt
|
|
1127
|
+
* @param versionId - ID of the version to activate
|
|
1128
|
+
* @param reason - Optional activation reason (logged to history)
|
|
1129
|
+
* @throws Error if version not found for prompt
|
|
1130
|
+
*
|
|
1131
|
+
* @example
|
|
1132
|
+
* await store.setActiveVersion('user-auth', 'v3',
|
|
1133
|
+
* 'AutoTuner: +12% success rate');
|
|
1134
|
+
*/
|
|
1135
|
+
setActiveVersion(promptId, versionId, reason) {
|
|
1136
|
+
return new Promise((resolve, reject) => {
|
|
1137
|
+
try {
|
|
1138
|
+
const version = this.getVersion(promptId, versionId);
|
|
1139
|
+
if (!version) {
|
|
1140
|
+
reject(new Error(`Version "${versionId}" not found for prompt "${promptId}"`));
|
|
1141
|
+
return;
|
|
1142
|
+
}
|
|
1143
|
+
performActivation(this.db, { promptId, versionId });
|
|
1144
|
+
this.recordActivationHistory(promptId, versionId, reason || "system:set-active");
|
|
1145
|
+
resolve();
|
|
1146
|
+
} catch (error) {
|
|
1147
|
+
reject(error);
|
|
1148
|
+
}
|
|
1149
|
+
});
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* Records version activation in the audit trail
|
|
1153
|
+
*
|
|
1154
|
+
* Creates an immutable record of who activated what version and why.
|
|
1155
|
+
* Uses activation_history table for audit compliance.
|
|
1156
|
+
*
|
|
1157
|
+
* @param promptId - ID of the prompt
|
|
1158
|
+
* @param versionId - ID of the activated version
|
|
1159
|
+
* @param reason - Activation reason (required for audit trail)
|
|
1160
|
+
* @throws Error if version not found or database error
|
|
1161
|
+
*
|
|
1162
|
+
* @example
|
|
1163
|
+
* await store.trackActivation('user-auth', 'v3',
|
|
1164
|
+
* 'system:auto-tuner - Improved success rate by 8%');
|
|
1165
|
+
*/
|
|
1166
|
+
/**
|
|
1167
|
+
* List activation history rows for a prompt (newest first).
|
|
1168
|
+
*/
|
|
1169
|
+
listActivationHistory(promptId) {
|
|
1170
|
+
try {
|
|
1171
|
+
const stmt = this.db.prepare(`
|
|
1172
|
+
SELECT id, prompt_id, version_id, activated_at, activated_by, reason
|
|
1173
|
+
FROM activation_history
|
|
1174
|
+
WHERE prompt_id = ?
|
|
1175
|
+
ORDER BY activated_at DESC, id DESC
|
|
1176
|
+
`);
|
|
1177
|
+
const rows = stmt.all(promptId);
|
|
1178
|
+
return rows.map((row) => ({
|
|
1179
|
+
id: row.id,
|
|
1180
|
+
promptId: row.prompt_id,
|
|
1181
|
+
versionId: row.version_id,
|
|
1182
|
+
activatedAt: row.activated_at,
|
|
1183
|
+
activatedBy: row.activated_by,
|
|
1184
|
+
reason: row.reason
|
|
1185
|
+
}));
|
|
1186
|
+
} catch {
|
|
1187
|
+
return [];
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
trackActivation(promptId, versionId, reason) {
|
|
1191
|
+
return new Promise((resolve, reject) => {
|
|
1192
|
+
try {
|
|
1193
|
+
const version = this.getVersion(promptId, versionId);
|
|
1194
|
+
if (!version) {
|
|
1195
|
+
reject(new Error(`Version "${versionId}" not found for prompt "${promptId}"`));
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1199
|
+
const recordId = `activation-${promptId}-${versionId}-${Date.now()}`;
|
|
1200
|
+
const stmt = this.db.prepare(`
|
|
1201
|
+
INSERT INTO activation_history (
|
|
1202
|
+
id, prompt_id, version_id, activated_at, activated_by, reason
|
|
1203
|
+
)
|
|
1204
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
1205
|
+
`);
|
|
1206
|
+
stmt.run(
|
|
1207
|
+
recordId,
|
|
1208
|
+
promptId,
|
|
1209
|
+
versionId,
|
|
1210
|
+
now,
|
|
1211
|
+
"system:version-activation",
|
|
1212
|
+
// Mark as system-initiated
|
|
1213
|
+
reason
|
|
1214
|
+
);
|
|
1215
|
+
resolve();
|
|
1216
|
+
} catch (error) {
|
|
1217
|
+
reject(error);
|
|
1218
|
+
}
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
/**
|
|
1222
|
+
* Returns all variants generated from a version
|
|
1223
|
+
*
|
|
1224
|
+
* Includes mutation strategies applied and measured performance data.
|
|
1225
|
+
* Sorted by performance score descending.
|
|
1226
|
+
*
|
|
1227
|
+
* @param versionId - ID of the base version
|
|
1228
|
+
* @returns Array of variants sorted by performance (best first)
|
|
1229
|
+
*
|
|
1230
|
+
* @example
|
|
1231
|
+
* const variants = await store.getVariants('v1.0');
|
|
1232
|
+
* variants.forEach(v => {
|
|
1233
|
+
* console.log(`${v.id}: strategies=${v.mutationStrategies}, score=${v.successRate}`);
|
|
1234
|
+
* });
|
|
1235
|
+
*/
|
|
1236
|
+
getVariants(versionId) {
|
|
1237
|
+
return new Promise((resolve, reject) => {
|
|
1238
|
+
try {
|
|
1239
|
+
const stmt = this.db.prepare(`
|
|
1240
|
+
SELECT * FROM prompt_variants
|
|
1241
|
+
WHERE base_version_id = ?
|
|
1242
|
+
ORDER BY success_rate DESC, confidence DESC
|
|
1243
|
+
`);
|
|
1244
|
+
const rows = stmt.all(versionId);
|
|
1245
|
+
const variants = rows.map((row) => ({
|
|
1246
|
+
id: row.id,
|
|
1247
|
+
promptId: row.prompt_id,
|
|
1248
|
+
baseVersionId: row.base_version_id,
|
|
1249
|
+
mutationStrategies: parseJsonWithContext(
|
|
1250
|
+
row.mutation_strategies,
|
|
1251
|
+
"PromptStore.mutationStrategies"
|
|
1252
|
+
) ?? [],
|
|
1253
|
+
successRate: row.success_rate ?? void 0,
|
|
1254
|
+
completeness: row.completeness ?? void 0,
|
|
1255
|
+
durationMs: row.duration_ms ?? void 0,
|
|
1256
|
+
confidence: row.confidence ?? void 0,
|
|
1257
|
+
expectedImprovement: row.expected_improvement ?? void 0,
|
|
1258
|
+
createdAt: row.created_at
|
|
1259
|
+
}));
|
|
1260
|
+
resolve(variants);
|
|
1261
|
+
} catch (error) {
|
|
1262
|
+
reject(error);
|
|
1263
|
+
}
|
|
1264
|
+
});
|
|
1265
|
+
}
|
|
1266
|
+
/**
|
|
1267
|
+
* Returns version tree showing parent-child relationships
|
|
1268
|
+
*
|
|
1269
|
+
* Builds hierarchical tree structure showing how versions evolved.
|
|
1270
|
+
* Includes lineage information, performance scores, and mutation types.
|
|
1271
|
+
* Useful for visualization and understanding version evolution.
|
|
1272
|
+
*
|
|
1273
|
+
* @param promptId - ID of the prompt
|
|
1274
|
+
* @returns Version tree with root at the original version
|
|
1275
|
+
* @throws Error if prompt not found
|
|
1276
|
+
*
|
|
1277
|
+
* @example
|
|
1278
|
+
* const tree = await store.getVersionLineage('user-auth');
|
|
1279
|
+
* console.log(`Root: ${tree.rootVersion.id}`);
|
|
1280
|
+
* console.log(`Total versions: ${tree.totalVersions}`);
|
|
1281
|
+
* console.log(`Max depth: ${tree.depth}`);
|
|
1282
|
+
*/
|
|
1283
|
+
getVersionLineage(promptId) {
|
|
1284
|
+
return new Promise((resolve, reject) => {
|
|
1285
|
+
try {
|
|
1286
|
+
const prompt = this.getPrompt(promptId);
|
|
1287
|
+
if (!prompt) {
|
|
1288
|
+
reject(new Error(`Prompt with ID "${promptId}" not found`));
|
|
1289
|
+
return;
|
|
1290
|
+
}
|
|
1291
|
+
const versionStmt = this.db.prepare(`
|
|
1292
|
+
SELECT * FROM prompt_versions
|
|
1293
|
+
WHERE prompt_id = ?
|
|
1294
|
+
ORDER BY created_at ASC
|
|
1295
|
+
`);
|
|
1296
|
+
const versionRows = versionStmt.all(promptId);
|
|
1297
|
+
if (versionRows.length === 0) {
|
|
1298
|
+
resolve({
|
|
1299
|
+
promptId,
|
|
1300
|
+
rootVersion: {
|
|
1301
|
+
id: "root",
|
|
1302
|
+
contentHash: "",
|
|
1303
|
+
isActive: false,
|
|
1304
|
+
isGenerated: false,
|
|
1305
|
+
children: [],
|
|
1306
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1307
|
+
},
|
|
1308
|
+
totalVersions: 0,
|
|
1309
|
+
activeVersionId: prompt.currentVersion,
|
|
1310
|
+
depth: 0
|
|
1311
|
+
});
|
|
1312
|
+
return;
|
|
1313
|
+
}
|
|
1314
|
+
const versionMap = /* @__PURE__ */ new Map();
|
|
1315
|
+
for (const row of versionRows) {
|
|
1316
|
+
versionMap.set(row.id, {
|
|
1317
|
+
id: row.id,
|
|
1318
|
+
contentHash: row.content_hash,
|
|
1319
|
+
changelog: row.changelog || void 0,
|
|
1320
|
+
author: row.author || void 0,
|
|
1321
|
+
isActive: row.is_active === 1,
|
|
1322
|
+
isGenerated: row.is_generated === 1,
|
|
1323
|
+
generationModel: row.generation_model || void 0,
|
|
1324
|
+
parentVersionId: row.parent_version_id || void 0,
|
|
1325
|
+
children: [],
|
|
1326
|
+
createdAt: row.created_at,
|
|
1327
|
+
activatedAt: row.activated_at || void 0,
|
|
1328
|
+
performanceScore: void 0
|
|
1329
|
+
// Populated from performance table elsewhere
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
1332
|
+
const rootNodes = [];
|
|
1333
|
+
for (const row of versionRows) {
|
|
1334
|
+
const node = versionMap.get(row.id);
|
|
1335
|
+
const parentId = row.parent_version_id;
|
|
1336
|
+
const parent = parentId ? versionMap.get(parentId) : void 0;
|
|
1337
|
+
if (parent) {
|
|
1338
|
+
parent.children.push(node);
|
|
1339
|
+
} else {
|
|
1340
|
+
rootNodes.push(node);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
const calculateDepth = (node) => {
|
|
1344
|
+
if (node.children.length === 0) {
|
|
1345
|
+
return 1;
|
|
1346
|
+
}
|
|
1347
|
+
return 1 + Math.max(...node.children.map(calculateDepth));
|
|
1348
|
+
};
|
|
1349
|
+
const primaryRoot = rootNodes[0];
|
|
1350
|
+
if (!primaryRoot) {
|
|
1351
|
+
reject(new Error("Unable to determine root version"));
|
|
1352
|
+
return;
|
|
1353
|
+
}
|
|
1354
|
+
for (let i = 1; i < rootNodes.length; i++) {
|
|
1355
|
+
primaryRoot.children.push(rootNodes[i]);
|
|
1356
|
+
}
|
|
1357
|
+
const depth = calculateDepth(primaryRoot);
|
|
1358
|
+
const tree = {
|
|
1359
|
+
promptId,
|
|
1360
|
+
rootVersion: primaryRoot,
|
|
1361
|
+
totalVersions: versionRows.length,
|
|
1362
|
+
activeVersionId: prompt.currentVersion,
|
|
1363
|
+
depth
|
|
1364
|
+
};
|
|
1365
|
+
resolve(tree);
|
|
1366
|
+
} catch (error) {
|
|
1367
|
+
reject(error);
|
|
1368
|
+
}
|
|
1369
|
+
});
|
|
1370
|
+
}
|
|
1371
|
+
/**
|
|
1372
|
+
* Returns aggregated performance statistics across all versions
|
|
1373
|
+
*
|
|
1374
|
+
* Compares versions, identifies best/worst performers, analyzes trends,
|
|
1375
|
+
* and provides recommendations for optimization or rollback.
|
|
1376
|
+
*
|
|
1377
|
+
* @param promptId - ID of the prompt
|
|
1378
|
+
* @returns Performance statistics with recommendations
|
|
1379
|
+
* @throws Error if prompt not found
|
|
1380
|
+
*
|
|
1381
|
+
* @example
|
|
1382
|
+
* const stats = await store.getPerformanceStats('user-auth');
|
|
1383
|
+
* console.log(`Best version: ${stats.bestPerformingVersionId}`);
|
|
1384
|
+
* console.log(`Trend: ${stats.performanceTrend}`);
|
|
1385
|
+
* stats.recommendations.forEach(r => console.log(`${r.type}: ${r.reason}`));
|
|
1386
|
+
*/
|
|
1387
|
+
getPerformanceStats(promptId) {
|
|
1388
|
+
return new Promise((resolve, reject) => {
|
|
1389
|
+
try {
|
|
1390
|
+
const prompt = this.getPrompt(promptId);
|
|
1391
|
+
if (!prompt) {
|
|
1392
|
+
reject(new Error(`Prompt with ID "${promptId}" not found`));
|
|
1393
|
+
return;
|
|
1394
|
+
}
|
|
1395
|
+
const metricsStmt = this.db.prepare(`
|
|
1396
|
+
SELECT * FROM prompt_performance
|
|
1397
|
+
WHERE prompt_id = ?
|
|
1398
|
+
ORDER BY calculated_at DESC
|
|
1399
|
+
`);
|
|
1400
|
+
const metricsRows = metricsStmt.all(promptId);
|
|
1401
|
+
if (metricsRows.length === 0) {
|
|
1402
|
+
const emptyStats = {
|
|
1403
|
+
promptId,
|
|
1404
|
+
totalVersions: 0,
|
|
1405
|
+
activeVersionId: prompt.currentVersion,
|
|
1406
|
+
overallSuccessRate: 0,
|
|
1407
|
+
overallAvgCompleteness: 0,
|
|
1408
|
+
overallAvgDuration: 0,
|
|
1409
|
+
bestPerformingVersionId: "",
|
|
1410
|
+
bestSuccessRate: 0,
|
|
1411
|
+
lowestPerformingVersionId: "",
|
|
1412
|
+
lowestSuccessRate: 0,
|
|
1413
|
+
performanceTrend: "stable",
|
|
1414
|
+
trendDetails: [],
|
|
1415
|
+
recommendations: [],
|
|
1416
|
+
calculatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1417
|
+
};
|
|
1418
|
+
resolve(emptyStats);
|
|
1419
|
+
return;
|
|
1420
|
+
}
|
|
1421
|
+
const successRates = metricsRows.map((r) => r.success_rate);
|
|
1422
|
+
const completeness = metricsRows.map((r) => r.avg_completeness);
|
|
1423
|
+
const durations = metricsRows.map((r) => r.avg_duration);
|
|
1424
|
+
const overallSuccessRate = successRates.length > 0 ? successRates.reduce((a, b) => a + b, 0) / successRates.length : 0;
|
|
1425
|
+
const overallAvgCompleteness = completeness.length > 0 ? completeness.reduce((a, b) => a + b, 0) / completeness.length : 0;
|
|
1426
|
+
const overallAvgDuration = durations.length > 0 ? durations.reduce((a, b) => a + b, 0) / durations.length : 0;
|
|
1427
|
+
const sortedBySuccess = [...metricsRows].sort((a, b) => b.success_rate - a.success_rate);
|
|
1428
|
+
const bestPerforming = sortedBySuccess[0];
|
|
1429
|
+
const lowestPerforming = sortedBySuccess[sortedBySuccess.length - 1];
|
|
1430
|
+
if (!bestPerforming || !lowestPerforming) {
|
|
1431
|
+
reject(new Error("Unable to determine best/lowest performing versions"));
|
|
1432
|
+
return;
|
|
1433
|
+
}
|
|
1434
|
+
const trendDetails = metricsRows.slice(0, 5).reverse().map((row) => ({
|
|
1435
|
+
versionId: row.version_id,
|
|
1436
|
+
successRate: row.success_rate,
|
|
1437
|
+
timestamp: row.calculated_at
|
|
1438
|
+
}));
|
|
1439
|
+
let performanceTrend = "stable";
|
|
1440
|
+
if (trendDetails.length >= 2) {
|
|
1441
|
+
const oldTrend = trendDetails[0];
|
|
1442
|
+
const newTrend = trendDetails[trendDetails.length - 1];
|
|
1443
|
+
if (oldTrend && newTrend) {
|
|
1444
|
+
const oldSuccess = oldTrend.successRate;
|
|
1445
|
+
const newSuccess = newTrend.successRate;
|
|
1446
|
+
const delta = newSuccess - oldSuccess;
|
|
1447
|
+
const threshold = 0.05;
|
|
1448
|
+
if (delta > threshold) {
|
|
1449
|
+
performanceTrend = "improving";
|
|
1450
|
+
} else if (delta < -threshold) {
|
|
1451
|
+
performanceTrend = "declining";
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
const recommendations = [];
|
|
1456
|
+
if (bestPerforming.version_id !== prompt.currentVersion) {
|
|
1457
|
+
recommendations.push({
|
|
1458
|
+
type: "promote",
|
|
1459
|
+
targetVersionId: bestPerforming.version_id,
|
|
1460
|
+
reason: `Version ${bestPerforming.version_id} has highest success rate (${(bestPerforming.success_rate * 100).toFixed(1)}%)`,
|
|
1461
|
+
expectedImprovement: bestPerforming.success_rate - overallSuccessRate
|
|
1462
|
+
});
|
|
1463
|
+
}
|
|
1464
|
+
if (performanceTrend === "declining") {
|
|
1465
|
+
recommendations.push({
|
|
1466
|
+
type: "rollback",
|
|
1467
|
+
targetVersionId: bestPerforming.version_id,
|
|
1468
|
+
reason: "Performance is declining over recent versions",
|
|
1469
|
+
expectedImprovement: bestPerforming.success_rate - overallSuccessRate
|
|
1470
|
+
});
|
|
1471
|
+
}
|
|
1472
|
+
const stats = {
|
|
1473
|
+
promptId,
|
|
1474
|
+
totalVersions: metricsRows.length,
|
|
1475
|
+
activeVersionId: prompt.currentVersion,
|
|
1476
|
+
overallSuccessRate,
|
|
1477
|
+
overallAvgCompleteness,
|
|
1478
|
+
overallAvgDuration,
|
|
1479
|
+
bestPerformingVersionId: bestPerforming.version_id,
|
|
1480
|
+
bestSuccessRate: bestPerforming.success_rate,
|
|
1481
|
+
lowestPerformingVersionId: lowestPerforming.version_id,
|
|
1482
|
+
lowestSuccessRate: lowestPerforming.success_rate,
|
|
1483
|
+
performanceTrend,
|
|
1484
|
+
trendDetails,
|
|
1485
|
+
recommendations,
|
|
1486
|
+
calculatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1487
|
+
};
|
|
1488
|
+
resolve(stats);
|
|
1489
|
+
} catch (error) {
|
|
1490
|
+
reject(error);
|
|
1491
|
+
}
|
|
1492
|
+
});
|
|
1493
|
+
}
|
|
1494
|
+
/**
|
|
1495
|
+
* Close database connection
|
|
1496
|
+
*/
|
|
1497
|
+
close() {
|
|
1498
|
+
this.db.close();
|
|
1499
|
+
}
|
|
1500
|
+
// Private helper methods
|
|
1501
|
+
rowToPrompt(row) {
|
|
1502
|
+
return {
|
|
1503
|
+
id: row.id,
|
|
1504
|
+
name: row.name,
|
|
1505
|
+
description: row.description,
|
|
1506
|
+
category: row.category,
|
|
1507
|
+
status: row.status,
|
|
1508
|
+
variant: row.variant ? row.variant : void 0,
|
|
1509
|
+
tags: parseJsonWithContext(row.tags, "PromptStore.tags") ?? [],
|
|
1510
|
+
autoOptimize: row.auto_opt_in === 1,
|
|
1511
|
+
currentVersion: row.current_version,
|
|
1512
|
+
createdAt: row.created_at,
|
|
1513
|
+
updatedAt: row.updated_at,
|
|
1514
|
+
archivedAt: row.archived_at || void 0,
|
|
1515
|
+
usageCount: row.usage_count,
|
|
1516
|
+
lastUsedAt: row.last_used_at || void 0
|
|
1517
|
+
};
|
|
1518
|
+
}
|
|
1519
|
+
rowToVersion(row) {
|
|
1520
|
+
const prompt = this.getPrompt(row.prompt_id);
|
|
1521
|
+
if (!prompt) {
|
|
1522
|
+
throw new Error(`Prompt "${row.prompt_id}" not found while resolving version "${row.id}"`);
|
|
1523
|
+
}
|
|
1524
|
+
const content = this.getVersionContent(row.prompt_id, row.id, prompt.status);
|
|
1525
|
+
return {
|
|
1526
|
+
id: row.id,
|
|
1527
|
+
promptId: row.prompt_id,
|
|
1528
|
+
content,
|
|
1529
|
+
contentHash: row.content_hash,
|
|
1530
|
+
changelog: row.changelog || void 0,
|
|
1531
|
+
author: row.author || void 0,
|
|
1532
|
+
isActive: row.is_active === 1,
|
|
1533
|
+
isGenerated: row.is_generated === 1,
|
|
1534
|
+
generationModel: row.generation_model || void 0,
|
|
1535
|
+
generationPrompt: row.generation_prompt || void 0,
|
|
1536
|
+
createdAt: row.created_at,
|
|
1537
|
+
activatedAt: row.activated_at || void 0,
|
|
1538
|
+
deactivatedAt: row.deactivated_at || void 0
|
|
1539
|
+
};
|
|
1540
|
+
}
|
|
1541
|
+
rowToPerformance(row) {
|
|
1542
|
+
return {
|
|
1543
|
+
promptId: row.prompt_id,
|
|
1544
|
+
versionId: row.version_id,
|
|
1545
|
+
variant: row.variant ? row.variant : null,
|
|
1546
|
+
totalExecutions: row.total_executions,
|
|
1547
|
+
successfulExecutions: row.successful_executions,
|
|
1548
|
+
failedExecutions: row.failed_executions,
|
|
1549
|
+
successRate: row.success_rate,
|
|
1550
|
+
avgCompleteness: row.avg_completeness,
|
|
1551
|
+
avgCodeDeliveryRate: row.avg_code_delivery_rate,
|
|
1552
|
+
avgDuration: row.avg_duration,
|
|
1553
|
+
minCompleteness: row.min_completeness,
|
|
1554
|
+
maxCompleteness: row.max_completeness,
|
|
1555
|
+
stdDevCompleteness: row.std_dev_completeness,
|
|
1556
|
+
sampleSize: row.sample_size,
|
|
1557
|
+
firstExecutionAt: row.first_execution_at,
|
|
1558
|
+
lastExecutionAt: row.last_execution_at,
|
|
1559
|
+
calculatedAt: row.calculated_at
|
|
1560
|
+
};
|
|
1561
|
+
}
|
|
1562
|
+
hashContent(content) {
|
|
1563
|
+
return crypto.createHash("sha256").update(content).digest("hex");
|
|
1564
|
+
}
|
|
1565
|
+
saveVersionContent(promptId, versionId, content, status) {
|
|
1566
|
+
const contentPath = this.getVersionContentPath(promptId, versionId, status);
|
|
1567
|
+
atomicWriteTextSync(contentPath, content);
|
|
1568
|
+
}
|
|
1569
|
+
deleteVersionContent(promptId, versionId, status) {
|
|
1570
|
+
const contentPath = this.getVersionContentPath(promptId, versionId, status);
|
|
1571
|
+
try {
|
|
1572
|
+
fs.unlinkSync(contentPath);
|
|
1573
|
+
} catch (err) {
|
|
1574
|
+
const code = err.code;
|
|
1575
|
+
if (code !== "ENOENT") {
|
|
1576
|
+
throw err;
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
movePromptFiles(id, from, to) {
|
|
1581
|
+
const fromDir = from === "archived" ? this.archivedDir : this.activeDir;
|
|
1582
|
+
const toDir = to === "archived" ? this.archivedDir : this.activeDir;
|
|
1583
|
+
this.ensureSafePromptId(id);
|
|
1584
|
+
const versionRows = this.db.prepare("SELECT id FROM prompt_versions WHERE prompt_id = ?").all(id);
|
|
1585
|
+
for (const row of versionRows) {
|
|
1586
|
+
this.ensureSafeVersionId(row.id);
|
|
1587
|
+
const srcPath = path.join(fromDir, `${id}-${row.id}.txt`);
|
|
1588
|
+
const destPath = path.join(toDir, `${id}-${row.id}.txt`);
|
|
1589
|
+
if (fs.existsSync(srcPath)) {
|
|
1590
|
+
fs.renameSync(srcPath, destPath);
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
/**
|
|
1595
|
+
* Search prompts based on criteria
|
|
1596
|
+
*/
|
|
1597
|
+
searchPrompts(queryOrCriteria, filterCriteria) {
|
|
1598
|
+
try {
|
|
1599
|
+
const criteria = typeof queryOrCriteria === "string" ? { query: queryOrCriteria, ...filterCriteria } : queryOrCriteria;
|
|
1600
|
+
let query = "SELECT * FROM prompts WHERE 1=1";
|
|
1601
|
+
const params = [];
|
|
1602
|
+
if (criteria.query) {
|
|
1603
|
+
query += " AND (name LIKE ? OR description LIKE ? OR tags LIKE ?)";
|
|
1604
|
+
const searchTerm = `%${criteria.query}%`;
|
|
1605
|
+
params.push(searchTerm, searchTerm, searchTerm);
|
|
1606
|
+
}
|
|
1607
|
+
if (criteria.category) {
|
|
1608
|
+
query += " AND category = ?";
|
|
1609
|
+
params.push(criteria.category);
|
|
1610
|
+
}
|
|
1611
|
+
if (criteria.status) {
|
|
1612
|
+
query += " AND status = ?";
|
|
1613
|
+
params.push(criteria.status);
|
|
1614
|
+
}
|
|
1615
|
+
if (criteria.tags && criteria.tags.length > 0) {
|
|
1616
|
+
const normalizedTags = criteria.tags.map((tag) => typeof tag === "string" ? tag.trim() : "").filter((tag) => tag.length > 0);
|
|
1617
|
+
if (normalizedTags.length > 0) {
|
|
1618
|
+
query += " AND (";
|
|
1619
|
+
for (const tag of normalizedTags) {
|
|
1620
|
+
query += "tags LIKE ? ESCAPE '\\' OR ";
|
|
1621
|
+
params.push(`%${escapeLikePattern(tag)}%`);
|
|
1622
|
+
}
|
|
1623
|
+
query = `${query.slice(0, -4)})`;
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
query += " ORDER BY usage_count DESC, updated_at DESC";
|
|
1627
|
+
const stmt = this.db.prepare(query);
|
|
1628
|
+
const rows = stmt.all(...params);
|
|
1629
|
+
return rows.map((row) => this.rowToPrompt(row));
|
|
1630
|
+
} catch (error) {
|
|
1631
|
+
throw new Error(
|
|
1632
|
+
`searchPrompts failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1633
|
+
);
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
/**
|
|
1637
|
+
* Get all metrics for a prompt
|
|
1638
|
+
*/
|
|
1639
|
+
getAllMetrics(promptId) {
|
|
1640
|
+
try {
|
|
1641
|
+
const stmt = this.db.prepare(`
|
|
1642
|
+
SELECT * FROM prompt_performance
|
|
1643
|
+
WHERE prompt_id = ?
|
|
1644
|
+
ORDER BY calculated_at DESC
|
|
1645
|
+
`);
|
|
1646
|
+
const rows = stmt.all(promptId);
|
|
1647
|
+
return rows.map((row) => this.rowToPerformance(row));
|
|
1648
|
+
} catch (_error) {
|
|
1649
|
+
return [];
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
/**
|
|
1653
|
+
* Get the poetic directory path
|
|
1654
|
+
*/
|
|
1655
|
+
getPoticDir() {
|
|
1656
|
+
return this.poeticDir;
|
|
1657
|
+
}
|
|
1658
|
+
/**
|
|
1659
|
+
* Save a prompt variant to database
|
|
1660
|
+
*/
|
|
1661
|
+
saveVariant(variant) {
|
|
1662
|
+
try {
|
|
1663
|
+
const versionStmt = this.db.prepare(
|
|
1664
|
+
"SELECT id FROM prompt_versions WHERE prompt_id = ? AND id = ?"
|
|
1665
|
+
);
|
|
1666
|
+
const versionExists = versionStmt.get(variant.promptId, variant.baseVersionId);
|
|
1667
|
+
if (!versionExists) {
|
|
1668
|
+
throw new Error(
|
|
1669
|
+
`Base version "${variant.baseVersionId}" not found for prompt "${variant.promptId}"`
|
|
1670
|
+
);
|
|
1671
|
+
}
|
|
1672
|
+
const stmt = this.db.prepare(`
|
|
1673
|
+
INSERT OR REPLACE INTO prompt_variants (
|
|
1674
|
+
id,
|
|
1675
|
+
prompt_id,
|
|
1676
|
+
base_version_id,
|
|
1677
|
+
mutation_strategies,
|
|
1678
|
+
success_rate,
|
|
1679
|
+
completeness,
|
|
1680
|
+
duration_ms,
|
|
1681
|
+
confidence,
|
|
1682
|
+
expected_improvement,
|
|
1683
|
+
created_at
|
|
1684
|
+
)
|
|
1685
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1686
|
+
`);
|
|
1687
|
+
stmt.run(
|
|
1688
|
+
variant.id,
|
|
1689
|
+
variant.promptId,
|
|
1690
|
+
variant.baseVersionId,
|
|
1691
|
+
JSON.stringify(variant.mutationStrategies),
|
|
1692
|
+
variant.successRate || null,
|
|
1693
|
+
variant.completeness || null,
|
|
1694
|
+
variant.durationMs || null,
|
|
1695
|
+
variant.confidence || null,
|
|
1696
|
+
variant.expectedImprovement || null,
|
|
1697
|
+
variant.createdAt
|
|
1698
|
+
);
|
|
1699
|
+
} catch (error) {
|
|
1700
|
+
throw new Error(`Failed to save variant: ${error.message}`);
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
ensureSafePromptId(promptId) {
|
|
1704
|
+
if (!PROMPT_ID_PATTERN.test(promptId) && !LEGACY_PROMPT_ID_PATTERN.test(promptId)) {
|
|
1705
|
+
throw new Error(
|
|
1706
|
+
"Prompt ID must be a safe identifier (lowercase letters, numbers, hyphens; legacy underscores are readable)"
|
|
1707
|
+
);
|
|
1708
|
+
}
|
|
1709
|
+
if (promptId.includes("/") || promptId.includes("\\")) {
|
|
1710
|
+
throw new Error("Prompt ID cannot contain path separators");
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
ensureSafeVersionId(versionId) {
|
|
1714
|
+
if (!VERSION_ID_PATTERN.test(versionId)) {
|
|
1715
|
+
throw new Error(
|
|
1716
|
+
"Version ID must start with an alphanumeric character and may only include dots, underscores, or hyphens"
|
|
1717
|
+
);
|
|
1718
|
+
}
|
|
1719
|
+
if (versionId.includes("/") || versionId.includes("\\")) {
|
|
1720
|
+
throw new Error("Version ID cannot contain path separators");
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
getVersionContentPath(promptId, versionId, status = "active") {
|
|
1724
|
+
this.ensureSafePromptId(promptId);
|
|
1725
|
+
this.ensureSafeVersionId(versionId);
|
|
1726
|
+
const baseDir = status === "archived" ? this.archivedDir : this.activeDir;
|
|
1727
|
+
return path.join(baseDir, `${promptId}-${versionId}.txt`);
|
|
1728
|
+
}
|
|
1729
|
+
};
|
|
1730
|
+
|
|
1731
|
+
export {
|
|
1732
|
+
PromptStore
|
|
1733
|
+
};
|
|
1734
|
+
//# sourceMappingURL=chunk-OQ6K46CK.js.map
|