@ebrindley/build 0.0.0-stage → 1.42.1-rc28
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/.build-project/providers/catalog.json +13951 -0
- package/.build-project/providers/pricing.json +1978 -0
- package/.build-project/providers/registry.json +4103 -0
- package/.github/SECURITY.md +75 -0
- package/.nvmrc +1 -0
- package/CHANGELOG.md +661 -0
- package/CODE_OF_CONDUCT.md +44 -0
- package/CONTRIBUTING.md +24 -0
- package/INSTALL.md +623 -0
- package/LICENSE +21 -0
- package/README.md +118 -2
- package/THIRD_PARTY_NOTICES.txt +26 -0
- package/dist/ai-judge-UE5UOYOO.js +191 -0
- package/dist/allowlist-grounding-KPLN6NC5.js +16 -0
- package/dist/allowlist-utils-MZZKKXRD.js +31 -0
- package/dist/apply-completion-mode-EM37UZHB.js +110 -0
- package/dist/artifact-migrator-WPACNSEP.js +276 -0
- package/dist/ask-2OZ4JFQR.js +176 -0
- package/dist/auth-6UKBTJUQ.js +185 -0
- package/dist/auth-H5KJL6HL.js +165 -0
- package/dist/auth-LVJRJDMU.js +12 -0
- package/dist/auth-NHZOCNRR.js +94 -0
- package/dist/auth-PBXHWXGW.js +95 -0
- package/dist/auth-T7Y5DCAH.js +91 -0
- package/dist/auth-TVVKCHQW.js +13 -0
- package/dist/auth-UHB2UCSS.js +97 -0
- package/dist/auth-VACA3VUL.js +98 -0
- package/dist/auth-VVLC77S3.js +44 -0
- package/dist/auth-liveness-XO4AGDDD.js +53 -0
- package/dist/autoloop-cleanup-SI3VGAAR.js +106 -0
- package/dist/autoloop-evidence-gates-J5GG5YQB.js +39 -0
- package/dist/autoloop-gate-policy-SUNAEP6Q.js +169 -0
- package/dist/autoloop-helpers-VQGQNTT6.js +52 -0
- package/dist/autoloop-ledger-P6TIDP7C.js +96 -0
- package/dist/autoloop-ledger-subscriber-HFAGOZXH.js +161 -0
- package/dist/autoloop-run-defaults-GWGZBNT7.js +27 -0
- package/dist/autoloop-run-lock-GBWRM5A2.js +197 -0
- package/dist/autoloop-success-C32QVWOP.js +93 -0
- package/dist/autoloop-termination-summary-GI6IBQWD.js +58 -0
- package/dist/autoloop-trajectory-AMKSQISD.js +70 -0
- package/dist/autoloop-wall-clock-T7ZVIQOC.js +12 -0
- package/dist/automatic-branch-cleanup-R62X2C5O.js +49 -0
- package/dist/autonomous-loop-controller-2WL363LW.js +4386 -0
- package/dist/backend-YUTFDZXZ.js +30 -0
- package/dist/background-executor-Z3ODTMD7.js +260 -0
- package/dist/backlog-75QPEAMW.js +403 -0
- package/dist/backlog-execution-intent-GWUV5TUK.js +19 -0
- package/dist/backup-active-store-XHWLN34M.js +16 -0
- package/dist/backup-machine-stores-UI4LTJOY.js +251 -0
- package/dist/backup-telemetry-db-Z4ICYCNW.js +26 -0
- package/dist/branch-archive-manager-FMSQ7YJF.js +18 -0
- package/dist/branch-cleanup-manager-ST6FJGND.js +35 -0
- package/dist/build-gate-7NKWPY62.js +68 -0
- package/dist/build-root-S7DINODY.js +18 -0
- package/dist/change-summary-R6CB6VXJ.js +50 -0
- package/dist/chunk-24MNKKOM.js +173 -0
- package/dist/chunk-2H6VZFIO.js +235 -0
- package/dist/chunk-2JIX3EKV.js +39 -0
- package/dist/chunk-2KO7HVZM.js +106 -0
- package/dist/chunk-2L36U25O.js +100 -0
- package/dist/chunk-2NMNFUQA.js +475 -0
- package/dist/chunk-2OUAEH67.js +83 -0
- package/dist/chunk-2VLJUXJU.js +115 -0
- package/dist/chunk-2VUEDIUM.js +77 -0
- package/dist/chunk-2Y2IIHPI.js +430 -0
- package/dist/chunk-2YRG3LHZ.js +220 -0
- package/dist/chunk-2Z5Q3SUY.js +65 -0
- package/dist/chunk-32IYXIE5.js +873 -0
- package/dist/chunk-33IGPPUI.js +292 -0
- package/dist/chunk-352PCJLK.js +283 -0
- package/dist/chunk-35J4NE6S.js +226 -0
- package/dist/chunk-3C7WBIVK.js +1016 -0
- package/dist/chunk-3H3EY6U7.js +1225 -0
- package/dist/chunk-3H4MWYIC.js +198 -0
- package/dist/chunk-3HHWQR3N.js +2479 -0
- package/dist/chunk-3JKNRYEE.js +14 -0
- package/dist/chunk-3LECCYZY.js +128 -0
- package/dist/chunk-3LOY6YZI.js +852 -0
- package/dist/chunk-3M57DADF.js +44 -0
- package/dist/chunk-3NOTLVLG.js +3803 -0
- package/dist/chunk-3OPP2OZB.js +1480 -0
- package/dist/chunk-3P5IN5E7.js +9 -0
- package/dist/chunk-3PL22IYZ.js +20 -0
- package/dist/chunk-3REDAJUJ.js +14 -0
- package/dist/chunk-3S2R4XJI.js +203 -0
- package/dist/chunk-3UBZI5DW.js +61 -0
- package/dist/chunk-3VV5OBGG.js +308 -0
- package/dist/chunk-3WY5TU2O.js +823 -0
- package/dist/chunk-43OKHTW4.js +82 -0
- package/dist/chunk-45KUJBDI.js +112 -0
- package/dist/chunk-47X5LM7B.js +224 -0
- package/dist/chunk-4B6FQJ77.js +268 -0
- package/dist/chunk-4BTDUT2S.js +42 -0
- package/dist/chunk-4DJL2VXA.js +24 -0
- package/dist/chunk-4EBSXZ73.js +48 -0
- package/dist/chunk-4QKP6I4C.js +294 -0
- package/dist/chunk-4U6XK2DG.js +300 -0
- package/dist/chunk-4UMRUFBD.js +132 -0
- package/dist/chunk-4US4SYJ4.js +569 -0
- package/dist/chunk-4ZPLWEZO.js +154 -0
- package/dist/chunk-56WPYDJH.js +624 -0
- package/dist/chunk-57WRCJJW.js +50 -0
- package/dist/chunk-5AW4RMNG.js +24 -0
- package/dist/chunk-5EQN56OZ.js +155 -0
- package/dist/chunk-5F43TUIN.js +38 -0
- package/dist/chunk-5FKHIKTS.js +115 -0
- package/dist/chunk-5HDP7XZG.js +91 -0
- package/dist/chunk-5KQETTNS.js +152 -0
- package/dist/chunk-5PDVN2KO.js +498 -0
- package/dist/chunk-5UBIFVRD.js +509 -0
- package/dist/chunk-5YDE3Q62.js +46 -0
- package/dist/chunk-626AJVMU.js +302 -0
- package/dist/chunk-633XZ7UF.js +3583 -0
- package/dist/chunk-63DHNHGA.js +236 -0
- package/dist/chunk-666656AR.js +568 -0
- package/dist/chunk-67YRJPJO.js +19 -0
- package/dist/chunk-6CAU7VBA.js +20 -0
- package/dist/chunk-6CB3KJRY.js +21 -0
- package/dist/chunk-6DBMALXL.js +29 -0
- package/dist/chunk-6E25C4IA.js +269 -0
- package/dist/chunk-6FIBNIQU.js +73 -0
- package/dist/chunk-6G57FYBV.js +189 -0
- package/dist/chunk-6KZKRTG3.js +4885 -0
- package/dist/chunk-6LAH2UV2.js +525 -0
- package/dist/chunk-6PZY2TTU.js +921 -0
- package/dist/chunk-6T6NHXK4.js +230 -0
- package/dist/chunk-6TBEX4R4.js +432 -0
- package/dist/chunk-6TRD7TEE.js +911 -0
- package/dist/chunk-6XCP2RAI.js +47 -0
- package/dist/chunk-726G6WDL.js +351 -0
- package/dist/chunk-75EMT7BF.js +616 -0
- package/dist/chunk-762ACDZJ.js +4696 -0
- package/dist/chunk-77I6G4CO.js +1 -0
- package/dist/chunk-7DJ6SQH3.js +510 -0
- package/dist/chunk-7HPCIOMA.js +1383 -0
- package/dist/chunk-7HYBSRPZ.js +17503 -0
- package/dist/chunk-7KBEOPVB.js +73 -0
- package/dist/chunk-7LHJDJB3.js +2222 -0
- package/dist/chunk-7NVJMH52.js +306 -0
- package/dist/chunk-7RMARDVH.js +33 -0
- package/dist/chunk-7SEWU4QG.js +36 -0
- package/dist/chunk-7TUTZTI2.js +911 -0
- package/dist/chunk-7VBDFPUM.js +340 -0
- package/dist/chunk-7VRJHTGZ.js +6406 -0
- package/dist/chunk-7YAOUUKK.js +493 -0
- package/dist/chunk-AAAODV76.js +860 -0
- package/dist/chunk-AB4HUJVQ.js +339 -0
- package/dist/chunk-AEQWV746.js +611 -0
- package/dist/chunk-AHU3FKPA.js +11639 -0
- package/dist/chunk-AISTV5XU.js +226 -0
- package/dist/chunk-AJBTKGJZ.js +48 -0
- package/dist/chunk-AJJNW7XT.js +248 -0
- package/dist/chunk-AJN5Y5YZ.js +160 -0
- package/dist/chunk-ALDTFNZ3.js +150 -0
- package/dist/chunk-ARARVIZK.js +281 -0
- package/dist/chunk-ATBM6AW5.js +53 -0
- package/dist/chunk-ATKEKM3E.js +206 -0
- package/dist/chunk-AUJLW6JZ.js +92 -0
- package/dist/chunk-AY3MHEFM.js +24 -0
- package/dist/chunk-B7PYTV72.js +236 -0
- package/dist/chunk-B7YRSULE.js +1423 -0
- package/dist/chunk-BAWJNMWF.js +339 -0
- package/dist/chunk-BBPIILO2.js +88 -0
- package/dist/chunk-BD3PGW6A.js +957 -0
- package/dist/chunk-BDPYFAB4.js +44 -0
- package/dist/chunk-BIUV23HH.js +729 -0
- package/dist/chunk-BQ3VAGXH.js +243 -0
- package/dist/chunk-BQJOGAWT.js +31 -0
- package/dist/chunk-BT7EG7CO.js +68 -0
- package/dist/chunk-BV3XQQLU.js +27 -0
- package/dist/chunk-BY6ODHNZ.js +78 -0
- package/dist/chunk-BZRLSZNV.js +79 -0
- package/dist/chunk-C3DH3NCY.js +2773 -0
- package/dist/chunk-C3KCMAJP.js +756 -0
- package/dist/chunk-C7AGUJ5K.js +267 -0
- package/dist/chunk-CBSWKQCX.js +342 -0
- package/dist/chunk-CE5OZBYY.js +21 -0
- package/dist/chunk-CFCVYHSW.js +373 -0
- package/dist/chunk-CHA2HDE5.js +126 -0
- package/dist/chunk-CIHWPGS5.js +146 -0
- package/dist/chunk-CJBSZX3F.js +127 -0
- package/dist/chunk-CLA6QIJM.js +43 -0
- package/dist/chunk-CPSVQR2I.js +365 -0
- package/dist/chunk-CRPRVNQ4.js +254 -0
- package/dist/chunk-CSIE4Y7C.js +1093 -0
- package/dist/chunk-CSOPSYDY.js +142 -0
- package/dist/chunk-CSXLLEGB.js +205 -0
- package/dist/chunk-CTDLERWU.js +293 -0
- package/dist/chunk-CULBXMSK.js +110 -0
- package/dist/chunk-D2M2Y5ID.js +21 -0
- package/dist/chunk-D37WY7SH.js +1060 -0
- package/dist/chunk-D4VJFCGZ.js +89 -0
- package/dist/chunk-D6WTZMZB.js +48 -0
- package/dist/chunk-DBHOWDUH.js +976 -0
- package/dist/chunk-DCACX7BV.js +19364 -0
- package/dist/chunk-DFHX4XYA.js +128 -0
- package/dist/chunk-DIKBRRKE.js +176 -0
- package/dist/chunk-DJG5RIOR.js +9 -0
- package/dist/chunk-DNIOIISW.js +616 -0
- package/dist/chunk-DOA5G7IA.js +315 -0
- package/dist/chunk-DP7FKP6W.js +855 -0
- package/dist/chunk-DS2JZ677.js +79 -0
- package/dist/chunk-DSRLVYBS.js +82 -0
- package/dist/chunk-EAEVKNJA.js +209 -0
- package/dist/chunk-EEUESN3T.js +575 -0
- package/dist/chunk-EJ4LUU5Y.js +73 -0
- package/dist/chunk-EJIWTPSZ.js +1063 -0
- package/dist/chunk-EJVCDTAN.js +116 -0
- package/dist/chunk-EKLUBDBQ.js +627 -0
- package/dist/chunk-EN62WLFD.js +849 -0
- package/dist/chunk-ENYRCL43.js +26 -0
- package/dist/chunk-EP22ZMFO.js +273 -0
- package/dist/chunk-EP4SVAVI.js +87 -0
- package/dist/chunk-EPAMVGI3.js +1562 -0
- package/dist/chunk-EPRMH6HO.js +24 -0
- package/dist/chunk-ES6NWJ36.js +4057 -0
- package/dist/chunk-ETA2K4KI.js +30 -0
- package/dist/chunk-ETAD4NKD.js +31 -0
- package/dist/chunk-EUWIIDQ7.js +93 -0
- package/dist/chunk-EVE3OD2W.js +141 -0
- package/dist/chunk-EXA26FFC.js +459 -0
- package/dist/chunk-EXSPAA35.js +244 -0
- package/dist/chunk-F55YABKV.js +258 -0
- package/dist/chunk-F5DNGU5W.js +27 -0
- package/dist/chunk-F622MJYV.js +103 -0
- package/dist/chunk-F6NIQD74.js +5111 -0
- package/dist/chunk-FAWJTC34.js +43 -0
- package/dist/chunk-FAZBRHGG.js +47 -0
- package/dist/chunk-FIEUSGNJ.js +39 -0
- package/dist/chunk-FKCG7K6H.js +1146 -0
- package/dist/chunk-FOVVXV45.js +229 -0
- package/dist/chunk-FRBPKBFE.js +30 -0
- package/dist/chunk-FSA5BPFI.js +268 -0
- package/dist/chunk-FSJ5TTZ3.js +29 -0
- package/dist/chunk-FT7SGLXT.js +193 -0
- package/dist/chunk-FUUVZZUB.js +62 -0
- package/dist/chunk-FYMRVUNZ.js +1697 -0
- package/dist/chunk-FYTAA5FG.js +162 -0
- package/dist/chunk-G3VB2UCZ.js +3892 -0
- package/dist/chunk-G6OIMVXH.js +405 -0
- package/dist/chunk-G7PQCXVH.js +228 -0
- package/dist/chunk-GAB6UW52.js +1087 -0
- package/dist/chunk-GAFJEYLK.js +29 -0
- package/dist/chunk-GC4CRMTS.js +642 -0
- package/dist/chunk-GFHSIWHL.js +5297 -0
- package/dist/chunk-GI5M67YA.js +735 -0
- package/dist/chunk-GIJWHUWF.js +191 -0
- package/dist/chunk-GO6DRECI.js +1 -0
- package/dist/chunk-GOFVBTMN.js +314 -0
- package/dist/chunk-GQIP72ZJ.js +13 -0
- package/dist/chunk-GQXLXRFA.js +28 -0
- package/dist/chunk-GT6HFKJB.js +48 -0
- package/dist/chunk-GVJGSSKM.js +174 -0
- package/dist/chunk-GWHGTG37.js +36 -0
- package/dist/chunk-GZAJHLKO.js +18 -0
- package/dist/chunk-GZK62I3N.js +314 -0
- package/dist/chunk-H3HGMISG.js +483 -0
- package/dist/chunk-H3ISZJMJ.js +403 -0
- package/dist/chunk-H4HXVWEC.js +9 -0
- package/dist/chunk-H6MJGKAW.js +120 -0
- package/dist/chunk-HBTTGVR5.js +353 -0
- package/dist/chunk-HBZ322WZ.js +35 -0
- package/dist/chunk-HEP3ILP4.js +34 -0
- package/dist/chunk-HGFXODKO.js +106 -0
- package/dist/chunk-HHWDTB6S.js +59 -0
- package/dist/chunk-HKO45NLZ.js +286 -0
- package/dist/chunk-HLVTEA6A.js +89 -0
- package/dist/chunk-HS3SY6HN.js +160 -0
- package/dist/chunk-HT5OCGKN.js +899 -0
- package/dist/chunk-HXIIEMGF.js +78 -0
- package/dist/chunk-I56TH7VM.js +46 -0
- package/dist/chunk-I6FN3R5D.js +352 -0
- package/dist/chunk-I7SCBHJN.js +655 -0
- package/dist/chunk-IJM4GKAT.js +529 -0
- package/dist/chunk-IMEYU36R.js +344 -0
- package/dist/chunk-INJ3SS6A.js +936 -0
- package/dist/chunk-IUKOPCCE.js +441 -0
- package/dist/chunk-IVEPZQJO.js +33 -0
- package/dist/chunk-IVZEONFC.js +43 -0
- package/dist/chunk-IWBHRSG7.js +936 -0
- package/dist/chunk-IYY3HQAD.js +484 -0
- package/dist/chunk-J2ICMYDA.js +48 -0
- package/dist/chunk-J2QCFLUN.js +505 -0
- package/dist/chunk-J5HM6V5P.js +1039 -0
- package/dist/chunk-J6NZX6QH.js +398 -0
- package/dist/chunk-JBBB2Y47.js +432 -0
- package/dist/chunk-JDCZQZU7.js +42 -0
- package/dist/chunk-JEDNXGSS.js +169 -0
- package/dist/chunk-JHP7OT6K.js +89 -0
- package/dist/chunk-JLS65NUQ.js +14 -0
- package/dist/chunk-JNMWYMC6.js +38 -0
- package/dist/chunk-JNSTWNNW.js +25 -0
- package/dist/chunk-JOSK6GEU.js +9564 -0
- package/dist/chunk-JQUMSIGC.js +100 -0
- package/dist/chunk-JVHGMURQ.js +1106 -0
- package/dist/chunk-JYXS47FQ.js +951 -0
- package/dist/chunk-K2ZMW2Z5.js +2147 -0
- package/dist/chunk-K7FAFORM.js +14 -0
- package/dist/chunk-KBJXX3ON.js +333 -0
- package/dist/chunk-KHFKVQWY.js +486 -0
- package/dist/chunk-KHMEI3DQ.js +173 -0
- package/dist/chunk-KHW3UD7B.js +69 -0
- package/dist/chunk-KKQKWAMF.js +365 -0
- package/dist/chunk-KOKXJV2U.js +455 -0
- package/dist/chunk-KQ4NGOJI.js +14 -0
- package/dist/chunk-KQYQOXMS.js +342 -0
- package/dist/chunk-KTMW65UX.js +14 -0
- package/dist/chunk-KUEWV2JH.js +593 -0
- package/dist/chunk-KXYDV3HP.js +1523 -0
- package/dist/chunk-KZ4JMGZ5.js +96 -0
- package/dist/chunk-KZWGBUIO.js +2659 -0
- package/dist/chunk-L2CBG5IX.js +1892 -0
- package/dist/chunk-L2S235CU.js +314 -0
- package/dist/chunk-L32WD57F.js +98 -0
- package/dist/chunk-LDJCKAJP.js +123 -0
- package/dist/chunk-LDWNBEN7.js +541 -0
- package/dist/chunk-LJVH57G2.js +241 -0
- package/dist/chunk-LPQ7NZEN.js +209 -0
- package/dist/chunk-LRGH3CCV.js +148 -0
- package/dist/chunk-LULOGMMM.js +1133 -0
- package/dist/chunk-LWGKN2GY.js +8284 -0
- package/dist/chunk-LX4F24ZH.js +157 -0
- package/dist/chunk-M4BUEXXF.js +839 -0
- package/dist/chunk-M6UHOC4I.js +553 -0
- package/dist/chunk-MCBNWZNO.js +657 -0
- package/dist/chunk-MEMSY6VY.js +223 -0
- package/dist/chunk-MHLEZQQI.js +145 -0
- package/dist/chunk-MJ6WNSIX.js +192 -0
- package/dist/chunk-MKASIKWZ.js +442 -0
- package/dist/chunk-MNOVBYFU.js +60 -0
- package/dist/chunk-MO2BYAAF.js +2896 -0
- package/dist/chunk-MP6P7Y2A.js +180 -0
- package/dist/chunk-MQ4TFJAG.js +3365 -0
- package/dist/chunk-MT2WAIR3.js +131 -0
- package/dist/chunk-MTU7VTNN.js +1122 -0
- package/dist/chunk-MULMXX4V.js +150 -0
- package/dist/chunk-MW2DWWVA.js +147 -0
- package/dist/chunk-MY3ZPUN4.js +151 -0
- package/dist/chunk-MYLH2S4G.js +64 -0
- package/dist/chunk-MZ5WYKNA.js +28 -0
- package/dist/chunk-N3Q2JNPV.js +249 -0
- package/dist/chunk-N5DX4JAK.js +12 -0
- package/dist/chunk-NAINGKHF.js +35 -0
- package/dist/chunk-NEQUQHOX.js +223 -0
- package/dist/chunk-NHNPEZS4.js +1408 -0
- package/dist/chunk-NHTIXJCR.js +17 -0
- package/dist/chunk-NKLPMBNV.js +1154 -0
- package/dist/chunk-NMVZ5YES.js +199 -0
- package/dist/chunk-NRFRY3GE.js +256 -0
- package/dist/chunk-NTD6CSI6.js +1266 -0
- package/dist/chunk-NUO7B3SH.js +318 -0
- package/dist/chunk-NVOHIJKG.js +1319 -0
- package/dist/chunk-NXH3RX7O.js +523 -0
- package/dist/chunk-NXZ3DURF.js +257 -0
- package/dist/chunk-O26L6F7F.js +209 -0
- package/dist/chunk-O5RRIUEP.js +124 -0
- package/dist/chunk-O5X6BKAO.js +10 -0
- package/dist/chunk-O6ZQUVTR.js +31 -0
- package/dist/chunk-O7FE75QZ.js +306 -0
- package/dist/chunk-OC7Z6AJQ.js +81 -0
- package/dist/chunk-OH7IEZ63.js +307 -0
- package/dist/chunk-OI734GRS.js +115 -0
- package/dist/chunk-OJBH62DK.js +684 -0
- package/dist/chunk-OKJLVSTJ.js +247 -0
- package/dist/chunk-OMX5VL43.js +79 -0
- package/dist/chunk-ONHAMBN6.js +12 -0
- package/dist/chunk-ONYPLIVE.js +753 -0
- package/dist/chunk-OSK7QWPD.js +637 -0
- package/dist/chunk-OTXLMJKP.js +438 -0
- package/dist/chunk-OV5PKQMA.js +213 -0
- package/dist/chunk-OXK5HA4B.js +31 -0
- package/dist/chunk-OYDWFQA4.js +272 -0
- package/dist/chunk-OZAUKWHB.js +22 -0
- package/dist/chunk-P5P2EKGH.js +94 -0
- package/dist/chunk-P6SSWAKY.js +29 -0
- package/dist/chunk-P7CQGPLS.js +30 -0
- package/dist/chunk-P7RVCHQV.js +197 -0
- package/dist/chunk-PEBWDYIW.js +726 -0
- package/dist/chunk-PFCXFO7A.js +9193 -0
- package/dist/chunk-PFLDWMX6.js +168 -0
- package/dist/chunk-PHZGLQSK.js +15883 -0
- package/dist/chunk-PNFTPNSR.js +20 -0
- package/dist/chunk-PPHXX4W7.js +175 -0
- package/dist/chunk-PPZESPJT.js +262 -0
- package/dist/chunk-PRDHI2L5.js +296 -0
- package/dist/chunk-PSTKWHHN.js +32 -0
- package/dist/chunk-PV53ODOT.js +555 -0
- package/dist/chunk-PVJBTI7P.js +24 -0
- package/dist/chunk-PXKERBKX.js +100 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-Q3DHEZA5.js +85 -0
- package/dist/chunk-Q5RZDVQK.js +204 -0
- package/dist/chunk-Q64IR2Z2.js +4933 -0
- package/dist/chunk-Q6Z5UGPL.js +398 -0
- package/dist/chunk-QAMAV4DT.js +627 -0
- package/dist/chunk-QBWF4444.js +112 -0
- package/dist/chunk-QDKYT4CI.js +22805 -0
- package/dist/chunk-QFLBRWCJ.js +126 -0
- package/dist/chunk-QILAQACE.js +107 -0
- package/dist/chunk-QJ6OEH4K.js +3683 -0
- package/dist/chunk-QK3NLYTV.js +320 -0
- package/dist/chunk-QOFLUS24.js +535 -0
- package/dist/chunk-QOIASNEJ.js +98 -0
- package/dist/chunk-QP4UTSOV.js +3587 -0
- package/dist/chunk-QP5ST7RI.js +904 -0
- package/dist/chunk-QS5AGRZN.js +167 -0
- package/dist/chunk-QTAOU53N.js +107 -0
- package/dist/chunk-QTCLJHLZ.js +351 -0
- package/dist/chunk-QTOLTG4L.js +119 -0
- package/dist/chunk-QWDV4OSL.js +142 -0
- package/dist/chunk-QWMQ74KD.js +508 -0
- package/dist/chunk-QX6LOMMH.js +158 -0
- package/dist/chunk-QXBKIHY7.js +238 -0
- package/dist/chunk-QXBKTJT6.js +270 -0
- package/dist/chunk-QYQOVOLR.js +196 -0
- package/dist/chunk-R2CKS6WT.js +73 -0
- package/dist/chunk-R2TIYG7U.js +68 -0
- package/dist/chunk-R2W3LESH.js +465 -0
- package/dist/chunk-R5EXHMUN.js +100 -0
- package/dist/chunk-RBBTBCHX.js +289 -0
- package/dist/chunk-RBKLOUXA.js +121 -0
- package/dist/chunk-RCP2Y6DQ.js +86 -0
- package/dist/chunk-RCYEJSD5.js +260 -0
- package/dist/chunk-RFDVSI4N.js +134 -0
- package/dist/chunk-RGJU63FV.js +1717 -0
- package/dist/chunk-RI4EX2QE.js +18 -0
- package/dist/chunk-RIMARPCF.js +152 -0
- package/dist/chunk-RJ6RSNT6.js +42 -0
- package/dist/chunk-RNI2GUIF.js +131 -0
- package/dist/chunk-RPHUWJ3K.js +264 -0
- package/dist/chunk-RPIMAMV7.js +361 -0
- package/dist/chunk-RQFX6YRN.js +49 -0
- package/dist/chunk-RRC5BL7B.js +285 -0
- package/dist/chunk-RSYTSBOO.js +79 -0
- package/dist/chunk-RWQQIKIC.js +35 -0
- package/dist/chunk-RZUBOZH2.js +373 -0
- package/dist/chunk-S2E632FQ.js +380 -0
- package/dist/chunk-S2VQCZO4.js +22 -0
- package/dist/chunk-S2XIMQJQ.js +681 -0
- package/dist/chunk-S47ISY27.js +183 -0
- package/dist/chunk-S6I4KISU.js +142 -0
- package/dist/chunk-S6TAFQI5.js +2403 -0
- package/dist/chunk-SBBNT5ZJ.js +27 -0
- package/dist/chunk-SDJV2DTQ.js +491 -0
- package/dist/chunk-SDPIFNLD.js +33 -0
- package/dist/chunk-SF6YK3JI.js +835 -0
- package/dist/chunk-SK3ZFONO.js +976 -0
- package/dist/chunk-SKTFRFQ7.js +1775 -0
- package/dist/chunk-SNGM452K.js +2002 -0
- package/dist/chunk-STW7OFOA.js +581 -0
- package/dist/chunk-SU6UFUQY.js +1351 -0
- package/dist/chunk-SVJM3LJA.js +27 -0
- package/dist/chunk-SVUNZOPG.js +129 -0
- package/dist/chunk-T5XLUYV3.js +34 -0
- package/dist/chunk-T7E5JS6N.js +57 -0
- package/dist/chunk-TA3N5MMO.js +450 -0
- package/dist/chunk-TAJPCXSB.js +13 -0
- package/dist/chunk-TDEMDRN2.js +1639 -0
- package/dist/chunk-TDSEX5CF.js +24 -0
- package/dist/chunk-TGCVL74Y.js +28 -0
- package/dist/chunk-TGXXYDL4.js +1012 -0
- package/dist/chunk-TIKTYUJO.js +296 -0
- package/dist/chunk-TIZAJD4M.js +6029 -0
- package/dist/chunk-TLSEZZCG.js +5549 -0
- package/dist/chunk-TMBDRHAX.js +19 -0
- package/dist/chunk-TRURQUBP.js +1217 -0
- package/dist/chunk-TSQ256N5.js +152 -0
- package/dist/chunk-TUQMMFEQ.js +2244 -0
- package/dist/chunk-U424MJLC.js +81 -0
- package/dist/chunk-U4DRS6ZW.js +11 -0
- package/dist/chunk-U5KS22IN.js +204 -0
- package/dist/chunk-UAPHFJPN.js +673 -0
- package/dist/chunk-UB7LQITD.js +1040 -0
- package/dist/chunk-UBVRHGAZ.js +237 -0
- package/dist/chunk-UDNNAQN5.js +98 -0
- package/dist/chunk-UJP3XM54.js +342 -0
- package/dist/chunk-UJYDH2MW.js +305 -0
- package/dist/chunk-UKMPASIC.js +399 -0
- package/dist/chunk-UKUL3EHK.js +763 -0
- package/dist/chunk-UPHU64NB.js +1327 -0
- package/dist/chunk-URMSZXAD.js +43 -0
- package/dist/chunk-US3RT6CY.js +525 -0
- package/dist/chunk-UTDEOPKV.js +30 -0
- package/dist/chunk-UUUDKV7N.js +13 -0
- package/dist/chunk-UVKWU3SM.js +39 -0
- package/dist/chunk-V2TVPO3X.js +521 -0
- package/dist/chunk-V3KLVK7B.js +398 -0
- package/dist/chunk-V3YFFHDR.js +17 -0
- package/dist/chunk-VAG6GUBR.js +1162 -0
- package/dist/chunk-VBENAHDA.js +1814 -0
- package/dist/chunk-VBNCKCCI.js +16 -0
- package/dist/chunk-VCGSWN5M.js +1300 -0
- package/dist/chunk-VE2O2I7M.js +115 -0
- package/dist/chunk-VIFHYTI5.js +31 -0
- package/dist/chunk-VJER3FUS.js +5080 -0
- package/dist/chunk-VLMDM56Q.js +268 -0
- package/dist/chunk-VMFZEVVX.js +99 -0
- package/dist/chunk-VNDPQVUZ.js +1853 -0
- package/dist/chunk-VSPJRLGA.js +4783 -0
- package/dist/chunk-VSWC5ZXI.js +103 -0
- package/dist/chunk-VYI4DSZP.js +2017 -0
- package/dist/chunk-W4BAIQ6L.js +1212 -0
- package/dist/chunk-W7VQAL2K.js +2203 -0
- package/dist/chunk-WEI3ZDZH.js +33 -0
- package/dist/chunk-WEIUS5NT.js +26 -0
- package/dist/chunk-WEW7UFWE.js +546 -0
- package/dist/chunk-WGQAXLNA.js +384 -0
- package/dist/chunk-WJAL4JL3.js +206 -0
- package/dist/chunk-WKFOJ5ZG.js +141 -0
- package/dist/chunk-WMWQEFLN.js +2177 -0
- package/dist/chunk-WNECKKO2.js +154 -0
- package/dist/chunk-WPKLYOAM.js +195 -0
- package/dist/chunk-WSH37YQN.js +243 -0
- package/dist/chunk-WV3KQDPE.js +84 -0
- package/dist/chunk-WZFC4V4U.js +389 -0
- package/dist/chunk-XCOIBNET.js +13 -0
- package/dist/chunk-XDM65LBX.js +53 -0
- package/dist/chunk-XGU6PBO5.js +645 -0
- package/dist/chunk-XHOI4V62.js +43 -0
- package/dist/chunk-XIBVFMLQ.js +6858 -0
- package/dist/chunk-XJ2E7YEJ.js +117 -0
- package/dist/chunk-XON4ZCYX.js +69 -0
- package/dist/chunk-XQPEWJPI.js +127 -0
- package/dist/chunk-XSJTIFUY.js +31 -0
- package/dist/chunk-XT7OVWM3.js +64 -0
- package/dist/chunk-XTXYIISX.js +1104 -0
- package/dist/chunk-XV7NZL4B.js +57 -0
- package/dist/chunk-XWIZ6B5S.js +109 -0
- package/dist/chunk-XWLIKOBX.js +240 -0
- package/dist/chunk-XZOXEIN4.js +156 -0
- package/dist/chunk-XZRS7I7W.js +3673 -0
- package/dist/chunk-Y4ZDDHB6.js +44 -0
- package/dist/chunk-Y733RB7T.js +194 -0
- package/dist/chunk-YBHUB4XR.js +14931 -0
- package/dist/chunk-YKC75XK4.js +147 -0
- package/dist/chunk-YKMXFVK7.js +27 -0
- package/dist/chunk-YO5BAJ55.js +225 -0
- package/dist/chunk-YPDCLXNZ.js +568 -0
- package/dist/chunk-YSQPGVFK.js +116 -0
- package/dist/chunk-YTVVTIWJ.js +716 -0
- package/dist/chunk-YVCMDVBB.js +698 -0
- package/dist/chunk-YYTOA6DP.js +114 -0
- package/dist/chunk-Z5WGNULV.js +88 -0
- package/dist/chunk-Z6NGVVXG.js +66 -0
- package/dist/chunk-Z7CDQNH3.js +20 -0
- package/dist/chunk-ZH4G3FU5.js +187 -0
- package/dist/chunk-ZJB6SQPA.js +257 -0
- package/dist/chunk-ZL6E4HMY.js +42 -0
- package/dist/chunk-ZMLOC3DW.js +62 -0
- package/dist/chunk-ZORW64QH.js +101 -0
- package/dist/chunk-ZVVD2XGV.js +1369 -0
- package/dist/cli-utils-ER33ODC5.js +31 -0
- package/dist/cli-validation-6CHPTANV.js +146 -0
- package/dist/commit-utils-3STAY7C7.js +49 -0
- package/dist/compatibility-notice-IHNXR2JR.js +21 -0
- package/dist/compete-config-resolver-V3GDNJMM.js +125 -0
- package/dist/compete-results-XUM3PJHS.js +318 -0
- package/dist/competition-outcome-tracker-NWSMVUPG.js +62 -0
- package/dist/config-4HHE4OIK.js +238 -0
- package/dist/config-D6YAZASH.js +10 -0
- package/dist/config-MIPRDYYV.js +46 -0
- package/dist/config-audit-GA5DCUAI.js +371 -0
- package/dist/config-explain-4LMO556H.js +71 -0
- package/dist/config-loader-RGP634PC.js +51 -0
- package/dist/config-manager-J2UTO635.js +114 -0
- package/dist/config-merger-TVUJBZTS.js +14 -0
- package/dist/config-validator-H4ZVIE56.js +122 -0
- package/dist/cost-HSIV5U2Y.js +85 -0
- package/dist/data-migration-state-OAUL2WPQ.js +35 -0
- package/dist/db-migrator-NUOW5NKR.js +34 -0
- package/dist/default-paths-UILB62BN.js +49 -0
- package/dist/discovery-V6GYUJUC.js +53 -0
- package/dist/doctor-BBSMCDWE.js +271 -0
- package/dist/doctor-context-blocks-LPY75VZA.js +231 -0
- package/dist/doctor-instructions-import-JXHDDOE5.js +70 -0
- package/dist/doctor-purpose-6YJOXPBE.js +30 -0
- package/dist/domain-analyzer-S35ABUNA.js +48 -0
- package/dist/ensure-initialized-Q6PEU55O.js +78 -0
- package/dist/entry.js +922 -0
- package/dist/error-parser-core-MZFMFANN.js +70 -0
- package/dist/evaluation-context-GQBYDAEV.js +63 -0
- package/dist/evidence-plan-resolver-5FUAP3SA.js +111 -0
- package/dist/execution-data-writer-YCG5UH37.js +72 -0
- package/dist/execution-policy-applier-PWZM5LNA.js +63 -0
- package/dist/execution-preflight-DASJWWQF.js +223 -0
- package/dist/execution-roles-KNSNNB2D.js +112 -0
- package/dist/exit-code-error-QIY5DOKF.js +18 -0
- package/dist/external-temp-cleanup-CAW7LQ6R.js +360 -0
- package/dist/factory-YCYCB7AE.js +209 -0
- package/dist/file-utils-ZQYNBQBW.js +45 -0
- package/dist/flywheel-allowlist-revert-H22HA6JE.js +21 -0
- package/dist/flywheel-autoloop-executor-PDOASJEZ.js +316 -0
- package/dist/flywheel-autoloop-unverified-TOKYFCDC.js +36 -0
- package/dist/flywheel-competition-executor-YJUMMEJO.js +320 -0
- package/dist/flywheel-executor-JWU43KAY.js +437 -0
- package/dist/flywheel-git-isolation-FQ2TRWMB.js +56 -0
- package/dist/flywheel-manifest-HDPNMWWF.js +114 -0
- package/dist/flywheel-model-defaults-UHAKTZT3.js +110 -0
- package/dist/flywheel-preflight-III2C7TH.js +163 -0
- package/dist/flywheel-resume-2O45MS7Y.js +31 -0
- package/dist/flywheel-resume-execution-lease-P2BK257J.js +59 -0
- package/dist/flywheel-safety-AVAVFXIJ.js +19 -0
- package/dist/flywheel-scope-decision-ALJUUNGG.js +14 -0
- package/dist/get-telemetry-logger-MPDVO2JA.js +155 -0
- package/dist/git-message-style-KCXGMTDT.js +104 -0
- package/dist/guidance-profile-config-G3K5YQOO.js +113 -0
- package/dist/guidance-profile-renderer-TX4TNDFL.js +23 -0
- package/dist/identity-XLQJ4YJF.js +25 -0
- package/dist/index-query-6NUY4FKX.js +37 -0
- package/dist/index.js +85588 -0
- package/dist/indexer-DL54CM3K.js +44 -0
- package/dist/init-OUZ72344.js +245 -0
- package/dist/instructions-import-offer-NSYXSITC.js +363 -0
- package/dist/instructions-run-NBII7W36.js +114 -0
- package/dist/interrupted-work-E4TLKJLE.js +43 -0
- package/dist/invoke-provider-auth-NEWEIHCI.js +38 -0
- package/dist/judge-scoring.json +64 -0
- package/dist/lab-mode-YXQ2Y3NG.js +44 -0
- package/dist/lab-utils-5QAMDJR5.js +29 -0
- package/dist/linux-host-class-YDWQX65O.js +31 -0
- package/dist/llm-judge-executor-OJSNCTFJ.js +179 -0
- package/dist/local-ci-config-VZ4WWDT5.js +48 -0
- package/dist/local-executor-DCMDDRX2.js +280 -0
- package/dist/logger-5KNKS3O4.js +154 -0
- package/dist/matrix-prompt-builder-4ZBOGZSB.js +527 -0
- package/dist/matrix-result-parser-EZJM4YXP.js +14 -0
- package/dist/merge-batch-RTEEMVDB.js +313 -0
- package/dist/merge-batch-members-VIWGVRHP.js +24 -0
- package/dist/merge-queue-TIIUSOY6.js +126 -0
- package/dist/merge-queue-trust-DUNZ4J65.js +21 -0
- package/dist/metadata-UKSMWM6J.js +29 -0
- package/dist/model-catalog-readiness-R5KJBP5M.js +202 -0
- package/dist/model-invocations-db-XTUPPQ34.js +70 -0
- package/dist/model-resolver-JFZ2MHOJ.js +39 -0
- package/dist/model-resolver-SCQ57KAQ.js +217 -0
- package/dist/model-roles-D3OR4NAH.js +110 -0
- package/dist/monitor-F4SIU5G2.js +96 -0
- package/dist/nested-worktrees-2WUWQ75N.js +23 -0
- package/dist/next-S3IRLVER.js +96 -0
- package/dist/next-UKPFRXOO.js +148 -0
- package/dist/opportunistic-TL4S26VX.js +86 -0
- package/dist/optimization-config-resolver-NAEIYU6A.js +148 -0
- package/dist/package-HJR4QJT4.js +10 -0
- package/dist/parse-git-status-7PIYFPS2.js +21 -0
- package/dist/path-security-5WJSY56G.js +41 -0
- package/dist/paths-JUI7C4KU.js +45 -0
- package/dist/plan-backlog-list-fast-SSTQL5XP.js +89 -0
- package/dist/plan-backlog-show-fast-PFRAQ3JB.js +114 -0
- package/dist/plan-sprint-list-fast-HD2KBZSY.js +110 -0
- package/dist/plan-sprint-status-fast-YFYH7WQF.js +116 -0
- package/dist/plan-task-status-fast-JU5PNLUU.js +114 -0
- package/dist/plan-to-flywheel-PY5MSY2H.js +529 -0
- package/dist/preflight-PJHGTJNZ.js +12 -0
- package/dist/process-registry-B4ZUCN7T.js +28 -0
- package/dist/process-scanner-TU3QHWVB.js +23 -0
- package/dist/processes-6FHVGT72.js +28 -0
- package/dist/processes-json-fast-YWTMUWXB.js +72 -0
- package/dist/profile-HWTC56SG.js +209 -0
- package/dist/project-runtime-paths-2UQNG5Y4.js +41 -0
- package/dist/protected-branches-N36LDBFY.js +71 -0
- package/dist/provider-aware-resource-manager-YTFAHNGJ.js +40 -0
- package/dist/provider-matrix-2KO2V5OM.js +214 -0
- package/dist/provider-matrix-renderer-MEC3PER7.js +139 -0
- package/dist/provider-output-forwarding-2AHL7YMA.js +26 -0
- package/dist/provider-registry-WCZ65QHC.js +136 -0
- package/dist/provider-temp-cleanup-IUNPJCZF.js +14 -0
- package/dist/prune-engine-EOQVWEP6.js +448 -0
- package/dist/publication-turn-S42RZTQF.js +44 -0
- package/dist/quality-gate-JQMVCKOO.js +72 -0
- package/dist/quickstart-3O6FRCFB.js +105 -0
- package/dist/readiness-GW6ABRHB.js +139 -0
- package/dist/readiness-KFZCXDTT.js +215 -0
- package/dist/registry-7XG376SY.js +217 -0
- package/dist/repair-helpers-TTV5FEF4.js +117 -0
- package/dist/repo-root-YG6MQZDW.js +28 -0
- package/dist/resolution-engine-FFEK7HQ2.js +187 -0
- package/dist/resolve-provider-cli-ZEXVZKET.js +44 -0
- package/dist/restore-telemetry-db-E7BR5PO7.js +459 -0
- package/dist/routing-events-AW6SRZ6G.js +13 -0
- package/dist/routing-history-store-FMDDQL6W.js +39 -0
- package/dist/routing-planner-C6OHO3EY.js +221 -0
- package/dist/runner-KHDNQ5KU.js +1194 -0
- package/dist/runner-PIS2BW7Y.js +1801 -0
- package/dist/safety-E3JJVSFL.js +67 -0
- package/dist/safety-stanza-HE6GXP4G.js +49 -0
- package/dist/sandbox-7LBZC5PE.js +72 -0
- package/dist/sandbox-ASWCDYZL.js +80 -0
- package/dist/schema-extensions.sql +234 -0
- package/dist/security-JI22TBEB.js +17 -0
- package/dist/setup-bb-plugin-FQXLA76Y.js +531 -0
- package/dist/setup-claude-code-NF4ZSHVE.js +197 -0
- package/dist/setup-temp-cleanup-2APZ4HMA.js +29 -0
- package/dist/shared-utils-34HJZ6JX.js +40 -0
- package/dist/simple-artifact-goal-MQLDDMMX.js +29 -0
- package/dist/sprint-N7JFTEGL.js +403 -0
- package/dist/sprint-bridge-KJXIBNRJ.js +117 -0
- package/dist/sprint-completion-dependents-34SR7JVL.js +43 -0
- package/dist/sprint-execution-service-A6JPUBWY.js +376 -0
- package/dist/sprint-manager-MU2ZUWN2.js +140 -0
- package/dist/sqlite-timeout-config-U2CT4LKU.js +13 -0
- package/dist/sqlite-wrapper-FSGJ2QEW.js +19 -0
- package/dist/stale-cleanup-orchestrator-4X6324VF.js +71 -0
- package/dist/storage-access-I3V5LER7.js +31 -0
- package/dist/store-XVG64ZR2.js +25 -0
- package/dist/task-classifier-MN2DYE5R.js +558 -0
- package/dist/task-list-fast-7AT6LTTA.js +112 -0
- package/dist/task-manager-LHPBBRRE.js +136 -0
- package/dist/task-report-OLPAWBTK.js +64 -0
- package/dist/task-type-detector-6RG3YNZF.js +27 -0
- package/dist/task-type-resolver-EQHOUIHT.js +64 -0
- package/dist/telemetry-5VYSK772.js +212 -0
- package/dist/telemetry-health-tracker-4GFW2EMP.js +12 -0
- package/dist/telemetry-path-resolver-H3NFHHQY.js +34 -0
- package/dist/telemetry-reliability-URJDTNPZ.js +76 -0
- package/dist/transports-NREZQTJK.js +106 -0
- package/dist/unified-cost-tracker-5MTBJ2CL.js +59 -0
- package/dist/unified-state-cleanup-GGAXLHXF.js +292 -0
- package/dist/universal-cost-calculator-JTFEJVWK.js +70 -0
- package/dist/user-agents-QLIGPLP2.js +30 -0
- package/dist/variant-execution-I4ZZUAWY.js +319 -0
- package/dist/variant-opt-parser-JHCXKY2K.js +251 -0
- package/dist/variant-request-input-PL37N3AN.js +11 -0
- package/dist/variant-state-cleanup-KHMXRBZN.js +287 -0
- package/dist/variant-worker-COB5YTJX.js +4517 -0
- package/dist/variant-worker.js +26 -0
- package/dist/variants-XGDSXYG3.js +267 -0
- package/dist/verification-command-YSPU4VBH.js +66 -0
- package/dist/verify-command-timeout-DQUYH33Z.js +11 -0
- package/dist/verify-commands-LOHMOFKC.js +65 -0
- package/dist/warning-JSKSFKBT.js +13 -0
- package/dist/work-edge-K65NHVWY.js +50 -0
- package/dist/work-item-writer-KY5ZWZWW.js +30 -0
- package/dist/worker-JNXXEIT6.js +1504 -0
- package/dist/worker.js +21 -0
- package/dist/workspace-tree-identity-JO5PSKTW.js +52 -0
- package/dist/worktree-environment-WTVABAQW.js +64 -0
- package/dist/worktree-metrics-VZRQI26T.js +66 -0
- package/dist/writeback-TQFQBJNU.js +50 -0
- package/docs/CLI_REFERENCE.md +8287 -0
- package/docs/PROVIDER_SETUP.md +1737 -0
- package/docs/README.md +96 -0
- package/docs/TROUBLESHOOTING.md +2209 -0
- package/docs/getting-started/QUICK_START.md +260 -0
- package/docs/getting-started/README.md +198 -0
- package/docs/getting-started/SETUP.md +25 -0
- package/docs/reference/AGENT_CONTEXT.md +84 -0
- package/docs/reference/DELIVERY_ONBOARDING.md +198 -0
- package/docs/reference/PROVIDER_RELEASE_TIERS.md +34 -0
- package/docs/reference/SECURITY.md +291 -0
- package/docs/reference/TELEMETRY_PRIVACY.md +259 -0
- package/integrations/bb-plugin-build/README.md +391 -0
- package/integrations/bb-plugin-build/app.css +431 -0
- package/integrations/bb-plugin-build/app.tsx +6210 -0
- package/integrations/bb-plugin-build/package.json +45 -0
- package/integrations/bb-plugin-build/server.ts +488 -0
- package/integrations/bb-plugin-build/src/adapter.ts +3672 -0
- package/integrations/bb-plugin-build/src/backlog-authoring-model.ts +150 -0
- package/integrations/bb-plugin-build/src/backlog-authoring-schema.ts +458 -0
- package/integrations/bb-plugin-build/src/backlog-authoring-service.ts +467 -0
- package/integrations/bb-plugin-build/src/backlog-authoring-view.ts +1025 -0
- package/integrations/bb-plugin-build/src/command-evidence-schema.ts +13 -0
- package/integrations/bb-plugin-build/src/competition-defaults-schema.ts +122 -0
- package/integrations/bb-plugin-build/src/competition-defaults-service.ts +105 -0
- package/integrations/bb-plugin-build/src/competition-defaults-view.ts +138 -0
- package/integrations/bb-plugin-build/src/contract.ts +718 -0
- package/integrations/bb-plugin-build/src/execution-activity-view.ts +98 -0
- package/integrations/bb-plugin-build/src/finalize-model.ts +205 -0
- package/integrations/bb-plugin-build/src/finalize-schema.ts +150 -0
- package/integrations/bb-plugin-build/src/finalize-service.ts +330 -0
- package/integrations/bb-plugin-build/src/finalize-view.ts +159 -0
- package/integrations/bb-plugin-build/src/judge-operations-readback.ts +303 -0
- package/integrations/bb-plugin-build/src/judge-operations-schema.ts +33 -0
- package/integrations/bb-plugin-build/src/judge-operations-view.ts +459 -0
- package/integrations/bb-plugin-build/src/model.ts +1318 -0
- package/integrations/bb-plugin-build/src/monitor-service.ts +233 -0
- package/integrations/bb-plugin-build/src/panel-read-ux.ts +97 -0
- package/integrations/bb-plugin-build/src/patch-preview-schema.ts +166 -0
- package/integrations/bb-plugin-build/src/patch-preview-service.ts +480 -0
- package/integrations/bb-plugin-build/src/patch-preview-view.ts +109 -0
- package/integrations/bb-plugin-build/src/planning-readback.ts +228 -0
- package/integrations/bb-plugin-build/src/planning-service.ts +647 -0
- package/integrations/bb-plugin-build/src/planning-sync-evidence.ts +37 -0
- package/integrations/bb-plugin-build/src/planning-workspace-readback.ts +33 -0
- package/integrations/bb-plugin-build/src/planning-workspace-schema.ts +131 -0
- package/integrations/bb-plugin-build/src/planning-workspace.ts +333 -0
- package/integrations/bb-plugin-build/src/poll-handoff.ts +136 -0
- package/integrations/bb-plugin-build/src/project-target-server.ts +21 -0
- package/integrations/bb-plugin-build/src/project-target.ts +45 -0
- package/integrations/bb-plugin-build/src/reference-index.ts +218 -0
- package/integrations/bb-plugin-build/src/repository-identity.ts +17 -0
- package/integrations/bb-plugin-build/src/repository-schema.ts +30 -0
- package/integrations/bb-plugin-build/src/result-explorer-view.ts +597 -0
- package/integrations/bb-plugin-build/src/result-readback-model.ts +163 -0
- package/integrations/bb-plugin-build/src/result-readback-schema.ts +319 -0
- package/integrations/bb-plugin-build/src/result-readback-service.ts +333 -0
- package/integrations/bb-plugin-build/src/run-page-view.ts +332 -0
- package/integrations/bb-plugin-build/src/setup-config-schema.ts +293 -0
- package/integrations/bb-plugin-build/src/setup-config-service.ts +620 -0
- package/integrations/bb-plugin-build/src/setup-config-view.ts +388 -0
- package/integrations/bb-plugin-build/src/sprint-close-model.ts +150 -0
- package/integrations/bb-plugin-build/src/sprint-close-schema.ts +128 -0
- package/integrations/bb-plugin-build/src/sprint-close-service.ts +293 -0
- package/integrations/bb-plugin-build/src/sprint-close-view.ts +116 -0
- package/integrations/bb-plugin-build/src/sprint-composition-model.ts +709 -0
- package/integrations/bb-plugin-build/src/sprint-composition-readback.ts +231 -0
- package/integrations/bb-plugin-build/src/sprint-composition-schema.ts +597 -0
- package/integrations/bb-plugin-build/src/sprint-composition-service.ts +773 -0
- package/integrations/bb-plugin-build/src/sprint-composition-view.ts +1221 -0
- package/integrations/bb-plugin-build/src/sprint-execution-schema.ts +188 -0
- package/integrations/bb-plugin-build/src/sprint-execution-service.ts +289 -0
- package/integrations/bb-plugin-build/src/sprint-execution-view.ts +54 -0
- package/integrations/bb-plugin-build/src/task-authoring-model.ts +563 -0
- package/integrations/bb-plugin-build/src/task-authoring-schema.ts +629 -0
- package/integrations/bb-plugin-build/src/task-authoring-service.ts +842 -0
- package/integrations/bb-plugin-build/src/task-authoring-view.ts +1227 -0
- package/integrations/bb-plugin-build/src/task-catalog-schema.ts +46 -0
- package/integrations/bb-plugin-build/src/task-catalog-service.ts +44 -0
- package/integrations/bb-plugin-build/src/task-detail-readback.ts +56 -0
- package/integrations/bb-plugin-build/src/task-detail-schema.ts +171 -0
- package/integrations/bb-plugin-build/src/task-navigation.ts +446 -0
- package/integrations/bb-plugin-build/src/workbench-route.ts +74 -0
- package/package.json +306 -4
- package/schemas/README.md +80 -0
- package/schemas/build.config.schema.json +2110 -0
- package/schemas/config-v1.schema.json +136 -0
- package/schemas/execution-config.schema.json +47 -0
- package/schemas/judge-scoring.schema.json +257 -0
- package/schemas/provider-config.schema.json +179 -0
- package/schemas/telemetry-config.schema.json +79 -0
- package/schemas/user-preferences.schema.json +141 -0
- package/scripts/assert-node-runtime.mjs +146 -0
- package/scripts/preflight-native.mjs +49 -0
- package/scripts/setup-git-hooks.mjs +39 -0
- package/scripts/sync.sh +2871 -0
- package/scripts/write-node-launcher.sh +138 -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/.build-project/README.md +41 -0
- package/templates/.build-project/agents/README.md +50 -0
- package/templates/.build-project/agents/architect.md +10 -0
- package/templates/.build-project/agents/code-reviewer.md +10 -0
- package/templates/.build-project/agents/debugger.md +10 -0
- package/templates/.build-project/agents/documenter.md +10 -0
- package/templates/.build-project/agents/test-automator.md +10 -0
- package/templates/.build-project/config/build.config.jsonc +64 -0
- package/templates/.build-project/config/project-context.template.json +6 -0
- package/templates/.build-project/config/task-type-aliases.presets/kanban.yaml +14 -0
- package/templates/.build-project/config/task-type-aliases.presets/scrum.yaml +17 -0
- package/templates/.build-project/config/task-type-aliases.presets/xp.yaml +12 -0
- package/templates/.build-project/config/task-type-aliases.yaml +29 -0
- package/templates/.build-project/gitignore.template +70 -0
- package/templates/.build-project/task-types/analysis.yaml +38 -0
- package/templates/.build-project/task-types/architecture.yaml +35 -0
- package/templates/.build-project/task-types/doc.yaml +34 -0
- package/templates/.build-project/task-types/feature.yaml +22 -0
- package/templates/.build-project/task-types/general.yaml +4 -0
- package/templates/.build-project/task-types/security.yaml +38 -0
- package/templates/AGENTS.template.md +85 -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/skills/code-review/SKILL.md +61 -0
- package/templates/builtin-workflows/skills/execution-contract-analysis/SKILL.md +24 -0
- package/templates/builtin-workflows/skills/execution-contract-code/SKILL.md +19 -0
- package/templates/builtin-workflows/skills/execution-contract-structured/SKILL.md +17 -0
- package/templates/ci/incident-intake.mjs +787 -0
- package/templates/ci/incidents.yml.template +103 -0
- package/templates/ci/node.yml.template +17 -0
- package/templates/ci/python.yml.template +17 -0
- package/templates/guard-kit/GUARD_SETUP.md.template +258 -0
- package/templates/guard-kit/build-guard.yml.template +189 -0
- package/templates/guard-kit/check.mjs.template +932 -0
- package/templates/guard-kit/config.json.template +7 -0
- package/templates/guard-kit/policy.json.template +1 -0
- package/templates/profiles/README.md +57 -0
- package/templates/profiles/frontier-claude.json +23 -0
- package/templates/profiles/frontier-codex.json +23 -0
|
@@ -0,0 +1,2017 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CONTEXT_DIR,
|
|
3
|
+
KNOWLEDGE_BLOCK_BEGIN,
|
|
4
|
+
knowledgeManifestPath
|
|
5
|
+
} from "./chunk-BQ3VAGXH.js";
|
|
6
|
+
import {
|
|
7
|
+
FRAMEWORK_LABELS,
|
|
8
|
+
collectFiles,
|
|
9
|
+
dependencyNameSet,
|
|
10
|
+
detectFrameworks,
|
|
11
|
+
extractDirectDependencies,
|
|
12
|
+
isFrameworkDependency,
|
|
13
|
+
isSkippedDirectory
|
|
14
|
+
} from "./chunk-PFCXFO7A.js";
|
|
15
|
+
import {
|
|
16
|
+
atomicWriteJsonSync,
|
|
17
|
+
atomicWriteText
|
|
18
|
+
} from "./chunk-RFDVSI4N.js";
|
|
19
|
+
import {
|
|
20
|
+
PROJECT_LANGUAGES,
|
|
21
|
+
detectProjectCapabilities,
|
|
22
|
+
isIgnoredProjectPath
|
|
23
|
+
} from "./chunk-AHU3FKPA.js";
|
|
24
|
+
|
|
25
|
+
// src/core/knowledge/detect.ts
|
|
26
|
+
import { createHash } from "crypto";
|
|
27
|
+
import { existsSync, readFileSync as readFileSync2, statSync } from "fs";
|
|
28
|
+
import path2 from "path";
|
|
29
|
+
|
|
30
|
+
// src/core/stack/vocabulary.ts
|
|
31
|
+
var STACK_DIMENSIONS = ["lang", "sdk", "fw", "domain", "tool"];
|
|
32
|
+
var DECLARABLE_LANGUAGES = PROJECT_LANGUAGES.filter(
|
|
33
|
+
(language) => language !== "docs" && language !== "unknown"
|
|
34
|
+
);
|
|
35
|
+
var DECLARABLE_LANGUAGE_SET = new Set(DECLARABLE_LANGUAGES);
|
|
36
|
+
var TOKEN_SHAPE_PATTERN = /^[a-z][a-z0-9.+-]{0,39}$/;
|
|
37
|
+
var SDK_TARGET_PATTERN = /^[a-z][a-z0-9]*-\d+(?:\.\d+)*$/;
|
|
38
|
+
function normalizeSdkToken(token) {
|
|
39
|
+
const dashIndex = token.search(/-\d/);
|
|
40
|
+
if (dashIndex <= 0) return token;
|
|
41
|
+
const platform = token.slice(0, dashIndex);
|
|
42
|
+
let version = token.slice(dashIndex + 1);
|
|
43
|
+
while (version.endsWith(".0")) version = version.slice(0, -2);
|
|
44
|
+
return `${platform}-${version}`;
|
|
45
|
+
}
|
|
46
|
+
var CLASSIFICATION_HINTS = {
|
|
47
|
+
terraform: "tool",
|
|
48
|
+
dbt: "tool",
|
|
49
|
+
docker: "tool",
|
|
50
|
+
kubernetes: "tool",
|
|
51
|
+
ansible: "tool",
|
|
52
|
+
pulumi: "tool",
|
|
53
|
+
bazel: "tool",
|
|
54
|
+
cmake: "tool",
|
|
55
|
+
gradle: "tool",
|
|
56
|
+
maven: "tool",
|
|
57
|
+
aws: "domain",
|
|
58
|
+
gcp: "domain",
|
|
59
|
+
azure: "domain",
|
|
60
|
+
snowflake: "domain",
|
|
61
|
+
databricks: "domain",
|
|
62
|
+
// arduino/latex are ecosystems/toolchains for classification purposes:
|
|
63
|
+
// `lang`/`sdk` hints are FORBIDDEN here because those dimensions carry
|
|
64
|
+
// extra validation (canonical ProjectLanguage / <platform>-<version>) that
|
|
65
|
+
// a hint must never bypass — enforced again in classifyStackToken.
|
|
66
|
+
arduino: "tool",
|
|
67
|
+
latex: "tool",
|
|
68
|
+
openapi: "domain",
|
|
69
|
+
graphql: "domain"
|
|
70
|
+
};
|
|
71
|
+
var TOOL_MARKERS = {
|
|
72
|
+
terraform: ["*.tf"],
|
|
73
|
+
dbt: ["dbt_project.yml", "dbt_project.yaml"],
|
|
74
|
+
docker: [
|
|
75
|
+
"Dockerfile",
|
|
76
|
+
"docker-compose.yml",
|
|
77
|
+
"docker-compose.yaml",
|
|
78
|
+
"compose.yml",
|
|
79
|
+
"compose.yaml"
|
|
80
|
+
],
|
|
81
|
+
kubernetes: ["kustomization.yml", "kustomization.yaml"],
|
|
82
|
+
ansible: ["ansible.cfg"],
|
|
83
|
+
pulumi: ["Pulumi.yaml", "Pulumi.yml"],
|
|
84
|
+
bazel: ["WORKSPACE", "MODULE.bazel"],
|
|
85
|
+
cmake: ["CMakeLists.txt"],
|
|
86
|
+
gradle: ["build.gradle", "build.gradle.kts"],
|
|
87
|
+
maven: ["pom.xml"],
|
|
88
|
+
arduino: ["*.ino"],
|
|
89
|
+
latex: ["*.tex"]
|
|
90
|
+
};
|
|
91
|
+
var DIMENSION_SET = new Set(STACK_DIMENSIONS);
|
|
92
|
+
function classifyStackToken(raw) {
|
|
93
|
+
const trimmed = raw.trim().toLowerCase();
|
|
94
|
+
if (!trimmed) return { ok: false, error: "Empty stack token." };
|
|
95
|
+
const colonIndex = trimmed.indexOf(":");
|
|
96
|
+
if (colonIndex > 0) {
|
|
97
|
+
const dim = trimmed.slice(0, colonIndex);
|
|
98
|
+
const token = trimmed.slice(colonIndex + 1);
|
|
99
|
+
if (!DIMENSION_SET.has(dim)) {
|
|
100
|
+
return {
|
|
101
|
+
ok: false,
|
|
102
|
+
error: `Unknown dimension prefix "${dim}:" in "${raw}". Valid prefixes: ${STACK_DIMENSIONS.map((d) => `${d}:`).join(" ")}`
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
if (!TOKEN_SHAPE_PATTERN.test(token)) {
|
|
106
|
+
return {
|
|
107
|
+
ok: false,
|
|
108
|
+
error: `Invalid token "${token}" in "${raw}": tokens are lowercase words of letters/digits/./+/- (max 40 chars).`
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const dimension = dim;
|
|
112
|
+
if (dimension === "lang" && !DECLARABLE_LANGUAGE_SET.has(token)) {
|
|
113
|
+
return {
|
|
114
|
+
ok: false,
|
|
115
|
+
error: `"${token}" is not a known project language. Known: ${DECLARABLE_LANGUAGES.join(", ")}. For frameworks/tools/domains use fw:/tool:/domain: prefixes.`
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
if (dimension === "sdk" && !SDK_TARGET_PATTERN.test(token)) {
|
|
119
|
+
return {
|
|
120
|
+
ok: false,
|
|
121
|
+
error: `sdk: tokens must be <platform>-<version> (e.g. macos-26, ios-17, k8s-1.31); got "${token}".`
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const normalized = dimension === "sdk" ? normalizeSdkToken(token) : token;
|
|
125
|
+
return { ok: true, token: { token: normalized, dimension, explicit: true } };
|
|
126
|
+
}
|
|
127
|
+
if (!TOKEN_SHAPE_PATTERN.test(trimmed)) {
|
|
128
|
+
return {
|
|
129
|
+
ok: false,
|
|
130
|
+
error: `Unrecognized stack token: "${raw}". Tokens are lowercase words of letters/digits/./+/- (max 40 chars), optionally prefixed with ${STACK_DIMENSIONS.map((d) => `${d}:`).join("/")}.`
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
if (DECLARABLE_LANGUAGE_SET.has(trimmed)) {
|
|
134
|
+
return { ok: true, token: { token: trimmed, dimension: "lang", explicit: false } };
|
|
135
|
+
}
|
|
136
|
+
if (SDK_TARGET_PATTERN.test(trimmed)) {
|
|
137
|
+
return {
|
|
138
|
+
ok: true,
|
|
139
|
+
token: { token: normalizeSdkToken(trimmed), dimension: "sdk", explicit: false }
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
const hinted = Object.hasOwn(CLASSIFICATION_HINTS, trimmed) ? CLASSIFICATION_HINTS[trimmed] : void 0;
|
|
143
|
+
if (hinted && hinted !== "lang" && hinted !== "sdk") {
|
|
144
|
+
return { ok: true, token: { token: trimmed, dimension: hinted, explicit: false } };
|
|
145
|
+
}
|
|
146
|
+
return { ok: true, token: { token: trimmed, dimension: "fw", explicit: false } };
|
|
147
|
+
}
|
|
148
|
+
function hasStrongAnchor(tokens) {
|
|
149
|
+
return tokens.some((t) => t.dimension === "lang" || t.dimension === "sdk" || t.explicit === true);
|
|
150
|
+
}
|
|
151
|
+
var DETECTABLE_FRAMEWORKS = FRAMEWORK_LABELS;
|
|
152
|
+
var DETECTABLE_SDK_PLATFORMS = /* @__PURE__ */ new Set([
|
|
153
|
+
"ios",
|
|
154
|
+
"macos",
|
|
155
|
+
"watchos",
|
|
156
|
+
"tvos",
|
|
157
|
+
"visionos"
|
|
158
|
+
]);
|
|
159
|
+
function isGatingToken(token) {
|
|
160
|
+
switch (token.dimension) {
|
|
161
|
+
case "lang":
|
|
162
|
+
return true;
|
|
163
|
+
case "sdk":
|
|
164
|
+
return DETECTABLE_SDK_PLATFORMS.has(sdkPlatform(token.token));
|
|
165
|
+
case "fw":
|
|
166
|
+
return DETECTABLE_FRAMEWORKS.has(token.token);
|
|
167
|
+
case "tool":
|
|
168
|
+
return Object.hasOwn(TOOL_MARKERS, token.token);
|
|
169
|
+
case "domain":
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function sdkPlatform(token) {
|
|
174
|
+
const dashIndex = token.search(/-\d/);
|
|
175
|
+
return dashIndex > 0 ? token.slice(0, dashIndex) : token;
|
|
176
|
+
}
|
|
177
|
+
function sdkVersion(token) {
|
|
178
|
+
const dashIndex = token.search(/-\d/);
|
|
179
|
+
return dashIndex > 0 ? token.slice(dashIndex + 1) : "";
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// src/core/knowledge/service-signals.ts
|
|
183
|
+
var SERVICE_SIGNALS = [
|
|
184
|
+
// Payments
|
|
185
|
+
{
|
|
186
|
+
token: "stripe",
|
|
187
|
+
category: "Payments",
|
|
188
|
+
envKeys: ["STRIPE_SECRET_KEY"],
|
|
189
|
+
packages: [
|
|
190
|
+
"stripe",
|
|
191
|
+
"@stripe/stripe-js",
|
|
192
|
+
"stripe-ios",
|
|
193
|
+
"stripe-python",
|
|
194
|
+
"stripe-go",
|
|
195
|
+
"stripe-php"
|
|
196
|
+
],
|
|
197
|
+
hostnames: ["api.stripe.com"],
|
|
198
|
+
docsUrl: "https://docs.stripe.com/api",
|
|
199
|
+
docDomain: "stripe.com",
|
|
200
|
+
description: "Stripe payments API \u2014 official API reference"
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
token: "paypal",
|
|
204
|
+
category: "Payments",
|
|
205
|
+
envKeys: ["PAYPAL_CLIENT_ID", "PAYPAL_CLIENT_SECRET"],
|
|
206
|
+
packages: ["@paypal/checkout-server-sdk", "@paypal/paypal-server-sdk"],
|
|
207
|
+
hostnames: ["api-m.paypal.com"],
|
|
208
|
+
docsUrl: "https://developer.paypal.com/api/rest/",
|
|
209
|
+
docDomain: "developer.paypal.com",
|
|
210
|
+
description: "PayPal REST API \u2014 official developer documentation"
|
|
211
|
+
},
|
|
212
|
+
// AI / LLM
|
|
213
|
+
{
|
|
214
|
+
token: "openai",
|
|
215
|
+
category: "AI/LLM",
|
|
216
|
+
envKeys: ["OPENAI_API_KEY"],
|
|
217
|
+
// SwiftPM repo slugs: MacPaw/OpenAI => `openai`; openai-swift community slug.
|
|
218
|
+
packages: ["openai", "openai-swift"],
|
|
219
|
+
hostnames: ["api.openai.com"],
|
|
220
|
+
docsUrl: "https://platform.openai.com/docs",
|
|
221
|
+
docDomain: "platform.openai.com",
|
|
222
|
+
description: "OpenAI API \u2014 official platform documentation"
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
token: "anthropic",
|
|
226
|
+
category: "AI/LLM",
|
|
227
|
+
envKeys: ["ANTHROPIC_API_KEY"],
|
|
228
|
+
// npm `@anthropic-ai/sdk`, PyPI `anthropic`; SwiftPM slugs anthropic-sdk-*.
|
|
229
|
+
packages: ["@anthropic-ai/sdk", "anthropic", "anthropic-sdk-swift", "swift-anthropic"],
|
|
230
|
+
hostnames: ["api.anthropic.com"],
|
|
231
|
+
docsUrl: "https://docs.anthropic.com",
|
|
232
|
+
docDomain: "anthropic.com",
|
|
233
|
+
description: "Anthropic Claude API \u2014 official documentation"
|
|
234
|
+
},
|
|
235
|
+
// Communications
|
|
236
|
+
{
|
|
237
|
+
token: "twilio",
|
|
238
|
+
category: "Communications",
|
|
239
|
+
envKeys: ["TWILIO_ACCOUNT_SID", "TWILIO_AUTH_TOKEN"],
|
|
240
|
+
packages: ["twilio"],
|
|
241
|
+
hostnames: ["api.twilio.com"],
|
|
242
|
+
docsUrl: "https://www.twilio.com/docs",
|
|
243
|
+
docDomain: "twilio.com",
|
|
244
|
+
description: "Twilio SMS/voice API \u2014 official documentation"
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
token: "sendgrid",
|
|
248
|
+
category: "Email",
|
|
249
|
+
envKeys: ["SENDGRID_API_KEY"],
|
|
250
|
+
packages: ["@sendgrid/mail", "@sendgrid/client"],
|
|
251
|
+
hostnames: ["api.sendgrid.com"],
|
|
252
|
+
docsUrl: "https://www.twilio.com/docs/sendgrid",
|
|
253
|
+
docDomain: "twilio.com",
|
|
254
|
+
description: "Twilio SendGrid email API \u2014 official documentation"
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
token: "resend",
|
|
258
|
+
category: "Email",
|
|
259
|
+
envKeys: ["RESEND_API_KEY"],
|
|
260
|
+
packages: ["resend"],
|
|
261
|
+
hostnames: ["api.resend.com"],
|
|
262
|
+
docsUrl: "https://resend.com/docs",
|
|
263
|
+
docDomain: "resend.com",
|
|
264
|
+
description: "Resend transactional email API \u2014 official documentation"
|
|
265
|
+
},
|
|
266
|
+
// Auth
|
|
267
|
+
{
|
|
268
|
+
token: "auth0",
|
|
269
|
+
category: "Authentication",
|
|
270
|
+
// AUTH0_DOMAIN alone is app-configurable; the secret is the strong signal.
|
|
271
|
+
envKeys: ["AUTH0_CLIENT_SECRET"],
|
|
272
|
+
packages: ["auth0", "express-openid-connect", "@auth0/auth0-react", "@auth0/nextjs-auth0"],
|
|
273
|
+
hostnames: [],
|
|
274
|
+
docsUrl: "https://auth0.com/docs",
|
|
275
|
+
docDomain: "auth0.com",
|
|
276
|
+
description: "Auth0 identity platform \u2014 official documentation"
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
token: "clerk",
|
|
280
|
+
category: "Authentication",
|
|
281
|
+
envKeys: ["CLERK_SECRET_KEY"],
|
|
282
|
+
packages: ["@clerk/nextjs", "@clerk/backend", "@clerk/clerk-sdk-node"],
|
|
283
|
+
hostnames: ["api.clerk.com"],
|
|
284
|
+
docsUrl: "https://clerk.com/docs",
|
|
285
|
+
docDomain: "clerk.com",
|
|
286
|
+
description: "Clerk authentication \u2014 official documentation"
|
|
287
|
+
},
|
|
288
|
+
// Backend / data platform
|
|
289
|
+
{
|
|
290
|
+
token: "supabase",
|
|
291
|
+
category: "Backend",
|
|
292
|
+
// Score on the service-role (secret) key, not the public anon key.
|
|
293
|
+
envKeys: ["SUPABASE_SERVICE_ROLE_KEY"],
|
|
294
|
+
packages: ["@supabase/supabase-js"],
|
|
295
|
+
hostnames: [],
|
|
296
|
+
docsUrl: "https://supabase.com/docs",
|
|
297
|
+
docDomain: "supabase.com",
|
|
298
|
+
description: "Supabase backend platform \u2014 official documentation"
|
|
299
|
+
},
|
|
300
|
+
// Fintech
|
|
301
|
+
{
|
|
302
|
+
token: "plaid",
|
|
303
|
+
category: "Fintech",
|
|
304
|
+
envKeys: ["PLAID_CLIENT_ID", "PLAID_SECRET"],
|
|
305
|
+
packages: ["plaid"],
|
|
306
|
+
hostnames: ["api.plaid.com", "sandbox.plaid.com", "production.plaid.com"],
|
|
307
|
+
docsUrl: "https://plaid.com/docs",
|
|
308
|
+
docDomain: "plaid.com",
|
|
309
|
+
description: "Plaid financial data API \u2014 official documentation"
|
|
310
|
+
},
|
|
311
|
+
// Datastores
|
|
312
|
+
{
|
|
313
|
+
token: "mongodb",
|
|
314
|
+
category: "Datastore",
|
|
315
|
+
envKeys: ["MONGODB_URI", "MONGO_URL"],
|
|
316
|
+
packages: ["mongodb", "mongoose"],
|
|
317
|
+
hostnames: [],
|
|
318
|
+
docsUrl: "https://www.mongodb.com/docs/drivers/",
|
|
319
|
+
docDomain: "mongodb.com",
|
|
320
|
+
description: "MongoDB drivers \u2014 official documentation"
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
token: "redis",
|
|
324
|
+
category: "Datastore",
|
|
325
|
+
envKeys: ["REDIS_URL"],
|
|
326
|
+
packages: ["redis", "ioredis"],
|
|
327
|
+
hostnames: [],
|
|
328
|
+
docsUrl: "https://redis.io/docs/latest/develop/",
|
|
329
|
+
docDomain: "redis.io",
|
|
330
|
+
description: "Redis \u2014 official developer documentation"
|
|
331
|
+
},
|
|
332
|
+
// Search
|
|
333
|
+
{
|
|
334
|
+
token: "algolia",
|
|
335
|
+
category: "Search",
|
|
336
|
+
envKeys: ["ALGOLIA_ADMIN_API_KEY", "ALGOLIA_API_KEY"],
|
|
337
|
+
packages: ["algoliasearch"],
|
|
338
|
+
hostnames: [],
|
|
339
|
+
docsUrl: "https://www.algolia.com/doc/",
|
|
340
|
+
docDomain: "algolia.com",
|
|
341
|
+
description: "Algolia search API \u2014 official documentation"
|
|
342
|
+
}
|
|
343
|
+
];
|
|
344
|
+
var SERVICE_DOC_DOMAINS = Array.from(
|
|
345
|
+
new Set(SERVICE_SIGNALS.map((s) => s.docDomain))
|
|
346
|
+
);
|
|
347
|
+
function serviceSignalForToken(token) {
|
|
348
|
+
return SERVICE_SIGNALS.find((s) => s.token === token);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// src/core/knowledge/long-tail.ts
|
|
352
|
+
var MAX_LONG_TAIL_LIBRARIES = 6;
|
|
353
|
+
var PUBLIC_NAME_SHAPE = /^[a-z0-9@][a-z0-9@._/:+-]{0,99}$/;
|
|
354
|
+
var SERVICE_PACKAGE_NAMES = new Set(
|
|
355
|
+
SERVICE_SIGNALS.flatMap((signal) => signal.packages.map((pkg) => pkg.toLowerCase()))
|
|
356
|
+
);
|
|
357
|
+
function namespaceOf(ecosystem, name) {
|
|
358
|
+
switch (ecosystem) {
|
|
359
|
+
case "npm":
|
|
360
|
+
return /^(@[^/]+)\//.exec(name)?.[1];
|
|
361
|
+
case "packagist":
|
|
362
|
+
return name.includes("/") ? name.split("/")[0] : void 0;
|
|
363
|
+
case "maven": {
|
|
364
|
+
const group = name.split(":")[0];
|
|
365
|
+
return group.split(".").slice(0, 2).join(".");
|
|
366
|
+
}
|
|
367
|
+
case "go": {
|
|
368
|
+
const segments = name.split("/");
|
|
369
|
+
return segments.length >= 3 ? segments.slice(0, 2).join("/") : void 0;
|
|
370
|
+
}
|
|
371
|
+
case "nuget":
|
|
372
|
+
return name.includes(".") ? name.split(".")[0] : void 0;
|
|
373
|
+
default:
|
|
374
|
+
return void 0;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
function privateNamespaces(localPackages) {
|
|
378
|
+
const namespaces = /* @__PURE__ */ new Set();
|
|
379
|
+
for (const local of localPackages) {
|
|
380
|
+
const namespace = namespaceOf(local.ecosystem, local.name);
|
|
381
|
+
if (namespace) namespaces.add(`${local.ecosystem}|${namespace}`);
|
|
382
|
+
}
|
|
383
|
+
return namespaces;
|
|
384
|
+
}
|
|
385
|
+
function isPrivateName(dependency, localNames, namespaces) {
|
|
386
|
+
if (localNames.has(`${dependency.ecosystem}|${dependency.name}`)) return true;
|
|
387
|
+
const namespace = namespaceOf(dependency.ecosystem, dependency.name);
|
|
388
|
+
return namespace !== void 0 && namespaces.has(`${dependency.ecosystem}|${namespace}`);
|
|
389
|
+
}
|
|
390
|
+
function selectLongTailLibraries(extracted, max = MAX_LONG_TAIL_LIBRARIES) {
|
|
391
|
+
const localNames = new Set(extracted.localPackages.map((p) => `${p.ecosystem}|${p.name}`));
|
|
392
|
+
const namespaces = privateNamespaces(extracted.localPackages);
|
|
393
|
+
const depthOf = (manifestPath) => manifestPath.split("/").length;
|
|
394
|
+
const eligible = extracted.dependencies.map((dependency, index) => ({ dependency, index })).filter(
|
|
395
|
+
({ dependency }) => dependency.registry && dependency.kind === "runtime" && PUBLIC_NAME_SHAPE.test(dependency.name) && !dependency.name.includes("//") && !isFrameworkDependency(dependency) && !SERVICE_PACKAGE_NAMES.has(dependency.name) && !isPrivateName(dependency, localNames, namespaces)
|
|
396
|
+
).sort(
|
|
397
|
+
(a, b) => depthOf(a.dependency.manifestPath) - depthOf(b.dependency.manifestPath) || a.index - b.index
|
|
398
|
+
);
|
|
399
|
+
const seen = /* @__PURE__ */ new Set();
|
|
400
|
+
const selected = [];
|
|
401
|
+
for (const { dependency } of eligible) {
|
|
402
|
+
const key = `${dependency.ecosystem}|${dependency.name}`;
|
|
403
|
+
if (seen.has(key)) continue;
|
|
404
|
+
seen.add(key);
|
|
405
|
+
selected.push({ ecosystem: dependency.ecosystem, name: dependency.name });
|
|
406
|
+
if (selected.length >= max) break;
|
|
407
|
+
}
|
|
408
|
+
return selected;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// src/core/knowledge/service-candidates.ts
|
|
412
|
+
import { readdirSync, readFileSync } from "fs";
|
|
413
|
+
import path from "path";
|
|
414
|
+
|
|
415
|
+
// src/core/knowledge/service-candidates-contract.ts
|
|
416
|
+
var CANDIDATE_KEY_SUFFIXES = [
|
|
417
|
+
"CLIENT_SECRET",
|
|
418
|
+
"CLIENT_ID",
|
|
419
|
+
"ACCOUNT_SID",
|
|
420
|
+
"SECRET_KEY",
|
|
421
|
+
// AUTH_TOKEN before TOKEN (longest-first): TWILIO_AUTH_TOKEN must extract
|
|
422
|
+
// `twilio` (matching the curated token), not a bogus `twilio_auth`.
|
|
423
|
+
"AUTH_TOKEN",
|
|
424
|
+
"API_KEY",
|
|
425
|
+
"SECRET",
|
|
426
|
+
"TOKEN",
|
|
427
|
+
"DSN"
|
|
428
|
+
];
|
|
429
|
+
var DEMOTED_SOURCE_SUFFIXES = /* @__PURE__ */ new Set([
|
|
430
|
+
"TOKEN",
|
|
431
|
+
"AUTH_TOKEN",
|
|
432
|
+
"SECRET"
|
|
433
|
+
]);
|
|
434
|
+
var STRIPPED_KEY_PREFIXES = [
|
|
435
|
+
"NEXT_PUBLIC_",
|
|
436
|
+
"REACT_APP_",
|
|
437
|
+
"VITE_",
|
|
438
|
+
"EXPO_PUBLIC_",
|
|
439
|
+
"NUXT_PUBLIC_"
|
|
440
|
+
];
|
|
441
|
+
var SUPPRESSED_TOKENS = /* @__PURE__ */ new Set([
|
|
442
|
+
"jwt",
|
|
443
|
+
"session",
|
|
444
|
+
"csrf",
|
|
445
|
+
"cookie",
|
|
446
|
+
"encryption",
|
|
447
|
+
"auth",
|
|
448
|
+
"oauth",
|
|
449
|
+
"refresh",
|
|
450
|
+
"bearer",
|
|
451
|
+
"access",
|
|
452
|
+
"id",
|
|
453
|
+
"signing",
|
|
454
|
+
"admin",
|
|
455
|
+
"db",
|
|
456
|
+
"database",
|
|
457
|
+
"fake",
|
|
458
|
+
"example",
|
|
459
|
+
"mock",
|
|
460
|
+
"dummy",
|
|
461
|
+
"test",
|
|
462
|
+
"your",
|
|
463
|
+
"my",
|
|
464
|
+
"sample",
|
|
465
|
+
// App/framework-internal secret owners — APP_SECRET, DJANGO_SECRET_KEY,
|
|
466
|
+
// NEXTAUTH_SECRET, FLASK_SECRET_KEY, RAILS_SECRET_KEY_BASE etc. are signing
|
|
467
|
+
// secrets for the app itself, never an external API service.
|
|
468
|
+
"app",
|
|
469
|
+
"server",
|
|
470
|
+
"api",
|
|
471
|
+
"web",
|
|
472
|
+
"client",
|
|
473
|
+
"django",
|
|
474
|
+
"flask",
|
|
475
|
+
"rails",
|
|
476
|
+
"laravel",
|
|
477
|
+
"express",
|
|
478
|
+
"nextauth",
|
|
479
|
+
"next_auth",
|
|
480
|
+
"devise",
|
|
481
|
+
"webhook",
|
|
482
|
+
"deploy",
|
|
483
|
+
"build",
|
|
484
|
+
"ci"
|
|
485
|
+
]);
|
|
486
|
+
var SUPPRESSED_TOKEN_PREFIXES = [
|
|
487
|
+
"fake_",
|
|
488
|
+
"example_",
|
|
489
|
+
"mock_",
|
|
490
|
+
"dummy_",
|
|
491
|
+
"test_",
|
|
492
|
+
"your_",
|
|
493
|
+
"my_",
|
|
494
|
+
"sample_"
|
|
495
|
+
];
|
|
496
|
+
var LLM_PROVIDER_KEY_NAMES = /* @__PURE__ */ new Set([
|
|
497
|
+
"ANTHROPIC_API_KEY",
|
|
498
|
+
"ANTHROPIC_AUTH_TOKEN",
|
|
499
|
+
"CLAUDE_CODE_OAUTH_TOKEN",
|
|
500
|
+
"OPENAI_API_KEY",
|
|
501
|
+
"GEMINI_API_KEY",
|
|
502
|
+
"GOOGLE_API_KEY",
|
|
503
|
+
"XAI_API_KEY",
|
|
504
|
+
"OPENROUTER_API_KEY",
|
|
505
|
+
"KIRO_API_KEY",
|
|
506
|
+
"ANTIGRAVITY_API_KEY",
|
|
507
|
+
"CURSOR_API_KEY",
|
|
508
|
+
"CODEX_API_KEY",
|
|
509
|
+
"CODEX_TOKEN",
|
|
510
|
+
"ZAI_API_KEY",
|
|
511
|
+
"GITHUB_TOKEN"
|
|
512
|
+
]);
|
|
513
|
+
var ENV_TEMPLATE_BASENAMES = /* @__PURE__ */ new Set([
|
|
514
|
+
".env.example",
|
|
515
|
+
".env.sample",
|
|
516
|
+
".env.template",
|
|
517
|
+
".env.dist"
|
|
518
|
+
]);
|
|
519
|
+
function envTemplateKeyNames(content) {
|
|
520
|
+
const keys = [];
|
|
521
|
+
for (const line of content.split(/\r?\n/)) {
|
|
522
|
+
const trimmed = line.trim();
|
|
523
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
524
|
+
const withoutExport = trimmed.replace(/^export\s+/, "");
|
|
525
|
+
const eq = withoutExport.indexOf("=");
|
|
526
|
+
const key = (eq >= 0 ? withoutExport.slice(0, eq) : withoutExport).trim();
|
|
527
|
+
if (/^[A-Z][A-Z0-9_]*$/.test(key)) keys.push(key);
|
|
528
|
+
}
|
|
529
|
+
return keys;
|
|
530
|
+
}
|
|
531
|
+
var CONFIG_BASENAMES = /* @__PURE__ */ new Set([".mcp.json"]);
|
|
532
|
+
var CONFIG_EXTENSIONS = [".yaml", ".yml", ".toml", ".json"];
|
|
533
|
+
var CANDIDATE_SOURCE_EXTENSIONS = [
|
|
534
|
+
".ts",
|
|
535
|
+
".tsx",
|
|
536
|
+
".mts",
|
|
537
|
+
".cts",
|
|
538
|
+
".js",
|
|
539
|
+
".jsx",
|
|
540
|
+
".mjs",
|
|
541
|
+
".cjs",
|
|
542
|
+
".swift",
|
|
543
|
+
".py",
|
|
544
|
+
".go",
|
|
545
|
+
".rb",
|
|
546
|
+
".java",
|
|
547
|
+
".kt",
|
|
548
|
+
".kts",
|
|
549
|
+
".cs",
|
|
550
|
+
".php",
|
|
551
|
+
".rs",
|
|
552
|
+
".c",
|
|
553
|
+
".cc",
|
|
554
|
+
".cpp",
|
|
555
|
+
".h",
|
|
556
|
+
".hpp",
|
|
557
|
+
".m",
|
|
558
|
+
".mm",
|
|
559
|
+
".dart",
|
|
560
|
+
".scala",
|
|
561
|
+
".ps1",
|
|
562
|
+
".r",
|
|
563
|
+
".sql",
|
|
564
|
+
".pl",
|
|
565
|
+
".ex",
|
|
566
|
+
".exs"
|
|
567
|
+
];
|
|
568
|
+
var CANDIDATE_SCAN_EXCLUDED_DIRS = /* @__PURE__ */ new Set([
|
|
569
|
+
"test",
|
|
570
|
+
"tests",
|
|
571
|
+
"__tests__",
|
|
572
|
+
"spec",
|
|
573
|
+
"fixture",
|
|
574
|
+
"fixtures",
|
|
575
|
+
"mock",
|
|
576
|
+
"mocks",
|
|
577
|
+
"example",
|
|
578
|
+
"examples",
|
|
579
|
+
"sample",
|
|
580
|
+
"samples",
|
|
581
|
+
"vendor",
|
|
582
|
+
"third_party",
|
|
583
|
+
"third-party",
|
|
584
|
+
"docs",
|
|
585
|
+
"templates",
|
|
586
|
+
"backups"
|
|
587
|
+
]);
|
|
588
|
+
var API_ISH_SUBDOMAINS = /* @__PURE__ */ new Set(["api", "data"]);
|
|
589
|
+
var MIN_PLAIN_HOST_OCCURRENCES = 3;
|
|
590
|
+
var HOSTNAME_NOISE_PATTERNS = [
|
|
591
|
+
/(^|\.)example\.(com|org|net)$/i,
|
|
592
|
+
/^localhost$/i,
|
|
593
|
+
/^127\.0\.0\.1$/,
|
|
594
|
+
/(^|\.)local$/i,
|
|
595
|
+
/^(custom|env|your|foo|bar)\.api\./i,
|
|
596
|
+
/\.api\.com$/i,
|
|
597
|
+
/^(github|raw\.githubusercontent|gist\.github)\.com$/i,
|
|
598
|
+
/^(en\.)?wikipedia\.org$/i,
|
|
599
|
+
/^json-schema\.org$/i,
|
|
600
|
+
/^(cdn|fonts|ajax)\./i
|
|
601
|
+
];
|
|
602
|
+
var MAX_CANDIDATE_SCAN_FILES = 5e3;
|
|
603
|
+
var MAX_CANDIDATE_CONTENT_SAMPLES = 120;
|
|
604
|
+
var CANDIDATE_ITEM_ID_PREFIX = "docs:candidate:";
|
|
605
|
+
var CANDIDATE_SEARCH_PRIORITY = [
|
|
606
|
+
"env-template",
|
|
607
|
+
"package",
|
|
608
|
+
"source",
|
|
609
|
+
"config",
|
|
610
|
+
"script",
|
|
611
|
+
"hostname"
|
|
612
|
+
];
|
|
613
|
+
var MAX_UNRESOLVED_LINES = 5;
|
|
614
|
+
function candidateSetSignature(candidates) {
|
|
615
|
+
return candidates.map((c) => {
|
|
616
|
+
const evidence = Array.from(new Set(c.evidence.map((ev) => `${ev.class}=${ev.matched}`))).sort().join("+");
|
|
617
|
+
const safety = isCandidateQuerySafe(c) ? "q1" : "q0";
|
|
618
|
+
return `${c.token}:${c.confidence}:${evidence}:${safety}`;
|
|
619
|
+
}).sort().join(",");
|
|
620
|
+
}
|
|
621
|
+
var QUERY_SAFE_EVIDENCE_CLASSES = /* @__PURE__ */ new Set([
|
|
622
|
+
"env-template",
|
|
623
|
+
"package",
|
|
624
|
+
"config"
|
|
625
|
+
]);
|
|
626
|
+
var QUERY_SAFE_TLDS = /* @__PURE__ */ new Set([
|
|
627
|
+
"com",
|
|
628
|
+
"org",
|
|
629
|
+
"net",
|
|
630
|
+
"io",
|
|
631
|
+
"dev",
|
|
632
|
+
"ai",
|
|
633
|
+
"co",
|
|
634
|
+
"gov",
|
|
635
|
+
"edu",
|
|
636
|
+
"app",
|
|
637
|
+
"sh",
|
|
638
|
+
"us",
|
|
639
|
+
"uk",
|
|
640
|
+
"de",
|
|
641
|
+
"fr",
|
|
642
|
+
"jp",
|
|
643
|
+
"in",
|
|
644
|
+
"ca",
|
|
645
|
+
"au",
|
|
646
|
+
"nl",
|
|
647
|
+
"se",
|
|
648
|
+
"ch",
|
|
649
|
+
"eu"
|
|
650
|
+
]);
|
|
651
|
+
function isQuerySafeHostname(host) {
|
|
652
|
+
const labels = host.split(".").filter(Boolean);
|
|
653
|
+
if (labels.length < 2 || labels.length > 3) return false;
|
|
654
|
+
if (labels.some((label) => ["corp", "internal", "intranet", "local", "lan"].includes(label))) {
|
|
655
|
+
return false;
|
|
656
|
+
}
|
|
657
|
+
const tld = labels[labels.length - 1];
|
|
658
|
+
return QUERY_SAFE_TLDS.has(tld);
|
|
659
|
+
}
|
|
660
|
+
function isCandidateQuerySafe(candidate) {
|
|
661
|
+
return candidate.evidence.some(
|
|
662
|
+
(ev) => QUERY_SAFE_EVIDENCE_CLASSES.has(ev.class) || ev.class === "hostname" && isQuerySafeHostname(ev.matched.toLowerCase())
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// src/core/knowledge/service-candidates.ts
|
|
667
|
+
var MAX_CANDIDATE_CONTENT_BYTES = 64 * 1024;
|
|
668
|
+
var SUFFIXES_LONGEST_FIRST = [...CANDIDATE_KEY_SUFFIXES].sort(
|
|
669
|
+
(a, b) => b.length - a.length
|
|
670
|
+
);
|
|
671
|
+
var GENERIC_TLDS = /* @__PURE__ */ new Set(["com", "net", "org", "io"]);
|
|
672
|
+
var CURATED_TOKENS = new Set(SERVICE_SIGNALS.map((s) => s.token));
|
|
673
|
+
var CURATED_ENV_KEY_TO_TOKEN = new Map(
|
|
674
|
+
SERVICE_SIGNALS.flatMap((s) => s.envKeys.map((key) => [key, s.token]))
|
|
675
|
+
);
|
|
676
|
+
function readTextSafe(filePath, maxBytes = MAX_CANDIDATE_CONTENT_BYTES) {
|
|
677
|
+
try {
|
|
678
|
+
return readFileSync(filePath, "utf8").slice(0, maxBytes);
|
|
679
|
+
} catch {
|
|
680
|
+
return "";
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
var TEST_FILE_BASENAME = /(\.test\.|\.spec\.|_test\.|^test_|^conftest\.py$|Tests?\.swift$|Spec\.swift$)/;
|
|
684
|
+
function classifySurface(basename) {
|
|
685
|
+
if (ENV_TEMPLATE_BASENAMES.has(basename)) return "env-template";
|
|
686
|
+
if (TEST_FILE_BASENAME.test(basename)) return null;
|
|
687
|
+
if (basename.endsWith(".sh")) return "script";
|
|
688
|
+
if (CONFIG_BASENAMES.has(basename)) return "config";
|
|
689
|
+
const ext = path.extname(basename).toLowerCase();
|
|
690
|
+
if (CONFIG_EXTENSIONS.includes(ext)) return "config";
|
|
691
|
+
if (CANDIDATE_SOURCE_EXTENSIONS.includes(ext)) return "source";
|
|
692
|
+
return null;
|
|
693
|
+
}
|
|
694
|
+
function hasExcludedSegment(relativePath) {
|
|
695
|
+
return relativePath.split(path.sep).some((segment) => CANDIDATE_SCAN_EXCLUDED_DIRS.has(segment.toLowerCase()));
|
|
696
|
+
}
|
|
697
|
+
function collectClassifiedFiles(root) {
|
|
698
|
+
const collected = [];
|
|
699
|
+
const stack = [""];
|
|
700
|
+
let visited = 0;
|
|
701
|
+
while (stack.length > 0 && visited < MAX_CANDIDATE_SCAN_FILES) {
|
|
702
|
+
const relativeDirectory = stack.pop() ?? "";
|
|
703
|
+
let entries;
|
|
704
|
+
try {
|
|
705
|
+
entries = readdirSync(path.join(root, relativeDirectory), { withFileTypes: true });
|
|
706
|
+
} catch {
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
709
|
+
for (const entry of entries) {
|
|
710
|
+
const relativePath = path.join(relativeDirectory, entry.name);
|
|
711
|
+
if (isIgnoredProjectPath(relativePath)) continue;
|
|
712
|
+
if (entry.isDirectory()) {
|
|
713
|
+
if (CANDIDATE_SCAN_EXCLUDED_DIRS.has(entry.name.toLowerCase())) continue;
|
|
714
|
+
stack.push(relativePath);
|
|
715
|
+
} else if (entry.isFile()) {
|
|
716
|
+
visited += 1;
|
|
717
|
+
if (hasExcludedSegment(relativePath)) continue;
|
|
718
|
+
const surface = classifySurface(entry.name);
|
|
719
|
+
if (surface && collected.length < MAX_CANDIDATE_CONTENT_SAMPLES) {
|
|
720
|
+
collected.push({ relativePath, surface });
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
if (visited >= MAX_CANDIDATE_SCAN_FILES) break;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
return collected;
|
|
727
|
+
}
|
|
728
|
+
function stripKeyPrefix(upperKey) {
|
|
729
|
+
for (const prefix of STRIPPED_KEY_PREFIXES) {
|
|
730
|
+
if (upperKey.startsWith(prefix)) return upperKey.slice(prefix.length);
|
|
731
|
+
}
|
|
732
|
+
return upperKey;
|
|
733
|
+
}
|
|
734
|
+
function extractToken(upperKey) {
|
|
735
|
+
const name = stripKeyPrefix(upperKey);
|
|
736
|
+
for (const suffix of SUFFIXES_LONGEST_FIRST) {
|
|
737
|
+
if (name === suffix) return null;
|
|
738
|
+
if (name.endsWith(`_${suffix}`)) {
|
|
739
|
+
const remainder = name.slice(0, name.length - suffix.length - 1);
|
|
740
|
+
if (!remainder) return null;
|
|
741
|
+
return { token: remainder.toLowerCase(), suffix };
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
return null;
|
|
745
|
+
}
|
|
746
|
+
function uppercaseKeyIdentifiers(content) {
|
|
747
|
+
return content.match(/\b[A-Z][A-Z0-9_]*\b/g) ?? [];
|
|
748
|
+
}
|
|
749
|
+
function configKeyIdentifiers(content) {
|
|
750
|
+
const keys = [];
|
|
751
|
+
for (const line of content.split(/\r?\n/)) {
|
|
752
|
+
const trimmed = line.trim();
|
|
753
|
+
if (!trimmed || trimmed.startsWith("#") || trimmed.startsWith("//")) continue;
|
|
754
|
+
const lhs = trimmed.match(/^["']?([A-Za-z][A-Za-z0-9_]*)["']?\s*[:=]/);
|
|
755
|
+
if (lhs?.[1]) keys.push(lhs[1]);
|
|
756
|
+
for (const jsonKey of trimmed.matchAll(/"([A-Za-z][A-Za-z0-9_]*)"\s*:/g)) {
|
|
757
|
+
if (jsonKey[1]) keys.push(jsonKey[1]);
|
|
758
|
+
}
|
|
759
|
+
for (const ref of trimmed.matchAll(/\$\{([A-Z][A-Z0-9_]*)\}/g)) {
|
|
760
|
+
if (ref[1]) keys.push(ref[1]);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
return keys;
|
|
764
|
+
}
|
|
765
|
+
function extractHostnames(content) {
|
|
766
|
+
const hosts = [];
|
|
767
|
+
for (const match of content.toLowerCase().matchAll(/\bhttps?:\/\/([a-z0-9.-]+)/g)) {
|
|
768
|
+
const host = match[1];
|
|
769
|
+
if (host) hosts.push(host);
|
|
770
|
+
}
|
|
771
|
+
return hosts;
|
|
772
|
+
}
|
|
773
|
+
function isNoiseHost(host) {
|
|
774
|
+
return HOSTNAME_NOISE_PATTERNS.some((pattern) => pattern.test(host));
|
|
775
|
+
}
|
|
776
|
+
function stripHostPrefix(host) {
|
|
777
|
+
return host.replace(/^(?:api|data|www)\./, "");
|
|
778
|
+
}
|
|
779
|
+
function hostSlug(host) {
|
|
780
|
+
const labels = stripHostPrefix(host).split(".").filter(Boolean);
|
|
781
|
+
if (labels.length >= 2) {
|
|
782
|
+
const last = labels[labels.length - 1];
|
|
783
|
+
if (last && GENERIC_TLDS.has(last)) labels.pop();
|
|
784
|
+
}
|
|
785
|
+
return labels.join("-").toLowerCase();
|
|
786
|
+
}
|
|
787
|
+
function hostPrimaryLabel(host) {
|
|
788
|
+
return (stripHostPrefix(host).split(".")[0] ?? "").toLowerCase();
|
|
789
|
+
}
|
|
790
|
+
function newAccumulator() {
|
|
791
|
+
return {
|
|
792
|
+
evidence: /* @__PURE__ */ new Map(),
|
|
793
|
+
hasEnvTemplate: false,
|
|
794
|
+
hasCuratedEnvKey: false,
|
|
795
|
+
hasSourceNonDemoted: false,
|
|
796
|
+
hasSourceDemoted: false,
|
|
797
|
+
hasScript: false,
|
|
798
|
+
hasConfig: false,
|
|
799
|
+
hasHostname: false,
|
|
800
|
+
hasApiIshHostname: false,
|
|
801
|
+
hasRepeatedHostname: false
|
|
802
|
+
};
|
|
803
|
+
}
|
|
804
|
+
function addEvidence(acc, cls, matched) {
|
|
805
|
+
const key = `${cls}|${matched}`;
|
|
806
|
+
if (!acc.evidence.has(key)) acc.evidence.set(key, { class: cls, matched });
|
|
807
|
+
}
|
|
808
|
+
function isSuppressedToken(token) {
|
|
809
|
+
if (SUPPRESSED_TOKENS.has(token)) return true;
|
|
810
|
+
return SUPPRESSED_TOKEN_PREFIXES.some(
|
|
811
|
+
(prefix) => token.startsWith(prefix)
|
|
812
|
+
);
|
|
813
|
+
}
|
|
814
|
+
function detectServiceCandidates(root, dependencyNames = dependencyNameSet(extractDirectDependencies(root), {
|
|
815
|
+
npmScopes: true
|
|
816
|
+
})) {
|
|
817
|
+
const accumulators = /* @__PURE__ */ new Map();
|
|
818
|
+
const getAcc = (token) => {
|
|
819
|
+
let acc = accumulators.get(token);
|
|
820
|
+
if (!acc) {
|
|
821
|
+
acc = newAccumulator();
|
|
822
|
+
accumulators.set(token, acc);
|
|
823
|
+
}
|
|
824
|
+
return acc;
|
|
825
|
+
};
|
|
826
|
+
const files = collectClassifiedFiles(root);
|
|
827
|
+
const hostCounts = /* @__PURE__ */ new Map();
|
|
828
|
+
for (const { relativePath, surface } of files) {
|
|
829
|
+
const content = readTextSafe(path.join(root, relativePath));
|
|
830
|
+
if (!content) continue;
|
|
831
|
+
if (surface === "source" || surface === "script") {
|
|
832
|
+
for (const host of extractHostnames(content)) {
|
|
833
|
+
hostCounts.set(host, (hostCounts.get(host) ?? 0) + 1);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
let keyNames;
|
|
837
|
+
if (surface === "env-template") keyNames = envTemplateKeyNames(content);
|
|
838
|
+
else if (surface === "config") keyNames = configKeyIdentifiers(content);
|
|
839
|
+
else keyNames = uppercaseKeyIdentifiers(content);
|
|
840
|
+
for (const rawKey of keyNames) {
|
|
841
|
+
const upperKey = rawKey.toUpperCase();
|
|
842
|
+
const extracted = extractToken(upperKey);
|
|
843
|
+
if (!extracted) continue;
|
|
844
|
+
const strippedKey = stripKeyPrefix(upperKey);
|
|
845
|
+
const curatedToken = CURATED_ENV_KEY_TO_TOKEN.get(upperKey) ?? CURATED_ENV_KEY_TO_TOKEN.get(strippedKey);
|
|
846
|
+
const token = curatedToken ?? extracted.token;
|
|
847
|
+
const suffix = extracted.suffix;
|
|
848
|
+
if (isSuppressedToken(token)) continue;
|
|
849
|
+
if (LLM_PROVIDER_KEY_NAMES.has(upperKey) && surface !== "source" && surface !== "env-template") {
|
|
850
|
+
continue;
|
|
851
|
+
}
|
|
852
|
+
const acc = getAcc(token);
|
|
853
|
+
const cls = surface;
|
|
854
|
+
const evidenceText = surface === "source" || surface === "script" ? `*_${suffix} (redacted)` : rawKey;
|
|
855
|
+
addEvidence(acc, cls, evidenceText);
|
|
856
|
+
if (surface === "env-template") {
|
|
857
|
+
acc.hasEnvTemplate = true;
|
|
858
|
+
if (CURATED_ENV_KEY_TO_TOKEN.has(upperKey)) acc.hasCuratedEnvKey = true;
|
|
859
|
+
} else if (surface === "script") acc.hasScript = true;
|
|
860
|
+
else if (surface === "config") acc.hasConfig = true;
|
|
861
|
+
else if (DEMOTED_SOURCE_SUFFIXES.has(suffix)) acc.hasSourceDemoted = true;
|
|
862
|
+
else acc.hasSourceNonDemoted = true;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
const squash = (s) => s.replace(/[-_.]/g, "");
|
|
866
|
+
const existingTokens = Array.from(accumulators.keys());
|
|
867
|
+
for (const [host, count] of hostCounts) {
|
|
868
|
+
if (isNoiseHost(host)) continue;
|
|
869
|
+
const firstLabel = host.split(".")[0] ?? "";
|
|
870
|
+
const apiIsh = API_ISH_SUBDOMAINS.has(firstLabel);
|
|
871
|
+
const primary = hostPrimaryLabel(host);
|
|
872
|
+
const squashedHost = squash(host);
|
|
873
|
+
const matchingTokens = existingTokens.filter((token) => {
|
|
874
|
+
const squashedToken = squash(token);
|
|
875
|
+
return squashedToken.length > 0 && (squashedHost.includes(squashedToken) || primary.length > 0 && squashedToken.includes(squash(primary)));
|
|
876
|
+
});
|
|
877
|
+
const containsExistingToken = matchingTokens.length > 0;
|
|
878
|
+
const repeated = count >= MIN_PLAIN_HOST_OCCURRENCES;
|
|
879
|
+
const qualifies = apiIsh || repeated || containsExistingToken;
|
|
880
|
+
if (!qualifies) continue;
|
|
881
|
+
const attach = (acc) => {
|
|
882
|
+
addEvidence(acc, "hostname", host);
|
|
883
|
+
acc.hasHostname = true;
|
|
884
|
+
if (apiIsh) acc.hasApiIshHostname = true;
|
|
885
|
+
if (repeated) acc.hasRepeatedHostname = true;
|
|
886
|
+
};
|
|
887
|
+
if (matchingTokens.length > 0) {
|
|
888
|
+
for (const token of matchingTokens) attach(getAcc(token));
|
|
889
|
+
} else {
|
|
890
|
+
const token = hostSlug(host);
|
|
891
|
+
if (!token || isSuppressedToken(token)) continue;
|
|
892
|
+
attach(getAcc(token));
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
const candidates = [];
|
|
896
|
+
for (const [token, acc] of accumulators) {
|
|
897
|
+
if (acc.evidence.size === 0) continue;
|
|
898
|
+
const hasSourceKey = acc.hasSourceNonDemoted || acc.hasSourceDemoted;
|
|
899
|
+
const hasManifestDep = dependencyNames.has(token);
|
|
900
|
+
const curatedWillOffer = acc.hasCuratedEnvKey || hasManifestDep;
|
|
901
|
+
if (CURATED_TOKENS.has(token) && curatedWillOffer && !hasSourceKey) continue;
|
|
902
|
+
const confidence = computeConfidence(acc, hasManifestDep) ? "confirmed" : "unconfirmed";
|
|
903
|
+
if (hasManifestDep) {
|
|
904
|
+
addEvidence(acc, "package", token);
|
|
905
|
+
}
|
|
906
|
+
const evidence = Array.from(acc.evidence.values()).sort(
|
|
907
|
+
(a, b) => a.class === b.class ? a.matched.localeCompare(b.matched) : a.class.localeCompare(b.class)
|
|
908
|
+
);
|
|
909
|
+
candidates.push({ token, confidence, evidence });
|
|
910
|
+
}
|
|
911
|
+
return candidates.sort((a, b) => a.token.localeCompare(b.token));
|
|
912
|
+
}
|
|
913
|
+
function computeConfidence(acc, hasManifestDep) {
|
|
914
|
+
if (acc.hasEnvTemplate || acc.hasSourceNonDemoted || acc.hasApiIshHostname || acc.hasRepeatedHostname) {
|
|
915
|
+
return true;
|
|
916
|
+
}
|
|
917
|
+
const lowClasses = /* @__PURE__ */ new Set();
|
|
918
|
+
if (acc.hasScript) lowClasses.add("script");
|
|
919
|
+
if (acc.hasConfig) lowClasses.add("config");
|
|
920
|
+
if (acc.hasHostname) lowClasses.add("hostname");
|
|
921
|
+
if (acc.hasSourceDemoted) lowClasses.add("demoted-source");
|
|
922
|
+
const corroborators = /* @__PURE__ */ new Set();
|
|
923
|
+
if (acc.hasHostname) corroborators.add("hostname");
|
|
924
|
+
if (hasManifestDep) corroborators.add("manifest-dep");
|
|
925
|
+
for (const low of lowClasses) {
|
|
926
|
+
for (const corroborator of corroborators) {
|
|
927
|
+
if (corroborator !== low) return true;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
return false;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
// src/core/knowledge/detect.ts
|
|
934
|
+
var MAX_SAMPLE_BYTES = 16e3;
|
|
935
|
+
var MAX_SERVICE_HOSTNAME_SAMPLES = 60;
|
|
936
|
+
var MAX_SERVICE_SCAN_FILES = 5e3;
|
|
937
|
+
var SERVICE_SOURCE_EXTENSIONS = [
|
|
938
|
+
".ts",
|
|
939
|
+
".tsx",
|
|
940
|
+
".js",
|
|
941
|
+
".jsx",
|
|
942
|
+
".mjs",
|
|
943
|
+
".swift",
|
|
944
|
+
".py",
|
|
945
|
+
".go",
|
|
946
|
+
".rb",
|
|
947
|
+
".java",
|
|
948
|
+
".kt",
|
|
949
|
+
".cs",
|
|
950
|
+
".php",
|
|
951
|
+
".rs"
|
|
952
|
+
];
|
|
953
|
+
var MCP_CONFIG_CANDIDATES = [".mcp.json", ".cursor/mcp.json", ".vscode/mcp.json"];
|
|
954
|
+
function readTextSafe2(filePath, maxBytes = MAX_SAMPLE_BYTES) {
|
|
955
|
+
try {
|
|
956
|
+
return readFileSync2(filePath, "utf8").slice(0, maxBytes);
|
|
957
|
+
} catch {
|
|
958
|
+
return "";
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
function fileSizeBytes(filePath) {
|
|
962
|
+
try {
|
|
963
|
+
const stat = statSync(filePath);
|
|
964
|
+
return stat.isFile() ? stat.size : 0;
|
|
965
|
+
} catch {
|
|
966
|
+
return 0;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
function detectSdkTargets(root) {
|
|
970
|
+
const targets = /* @__PURE__ */ new Set();
|
|
971
|
+
const packageSwift = readTextSafe2(path2.join(root, "Package.swift"), 32e3);
|
|
972
|
+
if (packageSwift) {
|
|
973
|
+
const platformPattern = /\.(iOS|macOS|watchOS|tvOS|visionOS)\s*\(\s*(?:\.v(\d+)(?:_\d+)?|"(\d+)(?:\.\d+)*")\s*\)/g;
|
|
974
|
+
for (const match of packageSwift.matchAll(platformPattern)) {
|
|
975
|
+
const platform = (match[1] ?? "").toLowerCase();
|
|
976
|
+
const version = match[2] ?? match[3];
|
|
977
|
+
if (platform && version) targets.add(`${platform}-${version}`);
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
const pbxprojFiles = collectFiles(
|
|
981
|
+
root,
|
|
982
|
+
(relativePath, basename) => basename === "project.pbxproj" && relativePath.includes(".xcodeproj"),
|
|
983
|
+
3
|
|
984
|
+
);
|
|
985
|
+
for (const relativePath of pbxprojFiles) {
|
|
986
|
+
const content = readTextSafe2(path2.join(root, relativePath), 256e3);
|
|
987
|
+
const ios = content.match(/IPHONEOS_DEPLOYMENT_TARGET\s*=\s*(\d+)(?:\.\d+)*/);
|
|
988
|
+
if (ios?.[1]) targets.add(`ios-${ios[1]}`);
|
|
989
|
+
const macos = content.match(/MACOSX_DEPLOYMENT_TARGET\s*=\s*(\d+)(?:\.\d+)*/);
|
|
990
|
+
if (macos?.[1]) targets.add(`macos-${macos[1]}`);
|
|
991
|
+
}
|
|
992
|
+
return Array.from(targets).sort();
|
|
993
|
+
}
|
|
994
|
+
var MAX_TOOL_SCAN_FILES = 5e3;
|
|
995
|
+
function detectTools(root) {
|
|
996
|
+
const exactNames = /* @__PURE__ */ new Map();
|
|
997
|
+
const suffixes = /* @__PURE__ */ new Map();
|
|
998
|
+
for (const [tool, markers] of Object.entries(TOOL_MARKERS)) {
|
|
999
|
+
for (const marker of markers) {
|
|
1000
|
+
if (marker.startsWith("*.")) suffixes.set(marker.slice(1), tool);
|
|
1001
|
+
else exactNames.set(marker, tool);
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
const found = /* @__PURE__ */ new Set();
|
|
1005
|
+
let visited = 0;
|
|
1006
|
+
collectFiles(
|
|
1007
|
+
root,
|
|
1008
|
+
(_relativePath, basename) => {
|
|
1009
|
+
visited += 1;
|
|
1010
|
+
const exact = exactNames.get(basename);
|
|
1011
|
+
if (exact) found.add(exact);
|
|
1012
|
+
for (const [suffix, tool] of suffixes) {
|
|
1013
|
+
if (basename.endsWith(suffix)) found.add(tool);
|
|
1014
|
+
}
|
|
1015
|
+
return visited >= MAX_TOOL_SCAN_FILES;
|
|
1016
|
+
},
|
|
1017
|
+
1,
|
|
1018
|
+
// Fixture, example, test, and vendored trees are not the user's tooling.
|
|
1019
|
+
{ skipDirectory: isSkippedDirectory }
|
|
1020
|
+
);
|
|
1021
|
+
return Array.from(found).sort();
|
|
1022
|
+
}
|
|
1023
|
+
function collectEnvKeyNames(root) {
|
|
1024
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1025
|
+
for (const candidate of ENV_TEMPLATE_BASENAMES) {
|
|
1026
|
+
const content = readTextSafe2(path2.join(root, candidate), 32e3);
|
|
1027
|
+
if (!content) continue;
|
|
1028
|
+
for (const key of envTemplateKeyNames(content)) keys.add(key);
|
|
1029
|
+
}
|
|
1030
|
+
return keys;
|
|
1031
|
+
}
|
|
1032
|
+
function isExcludedServicePath(relativePath) {
|
|
1033
|
+
const segments = relativePath.toLowerCase().split(path2.sep);
|
|
1034
|
+
return segments.some((segment) => CANDIDATE_SCAN_EXCLUDED_DIRS.has(segment));
|
|
1035
|
+
}
|
|
1036
|
+
function detectServices(root, dependencyNames) {
|
|
1037
|
+
const envKeyNames = collectEnvKeyNames(root);
|
|
1038
|
+
const anyHostnames = SERVICE_SIGNALS.some((s) => s.hostnames.length > 0);
|
|
1039
|
+
const sourceHostnames = anyHostnames ? collectServiceHostnames(root) : /* @__PURE__ */ new Set();
|
|
1040
|
+
const detected = [];
|
|
1041
|
+
for (const signal of SERVICE_SIGNALS) {
|
|
1042
|
+
const evidence = [];
|
|
1043
|
+
if (signal.envKeys.some((key) => envKeyNames.has(key))) evidence.push("env-key");
|
|
1044
|
+
if (signal.packages.some((pkg) => dependencyNames.has(pkg.toLowerCase()))) {
|
|
1045
|
+
evidence.push("package");
|
|
1046
|
+
}
|
|
1047
|
+
if (signal.hostnames.some((host) => sourceHostnames.has(host.toLowerCase()))) {
|
|
1048
|
+
evidence.push("hostname");
|
|
1049
|
+
}
|
|
1050
|
+
if (evidence.length === 0) continue;
|
|
1051
|
+
const strong = evidence.includes("env-key") || evidence.includes("package");
|
|
1052
|
+
const confidence = strong ? evidence.length >= 2 ? "high" : "medium" : "low";
|
|
1053
|
+
detected.push({ token: signal.token, confidence, evidence });
|
|
1054
|
+
}
|
|
1055
|
+
return detected.sort((a, b) => a.token.localeCompare(b.token));
|
|
1056
|
+
}
|
|
1057
|
+
function collectServiceHostnames(root) {
|
|
1058
|
+
const wanted = /* @__PURE__ */ new Set();
|
|
1059
|
+
for (const signal of SERVICE_SIGNALS) {
|
|
1060
|
+
for (const host of signal.hostnames) wanted.add(host.toLowerCase());
|
|
1061
|
+
}
|
|
1062
|
+
const found = /* @__PURE__ */ new Set();
|
|
1063
|
+
if (wanted.size === 0) return found;
|
|
1064
|
+
let visited = 0;
|
|
1065
|
+
const sourceFiles = collectFiles(
|
|
1066
|
+
root,
|
|
1067
|
+
(relativePath, basename) => {
|
|
1068
|
+
if (visited >= MAX_SERVICE_SCAN_FILES) return true;
|
|
1069
|
+
visited += 1;
|
|
1070
|
+
return !isExcludedServicePath(relativePath) && SERVICE_SOURCE_EXTENSIONS.some((ext) => basename.endsWith(ext));
|
|
1071
|
+
},
|
|
1072
|
+
MAX_SERVICE_HOSTNAME_SAMPLES
|
|
1073
|
+
);
|
|
1074
|
+
for (const relativePath of sourceFiles) {
|
|
1075
|
+
const content = readTextSafe2(path2.join(root, relativePath)).toLowerCase();
|
|
1076
|
+
if (!content) continue;
|
|
1077
|
+
for (const host of wanted) {
|
|
1078
|
+
if (!found.has(host) && content.includes(host)) found.add(host);
|
|
1079
|
+
}
|
|
1080
|
+
if (found.size === wanted.size) break;
|
|
1081
|
+
}
|
|
1082
|
+
return found;
|
|
1083
|
+
}
|
|
1084
|
+
function auditAgentConfig(root) {
|
|
1085
|
+
const agentsPath = path2.join(root, "AGENTS.md");
|
|
1086
|
+
const agentsPresent = existsSync(agentsPath);
|
|
1087
|
+
const agentsContent = agentsPresent ? readTextSafe2(agentsPath, 512e3) : "";
|
|
1088
|
+
const claudePath = path2.join(root, "CLAUDE.md");
|
|
1089
|
+
return {
|
|
1090
|
+
agentsMd: {
|
|
1091
|
+
present: agentsPresent,
|
|
1092
|
+
sizeBytes: agentsPresent ? fileSizeBytes(agentsPath) : 0,
|
|
1093
|
+
hasKnowledgeBlock: agentsContent.includes(KNOWLEDGE_BLOCK_BEGIN)
|
|
1094
|
+
},
|
|
1095
|
+
claudeMd: {
|
|
1096
|
+
present: existsSync(claudePath),
|
|
1097
|
+
sizeBytes: existsSync(claudePath) ? fileSizeBytes(claudePath) : 0
|
|
1098
|
+
},
|
|
1099
|
+
mcpConfigs: MCP_CONFIG_CANDIDATES.filter((candidate) => existsSync(path2.join(root, candidate))),
|
|
1100
|
+
knowledgeManifest: { present: existsSync(knowledgeManifestPath(root)) }
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
function computeStackFingerprint(detection) {
|
|
1104
|
+
const payload = {
|
|
1105
|
+
languages: [...detection.languages].sort(),
|
|
1106
|
+
frameworks: [...detection.frameworks].sort(),
|
|
1107
|
+
sdkTargets: [...detection.sdkTargets].sort()
|
|
1108
|
+
};
|
|
1109
|
+
if (detection.tools && detection.tools.length > 0) payload.tools = [...detection.tools].sort();
|
|
1110
|
+
if (detection.domains && detection.domains.length > 0)
|
|
1111
|
+
payload.domains = [...detection.domains].sort();
|
|
1112
|
+
return createHash("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
|
|
1113
|
+
}
|
|
1114
|
+
function detectStack(cwd, options = {}) {
|
|
1115
|
+
const root = path2.resolve(cwd);
|
|
1116
|
+
const capabilities = options.capabilities ?? detectProjectCapabilities(root);
|
|
1117
|
+
const extracted = extractDirectDependencies(root);
|
|
1118
|
+
const frameworks = detectFrameworks(root, { languages: capabilities.languages, extracted });
|
|
1119
|
+
const sdkTargets = capabilities.languages.includes("swift") ? detectSdkTargets(root) : [];
|
|
1120
|
+
const tools = detectTools(root);
|
|
1121
|
+
const partial = {
|
|
1122
|
+
languages: capabilities.languages,
|
|
1123
|
+
frameworks,
|
|
1124
|
+
sdkTargets,
|
|
1125
|
+
tools
|
|
1126
|
+
};
|
|
1127
|
+
const detectedServices = detectServices(root, dependencyNameSet(extracted));
|
|
1128
|
+
const serviceCandidates = detectServiceCandidates(
|
|
1129
|
+
root,
|
|
1130
|
+
dependencyNameSet(extracted, { npmScopes: true })
|
|
1131
|
+
);
|
|
1132
|
+
const libraryCandidates = selectLongTailLibraries(extracted);
|
|
1133
|
+
return {
|
|
1134
|
+
root,
|
|
1135
|
+
...partial,
|
|
1136
|
+
...detectedServices.length > 0 ? { detectedServices } : {},
|
|
1137
|
+
...serviceCandidates.length > 0 ? { serviceCandidates } : {},
|
|
1138
|
+
...libraryCandidates.length > 0 ? { libraryCandidates } : {},
|
|
1139
|
+
agentConfig: auditAgentConfig(root),
|
|
1140
|
+
fingerprint: computeStackFingerprint(partial)
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
// src/core/stack/declare-hint.ts
|
|
1145
|
+
function isPlaceholderLanguage(language) {
|
|
1146
|
+
return language === "unknown" || language === "docs";
|
|
1147
|
+
}
|
|
1148
|
+
var DECLARE_STACK_EXAMPLE_SPEC = "python,fw:fastapi";
|
|
1149
|
+
var DECLARE_STACK_COMMAND = 'build init knowledge declare "<spec>"';
|
|
1150
|
+
var DECLARE_STACK_BLOCK_HINT = `If the intended stack is already decided, declare it with \`${DECLARE_STACK_COMMAND}\` (for example "${DECLARE_STACK_EXAMPLE_SPEC}"). Optional; this line disappears once a stack is detected or declared.`;
|
|
1151
|
+
|
|
1152
|
+
// src/core/knowledge/intent.ts
|
|
1153
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3, unlinkSync } from "fs";
|
|
1154
|
+
import path3 from "path";
|
|
1155
|
+
import { z } from "zod";
|
|
1156
|
+
var IntentDimensionStatus = z.enum(["active", "satisfied", "conflict", "retired"]);
|
|
1157
|
+
var IntentDimensionSchema = z.object({
|
|
1158
|
+
token: z.string().min(1),
|
|
1159
|
+
dimension: z.enum(STACK_DIMENSIONS),
|
|
1160
|
+
status: IntentDimensionStatus,
|
|
1161
|
+
statusChangedAt: z.string().min(1),
|
|
1162
|
+
/** Present only in `conflict` status. */
|
|
1163
|
+
conflict: z.object({
|
|
1164
|
+
detectedToken: z.string().min(1),
|
|
1165
|
+
acknowledged: z.boolean()
|
|
1166
|
+
}).optional()
|
|
1167
|
+
});
|
|
1168
|
+
var StackIntentContractSchema = z.object({
|
|
1169
|
+
schemaVersion: z.literal(1),
|
|
1170
|
+
/** Verbatim user spec (provenance for notices and doctor). */
|
|
1171
|
+
spec: z.string().min(1),
|
|
1172
|
+
declaredAt: z.string().min(1),
|
|
1173
|
+
/** Optional free-text rationale (`--reason`). */
|
|
1174
|
+
rationale: z.string().optional(),
|
|
1175
|
+
/** Derived, stored for greppability: retired | conflict | active. */
|
|
1176
|
+
status: z.enum(["active", "conflict", "retired"]),
|
|
1177
|
+
dimensions: z.array(IntentDimensionSchema),
|
|
1178
|
+
retiredAt: z.string().nullable()
|
|
1179
|
+
});
|
|
1180
|
+
function stackIntentPath(cwd) {
|
|
1181
|
+
return path3.join(cwd, ".build-project", "context", "knowledge", "stack-intent.json");
|
|
1182
|
+
}
|
|
1183
|
+
function legacyDeclaredStackPath(cwd) {
|
|
1184
|
+
return path3.join(cwd, ".build-project", "state", "declared-stack.json");
|
|
1185
|
+
}
|
|
1186
|
+
function parseIntentSpec(spec) {
|
|
1187
|
+
const rawTokens = spec.split(/[,\s]+/).map((token) => token.trim()).filter((token) => token.length > 0);
|
|
1188
|
+
if (rawTokens.length === 0) {
|
|
1189
|
+
return {
|
|
1190
|
+
ok: false,
|
|
1191
|
+
error: "Empty --stack spec. Example: --stack swift,swiftui,macos-26 or --stack tool:terraform,domain:aws"
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
1195
|
+
for (const raw of rawTokens) {
|
|
1196
|
+
const result = classifyStackToken(raw);
|
|
1197
|
+
if (!result.ok) return { ok: false, error: result.error };
|
|
1198
|
+
const key = `${result.token.dimension}:${result.token.token}`;
|
|
1199
|
+
const existing = byKey.get(key);
|
|
1200
|
+
if (!existing || result.token.explicit && !existing.explicit) {
|
|
1201
|
+
byKey.set(key, result.token);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
const tokens = Array.from(byKey.values());
|
|
1205
|
+
if (!hasStrongAnchor(tokens)) {
|
|
1206
|
+
return {
|
|
1207
|
+
ok: false,
|
|
1208
|
+
error: "--stack needs at least one strong anchor: a known language (swift, python, ...), a versioned platform (macos-26, k8s-1.31), or an explicitly prefixed token (tool:terraform, domain:aws, fw:htmx)."
|
|
1209
|
+
};
|
|
1210
|
+
}
|
|
1211
|
+
return { ok: true, tokens };
|
|
1212
|
+
}
|
|
1213
|
+
function deriveContractStatus(dimensions) {
|
|
1214
|
+
if (dimensions.every((d) => d.status === "retired")) {
|
|
1215
|
+
return "retired";
|
|
1216
|
+
}
|
|
1217
|
+
if (dimensions.some((d) => d.status === "conflict" && d.conflict?.acknowledged !== true)) {
|
|
1218
|
+
return "conflict";
|
|
1219
|
+
}
|
|
1220
|
+
return "active";
|
|
1221
|
+
}
|
|
1222
|
+
function createIntentContract(spec, tokens, options = {}) {
|
|
1223
|
+
const nowIso = (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString();
|
|
1224
|
+
const dimensions = tokens.map((token) => ({
|
|
1225
|
+
token: token.token,
|
|
1226
|
+
dimension: token.dimension,
|
|
1227
|
+
status: "active",
|
|
1228
|
+
statusChangedAt: nowIso
|
|
1229
|
+
}));
|
|
1230
|
+
return {
|
|
1231
|
+
schemaVersion: 1,
|
|
1232
|
+
spec,
|
|
1233
|
+
declaredAt: nowIso,
|
|
1234
|
+
...options.rationale ? { rationale: options.rationale } : {},
|
|
1235
|
+
status: deriveContractStatus(dimensions),
|
|
1236
|
+
dimensions,
|
|
1237
|
+
retiredAt: null
|
|
1238
|
+
};
|
|
1239
|
+
}
|
|
1240
|
+
function readIntentContract(cwd) {
|
|
1241
|
+
const filePath = stackIntentPath(cwd);
|
|
1242
|
+
if (!existsSync2(filePath)) return { status: "absent" };
|
|
1243
|
+
try {
|
|
1244
|
+
const parsed = StackIntentContractSchema.safeParse(JSON.parse(readFileSync3(filePath, "utf8")));
|
|
1245
|
+
if (!parsed.success) {
|
|
1246
|
+
return { status: "invalid", error: parsed.error.issues[0]?.message ?? "schema mismatch" };
|
|
1247
|
+
}
|
|
1248
|
+
return { status: "ok", contract: parsed.data };
|
|
1249
|
+
} catch (error) {
|
|
1250
|
+
return { status: "invalid", error: error instanceof Error ? error.message : String(error) };
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
function writeIntentContract(cwd, contract) {
|
|
1254
|
+
const filePath = stackIntentPath(cwd);
|
|
1255
|
+
atomicWriteJsonSync(filePath, contract);
|
|
1256
|
+
}
|
|
1257
|
+
function removeIntentContract(cwd) {
|
|
1258
|
+
try {
|
|
1259
|
+
unlinkSync(stackIntentPath(cwd));
|
|
1260
|
+
} catch {
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
var LegacyDeclaredSchema = z.object({
|
|
1264
|
+
schemaVersion: z.literal(1),
|
|
1265
|
+
spec: z.string().min(1),
|
|
1266
|
+
declaredAt: z.string().min(1),
|
|
1267
|
+
languages: z.array(z.string()),
|
|
1268
|
+
frameworks: z.array(z.string()),
|
|
1269
|
+
sdkTargets: z.array(z.string())
|
|
1270
|
+
});
|
|
1271
|
+
function migrateLegacyDeclaration(cwd, options = {}) {
|
|
1272
|
+
const legacyPath = legacyDeclaredStackPath(cwd);
|
|
1273
|
+
if (!existsSync2(legacyPath)) return void 0;
|
|
1274
|
+
const existing = readIntentContract(cwd);
|
|
1275
|
+
if (existing.status !== "absent") {
|
|
1276
|
+
if (existing.status === "ok") {
|
|
1277
|
+
try {
|
|
1278
|
+
unlinkSync(legacyPath);
|
|
1279
|
+
} catch {
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
return void 0;
|
|
1283
|
+
}
|
|
1284
|
+
let legacy;
|
|
1285
|
+
try {
|
|
1286
|
+
const parsed = LegacyDeclaredSchema.safeParse(JSON.parse(readFileSync3(legacyPath, "utf8")));
|
|
1287
|
+
if (!parsed.success) return void 0;
|
|
1288
|
+
legacy = parsed.data;
|
|
1289
|
+
} catch {
|
|
1290
|
+
return void 0;
|
|
1291
|
+
}
|
|
1292
|
+
const rawTokens = [...legacy.languages, ...legacy.sdkTargets, ...legacy.frameworks];
|
|
1293
|
+
const tokens = [];
|
|
1294
|
+
for (const raw of rawTokens) {
|
|
1295
|
+
const result = classifyStackToken(raw);
|
|
1296
|
+
if (result.ok) tokens.push(result.token);
|
|
1297
|
+
}
|
|
1298
|
+
if (tokens.length === 0) return void 0;
|
|
1299
|
+
const contract = createIntentContract(legacy.spec, tokens, { now: options.now });
|
|
1300
|
+
const migrated = { ...contract, declaredAt: legacy.declaredAt };
|
|
1301
|
+
writeIntentContract(cwd, migrated);
|
|
1302
|
+
try {
|
|
1303
|
+
unlinkSync(legacyPath);
|
|
1304
|
+
} catch {
|
|
1305
|
+
}
|
|
1306
|
+
return migrated;
|
|
1307
|
+
}
|
|
1308
|
+
function resolveIntent(detection, contract, options = {}) {
|
|
1309
|
+
const nowIso = (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString();
|
|
1310
|
+
const detectedLanguages = new Set(detection.languages);
|
|
1311
|
+
const detectedFrameworks = new Set(detection.frameworks);
|
|
1312
|
+
const detectedSdk = new Set(detection.sdkTargets);
|
|
1313
|
+
const detectedTools = new Set(detection.tools ?? []);
|
|
1314
|
+
const detectedDomains = new Set(detection.domains ?? []);
|
|
1315
|
+
const detectedSdkByPlatform = /* @__PURE__ */ new Map();
|
|
1316
|
+
for (const target of detection.sdkTargets) {
|
|
1317
|
+
detectedSdkByPlatform.set(sdkPlatform(target), target);
|
|
1318
|
+
}
|
|
1319
|
+
const languages = new Set(detection.languages);
|
|
1320
|
+
const frameworks = new Set(detection.frameworks);
|
|
1321
|
+
const sdkTargets = new Set(detection.sdkTargets);
|
|
1322
|
+
const tools = new Set(detection.tools ?? []);
|
|
1323
|
+
const domains = new Set(detection.domains ?? []);
|
|
1324
|
+
const acknowledgedSdkPairs = [...detection.acknowledgedSdkPairs ?? []];
|
|
1325
|
+
const conflicts = [];
|
|
1326
|
+
let contractChanged = false;
|
|
1327
|
+
let declaredRealLanguage = false;
|
|
1328
|
+
const dimensions = contract.dimensions.map((dim) => {
|
|
1329
|
+
if (dim.status === "retired") return dim;
|
|
1330
|
+
const setStatus = (status, conflict) => {
|
|
1331
|
+
const unchanged = dim.status === status && dim.conflict?.detectedToken === conflict?.detectedToken && dim.conflict?.acknowledged === conflict?.acknowledged;
|
|
1332
|
+
if (unchanged) return dim;
|
|
1333
|
+
contractChanged = true;
|
|
1334
|
+
return {
|
|
1335
|
+
...dim,
|
|
1336
|
+
status,
|
|
1337
|
+
statusChangedAt: nowIso,
|
|
1338
|
+
...conflict ? { conflict } : { conflict: void 0 }
|
|
1339
|
+
};
|
|
1340
|
+
};
|
|
1341
|
+
switch (dim.dimension) {
|
|
1342
|
+
case "lang": {
|
|
1343
|
+
declaredRealLanguage = true;
|
|
1344
|
+
if (detectedLanguages.has(dim.token)) {
|
|
1345
|
+
return setStatus("satisfied");
|
|
1346
|
+
}
|
|
1347
|
+
languages.add(dim.token);
|
|
1348
|
+
return setStatus("active");
|
|
1349
|
+
}
|
|
1350
|
+
case "fw": {
|
|
1351
|
+
if (detectedFrameworks.has(dim.token)) return setStatus("satisfied");
|
|
1352
|
+
frameworks.add(dim.token);
|
|
1353
|
+
return setStatus("active");
|
|
1354
|
+
}
|
|
1355
|
+
case "tool": {
|
|
1356
|
+
if (detectedTools.has(dim.token)) return setStatus("satisfied");
|
|
1357
|
+
tools.add(dim.token);
|
|
1358
|
+
return setStatus("active");
|
|
1359
|
+
}
|
|
1360
|
+
case "domain": {
|
|
1361
|
+
if (detectedDomains.has(dim.token)) return setStatus("satisfied");
|
|
1362
|
+
domains.add(dim.token);
|
|
1363
|
+
return setStatus("active");
|
|
1364
|
+
}
|
|
1365
|
+
case "sdk": {
|
|
1366
|
+
if (detectedSdk.has(dim.token)) return setStatus("satisfied");
|
|
1367
|
+
const platform = sdkPlatform(dim.token);
|
|
1368
|
+
const detectedSame = detectedSdkByPlatform.get(platform);
|
|
1369
|
+
if (!detectedSame) {
|
|
1370
|
+
sdkTargets.add(dim.token);
|
|
1371
|
+
return setStatus("active");
|
|
1372
|
+
}
|
|
1373
|
+
const acknowledged = dim.conflict?.acknowledged === true && dim.conflict.detectedToken === detectedSame;
|
|
1374
|
+
if (acknowledged) {
|
|
1375
|
+
sdkTargets.add(dim.token);
|
|
1376
|
+
acknowledgedSdkPairs.push({
|
|
1377
|
+
platform,
|
|
1378
|
+
sdkVersion: sdkVersion(dim.token),
|
|
1379
|
+
deploymentVersion: sdkVersion(detectedSame)
|
|
1380
|
+
});
|
|
1381
|
+
return setStatus("conflict", { detectedToken: detectedSame, acknowledged: true });
|
|
1382
|
+
}
|
|
1383
|
+
const next = setStatus("conflict", { detectedToken: detectedSame, acknowledged: false });
|
|
1384
|
+
conflicts.push({ dimension: next, detectedToken: detectedSame });
|
|
1385
|
+
return next;
|
|
1386
|
+
}
|
|
1387
|
+
default: {
|
|
1388
|
+
const exhaustive = dim.dimension;
|
|
1389
|
+
return exhaustive;
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
});
|
|
1393
|
+
if (declaredRealLanguage) {
|
|
1394
|
+
languages.delete("docs");
|
|
1395
|
+
languages.delete("unknown");
|
|
1396
|
+
if (languages.size === 0) {
|
|
1397
|
+
for (const dim of dimensions) {
|
|
1398
|
+
if (dim.dimension === "lang") {
|
|
1399
|
+
languages.add(dim.token);
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
const partial = {
|
|
1405
|
+
languages: Array.from(languages).sort(),
|
|
1406
|
+
frameworks: Array.from(frameworks).sort(),
|
|
1407
|
+
sdkTargets: Array.from(sdkTargets).sort(),
|
|
1408
|
+
tools: Array.from(tools).sort(),
|
|
1409
|
+
domains: Array.from(domains).sort()
|
|
1410
|
+
};
|
|
1411
|
+
const updatedContract = {
|
|
1412
|
+
...contract,
|
|
1413
|
+
status: deriveContractStatus(dimensions),
|
|
1414
|
+
dimensions
|
|
1415
|
+
};
|
|
1416
|
+
if (updatedContract.status !== contract.status) contractChanged = true;
|
|
1417
|
+
const effective = {
|
|
1418
|
+
...detection,
|
|
1419
|
+
...partial,
|
|
1420
|
+
...acknowledgedSdkPairs.length > 0 ? { acknowledgedSdkPairs } : {},
|
|
1421
|
+
fingerprint: computeStackFingerprint(partial)
|
|
1422
|
+
};
|
|
1423
|
+
const dimensionDone = (d) => d.status === "satisfied" || d.status === "retired" || d.status === "conflict" && d.conflict?.acknowledged === true;
|
|
1424
|
+
const allCovered = dimensions.every(dimensionDone);
|
|
1425
|
+
const allSatisfied = allCovered || dimensions.every(
|
|
1426
|
+
(d) => dimensionDone(d) || !isGatingToken({ token: d.token, dimension: d.dimension, explicit: true })
|
|
1427
|
+
);
|
|
1428
|
+
return {
|
|
1429
|
+
effective,
|
|
1430
|
+
contract: updatedContract,
|
|
1431
|
+
contractChanged,
|
|
1432
|
+
conflicts,
|
|
1433
|
+
allSatisfied,
|
|
1434
|
+
allCovered
|
|
1435
|
+
};
|
|
1436
|
+
}
|
|
1437
|
+
function retireContract(contract, options = {}) {
|
|
1438
|
+
const nowIso = (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString();
|
|
1439
|
+
return {
|
|
1440
|
+
...contract,
|
|
1441
|
+
status: "retired",
|
|
1442
|
+
retiredAt: nowIso,
|
|
1443
|
+
dimensions: contract.dimensions.map(
|
|
1444
|
+
(dim) => dim.status === "retired" ? dim : { ...dim, status: "retired", statusChangedAt: nowIso }
|
|
1445
|
+
)
|
|
1446
|
+
};
|
|
1447
|
+
}
|
|
1448
|
+
function acknowledgeConflicts(contract, options = {}) {
|
|
1449
|
+
const nowIso = (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString();
|
|
1450
|
+
const dimensions = contract.dimensions.map((dim) => {
|
|
1451
|
+
if (dim.status !== "conflict" || dim.conflict?.acknowledged === true) return dim;
|
|
1452
|
+
return {
|
|
1453
|
+
...dim,
|
|
1454
|
+
statusChangedAt: nowIso,
|
|
1455
|
+
conflict: {
|
|
1456
|
+
...dim.conflict,
|
|
1457
|
+
acknowledged: true
|
|
1458
|
+
}
|
|
1459
|
+
};
|
|
1460
|
+
});
|
|
1461
|
+
return { ...contract, status: deriveContractStatus(dimensions), dimensions };
|
|
1462
|
+
}
|
|
1463
|
+
function acceptDetectedReality(contract, options = {}) {
|
|
1464
|
+
const nowIso = (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString();
|
|
1465
|
+
const dimensions = contract.dimensions.map((dim) => {
|
|
1466
|
+
if (dim.status !== "conflict") return dim;
|
|
1467
|
+
return { ...dim, status: "retired", statusChangedAt: nowIso, conflict: void 0 };
|
|
1468
|
+
});
|
|
1469
|
+
return { ...contract, status: deriveContractStatus(dimensions), dimensions };
|
|
1470
|
+
}
|
|
1471
|
+
function describeDimension(dim) {
|
|
1472
|
+
const base = `${dim.token.padEnd(12)} ${dim.dimension.padEnd(6)} ${dim.status}`;
|
|
1473
|
+
if (dim.status === "conflict" && dim.conflict) {
|
|
1474
|
+
const ack = dim.conflict.acknowledged ? " (acknowledged)" : "";
|
|
1475
|
+
return `${base}${ack} \u2014 detected ${dim.conflict.detectedToken}`;
|
|
1476
|
+
}
|
|
1477
|
+
if (dim.status === "active") return `${base} (not yet in code)`;
|
|
1478
|
+
return base;
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
// src/core/knowledge/resolved-detection.ts
|
|
1482
|
+
import { existsSync as existsSync3 } from "fs";
|
|
1483
|
+
function emptyStackDetection(root) {
|
|
1484
|
+
return {
|
|
1485
|
+
root,
|
|
1486
|
+
languages: [],
|
|
1487
|
+
frameworks: [],
|
|
1488
|
+
sdkTargets: [],
|
|
1489
|
+
tools: [],
|
|
1490
|
+
domains: [],
|
|
1491
|
+
fingerprint: "",
|
|
1492
|
+
agentConfig: {
|
|
1493
|
+
agentsMd: { present: false, sizeBytes: 0, hasKnowledgeBlock: false },
|
|
1494
|
+
claudeMd: { present: false, sizeBytes: 0 },
|
|
1495
|
+
mcpConfigs: [],
|
|
1496
|
+
knowledgeManifest: { present: false }
|
|
1497
|
+
}
|
|
1498
|
+
};
|
|
1499
|
+
}
|
|
1500
|
+
function resolvedStackDetection(cwd, options = {}) {
|
|
1501
|
+
let detection;
|
|
1502
|
+
try {
|
|
1503
|
+
detection = detectStack(cwd, options);
|
|
1504
|
+
} catch {
|
|
1505
|
+
return emptyStackDetection(cwd);
|
|
1506
|
+
}
|
|
1507
|
+
try {
|
|
1508
|
+
const stored = readIntentContract(cwd);
|
|
1509
|
+
if (stored.status !== "ok" || stored.contract.status === "retired") {
|
|
1510
|
+
return detection;
|
|
1511
|
+
}
|
|
1512
|
+
return resolveIntent(detection, stored.contract).effective;
|
|
1513
|
+
} catch {
|
|
1514
|
+
return detection;
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
function isStackUndetectedAndUndeclared(cwd) {
|
|
1518
|
+
try {
|
|
1519
|
+
const d = detectStack(cwd);
|
|
1520
|
+
const detected = d.languages.filter((language) => !isPlaceholderLanguage(language)).length + d.frameworks.length + d.sdkTargets.length + (d.tools ?? []).length + (d.domains ?? []).length;
|
|
1521
|
+
if (detected > 0) return false;
|
|
1522
|
+
if (existsSync3(legacyDeclaredStackPath(cwd))) return false;
|
|
1523
|
+
const stored = readIntentContract(cwd);
|
|
1524
|
+
return !(stored.status === "ok" && stored.contract.status !== "retired");
|
|
1525
|
+
} catch {
|
|
1526
|
+
return false;
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
// src/core/init-drift/state.ts
|
|
1531
|
+
import fs from "fs";
|
|
1532
|
+
import path5 from "path";
|
|
1533
|
+
|
|
1534
|
+
// src/core/init-drift/fingerprint.ts
|
|
1535
|
+
import { createHash as createHash2 } from "crypto";
|
|
1536
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync4, statSync as statSync2 } from "fs";
|
|
1537
|
+
import path4 from "path";
|
|
1538
|
+
var STACK_FINGERPRINT_VERSION = 1;
|
|
1539
|
+
var STACK_FILE_NAMES = [
|
|
1540
|
+
"package.json",
|
|
1541
|
+
"package-lock.json",
|
|
1542
|
+
"pnpm-lock.yaml",
|
|
1543
|
+
"yarn.lock",
|
|
1544
|
+
"bun.lock",
|
|
1545
|
+
"bun.lockb",
|
|
1546
|
+
"pyproject.toml",
|
|
1547
|
+
"poetry.lock",
|
|
1548
|
+
"uv.lock",
|
|
1549
|
+
"Pipfile",
|
|
1550
|
+
"Pipfile.lock",
|
|
1551
|
+
"go.mod",
|
|
1552
|
+
"go.sum",
|
|
1553
|
+
"Cargo.toml",
|
|
1554
|
+
"Cargo.lock",
|
|
1555
|
+
"Package.swift",
|
|
1556
|
+
"Package.resolved",
|
|
1557
|
+
"Gemfile",
|
|
1558
|
+
"Gemfile.lock",
|
|
1559
|
+
"composer.json",
|
|
1560
|
+
"composer.lock",
|
|
1561
|
+
"Dockerfile"
|
|
1562
|
+
];
|
|
1563
|
+
var REQUIREMENTS_PATTERN = /^requirements[\w.-]*\.(?:txt|in)$/i;
|
|
1564
|
+
var FRAMEWORK_SIGNAL_KEYS = [
|
|
1565
|
+
"tsconfig",
|
|
1566
|
+
"gradle",
|
|
1567
|
+
"pomXml",
|
|
1568
|
+
"cmakeLists",
|
|
1569
|
+
"mesonBuild",
|
|
1570
|
+
"dotnetSolution",
|
|
1571
|
+
"dotnetProject",
|
|
1572
|
+
"pubspecYaml",
|
|
1573
|
+
"dbtProject",
|
|
1574
|
+
"terraform",
|
|
1575
|
+
"kubernetesManifests"
|
|
1576
|
+
];
|
|
1577
|
+
function hashFileContent(filePath) {
|
|
1578
|
+
try {
|
|
1579
|
+
const content = readFileSync4(filePath);
|
|
1580
|
+
return createHash2("sha256").update(content).digest("hex");
|
|
1581
|
+
} catch {
|
|
1582
|
+
return void 0;
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
function listRootEntries(root) {
|
|
1586
|
+
try {
|
|
1587
|
+
return readdirSync2(root, { withFileTypes: true });
|
|
1588
|
+
} catch {
|
|
1589
|
+
return [];
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
function isDirectoryEntry(root, entry) {
|
|
1593
|
+
if (entry.isDirectory()) return true;
|
|
1594
|
+
if (!entry.isSymbolicLink()) return false;
|
|
1595
|
+
try {
|
|
1596
|
+
return statSync2(path4.join(root, entry.name)).isDirectory();
|
|
1597
|
+
} catch {
|
|
1598
|
+
return false;
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
function sortedRecord(record) {
|
|
1602
|
+
const out = {};
|
|
1603
|
+
for (const key of Object.keys(record).sort()) {
|
|
1604
|
+
const value = record[key];
|
|
1605
|
+
if (value !== void 0) out[key] = value;
|
|
1606
|
+
}
|
|
1607
|
+
return out;
|
|
1608
|
+
}
|
|
1609
|
+
function computeStackFingerprint2(cwd) {
|
|
1610
|
+
const root = path4.resolve(cwd);
|
|
1611
|
+
const manifests = {};
|
|
1612
|
+
const fileHashes = {};
|
|
1613
|
+
const recordFile = (relativeName) => {
|
|
1614
|
+
const hash = hashFileContent(path4.join(root, relativeName));
|
|
1615
|
+
if (hash === void 0) return;
|
|
1616
|
+
manifests[relativeName] = true;
|
|
1617
|
+
fileHashes[relativeName] = hash;
|
|
1618
|
+
};
|
|
1619
|
+
for (const name of STACK_FILE_NAMES) {
|
|
1620
|
+
recordFile(name);
|
|
1621
|
+
}
|
|
1622
|
+
const rootEntries = listRootEntries(root);
|
|
1623
|
+
for (const entry of rootEntries) {
|
|
1624
|
+
if (REQUIREMENTS_PATTERN.test(entry.name) && !manifests[entry.name]) {
|
|
1625
|
+
recordFile(entry.name);
|
|
1626
|
+
continue;
|
|
1627
|
+
}
|
|
1628
|
+
if (/\.xcodeproj$/i.test(entry.name) && isDirectoryEntry(root, entry)) {
|
|
1629
|
+
manifests[entry.name] = true;
|
|
1630
|
+
const pbxprojRelative = path4.join(entry.name, "project.pbxproj");
|
|
1631
|
+
const hash = hashFileContent(path4.join(root, pbxprojRelative));
|
|
1632
|
+
if (hash !== void 0) fileHashes[pbxprojRelative] = hash;
|
|
1633
|
+
continue;
|
|
1634
|
+
}
|
|
1635
|
+
if (/\.xcworkspace$/i.test(entry.name) && isDirectoryEntry(root, entry)) {
|
|
1636
|
+
manifests[entry.name] = true;
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
const capabilities = detectProjectCapabilities(root);
|
|
1640
|
+
const languages = [...capabilities.languages].sort();
|
|
1641
|
+
const capabilityManifests = capabilities.manifests;
|
|
1642
|
+
const frameworks = [
|
|
1643
|
+
...FRAMEWORK_SIGNAL_KEYS.filter((key) => capabilityManifests[key] === true),
|
|
1644
|
+
...detectFrameworks(root, { languages: capabilities.languages })
|
|
1645
|
+
].sort();
|
|
1646
|
+
return {
|
|
1647
|
+
version: STACK_FINGERPRINT_VERSION,
|
|
1648
|
+
languages,
|
|
1649
|
+
frameworks,
|
|
1650
|
+
manifests: sortedRecord(manifests),
|
|
1651
|
+
fileHashes: sortedRecord(fileHashes)
|
|
1652
|
+
};
|
|
1653
|
+
}
|
|
1654
|
+
function fingerprintDigest(fingerprint) {
|
|
1655
|
+
return createHash2("sha256").update(JSON.stringify(fingerprint)).digest("hex");
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1658
|
+
// src/core/init-drift/state.ts
|
|
1659
|
+
var DEFAULT_NUDGE_CAP = 100;
|
|
1660
|
+
var DELIVERED_NUDGE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
1661
|
+
function isStackDriftKind(kind) {
|
|
1662
|
+
return kind !== "ci-setup" && kind !== "context-blocks-stale";
|
|
1663
|
+
}
|
|
1664
|
+
function resolveStateDir(cwd) {
|
|
1665
|
+
return path5.join(path5.resolve(cwd), ".build-project", "state");
|
|
1666
|
+
}
|
|
1667
|
+
function resolveInitFingerprintPath(cwd) {
|
|
1668
|
+
return path5.join(resolveStateDir(cwd), "init-fingerprint.json");
|
|
1669
|
+
}
|
|
1670
|
+
function resolveInitNudgesPath(cwd) {
|
|
1671
|
+
return path5.join(resolveStateDir(cwd), "init-nudges.json");
|
|
1672
|
+
}
|
|
1673
|
+
function readJsonFile(filePath) {
|
|
1674
|
+
try {
|
|
1675
|
+
return JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
1676
|
+
} catch {
|
|
1677
|
+
return void 0;
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
function writeJsonFile(filePath, value) {
|
|
1681
|
+
fs.mkdirSync(path5.dirname(filePath), { recursive: true });
|
|
1682
|
+
fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}
|
|
1683
|
+
`, "utf-8");
|
|
1684
|
+
}
|
|
1685
|
+
function isRecord(value) {
|
|
1686
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1687
|
+
}
|
|
1688
|
+
function readStoredFingerprint(cwd) {
|
|
1689
|
+
const parsed = readJsonFile(resolveInitFingerprintPath(cwd));
|
|
1690
|
+
if (!isRecord(parsed)) return void 0;
|
|
1691
|
+
const fingerprint = parsed.fingerprint;
|
|
1692
|
+
if (!isRecord(fingerprint)) return void 0;
|
|
1693
|
+
if (!Array.isArray(fingerprint.languages) || !Array.isArray(fingerprint.frameworks) || !isRecord(fingerprint.manifests) || !isRecord(fingerprint.fileHashes)) {
|
|
1694
|
+
return void 0;
|
|
1695
|
+
}
|
|
1696
|
+
const stored = fingerprint;
|
|
1697
|
+
return {
|
|
1698
|
+
fingerprint: stored,
|
|
1699
|
+
digest: typeof parsed.digest === "string" ? parsed.digest : fingerprintDigest(stored),
|
|
1700
|
+
recordedAtMs: typeof parsed.recordedAtMs === "number" ? parsed.recordedAtMs : 0
|
|
1701
|
+
};
|
|
1702
|
+
}
|
|
1703
|
+
function writeStoredFingerprint(cwd, fingerprint, options = {}) {
|
|
1704
|
+
const now = options.now ?? Date.now;
|
|
1705
|
+
const file = {
|
|
1706
|
+
version: 1,
|
|
1707
|
+
digest: fingerprintDigest(fingerprint),
|
|
1708
|
+
recordedAtMs: now(),
|
|
1709
|
+
fingerprint
|
|
1710
|
+
};
|
|
1711
|
+
writeJsonFile(resolveInitFingerprintPath(cwd), file);
|
|
1712
|
+
}
|
|
1713
|
+
function isDriftRecord(value) {
|
|
1714
|
+
if (!isRecord(value)) return false;
|
|
1715
|
+
return typeof value.key === "string" && typeof value.kind === "string" && typeof value.subject === "string" && (value.change === "added" || value.change === "removed") && Array.isArray(value.evidence) && typeof value.detectedAtMs === "number";
|
|
1716
|
+
}
|
|
1717
|
+
function isDeliveryRecord(value) {
|
|
1718
|
+
if (!isRecord(value)) return false;
|
|
1719
|
+
return typeof value.key === "string" && typeof value.deliveredAtMs === "number" && typeof value.driftDetectedAtMs === "number";
|
|
1720
|
+
}
|
|
1721
|
+
function readNudgeState(cwd) {
|
|
1722
|
+
const parsed = readJsonFile(resolveInitNudgesPath(cwd));
|
|
1723
|
+
const state = { version: 1, drift: {}, deliveries: {} };
|
|
1724
|
+
if (!isRecord(parsed)) return state;
|
|
1725
|
+
if (isRecord(parsed.drift)) {
|
|
1726
|
+
for (const [key, value] of Object.entries(parsed.drift)) {
|
|
1727
|
+
if (isDriftRecord(value)) state.drift[key] = value;
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
if (isRecord(parsed.deliveries)) {
|
|
1731
|
+
for (const [key, value] of Object.entries(parsed.deliveries)) {
|
|
1732
|
+
if (isDeliveryRecord(value)) state.deliveries[key] = value;
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
return state;
|
|
1736
|
+
}
|
|
1737
|
+
function isDelivered(record, deliveries) {
|
|
1738
|
+
const delivery = deliveries[record.key];
|
|
1739
|
+
return delivery !== void 0 && delivery.driftDetectedAtMs === record.detectedAtMs;
|
|
1740
|
+
}
|
|
1741
|
+
function pruneNudgeState(state, nowMs, cap, ttlMs) {
|
|
1742
|
+
const drift = {};
|
|
1743
|
+
for (const [key, record] of Object.entries(state.drift)) {
|
|
1744
|
+
if (isDelivered(record, state.deliveries)) {
|
|
1745
|
+
const delivery = state.deliveries[key];
|
|
1746
|
+
const age = nowMs - (delivery?.deliveredAtMs ?? nowMs);
|
|
1747
|
+
if (age >= ttlMs && record.kind !== "ci-setup") continue;
|
|
1748
|
+
}
|
|
1749
|
+
drift[key] = record;
|
|
1750
|
+
}
|
|
1751
|
+
const entries = Object.entries(drift);
|
|
1752
|
+
if (entries.length > cap) {
|
|
1753
|
+
const byOldestFirst = (a, b) => a[1].detectedAtMs - b[1].detectedAtMs;
|
|
1754
|
+
const delivered = entries.filter(([, r]) => isDelivered(r, state.deliveries));
|
|
1755
|
+
const undelivered = entries.filter(([, r]) => !isDelivered(r, state.deliveries));
|
|
1756
|
+
delivered.sort(byOldestFirst);
|
|
1757
|
+
undelivered.sort(byOldestFirst);
|
|
1758
|
+
let excess = entries.length - cap;
|
|
1759
|
+
for (const [key] of delivered) {
|
|
1760
|
+
if (excess <= 0) break;
|
|
1761
|
+
delete drift[key];
|
|
1762
|
+
excess -= 1;
|
|
1763
|
+
}
|
|
1764
|
+
for (const [key] of undelivered) {
|
|
1765
|
+
if (excess <= 0) break;
|
|
1766
|
+
delete drift[key];
|
|
1767
|
+
excess -= 1;
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
const deliveries = {};
|
|
1771
|
+
for (const [key, delivery] of Object.entries(state.deliveries)) {
|
|
1772
|
+
if (drift[key] !== void 0) deliveries[key] = delivery;
|
|
1773
|
+
}
|
|
1774
|
+
return { version: 1, drift, deliveries };
|
|
1775
|
+
}
|
|
1776
|
+
function writeNudgeState(cwd, state, options) {
|
|
1777
|
+
const now = options.now ?? Date.now;
|
|
1778
|
+
const cap = options.cap ?? DEFAULT_NUDGE_CAP;
|
|
1779
|
+
const ttlMs = options.ttlMs ?? DELIVERED_NUDGE_TTL_MS;
|
|
1780
|
+
writeJsonFile(resolveInitNudgesPath(cwd), pruneNudgeState(state, now(), cap, ttlMs));
|
|
1781
|
+
}
|
|
1782
|
+
function recordDriftRecords(cwd, records, options = {}) {
|
|
1783
|
+
if (records.length === 0) return;
|
|
1784
|
+
const state = readNudgeState(cwd);
|
|
1785
|
+
for (const record of records) {
|
|
1786
|
+
state.drift[record.key] = record;
|
|
1787
|
+
}
|
|
1788
|
+
writeNudgeState(cwd, state, options);
|
|
1789
|
+
}
|
|
1790
|
+
function readDriftRecord(cwd, key) {
|
|
1791
|
+
const state = readNudgeState(cwd);
|
|
1792
|
+
const record = state.drift[key];
|
|
1793
|
+
return record ? { record, delivered: isDelivered(record, state.deliveries) } : void 0;
|
|
1794
|
+
}
|
|
1795
|
+
function forgetDriftRecord(cwd, key) {
|
|
1796
|
+
const state = readNudgeState(cwd);
|
|
1797
|
+
if (!state.drift[key]) return;
|
|
1798
|
+
delete state.drift[key];
|
|
1799
|
+
delete state.deliveries[key];
|
|
1800
|
+
writeNudgeState(cwd, state, {});
|
|
1801
|
+
}
|
|
1802
|
+
function listPendingDrift(cwd, options = {}) {
|
|
1803
|
+
const now = options.now ?? Date.now;
|
|
1804
|
+
const nowMs = now();
|
|
1805
|
+
const state = readNudgeState(cwd);
|
|
1806
|
+
return Object.values(state.drift).filter((record) => !isDelivered(record, state.deliveries)).sort((a, b) => a.detectedAtMs - b.detectedAtMs).map((record) => ({ ...record, ageMs: Math.max(0, nowMs - record.detectedAtMs) }));
|
|
1807
|
+
}
|
|
1808
|
+
function recordDelivery(cwd, keys, options = {}) {
|
|
1809
|
+
if (keys.length === 0) return;
|
|
1810
|
+
const now = options.now ?? Date.now;
|
|
1811
|
+
const nowMs = now();
|
|
1812
|
+
const state = readNudgeState(cwd);
|
|
1813
|
+
let changed = false;
|
|
1814
|
+
for (const key of keys) {
|
|
1815
|
+
const record = state.drift[key];
|
|
1816
|
+
if (record === void 0) continue;
|
|
1817
|
+
state.deliveries[key] = {
|
|
1818
|
+
key,
|
|
1819
|
+
deliveredAtMs: nowMs,
|
|
1820
|
+
driftDetectedAtMs: record.detectedAtMs
|
|
1821
|
+
};
|
|
1822
|
+
changed = true;
|
|
1823
|
+
}
|
|
1824
|
+
if (changed) writeNudgeState(cwd, state, options);
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
// src/core/context/render-stack-block.ts
|
|
1828
|
+
var STACK_BLOCK_MARKERS = {
|
|
1829
|
+
begin: "<!-- build-context-stack:begin -->",
|
|
1830
|
+
end: "<!-- build-context-stack:end -->"
|
|
1831
|
+
};
|
|
1832
|
+
var IDENTIFIER_PATTERN = /^[a-z0-9][a-z0-9.+-]*$/i;
|
|
1833
|
+
var MAX_IDENTIFIER_LENGTH = 64;
|
|
1834
|
+
function isSafeStackIdentifier(value) {
|
|
1835
|
+
return value.length > 0 && value.length <= MAX_IDENTIFIER_LENGTH && IDENTIFIER_PATTERN.test(value);
|
|
1836
|
+
}
|
|
1837
|
+
function renderStackContextBlock(input) {
|
|
1838
|
+
const lines = ["## Detected stack (managed by Build)", ""];
|
|
1839
|
+
const languages = input.languages.filter(isSafeStackIdentifier);
|
|
1840
|
+
const frameworks = input.frameworks.filter(isSafeStackIdentifier);
|
|
1841
|
+
const tools = (input.tools ?? []).filter(isSafeStackIdentifier);
|
|
1842
|
+
const domains = (input.domains ?? []).filter(isSafeStackIdentifier);
|
|
1843
|
+
const sdkTargets = (input.sdkTargets ?? []).filter(isSafeStackIdentifier);
|
|
1844
|
+
const dimensions = [
|
|
1845
|
+
["Languages", languages],
|
|
1846
|
+
["Frameworks", frameworks],
|
|
1847
|
+
["Tools", tools],
|
|
1848
|
+
["Domains", domains],
|
|
1849
|
+
["SDK targets", sdkTargets]
|
|
1850
|
+
];
|
|
1851
|
+
const present = dimensions.filter(([, values]) => values.length > 0);
|
|
1852
|
+
if (present.length === 0) {
|
|
1853
|
+
lines.push("No stack dimensions detected.");
|
|
1854
|
+
} else {
|
|
1855
|
+
for (const [label, values] of present) {
|
|
1856
|
+
lines.push(`${label}: ${values.join(", ")}`);
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
const stackKnown = languages.some((language) => !isPlaceholderLanguage(language)) || frameworks.length + tools.length + domains.length + sdkTargets.length > 0;
|
|
1860
|
+
if (!stackKnown) lines.push(DECLARE_STACK_BLOCK_HINT);
|
|
1861
|
+
lines.push(
|
|
1862
|
+
"",
|
|
1863
|
+
"Do not edit inside this block \u2014 it is regenerated by `build init`. Full detail lives in .build-project/context/stack.md."
|
|
1864
|
+
);
|
|
1865
|
+
return lines.join("\n");
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
// src/core/knowledge/sdk-pair.ts
|
|
1869
|
+
function renderAcknowledgedSdkPair(pair) {
|
|
1870
|
+
if (!isSafeStackIdentifier(pair.platform) || !isSafeStackIdentifier(pair.sdkVersion) || !isSafeStackIdentifier(pair.deploymentVersion)) {
|
|
1871
|
+
return "";
|
|
1872
|
+
}
|
|
1873
|
+
return `${pair.platform} ${pair.sdkVersion} SDK targeting ${pair.platform} ${pair.deploymentVersion} deployment`;
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
// src/core/context/stack.ts
|
|
1877
|
+
import path6 from "path";
|
|
1878
|
+
|
|
1879
|
+
// src/core/context/render-stack-md.ts
|
|
1880
|
+
var STACK_MD_GENERATED_HEADER = "<!-- Generated by build init. Do not edit; re-run build init to regenerate. -->";
|
|
1881
|
+
function renderStackMarkdown(input) {
|
|
1882
|
+
const lines = [
|
|
1883
|
+
STACK_MD_GENERATED_HEADER,
|
|
1884
|
+
"",
|
|
1885
|
+
"# Stack",
|
|
1886
|
+
"",
|
|
1887
|
+
`Fingerprint: ${input.fingerprint}`,
|
|
1888
|
+
"",
|
|
1889
|
+
"## Languages",
|
|
1890
|
+
""
|
|
1891
|
+
];
|
|
1892
|
+
if (input.languages.length === 0) {
|
|
1893
|
+
lines.push("None detected.");
|
|
1894
|
+
} else {
|
|
1895
|
+
for (const language of [...input.languages].sort()) {
|
|
1896
|
+
lines.push(`- ${language}`);
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
lines.push("", "## Frameworks", "");
|
|
1900
|
+
if (input.frameworks.length === 0) {
|
|
1901
|
+
lines.push("None detected.");
|
|
1902
|
+
} else {
|
|
1903
|
+
for (const framework of [...input.frameworks].sort()) {
|
|
1904
|
+
lines.push(`- ${framework}`);
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
if (input.tools.length > 0) {
|
|
1908
|
+
lines.push("", "## Tools", "");
|
|
1909
|
+
for (const tool of [...input.tools].sort()) {
|
|
1910
|
+
lines.push(`- ${tool}`);
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
if (input.domains.length > 0) {
|
|
1914
|
+
lines.push("", "## Domains", "");
|
|
1915
|
+
for (const domain of [...input.domains].sort()) {
|
|
1916
|
+
lines.push(`- ${domain}`);
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
if (input.sdkTargets.length > 0) {
|
|
1920
|
+
lines.push("", "## SDK targets", "");
|
|
1921
|
+
for (const target of [...input.sdkTargets].sort()) {
|
|
1922
|
+
lines.push(`- ${target}`);
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
lines.push("");
|
|
1926
|
+
return lines.join("\n");
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1929
|
+
// src/core/context/stack.ts
|
|
1930
|
+
var STACK_MD_FILENAME = "stack.md";
|
|
1931
|
+
function stackMarkdownPath(root) {
|
|
1932
|
+
return path6.join(root, CONTEXT_DIR, STACK_MD_FILENAME);
|
|
1933
|
+
}
|
|
1934
|
+
function stackDimensions(detection) {
|
|
1935
|
+
return {
|
|
1936
|
+
languages: [...detection.languages],
|
|
1937
|
+
frameworks: [...detection.frameworks],
|
|
1938
|
+
tools: [...detection.tools ?? []],
|
|
1939
|
+
domains: [...detection.domains ?? []],
|
|
1940
|
+
sdkTargets: [...detection.sdkTargets]
|
|
1941
|
+
};
|
|
1942
|
+
}
|
|
1943
|
+
function renderStackAgentsBlock(detection) {
|
|
1944
|
+
return renderStackContextBlock(stackDimensions(detection));
|
|
1945
|
+
}
|
|
1946
|
+
async function writeStackContext(root, detection) {
|
|
1947
|
+
const markdown = renderStackMarkdown({
|
|
1948
|
+
...stackDimensions(detection),
|
|
1949
|
+
fingerprint: detection.fingerprint
|
|
1950
|
+
});
|
|
1951
|
+
const target = stackMarkdownPath(root);
|
|
1952
|
+
await atomicWriteText(target, markdown, { trailingNewline: false });
|
|
1953
|
+
return target;
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
// src/core/ci/integration/messages.ts
|
|
1957
|
+
var MESSAGES = {
|
|
1958
|
+
pending: "CI setup remains pending because a reviewed prerequisite was unavailable.",
|
|
1959
|
+
unchosen: "CI has not been reviewed with Build for this repository.",
|
|
1960
|
+
existing: "GitHub workflows are present; their CI coverage and required checks have not been reviewed with Build.",
|
|
1961
|
+
intent: "Build could not read the saved CI choice.",
|
|
1962
|
+
repository: "The CI repository is ambiguous or no longer matches the saved choice.",
|
|
1963
|
+
hook: "The selected local CI hook is missing or is not executable in this checkout.",
|
|
1964
|
+
workflow: "A selected GitHub CI workflow is missing or cannot cover every pull request."
|
|
1965
|
+
};
|
|
1966
|
+
function ciAdvisoryMessage(code) {
|
|
1967
|
+
if (!Object.hasOwn(MESSAGES, code)) return "Info: Run build ci status to inspect CI.";
|
|
1968
|
+
return `Info: ${MESSAGES[code]} Run build init to review local or GitHub CI and preview any changes; build ci status inspects the current setup.`;
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
export {
|
|
1972
|
+
SERVICE_DOC_DOMAINS,
|
|
1973
|
+
serviceSignalForToken,
|
|
1974
|
+
CANDIDATE_ITEM_ID_PREFIX,
|
|
1975
|
+
CANDIDATE_SEARCH_PRIORITY,
|
|
1976
|
+
MAX_UNRESOLVED_LINES,
|
|
1977
|
+
candidateSetSignature,
|
|
1978
|
+
QUERY_SAFE_EVIDENCE_CLASSES,
|
|
1979
|
+
isQuerySafeHostname,
|
|
1980
|
+
isCandidateQuerySafe,
|
|
1981
|
+
detectStack,
|
|
1982
|
+
DECLARE_STACK_EXAMPLE_SPEC,
|
|
1983
|
+
DECLARE_STACK_COMMAND,
|
|
1984
|
+
STACK_BLOCK_MARKERS,
|
|
1985
|
+
isSafeStackIdentifier,
|
|
1986
|
+
renderAcknowledgedSdkPair,
|
|
1987
|
+
stackIntentPath,
|
|
1988
|
+
legacyDeclaredStackPath,
|
|
1989
|
+
parseIntentSpec,
|
|
1990
|
+
createIntentContract,
|
|
1991
|
+
readIntentContract,
|
|
1992
|
+
writeIntentContract,
|
|
1993
|
+
removeIntentContract,
|
|
1994
|
+
migrateLegacyDeclaration,
|
|
1995
|
+
resolveIntent,
|
|
1996
|
+
retireContract,
|
|
1997
|
+
acknowledgeConflicts,
|
|
1998
|
+
acceptDetectedReality,
|
|
1999
|
+
describeDimension,
|
|
2000
|
+
emptyStackDetection,
|
|
2001
|
+
resolvedStackDetection,
|
|
2002
|
+
isStackUndetectedAndUndeclared,
|
|
2003
|
+
renderStackAgentsBlock,
|
|
2004
|
+
writeStackContext,
|
|
2005
|
+
computeStackFingerprint2 as computeStackFingerprint,
|
|
2006
|
+
fingerprintDigest,
|
|
2007
|
+
isStackDriftKind,
|
|
2008
|
+
readStoredFingerprint,
|
|
2009
|
+
writeStoredFingerprint,
|
|
2010
|
+
recordDriftRecords,
|
|
2011
|
+
readDriftRecord,
|
|
2012
|
+
forgetDriftRecord,
|
|
2013
|
+
listPendingDrift,
|
|
2014
|
+
recordDelivery,
|
|
2015
|
+
ciAdvisoryMessage
|
|
2016
|
+
};
|
|
2017
|
+
//# sourceMappingURL=chunk-VYI4DSZP.js.map
|