@unbrained/pm-cli 2026.7.1 → 2026.7.3
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/.claude-plugin/marketplace.json +3 -3
- package/CHANGELOG.md +25 -0
- package/CONTRIBUTING.md +2 -2
- package/README.md +1 -1
- package/dist/cli/commander-usage.d.ts +2 -0
- package/dist/cli/commander-usage.js +110 -86
- package/dist/cli/commander-usage.js.map +1 -1
- package/dist/cli/commands/activity.js +79 -57
- package/dist/cli/commands/activity.js.map +1 -1
- package/dist/cli/commands/aggregate.js +102 -79
- package/dist/cli/commands/aggregate.js.map +1 -1
- package/dist/cli/commands/calendar.js +278 -243
- package/dist/cli/commands/calendar.js.map +1 -1
- package/dist/cli/commands/close-many.js +176 -114
- package/dist/cli/commands/close-many.js.map +1 -1
- package/dist/cli/commands/close.js +157 -129
- package/dist/cli/commands/close.js.map +1 -1
- package/dist/cli/commands/comments-audit.js +50 -42
- package/dist/cli/commands/comments-audit.js.map +1 -1
- package/dist/cli/commands/config.d.ts +2 -0
- package/dist/cli/commands/config.js +443 -879
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/context.js +365 -287
- package/dist/cli/commands/context.js.map +1 -1
- package/dist/cli/commands/contracts.js +352 -238
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/commands/create.js +32 -17
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/dedupe-audit.js +46 -39
- package/dist/cli/commands/dedupe-audit.js.map +1 -1
- package/dist/cli/commands/dedupe-merge.js +88 -69
- package/dist/cli/commands/dedupe-merge.js.map +1 -1
- package/dist/cli/commands/extension/doctor.js +56 -67
- package/dist/cli/commands/extension/doctor.js.map +1 -1
- package/dist/cli/commands/extension/shared.js +21 -15
- package/dist/cli/commands/extension/shared.js.map +1 -1
- package/dist/cli/commands/get.js +114 -81
- package/dist/cli/commands/get.js.map +1 -1
- package/dist/cli/commands/health.d.ts +17 -0
- package/dist/cli/commands/health.js +545 -417
- package/dist/cli/commands/health.js.map +1 -1
- package/dist/cli/commands/history-compact.js +209 -140
- package/dist/cli/commands/history-compact.js.map +1 -1
- package/dist/cli/commands/history-redact.js +162 -119
- package/dist/cli/commands/history-redact.js.map +1 -1
- package/dist/cli/commands/history-repair.js +120 -85
- package/dist/cli/commands/history-repair.js.map +1 -1
- package/dist/cli/commands/init-agent-guidance.js +32 -19
- package/dist/cli/commands/init-agent-guidance.js.map +1 -1
- package/dist/cli/commands/init.d.ts +8 -2
- package/dist/cli/commands/init.js +263 -162
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/list.js +152 -102
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/next.js +60 -40
- package/dist/cli/commands/next.js.map +1 -1
- package/dist/cli/commands/plan.js +373 -298
- package/dist/cli/commands/plan.js.map +1 -1
- package/dist/cli/commands/profile.js +23 -15
- package/dist/cli/commands/profile.js.map +1 -1
- package/dist/cli/commands/recurrence-parsers.js +43 -25
- package/dist/cli/commands/recurrence-parsers.js.map +1 -1
- package/dist/cli/commands/reindex.d.ts +21 -5
- package/dist/cli/commands/reindex.js +345 -205
- package/dist/cli/commands/reindex.js.map +1 -1
- package/dist/cli/commands/restore.d.ts +8 -7
- package/dist/cli/commands/restore.js +105 -69
- package/dist/cli/commands/restore.js.map +1 -1
- package/dist/cli/commands/schema.js +33 -30
- package/dist/cli/commands/schema.js.map +1 -1
- package/dist/cli/commands/search.d.ts +10 -2
- package/dist/cli/commands/search.js +503 -470
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/telemetry.js +98 -87
- package/dist/cli/commands/telemetry.js.map +1 -1
- package/dist/cli/commands/test-all.js +237 -168
- package/dist/cli/commands/test-all.js.map +1 -1
- package/dist/cli/commands/test.d.ts +6 -5
- package/dist/cli/commands/test.js +424 -344
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/commands/update-many.js +57 -42
- package/dist/cli/commands/update-many.js.map +1 -1
- package/dist/cli/commands/update.d.ts +1 -1
- package/dist/cli/commands/update.js +738 -671
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/commands/validate.d.ts +20 -1
- package/dist/cli/commands/validate.js +478 -343
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/error-guidance.js +406 -361
- package/dist/cli/error-guidance.js.map +1 -1
- package/dist/cli/extension-command-help.js +27 -19
- package/dist/cli/extension-command-help.js.map +1 -1
- package/dist/cli/help-json-payload.js +57 -49
- package/dist/cli/help-json-payload.js.map +1 -1
- package/dist/cli/main.d.ts +47 -0
- package/dist/cli/main.js +474 -371
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/migration-gates.js +22 -45
- package/dist/cli/migration-gates.js.map +1 -1
- package/dist/cli/register-list-query.js +299 -310
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.js +763 -779
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/register-operations.js +386 -362
- package/dist/cli/register-operations.js.map +1 -1
- package/dist/cli/register-setup.js +120 -101
- package/dist/cli/register-setup.js.map +1 -1
- package/dist/cli/registration-helpers.d.ts +4 -0
- package/dist/cli/registration-helpers.js +45 -56
- package/dist/cli/registration-helpers.js.map +1 -1
- package/dist/cli-bundle/chunks/{activity-DBLQVIP6.js → activity-5YWLSPGE.js} +9 -9
- package/dist/cli-bundle/chunks/activity-BIML7K2D.js +16 -0
- package/dist/cli-bundle/chunks/{aggregate-SDF7DUOD.js → aggregate-2V2M3JZU.js} +107 -83
- package/dist/cli-bundle/chunks/{aggregate-SDF7DUOD.js.map → aggregate-2V2M3JZU.js.map} +2 -2
- package/dist/cli-bundle/chunks/{aggregate-JTEF4BP7.js → aggregate-EK7DXML7.js} +108 -84
- package/dist/cli-bundle/chunks/aggregate-EK7DXML7.js.map +1 -0
- package/dist/cli-bundle/chunks/{append-LOVPGVPT.js → append-EZESUVJT.js} +8 -8
- package/dist/cli-bundle/chunks/{append-QCFJSDFL.js → append-JFG4WQMG.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-TP5Q5ZD3.js → chunk-32IUNTG4.js} +158 -119
- package/dist/cli-bundle/chunks/chunk-32IUNTG4.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-BHO33VBQ.js → chunk-3W2HJKJX.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-VARHOHYV.js → chunk-4EXFFP7T.js} +86 -52
- package/dist/cli-bundle/chunks/chunk-4EXFFP7T.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-4DUVCVLZ.js → chunk-4PFVUUYV.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-JSU5P7VS.js → chunk-4WB6S4YX.js} +308 -184
- package/dist/cli-bundle/chunks/chunk-4WB6S4YX.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-HXTQJXWT.js → chunk-572FKBRL.js} +61 -102
- package/dist/cli-bundle/chunks/chunk-572FKBRL.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-IJYK2T43.js → chunk-5E7N4T2Z.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-NKZAN7BD.js → chunk-5IZUBZBR.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-NOLPZMSV.js → chunk-5JIWFWOZ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-FFMQB7WR.js → chunk-67LARBDL.js} +493 -404
- package/dist/cli-bundle/chunks/chunk-67LARBDL.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-6AQZPVHQ.js → chunk-6CDCWKSX.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-3K2M5OYU.js → chunk-6KRFL33E.js} +308 -184
- package/dist/cli-bundle/chunks/chunk-6KRFL33E.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-LB6TP6MC.js → chunk-6NYJGMTY.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-SLMUGTK3.js → chunk-7CLLC75T.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-2466X6E4.js → chunk-7LYO6S5A.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-W4ULYO7Z.js → chunk-A3OQ7TFW.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-5CGRF3L5.js → chunk-AIKU3IIL.js} +153 -90
- package/dist/cli-bundle/chunks/chunk-AIKU3IIL.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-WYDHYJPO.js → chunk-AJHYQCBJ.js} +39 -5
- package/dist/cli-bundle/chunks/chunk-AJHYQCBJ.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-VZDBVEZR.js → chunk-B4O5S7I3.js} +79 -57
- package/dist/cli-bundle/chunks/{chunk-VZDBVEZR.js.map → chunk-B4O5S7I3.js.map} +2 -2
- package/dist/cli-bundle/chunks/{chunk-OTUHB4HS.js → chunk-BE2SR6QL.js} +92 -77
- package/dist/cli-bundle/chunks/chunk-BE2SR6QL.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-JLM7BHI7.js → chunk-BI4R7HI2.js} +75 -53
- package/dist/cli-bundle/chunks/chunk-BI4R7HI2.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-AXIDKKAT.js → chunk-CXR3CMBQ.js} +33 -6
- package/dist/cli-bundle/chunks/chunk-CXR3CMBQ.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-ZETXE4SE.js → chunk-ECU6MMTQ.js} +713 -613
- package/dist/cli-bundle/chunks/chunk-ECU6MMTQ.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-2D4HATP2.js → chunk-EJ2OCBHF.js} +54 -30
- package/dist/cli-bundle/chunks/chunk-EJ2OCBHF.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-BDTISOSD.js → chunk-EQURFOMH.js} +41 -26
- package/dist/cli-bundle/chunks/chunk-EQURFOMH.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-GJ326ZKX.js → chunk-ER4ME5U2.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-HZZEHPRG.js → chunk-ERG65A2L.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-IZBR4NRW.js → chunk-F6WNBITZ.js} +157 -113
- package/dist/cli-bundle/chunks/chunk-F6WNBITZ.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-L5OEFZQG.js → chunk-FH2H3CBD.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-JPECA746.js → chunk-FUFFPIYA.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-CF7RL6FR.js → chunk-FZJM2TXF.js} +110 -73
- package/dist/cli-bundle/chunks/chunk-FZJM2TXF.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-27BXPBAY.js → chunk-GUYNUXQT.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-MAUKX7JC.js → chunk-GVJE5T7Q.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-3J6JRJ3I.js → chunk-HB4FAT3O.js} +42 -60
- package/dist/cli-bundle/chunks/chunk-HB4FAT3O.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-55SNVXRQ.js → chunk-HQAF23Q2.js} +626 -484
- package/dist/cli-bundle/chunks/chunk-HQAF23Q2.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-ZRP4VG5U.js → chunk-JBZ2NTKX.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-RMMQ74TG.js → chunk-JPATY4SE.js} +54 -30
- package/dist/cli-bundle/chunks/chunk-JPATY4SE.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-IPYBJWTE.js → chunk-K5DT2YKM.js} +109 -72
- package/dist/cli-bundle/chunks/chunk-K5DT2YKM.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-EJUDVUYZ.js → chunk-KEZOIPCR.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-RVUALSJF.js → chunk-KHVGM5CS.js} +466 -365
- package/dist/cli-bundle/chunks/chunk-KHVGM5CS.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-YITK2PJ6.js → chunk-KS6ATO47.js} +288 -175
- package/dist/cli-bundle/chunks/chunk-KS6ATO47.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-7R4QEMZZ.js → chunk-L4SLHV6G.js} +463 -362
- package/dist/cli-bundle/chunks/chunk-L4SLHV6G.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-RLDHZHQS.js → chunk-LBE5QFMZ.js} +158 -114
- package/dist/cli-bundle/chunks/chunk-LBE5QFMZ.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-22WKIL3H.js → chunk-LCWQP6NM.js} +76 -54
- package/dist/cli-bundle/chunks/chunk-LCWQP6NM.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-KNPEF7QG.js → chunk-LOWVNZBZ.js} +91 -76
- package/dist/cli-bundle/chunks/chunk-LOWVNZBZ.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-HYTGA6GI.js → chunk-MDHWWBNZ.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-N74UMG5H.js → chunk-MEZZZBYX.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-V3NOKJF2.js → chunk-MHRS5FUX.js} +288 -175
- package/dist/cli-bundle/chunks/chunk-MHRS5FUX.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-3XZCOZ5J.js → chunk-NOIEVOK5.js} +391 -313
- package/dist/cli-bundle/chunks/chunk-NOIEVOK5.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-SDR5J34Q.js → chunk-NZ7QIUP5.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-UYUYDGIB.js → chunk-OGLGI22K.js} +115 -67
- package/dist/cli-bundle/chunks/{chunk-UYUYDGIB.js.map → chunk-OGLGI22K.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-DDPTYJIM.js → chunk-P5L7Z2O6.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BZCEN4JA.js → chunk-PULUSQAV.js} +492 -403
- package/dist/cli-bundle/chunks/chunk-PULUSQAV.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-3VGN2UWE.js → chunk-QCDTQCMW.js} +22 -30
- package/dist/cli-bundle/chunks/chunk-QCDTQCMW.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-4A3BJ675.js → chunk-QNNQAAZ5.js} +24 -18
- package/dist/cli-bundle/chunks/{chunk-4A3BJ675.js.map → chunk-QNNQAAZ5.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-MDPEOIGN.js → chunk-RAHINBVP.js} +60 -101
- package/dist/cli-bundle/chunks/chunk-RAHINBVP.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-CWFNTKQJ.js → chunk-RJH5VQHW.js} +43 -61
- package/dist/cli-bundle/chunks/chunk-RJH5VQHW.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-OGXLACHC.js → chunk-SU2E4AWU.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-HPPFYYOV.js → chunk-SU3TB4NS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-JWXRETDF.js → chunk-SYE6WMV6.js} +626 -484
- package/dist/cli-bundle/chunks/chunk-SYE6WMV6.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-NWMZWYYB.js → chunk-T3P7PMZP.js} +42 -27
- package/dist/cli-bundle/chunks/chunk-T3P7PMZP.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-G7I7DEZA.js → chunk-T4XBKJ3F.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-RH5ZBYFD.js → chunk-T6AXEBOP.js} +23 -17
- package/dist/cli-bundle/chunks/{chunk-RH5ZBYFD.js.map → chunk-T6AXEBOP.js.map} +2 -2
- package/dist/cli-bundle/chunks/{chunk-5QFDBI4F.js → chunk-TQ6AX5SQ.js} +58 -69
- package/dist/cli-bundle/chunks/{chunk-5QFDBI4F.js.map → chunk-TQ6AX5SQ.js.map} +2 -2
- package/dist/cli-bundle/chunks/{chunk-4XOIEKSD.js → chunk-U3S2B7TA.js} +86 -52
- package/dist/cli-bundle/chunks/chunk-U3S2B7TA.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-VICZWYGZ.js → chunk-U5TR4N7J.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-EVMTBV6V.js → chunk-UMNQZS4H.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-A7FPBAQS.js → chunk-WJA3PXW7.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-RGEMWD6Q.js → chunk-WRYERRZX.js} +157 -118
- package/dist/cli-bundle/chunks/chunk-WRYERRZX.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-NUHHPVVS.js → chunk-WYOIIFSE.js} +712 -612
- package/dist/cli-bundle/chunks/chunk-WYOIIFSE.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-4DSGXSBL.js → chunk-XRYSCRZR.js} +116 -68
- package/dist/cli-bundle/chunks/{chunk-4DSGXSBL.js.map → chunk-XRYSCRZR.js.map} +3 -3
- package/dist/cli-bundle/chunks/{chunk-NU2UEROZ.js → chunk-YF746GTH.js} +59 -70
- package/dist/cli-bundle/chunks/{chunk-NU2UEROZ.js.map → chunk-YF746GTH.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-JMP4E6D7.js → chunk-YPWUSH72.js} +390 -312
- package/dist/cli-bundle/chunks/{chunk-JMP4E6D7.js.map → chunk-YPWUSH72.js.map} +2 -2
- package/dist/cli-bundle/chunks/{chunk-QCWF6IYD.js → chunk-YSDFIY7N.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-UZIWVBE6.js → chunk-YSGTMDWC.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-NFDPYAIP.js → chunk-YVKZ3ANP.js} +21 -29
- package/dist/cli-bundle/chunks/chunk-YVKZ3ANP.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-OKQ22KTH.js → chunk-Z4DGFQDH.js} +80 -58
- package/dist/cli-bundle/chunks/{chunk-OKQ22KTH.js.map → chunk-Z4DGFQDH.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-64HNBBFQ.js → chunk-Z5F6XZXE.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-AVEE5EHK.js → chunk-Z7RPDF2Y.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-3S2KT7NG.js → chunk-ZFTKYWIF.js} +152 -89
- package/dist/cli-bundle/chunks/chunk-ZFTKYWIF.js.map +7 -0
- package/dist/cli-bundle/chunks/{claim-T3GCKV7C.js → claim-2BGBGSVI.js} +8 -8
- package/dist/cli-bundle/chunks/{claim-EMQLYPRW.js → claim-5GU7OE67.js} +8 -8
- package/dist/cli-bundle/chunks/close-6YODBUIV.js +14 -0
- package/dist/cli-bundle/chunks/{close-TQYAAFJP.js → close-AFVKPR57.js} +7 -7
- package/dist/cli-bundle/chunks/{close-many-BG5QQIDQ.js → close-many-7KLOSYLP.js} +186 -122
- package/dist/cli-bundle/chunks/close-many-7KLOSYLP.js.map +7 -0
- package/dist/cli-bundle/chunks/{close-many-LDRVEQY2.js → close-many-JKUJMHLG.js} +187 -123
- package/dist/cli-bundle/chunks/close-many-JKUJMHLG.js.map +1 -0
- package/dist/cli-bundle/chunks/{comments-YUXJRZPQ.js → comments-DNWHEBOS.js} +9 -9
- package/dist/cli-bundle/chunks/{comments-QCKR2YY2.js → comments-RW23R3VE.js} +9 -9
- package/dist/cli-bundle/chunks/config-AUM5WBYA.js +1072 -0
- package/dist/cli-bundle/chunks/config-AUM5WBYA.js.map +7 -0
- package/dist/cli-bundle/chunks/config-OZWSA2NP.js +1062 -0
- package/dist/cli-bundle/chunks/config-OZWSA2NP.js.map +1 -0
- package/dist/cli-bundle/chunks/{context-B6275WPX.js → context-OYXRGY7S.js} +12 -12
- package/dist/cli-bundle/chunks/{context-OCZ3FJ4Z.js → context-PKCEHQY3.js} +12 -12
- package/dist/cli-bundle/chunks/{contracts-HN7ABKLP.js → contracts-L6ODXNUM.js} +320 -199
- package/dist/cli-bundle/chunks/contracts-L6ODXNUM.js.map +7 -0
- package/dist/cli-bundle/chunks/{contracts-W4FZVVD6.js → contracts-X74F2GSM.js} +321 -200
- package/dist/cli-bundle/chunks/contracts-X74F2GSM.js.map +1 -0
- package/dist/cli-bundle/chunks/{copy-DEM4DATS.js → copy-6XOR3HKN.js} +5 -5
- package/dist/cli-bundle/chunks/{copy-BTJOSKKT.js → copy-I4NCLBR4.js} +5 -5
- package/dist/cli-bundle/chunks/{create-RLRJMRTM.js → create-PM45M6PE.js} +12 -12
- package/dist/cli-bundle/chunks/create-Z7YCH3BE.js +28 -0
- package/dist/cli-bundle/chunks/{delete-BHK7VB2Z.js → delete-7YXHYG67.js} +5 -5
- package/dist/cli-bundle/chunks/{delete-LSVHAB4Y.js → delete-LPISP43T.js} +5 -5
- package/dist/cli-bundle/chunks/{deps-XHYXWEPT.js → deps-N2T26FME.js} +5 -5
- package/dist/cli-bundle/chunks/{deps-4UDFJRUA.js → deps-WATKQDE3.js} +5 -5
- package/dist/cli-bundle/chunks/{docs-GYZNVS26.js → docs-6LQ3GLM7.js} +7 -7
- package/dist/cli-bundle/chunks/{docs-26S44RXU.js → docs-Z3X6JZLT.js} +7 -7
- package/dist/cli-bundle/chunks/{eval-UYF3ZPVO.js → eval-6DCLG52D.js} +10 -10
- package/dist/cli-bundle/chunks/{eval-PGRVIJQU.js → eval-Y3ZCUTHK.js} +10 -10
- package/dist/cli-bundle/chunks/{extension-CPSLJQVE.js → extension-BNINIMT7.js} +11 -11
- package/dist/cli-bundle/chunks/{extension-CXJ6RELI.js → extension-QWE4YYK5.js} +11 -11
- package/dist/cli-bundle/chunks/{files-NQHEXUZD.js → files-6SGKHS6O.js} +7 -7
- package/dist/cli-bundle/chunks/{files-MBNICQFM.js → files-FUYPSOFJ.js} +7 -7
- package/dist/cli-bundle/chunks/{focus-DWYIG7GU.js → focus-2Q3K76G2.js} +6 -6
- package/dist/cli-bundle/chunks/{focus-XZW5423D.js → focus-ATLBWXXD.js} +6 -6
- package/dist/cli-bundle/chunks/{gc-LPVMKJQJ.js → gc-RUYEMNRF.js} +3 -3
- package/dist/cli-bundle/chunks/{gc-7GQYOS2G.js → gc-TDWSDR66.js} +3 -3
- package/dist/cli-bundle/chunks/{get-A7MAOHCU.js → get-2WGLX74N.js} +120 -80
- package/dist/cli-bundle/chunks/get-2WGLX74N.js.map +7 -0
- package/dist/cli-bundle/chunks/{get-DSDEKJ3L.js → get-LY6M2JIM.js} +121 -81
- package/dist/cli-bundle/chunks/get-LY6M2JIM.js.map +1 -0
- package/dist/cli-bundle/chunks/{health-3IPFLKXB.js → health-4RKHYS3T.js} +535 -371
- package/dist/cli-bundle/chunks/health-4RKHYS3T.js.map +1 -0
- package/dist/cli-bundle/chunks/{health-GZXGBZ36.js → health-TMFVNYRA.js} +534 -370
- package/dist/cli-bundle/chunks/health-TMFVNYRA.js.map +7 -0
- package/dist/cli-bundle/chunks/history-CGNQJXFE.js +18 -0
- package/dist/cli-bundle/chunks/{history-NERDJNUB.js → history-SGRRS72R.js} +8 -8
- package/dist/cli-bundle/chunks/{history-compact-2WRZ2WK4.js → history-compact-LOED43R3.js} +213 -134
- package/dist/cli-bundle/chunks/history-compact-LOED43R3.js.map +7 -0
- package/dist/cli-bundle/chunks/{history-compact-HR7BB4LR.js → history-compact-V5DNAQHH.js} +214 -135
- package/dist/cli-bundle/chunks/history-compact-V5DNAQHH.js.map +1 -0
- package/dist/cli-bundle/chunks/{history-redact-O3NBCNWC.js → history-redact-IRL7WJ3E.js} +9 -9
- package/dist/cli-bundle/chunks/history-redact-N3JK7VBW.js +19 -0
- package/dist/cli-bundle/chunks/{history-repair-XA3LC4GA.js → history-repair-4WVBVHFR.js} +124 -84
- package/dist/cli-bundle/chunks/history-repair-4WVBVHFR.js.map +1 -0
- package/dist/cli-bundle/chunks/{history-repair-LCMOS45X.js → history-repair-PGYQJMGD.js} +123 -83
- package/dist/cli-bundle/chunks/history-repair-PGYQJMGD.js.map +7 -0
- package/dist/cli-bundle/chunks/{init-64XDLQJB.js → init-4GESW7RM.js} +12 -12
- package/dist/cli-bundle/chunks/init-XIDPABA4.js +22 -0
- package/dist/cli-bundle/chunks/{learnings-LPKCSJX7.js → learnings-4BHWFFUV.js} +9 -9
- package/dist/cli-bundle/chunks/{learnings-JR6MA5TI.js → learnings-4FJY7WIW.js} +9 -9
- package/dist/cli-bundle/chunks/{list-G5Y65VF6.js → list-472TIOVK.js} +8 -8
- package/dist/cli-bundle/chunks/{list-DNBJVO3E.js → list-D7BF5CL2.js} +8 -8
- package/dist/cli-bundle/chunks/{next-FYTQF6HG.js → next-D5STGWI2.js} +71 -46
- package/dist/cli-bundle/chunks/next-D5STGWI2.js.map +1 -0
- package/dist/cli-bundle/chunks/{next-BCERKDUR.js → next-SFQZVX2B.js} +70 -45
- package/dist/cli-bundle/chunks/next-SFQZVX2B.js.map +7 -0
- package/dist/cli-bundle/chunks/{notes-2BMU3VVQ.js → notes-6KNOSLIT.js} +9 -9
- package/dist/cli-bundle/chunks/{notes-6KTGO2OJ.js → notes-W4UEICGF.js} +9 -9
- package/dist/cli-bundle/chunks/{plan-RKZHQVXR.js → plan-JO6V7BXO.js} +373 -279
- package/dist/cli-bundle/chunks/plan-JO6V7BXO.js.map +1 -0
- package/dist/cli-bundle/chunks/{plan-4WXEQCTN.js → plan-MJQW5XK3.js} +372 -278
- package/dist/cli-bundle/chunks/plan-MJQW5XK3.js.map +7 -0
- package/dist/cli-bundle/chunks/{profile-4OMM32CD.js → profile-3TOTMUR4.js} +27 -19
- package/dist/cli-bundle/chunks/profile-3TOTMUR4.js.map +7 -0
- package/dist/cli-bundle/chunks/{profile-QLER5ENE.js → profile-WIQY2KCV.js} +28 -20
- package/dist/cli-bundle/chunks/profile-WIQY2KCV.js.map +1 -0
- package/dist/cli-bundle/chunks/register-list-query-ELBHCCFI.js +416 -0
- package/dist/cli-bundle/chunks/register-list-query-ELBHCCFI.js.map +7 -0
- package/dist/cli-bundle/chunks/register-list-query-GAPQ6DM3.js +406 -0
- package/dist/cli-bundle/chunks/register-list-query-GAPQ6DM3.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-mutation-KK7PHYYU.js → register-mutation-ROFE2YPC.js} +729 -702
- package/dist/cli-bundle/chunks/register-mutation-ROFE2YPC.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-mutation-ENNDUAZG.js → register-mutation-SJWMVIJ2.js} +730 -703
- package/dist/cli-bundle/chunks/register-mutation-SJWMVIJ2.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-operations-HZ6XERQG.js → register-operations-IADFVH53.js} +389 -365
- package/dist/cli-bundle/chunks/register-operations-IADFVH53.js.map +7 -0
- package/dist/cli-bundle/chunks/register-operations-MEKU3AKC.js +510 -0
- package/dist/cli-bundle/chunks/register-operations-MEKU3AKC.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-setup-ZKJ53RS7.js → register-setup-3QJY43CY.js} +128 -103
- package/dist/cli-bundle/chunks/register-setup-3QJY43CY.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-setup-P67EMBDJ.js → register-setup-AJWUSSQX.js} +129 -104
- package/dist/cli-bundle/chunks/register-setup-AJWUSSQX.js.map +1 -0
- package/dist/cli-bundle/chunks/{restore-4MHZFJ2E.js → restore-44IHMMZZ.js} +9 -9
- package/dist/cli-bundle/chunks/restore-EXHU34EU.js +17 -0
- package/dist/cli-bundle/chunks/{scheduling-shortcuts-LB6DOLRL.js → scheduling-shortcuts-OLHNLAZY.js} +12 -12
- package/dist/cli-bundle/chunks/{scheduling-shortcuts-UTOYKLXQ.js → scheduling-shortcuts-TSBK4AY5.js} +12 -12
- package/dist/cli-bundle/chunks/{schema-73HR2OJW.js → schema-IB2NZZWD.js} +7 -7
- package/dist/cli-bundle/chunks/{schema-U6LJKSIR.js → schema-VBCELP5G.js} +7 -7
- package/dist/cli-bundle/chunks/{search-AXPXKZER.js → search-7UBETML4.js} +10 -10
- package/dist/cli-bundle/chunks/{search-KILGT37L.js → search-R227JOL6.js} +10 -10
- package/dist/cli-bundle/chunks/{stats-W5KNVJWQ.js → stats-FAG7COEH.js} +6 -6
- package/dist/cli-bundle/chunks/{stats-PSYVVTNZ.js → stats-MCK7PLYS.js} +6 -6
- package/dist/cli-bundle/chunks/{telemetry-GAHHQTOS.js → telemetry-DRPDZMAO.js} +84 -70
- package/dist/cli-bundle/chunks/telemetry-DRPDZMAO.js.map +7 -0
- package/dist/cli-bundle/chunks/{telemetry-BZUF6H7G.js → telemetry-GVVUQSJQ.js} +85 -71
- package/dist/cli-bundle/chunks/telemetry-GVVUQSJQ.js.map +1 -0
- package/dist/cli-bundle/chunks/{test-PWDIZ255.js → test-QY44WAMR.js} +15 -15
- package/dist/cli-bundle/chunks/{test-ACD52Z3S.js → test-SY76DZTO.js} +15 -15
- package/dist/cli-bundle/chunks/test-all-QD6QAEG7.js +430 -0
- package/dist/cli-bundle/chunks/test-all-QD6QAEG7.js.map +7 -0
- package/dist/cli-bundle/chunks/test-all-USPJHXFR.js +427 -0
- package/dist/cli-bundle/chunks/test-all-USPJHXFR.js.map +1 -0
- package/dist/cli-bundle/chunks/{test-runs-UXIXPDKU.js → test-runs-MG5VIGSK.js} +185 -147
- package/dist/cli-bundle/chunks/test-runs-MG5VIGSK.js.map +1 -0
- package/dist/cli-bundle/chunks/{test-runs-PLRAZEFW.js → test-runs-QIR5MJPL.js} +184 -146
- package/dist/cli-bundle/chunks/test-runs-QIR5MJPL.js.map +7 -0
- package/dist/cli-bundle/chunks/update-A7EICML6.js +24 -0
- package/dist/cli-bundle/chunks/{update-KFX2SIAC.js → update-IKJZWLQC.js} +15 -15
- package/dist/cli-bundle/chunks/{update-many-RNSBX2TA.js → update-many-BEMTDA2X.js} +84 -69
- package/dist/cli-bundle/chunks/{update-many-RNSBX2TA.js.map → update-many-BEMTDA2X.js.map} +1 -1
- package/dist/cli-bundle/chunks/{update-many-Z5GJS5LC.js → update-many-RATAARHU.js} +83 -68
- package/dist/cli-bundle/chunks/{update-many-Z5GJS5LC.js.map → update-many-RATAARHU.js.map} +2 -2
- package/dist/cli-bundle/chunks/{upgrade-BRL6KCOJ.js → upgrade-NWMR3VQL.js} +11 -11
- package/dist/cli-bundle/chunks/{upgrade-HAK6JG2O.js → upgrade-VU46BLJZ.js} +11 -11
- package/dist/cli-bundle/chunks/{validate-X5W76YJL.js → validate-GAJ6FUSI.js} +451 -321
- package/dist/cli-bundle/chunks/validate-GAJ6FUSI.js.map +1 -0
- package/dist/cli-bundle/chunks/{validate-MTUVL5VC.js → validate-NRY6MFXN.js} +450 -320
- package/dist/cli-bundle/chunks/validate-NRY6MFXN.js.map +7 -0
- package/dist/cli-bundle/main.js +1107 -916
- package/dist/cli-bundle/main.js.map +3 -3
- package/dist/core/config/nested-settings.js +89 -67
- package/dist/core/config/nested-settings.js.map +1 -1
- package/dist/core/governance/metadata-coverage.js +20 -28
- package/dist/core/governance/metadata-coverage.js.map +1 -1
- package/dist/core/history/drift-scan.js +93 -81
- package/dist/core/history/drift-scan.js.map +1 -1
- package/dist/core/item/item-type-definition.js +14 -14
- package/dist/core/item/item-type-definition.js.map +1 -1
- package/dist/core/item/type-registry.js +114 -99
- package/dist/core/item/type-registry.js.map +1 -1
- package/dist/core/output/mutation-projection.js +42 -26
- package/dist/core/output/mutation-projection.js.map +1 -1
- package/dist/core/schema/runtime-schema.js +97 -80
- package/dist/core/schema/runtime-schema.js.map +1 -1
- package/dist/core/schema/status-defs-file.js +26 -3
- package/dist/core/schema/status-defs-file.js.map +1 -1
- package/dist/core/search/corpus.js +25 -19
- package/dist/core/search/corpus.js.map +1 -1
- package/dist/core/search/semantic-defaults.js +64 -37
- package/dist/core/search/semantic-defaults.js.map +1 -1
- package/dist/core/search/vector-stores.js +32 -17
- package/dist/core/search/vector-stores.js.map +1 -1
- package/dist/core/sentry/helpers.js +31 -28
- package/dist/core/sentry/helpers.js.map +1 -1
- package/dist/core/sentry/instrument.js +54 -43
- package/dist/core/sentry/instrument.js.map +1 -1
- package/dist/core/shared/memo.d.ts +12 -0
- package/dist/core/shared/memo.js +25 -0
- package/dist/core/shared/memo.js.map +1 -0
- package/dist/core/shared/serialization.js +24 -14
- package/dist/core/shared/serialization.js.map +1 -1
- package/dist/core/shared/time.js +26 -4
- package/dist/core/shared/time.js.map +1 -1
- package/dist/core/store/front-matter-cache.d.ts +5 -0
- package/dist/core/store/front-matter-cache.js +316 -171
- package/dist/core/store/front-matter-cache.js.map +1 -1
- package/dist/core/store/item-store.js +33 -26
- package/dist/core/store/item-store.js.map +1 -1
- package/dist/core/store/settings.js +247 -203
- package/dist/core/store/settings.js.map +1 -1
- package/dist/core/test/background-runs.js +189 -160
- package/dist/core/test/background-runs.js.map +1 -1
- package/dist/sdk/cli-contracts/flag-contracts.js +71 -99
- package/dist/sdk/cli-contracts/flag-contracts.js.map +1 -1
- package/dist/sdk/compose.js +51 -42
- package/dist/sdk/compose.js.map +1 -1
- package/docs/AGENT_GUIDE.md +2 -2
- package/docs/ARCHITECTURE.md +2 -2
- package/docs/COMMANDS.md +8 -4
- package/docs/CONFIGURATION.md +1 -1
- package/docs/EXTENSIONS.md +12 -12
- package/docs/ONBOARDING.md +4 -2
- package/docs/README.md +2 -0
- package/docs/examples/starter-extension/README.md +11 -10
- package/marketplace.json +3 -3
- package/package.json +2 -2
- package/packages/pm-beads/extensions/beads/runtime.ts +240 -167
- package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +65 -58
- package/packages/pm-todos/extensions/todos/runtime.ts +65 -42
- package/plugins/pm-claude/.claude-plugin/plugin.json +2 -2
- package/plugins/pm-claude/README.md +6 -3
- package/plugins/pm-claude/commands/pm-init.md +1 -1
- package/dist/cli-bundle/chunks/activity-AW6XVFH6.js +0 -16
- package/dist/cli-bundle/chunks/aggregate-JTEF4BP7.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-22WKIL3H.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-2D4HATP2.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-3J6JRJ3I.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-3K2M5OYU.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-3S2KT7NG.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-3VGN2UWE.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-3XZCOZ5J.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-4XOIEKSD.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-55SNVXRQ.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-5CGRF3L5.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-7R4QEMZZ.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-AXIDKKAT.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-BDTISOSD.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-BZCEN4JA.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-CF7RL6FR.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-CWFNTKQJ.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-FFMQB7WR.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-HXTQJXWT.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-IPYBJWTE.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-IZBR4NRW.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-JLM7BHI7.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-JSU5P7VS.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-JWXRETDF.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-KNPEF7QG.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-MDPEOIGN.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-NFDPYAIP.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-NUHHPVVS.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-NWMZWYYB.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-OTUHB4HS.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-RGEMWD6Q.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-RLDHZHQS.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-RMMQ74TG.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-RVUALSJF.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-TP5Q5ZD3.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-V3NOKJF2.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-VARHOHYV.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-WYDHYJPO.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-YITK2PJ6.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-ZETXE4SE.js.map +0 -1
- package/dist/cli-bundle/chunks/close-E6ZZGCJY.js +0 -14
- package/dist/cli-bundle/chunks/close-many-BG5QQIDQ.js.map +0 -7
- package/dist/cli-bundle/chunks/close-many-LDRVEQY2.js.map +0 -1
- package/dist/cli-bundle/chunks/config-DMSU64QO.js +0 -1541
- package/dist/cli-bundle/chunks/config-DMSU64QO.js.map +0 -7
- package/dist/cli-bundle/chunks/config-QH2DICD6.js +0 -1531
- package/dist/cli-bundle/chunks/config-QH2DICD6.js.map +0 -1
- package/dist/cli-bundle/chunks/contracts-HN7ABKLP.js.map +0 -7
- package/dist/cli-bundle/chunks/contracts-W4FZVVD6.js.map +0 -1
- package/dist/cli-bundle/chunks/create-OH3BDGBB.js +0 -28
- package/dist/cli-bundle/chunks/get-A7MAOHCU.js.map +0 -7
- package/dist/cli-bundle/chunks/get-DSDEKJ3L.js.map +0 -1
- package/dist/cli-bundle/chunks/health-3IPFLKXB.js.map +0 -1
- package/dist/cli-bundle/chunks/health-GZXGBZ36.js.map +0 -7
- package/dist/cli-bundle/chunks/history-WSZHY3PN.js +0 -18
- package/dist/cli-bundle/chunks/history-compact-2WRZ2WK4.js.map +0 -7
- package/dist/cli-bundle/chunks/history-compact-HR7BB4LR.js.map +0 -1
- package/dist/cli-bundle/chunks/history-redact-MP6CH7U5.js +0 -19
- package/dist/cli-bundle/chunks/history-repair-LCMOS45X.js.map +0 -7
- package/dist/cli-bundle/chunks/history-repair-XA3LC4GA.js.map +0 -1
- package/dist/cli-bundle/chunks/init-PAX32BJA.js +0 -22
- package/dist/cli-bundle/chunks/next-BCERKDUR.js.map +0 -7
- package/dist/cli-bundle/chunks/next-FYTQF6HG.js.map +0 -1
- package/dist/cli-bundle/chunks/plan-4WXEQCTN.js.map +0 -7
- package/dist/cli-bundle/chunks/plan-RKZHQVXR.js.map +0 -1
- package/dist/cli-bundle/chunks/profile-4OMM32CD.js.map +0 -7
- package/dist/cli-bundle/chunks/profile-QLER5ENE.js.map +0 -1
- package/dist/cli-bundle/chunks/register-list-query-7LV46VAU.js +0 -400
- package/dist/cli-bundle/chunks/register-list-query-7LV46VAU.js.map +0 -1
- package/dist/cli-bundle/chunks/register-list-query-SNG5PGA4.js +0 -410
- package/dist/cli-bundle/chunks/register-list-query-SNG5PGA4.js.map +0 -7
- package/dist/cli-bundle/chunks/register-mutation-ENNDUAZG.js.map +0 -1
- package/dist/cli-bundle/chunks/register-mutation-KK7PHYYU.js.map +0 -7
- package/dist/cli-bundle/chunks/register-operations-C6OWLDSH.js +0 -486
- package/dist/cli-bundle/chunks/register-operations-C6OWLDSH.js.map +0 -1
- package/dist/cli-bundle/chunks/register-operations-HZ6XERQG.js.map +0 -7
- package/dist/cli-bundle/chunks/register-setup-P67EMBDJ.js.map +0 -1
- package/dist/cli-bundle/chunks/register-setup-ZKJ53RS7.js.map +0 -7
- package/dist/cli-bundle/chunks/restore-YALDGTQR.js +0 -17
- package/dist/cli-bundle/chunks/telemetry-BZUF6H7G.js.map +0 -1
- package/dist/cli-bundle/chunks/telemetry-GAHHQTOS.js.map +0 -7
- package/dist/cli-bundle/chunks/test-all-L2MDDUCA.js +0 -358
- package/dist/cli-bundle/chunks/test-all-L2MDDUCA.js.map +0 -1
- package/dist/cli-bundle/chunks/test-all-RBZ6DLU2.js +0 -361
- package/dist/cli-bundle/chunks/test-all-RBZ6DLU2.js.map +0 -7
- package/dist/cli-bundle/chunks/test-runs-PLRAZEFW.js.map +0 -7
- package/dist/cli-bundle/chunks/test-runs-UXIXPDKU.js.map +0 -1
- package/dist/cli-bundle/chunks/update-AMRSOIWP.js +0 -24
- package/dist/cli-bundle/chunks/validate-MTUVL5VC.js.map +0 -7
- package/dist/cli-bundle/chunks/validate-X5W76YJL.js.map +0 -1
- /package/dist/cli-bundle/chunks/{activity-DBLQVIP6.js.map → activity-5YWLSPGE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{activity-AW6XVFH6.js.map → activity-BIML7K2D.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{append-LOVPGVPT.js.map → append-EZESUVJT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{append-QCFJSDFL.js.map → append-JFG4WQMG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-BHO33VBQ.js.map → chunk-3W2HJKJX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-4DUVCVLZ.js.map → chunk-4PFVUUYV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-IJYK2T43.js.map → chunk-5E7N4T2Z.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-NKZAN7BD.js.map → chunk-5IZUBZBR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-NOLPZMSV.js.map → chunk-5JIWFWOZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-6AQZPVHQ.js.map → chunk-6CDCWKSX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-LB6TP6MC.js.map → chunk-6NYJGMTY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-SLMUGTK3.js.map → chunk-7CLLC75T.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-2466X6E4.js.map → chunk-7LYO6S5A.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-W4ULYO7Z.js.map → chunk-A3OQ7TFW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GJ326ZKX.js.map → chunk-ER4ME5U2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-HZZEHPRG.js.map → chunk-ERG65A2L.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-L5OEFZQG.js.map → chunk-FH2H3CBD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-JPECA746.js.map → chunk-FUFFPIYA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-27BXPBAY.js.map → chunk-GUYNUXQT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-MAUKX7JC.js.map → chunk-GVJE5T7Q.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-ZRP4VG5U.js.map → chunk-JBZ2NTKX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-EJUDVUYZ.js.map → chunk-KEZOIPCR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-HYTGA6GI.js.map → chunk-MDHWWBNZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-N74UMG5H.js.map → chunk-MEZZZBYX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-SDR5J34Q.js.map → chunk-NZ7QIUP5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-DDPTYJIM.js.map → chunk-P5L7Z2O6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-OGXLACHC.js.map → chunk-SU2E4AWU.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-HPPFYYOV.js.map → chunk-SU3TB4NS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-G7I7DEZA.js.map → chunk-T4XBKJ3F.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-VICZWYGZ.js.map → chunk-U5TR4N7J.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-EVMTBV6V.js.map → chunk-UMNQZS4H.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-A7FPBAQS.js.map → chunk-WJA3PXW7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-QCWF6IYD.js.map → chunk-YSDFIY7N.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UZIWVBE6.js.map → chunk-YSGTMDWC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-64HNBBFQ.js.map → chunk-Z5F6XZXE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-AVEE5EHK.js.map → chunk-Z7RPDF2Y.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{claim-T3GCKV7C.js.map → claim-2BGBGSVI.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{claim-EMQLYPRW.js.map → claim-5GU7OE67.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-E6ZZGCJY.js.map → close-6YODBUIV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-TQYAAFJP.js.map → close-AFVKPR57.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{comments-YUXJRZPQ.js.map → comments-DNWHEBOS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{comments-QCKR2YY2.js.map → comments-RW23R3VE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{context-B6275WPX.js.map → context-OYXRGY7S.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{context-OCZ3FJ4Z.js.map → context-PKCEHQY3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{copy-DEM4DATS.js.map → copy-6XOR3HKN.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{copy-BTJOSKKT.js.map → copy-I4NCLBR4.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-RLRJMRTM.js.map → create-PM45M6PE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-OH3BDGBB.js.map → create-Z7YCH3BE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{delete-BHK7VB2Z.js.map → delete-7YXHYG67.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{delete-LSVHAB4Y.js.map → delete-LPISP43T.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-XHYXWEPT.js.map → deps-N2T26FME.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-4UDFJRUA.js.map → deps-WATKQDE3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{docs-GYZNVS26.js.map → docs-6LQ3GLM7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{docs-26S44RXU.js.map → docs-Z3X6JZLT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{eval-UYF3ZPVO.js.map → eval-6DCLG52D.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{eval-PGRVIJQU.js.map → eval-Y3ZCUTHK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{extension-CPSLJQVE.js.map → extension-BNINIMT7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{extension-CXJ6RELI.js.map → extension-QWE4YYK5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{files-NQHEXUZD.js.map → files-6SGKHS6O.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{files-MBNICQFM.js.map → files-FUYPSOFJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{focus-DWYIG7GU.js.map → focus-2Q3K76G2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{focus-XZW5423D.js.map → focus-ATLBWXXD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{gc-LPVMKJQJ.js.map → gc-RUYEMNRF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{gc-7GQYOS2G.js.map → gc-TDWSDR66.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-WSZHY3PN.js.map → history-CGNQJXFE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-NERDJNUB.js.map → history-SGRRS72R.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-redact-O3NBCNWC.js.map → history-redact-IRL7WJ3E.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-redact-MP6CH7U5.js.map → history-redact-N3JK7VBW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{init-64XDLQJB.js.map → init-4GESW7RM.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{init-PAX32BJA.js.map → init-XIDPABA4.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{learnings-LPKCSJX7.js.map → learnings-4BHWFFUV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{learnings-JR6MA5TI.js.map → learnings-4FJY7WIW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{list-G5Y65VF6.js.map → list-472TIOVK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{list-DNBJVO3E.js.map → list-D7BF5CL2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{notes-2BMU3VVQ.js.map → notes-6KNOSLIT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{notes-6KTGO2OJ.js.map → notes-W4UEICGF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{restore-4MHZFJ2E.js.map → restore-44IHMMZZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{restore-YALDGTQR.js.map → restore-EXHU34EU.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{scheduling-shortcuts-LB6DOLRL.js.map → scheduling-shortcuts-OLHNLAZY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{scheduling-shortcuts-UTOYKLXQ.js.map → scheduling-shortcuts-TSBK4AY5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{schema-73HR2OJW.js.map → schema-IB2NZZWD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{schema-U6LJKSIR.js.map → schema-VBCELP5G.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{search-AXPXKZER.js.map → search-7UBETML4.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{search-KILGT37L.js.map → search-R227JOL6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{stats-W5KNVJWQ.js.map → stats-FAG7COEH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{stats-PSYVVTNZ.js.map → stats-MCK7PLYS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{test-PWDIZ255.js.map → test-QY44WAMR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{test-ACD52Z3S.js.map → test-SY76DZTO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-AMRSOIWP.js.map → update-A7EICML6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-KFX2SIAC.js.map → update-IKJZWLQC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{upgrade-BRL6KCOJ.js.map → upgrade-NWMR3VQL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{upgrade-HAK6JG2O.js.map → upgrade-VU46BLJZ.js.map} +0 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm validate command surface and its agent-facing runtime behavior.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d434e454-cb3f-5eaa-b841-d6f815e0446d")}catch(e){}}();
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import { realpathSync } from "node:fs";
|
|
10
10
|
import { execFile } from "node:child_process";
|
|
@@ -122,6 +122,9 @@ const METADATA_TRUNCATED_KEY_BY_FIELD = {
|
|
|
122
122
|
const GIT_LS_FILES_MAX_BUFFER = 32 * 1024 * 1024;
|
|
123
123
|
const FILE_LIST_SUMMARY_LIMIT = 40;
|
|
124
124
|
const DIAGNOSTIC_LIST_SUMMARY_LIMIT = 5;
|
|
125
|
+
// Conservative pre-stat guard for common filesystem limits; over-limit links are unreadable, not prune-safe.
|
|
126
|
+
const LINKED_ARTIFACT_MAX_PATH_LENGTH = 4096;
|
|
127
|
+
const LINKED_ARTIFACT_MAX_SEGMENT_LENGTH = 255;
|
|
125
128
|
const execFileAsync = promisify(execFile);
|
|
126
129
|
function normalizeRelativePath(value) {
|
|
127
130
|
return value.replaceAll("\\", "/").replace(/^\.\/+/, "").replace(/^\/+/, "");
|
|
@@ -651,35 +654,115 @@ function summarizeDuplicateIssueCodes(duplicates, verboseDiagnostics) {
|
|
|
651
654
|
warnings: [`${DUPLICATE_ISSUE_CODE_WARNING_TOKEN}:${duplicates.length}`],
|
|
652
655
|
};
|
|
653
656
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
// (closed/canceled) historical items; core/minimal/custom profiles treat a
|
|
660
|
-
// retired item's missing estimate or acceptance criteria as resolved.
|
|
661
|
-
const enforcePlanningFieldsOnTerminal = metadataPolicy.profile === "strict";
|
|
657
|
+
function initializeMissingMetadataByField() {
|
|
658
|
+
return Object.fromEntries(SUPPORTED_METADATA_REQUIRED_FIELDS.map((field) => [field, []]));
|
|
659
|
+
}
|
|
660
|
+
function collectMissingMetadataByField(items, statusRegistry, enforcePlanningFieldsOnTerminal) {
|
|
661
|
+
const missingByField = initializeMissingMetadataByField();
|
|
662
662
|
for (const item of items) {
|
|
663
663
|
for (const field of SUPPORTED_METADATA_REQUIRED_FIELDS) {
|
|
664
|
-
if (
|
|
665
|
-
|
|
664
|
+
if (isMetadataFieldMissing(item, field, statusRegistry, enforcePlanningFieldsOnTerminal)) {
|
|
665
|
+
missingByField[field].push(item.id);
|
|
666
666
|
}
|
|
667
|
-
missingByField[field].push(item.id);
|
|
668
667
|
}
|
|
669
668
|
}
|
|
669
|
+
return missingByField;
|
|
670
|
+
}
|
|
671
|
+
function buildMetadataWarningTokens(metadataPolicy, missingByField, duplicateWarnings) {
|
|
670
672
|
const warningTokens = [...metadataPolicy.warnings];
|
|
671
673
|
for (const field of metadataPolicy.required_fields) {
|
|
672
674
|
const missingItems = missingByField[field];
|
|
673
|
-
if (missingItems.length
|
|
675
|
+
if (missingItems.length > 0) {
|
|
676
|
+
warningTokens.push(`${METADATA_WARNING_TOKEN_BY_FIELD[field]}:${missingItems.length}`);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
warningTokens.push(...duplicateWarnings);
|
|
680
|
+
return warningTokens;
|
|
681
|
+
}
|
|
682
|
+
function buildMetadataCounts(metadataPolicy, missingByField) {
|
|
683
|
+
const counts = {};
|
|
684
|
+
for (const field of metadataPolicy.required_fields) {
|
|
685
|
+
const missing = missingByField[field];
|
|
686
|
+
const value = missing ? missing.length : 0;
|
|
687
|
+
const countKey = METADATA_COUNT_KEY_BY_FIELD[field];
|
|
688
|
+
if (value > 0 && countKey) {
|
|
689
|
+
counts[countKey] = value;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
return counts;
|
|
693
|
+
}
|
|
694
|
+
function buildMissingFieldOccurrences(metadataPolicy, missingByField, itemsById) {
|
|
695
|
+
const occurrences = [];
|
|
696
|
+
for (const field of metadataPolicy.required_fields) {
|
|
697
|
+
const missing = missingByField[field];
|
|
698
|
+
if (!missing) {
|
|
674
699
|
continue;
|
|
675
700
|
}
|
|
676
|
-
|
|
701
|
+
for (const itemId of missing) {
|
|
702
|
+
const itemType = itemsById.get(itemId)?.type;
|
|
703
|
+
const normalizedItemType = typeof itemType === "string" && itemType.length > 0 ? itemType : "Unknown";
|
|
704
|
+
occurrences.push({ item_type: normalizedItemType, field });
|
|
705
|
+
}
|
|
677
706
|
}
|
|
707
|
+
return occurrences;
|
|
708
|
+
}
|
|
709
|
+
/* v8 ignore start -- metadata policy keys are validated before this summarizer; fallback branches are defensive */
|
|
710
|
+
function attachMissingMetadataItemIds(details, metadataPolicy, missingByField, verboseDiagnostics) {
|
|
711
|
+
for (const field of metadataPolicy.required_fields) {
|
|
712
|
+
const missing = missingByField[field];
|
|
713
|
+
if (!missing || missing.length === 0) {
|
|
714
|
+
continue;
|
|
715
|
+
}
|
|
716
|
+
const idsKey = METADATA_ITEM_IDS_KEY_BY_FIELD[field];
|
|
717
|
+
const truncatedKey = METADATA_TRUNCATED_KEY_BY_FIELD[field];
|
|
718
|
+
if (!idsKey || !truncatedKey) {
|
|
719
|
+
continue;
|
|
720
|
+
}
|
|
721
|
+
const summarized = summarizeList(missing, verboseDiagnostics ? missing.length : DIAGNOSTIC_LIST_SUMMARY_LIMIT);
|
|
722
|
+
details[idsKey] = summarized.values;
|
|
723
|
+
details[truncatedKey] = summarized.truncated;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
/* v8 ignore stop */
|
|
727
|
+
function buildCloseReasonBackfillRows(metadataPolicy, missingByField, itemsById) {
|
|
728
|
+
if (!metadataPolicy.required_fields.includes("close_reason")) {
|
|
729
|
+
return [];
|
|
730
|
+
}
|
|
731
|
+
const missing = missingByField.close_reason;
|
|
732
|
+
if (!missing) {
|
|
733
|
+
return [];
|
|
734
|
+
}
|
|
735
|
+
return missing.map((itemId) => ({
|
|
736
|
+
id: itemId,
|
|
737
|
+
resolution: toNonEmptyStringOrUndefined(itemsById.get(itemId)?.resolution),
|
|
738
|
+
}));
|
|
739
|
+
}
|
|
740
|
+
function buildEstimateBackfillRows(metadataPolicy, missingByField, itemsById) {
|
|
741
|
+
if (!metadataPolicy.required_fields.includes("estimated_minutes")) {
|
|
742
|
+
return [];
|
|
743
|
+
}
|
|
744
|
+
const missing = missingByField.estimated_minutes;
|
|
745
|
+
if (!missing) {
|
|
746
|
+
return [];
|
|
747
|
+
}
|
|
748
|
+
return missing.map((itemId) => ({
|
|
749
|
+
id: itemId,
|
|
750
|
+
type: toNonEmptyStringOrUndefined(itemsById.get(itemId)?.type),
|
|
751
|
+
}));
|
|
752
|
+
}
|
|
753
|
+
/* c8 ignore start -- metadata diagnostics/backfill planning permutations are covered by validate integration suites */
|
|
754
|
+
function buildMetadataCheck(items, metadataPolicy, statusRegistry, verboseDiagnostics) {
|
|
755
|
+
const itemsById = new Map(items.map((item) => [item.id, item]));
|
|
756
|
+
// GH-276: only the `strict` profile enforces planning fields on terminal
|
|
757
|
+
// (closed/canceled) historical items; core/minimal/custom profiles treat a
|
|
758
|
+
// retired item's missing estimate or acceptance criteria as resolved.
|
|
759
|
+
const enforcePlanningFieldsOnTerminal = metadataPolicy.profile === "strict";
|
|
760
|
+
const missingByField = collectMissingMetadataByField(items, statusRegistry, enforcePlanningFieldsOnTerminal);
|
|
678
761
|
// Duplicate logical issue-code detection (GH-235): advisory warning when two
|
|
679
762
|
// or more items share a leading title issue code (e.g. `ISSUE-004`).
|
|
680
763
|
const duplicateIssueCodes = findDuplicateIssueCodes(items);
|
|
681
764
|
const duplicateIssueCodeSummary = summarizeDuplicateIssueCodes(duplicateIssueCodes, verboseDiagnostics);
|
|
682
|
-
warningTokens
|
|
765
|
+
const warningTokens = buildMetadataWarningTokens(metadataPolicy, missingByField, duplicateIssueCodeSummary.warnings);
|
|
683
766
|
// Zero-suppress counts to reduce agent token cost (telemetry pm-tylj).
|
|
684
767
|
// Only emit counts for the ACTIVE required fields of the resolved profile so a
|
|
685
768
|
// looser profile (e.g. core) never reports missing reviewer/risk/sprint/etc.
|
|
@@ -687,25 +770,12 @@ function buildMetadataCheck(items, metadataPolicy, statusRegistry, verboseDiagno
|
|
|
687
770
|
// shape could include an unsupported field in required_fields — fall back
|
|
688
771
|
// to 0 instead of throwing TypeError, and skip writing when the count-key
|
|
689
772
|
// mapping is undefined.
|
|
690
|
-
const counts =
|
|
691
|
-
for (const field of metadataPolicy.required_fields) {
|
|
692
|
-
const value = missingByField[field]?.length ?? 0;
|
|
693
|
-
const countKey = METADATA_COUNT_KEY_BY_FIELD[field];
|
|
694
|
-
if (value > 0 && countKey) {
|
|
695
|
-
counts[countKey] = value;
|
|
696
|
-
}
|
|
697
|
-
}
|
|
773
|
+
const counts = buildMetadataCounts(metadataPolicy, missingByField);
|
|
698
774
|
// Per-item-type grouping of missing required-field counts (pm-pmyq /
|
|
699
775
|
// GH-172): counts only — never row dumps — and only for the ACTIVE required
|
|
700
776
|
// fields, so the grouping mirrors `counts` at type granularity (e.g.
|
|
701
777
|
// `{ Task: { close_reason: 3 } }`). Zero-suppressed at both levels.
|
|
702
|
-
const missingFieldOccurrences =
|
|
703
|
-
for (const field of metadataPolicy.required_fields) {
|
|
704
|
-
for (const itemId of missingByField[field] ?? []) {
|
|
705
|
-
const itemType = itemsById.get(itemId)?.type;
|
|
706
|
-
missingFieldOccurrences.push({ item_type: typeof itemType === "string" && itemType.length > 0 ? itemType : "Unknown", field });
|
|
707
|
-
}
|
|
708
|
-
}
|
|
778
|
+
const missingFieldOccurrences = buildMissingFieldOccurrences(metadataPolicy, missingByField, itemsById);
|
|
709
779
|
const missingByType = buildMissingByTypeCounts(missingFieldOccurrences);
|
|
710
780
|
const details = {
|
|
711
781
|
checked_items: items.length,
|
|
@@ -731,40 +801,17 @@ function buildMetadataCheck(items, metadataPolicy, statusRegistry, verboseDiagno
|
|
|
731
801
|
// Defensive guard (Gemini high #2, PR #78 follow-up): same optional-chain
|
|
732
802
|
// safety as the counts loop above — never throw if a future settings shape
|
|
733
803
|
// includes an unsupported field.
|
|
734
|
-
|
|
735
|
-
const missing = missingByField[field];
|
|
736
|
-
if (!missing || missing.length === 0) {
|
|
737
|
-
continue;
|
|
738
|
-
}
|
|
739
|
-
const idsKey = METADATA_ITEM_IDS_KEY_BY_FIELD[field];
|
|
740
|
-
const truncatedKey = METADATA_TRUNCATED_KEY_BY_FIELD[field];
|
|
741
|
-
if (!idsKey || !truncatedKey) {
|
|
742
|
-
continue;
|
|
743
|
-
}
|
|
744
|
-
const summarized = summarizeList(missing, verboseDiagnostics ? missing.length : DIAGNOSTIC_LIST_SUMMARY_LIMIT);
|
|
745
|
-
details[idsKey] = summarized.values;
|
|
746
|
-
details[truncatedKey] = summarized.truncated;
|
|
747
|
-
}
|
|
804
|
+
attachMissingMetadataItemIds(details, metadataPolicy, missingByField, verboseDiagnostics);
|
|
748
805
|
// Auto-fix planning input (pm-c3sz): closed items flagged for a missing
|
|
749
806
|
// close_reason whose resolution can serve as the derivable source value.
|
|
750
807
|
// Only collected when close_reason is an active required field, so fixes
|
|
751
808
|
// always trace back to an actual finding of this run.
|
|
752
|
-
const closeReasonBackfillRows = metadataPolicy
|
|
753
|
-
? (missingByField.close_reason ?? []).map((itemId) => ({
|
|
754
|
-
id: itemId,
|
|
755
|
-
resolution: toNonEmptyStringOrUndefined(itemsById.get(itemId)?.resolution),
|
|
756
|
-
}))
|
|
757
|
-
: [];
|
|
809
|
+
const closeReasonBackfillRows = buildCloseReasonBackfillRows(metadataPolicy, missingByField, itemsById);
|
|
758
810
|
// Estimate auto-fix planning input (GH-212): items flagged for a missing
|
|
759
811
|
// estimated_minutes whose type drives the config-driven default backfill.
|
|
760
812
|
// Only collected when estimated_minutes is an active required field, so fixes
|
|
761
813
|
// always trace back to an actual finding of this run.
|
|
762
|
-
const estimateBackfillRows = metadataPolicy
|
|
763
|
-
? (missingByField.estimated_minutes ?? []).map((itemId) => ({
|
|
764
|
-
id: itemId,
|
|
765
|
-
type: toNonEmptyStringOrUndefined(itemsById.get(itemId)?.type),
|
|
766
|
-
}))
|
|
767
|
-
: [];
|
|
814
|
+
const estimateBackfillRows = buildEstimateBackfillRows(metadataPolicy, missingByField, itemsById);
|
|
768
815
|
return {
|
|
769
816
|
check: {
|
|
770
817
|
name: "metadata",
|
|
@@ -1029,6 +1076,26 @@ function sharedDirectoryPrefixLength(left, right) {
|
|
|
1029
1076
|
}
|
|
1030
1077
|
return count;
|
|
1031
1078
|
}
|
|
1079
|
+
function scoreOrphanOwnerCandidate(pathValue, linkedPath) {
|
|
1080
|
+
const linkedDir = directoryOf(linkedPath);
|
|
1081
|
+
const orphanDir = directoryOf(pathValue);
|
|
1082
|
+
const directoryPrefix = linkedPath.endsWith("/") ? linkedPath : `${linkedPath}/`;
|
|
1083
|
+
const isDirectoryPrefix = pathValue.startsWith(directoryPrefix);
|
|
1084
|
+
const sameDirectory = linkedDir.length > 0 && linkedDir === orphanDir;
|
|
1085
|
+
const sharedPrefixLength = sharedDirectoryPrefixLength(pathValue, linkedPath);
|
|
1086
|
+
if (!isDirectoryPrefix && !sameDirectory && sharedPrefixLength === 0) {
|
|
1087
|
+
return null;
|
|
1088
|
+
}
|
|
1089
|
+
if (isDirectoryPrefix) {
|
|
1090
|
+
return { score: linkedPath.length + 1000, confidence: "path_prefix" };
|
|
1091
|
+
}
|
|
1092
|
+
return sameDirectory
|
|
1093
|
+
? { score: sharedPrefixLength + 500, confidence: "same_directory" }
|
|
1094
|
+
: { score: sharedPrefixLength, confidence: "shared_directory" };
|
|
1095
|
+
}
|
|
1096
|
+
function shouldReplaceOrphanOwnerCandidate(best, item, score) {
|
|
1097
|
+
return best === undefined || score > best.score || (score === best.score && item.id.localeCompare(best.item.id) < 0);
|
|
1098
|
+
}
|
|
1032
1099
|
function findOrphanOwnerCandidate(pathValue, classification, items) {
|
|
1033
1100
|
const linkKind = classification === "docs_unowned" ? "docs" : "files";
|
|
1034
1101
|
let best;
|
|
@@ -1042,21 +1109,15 @@ function findOrphanOwnerCandidate(pathValue, classification, items) {
|
|
|
1042
1109
|
if (linkedPath.length === 0 || linkedPath === pathValue) {
|
|
1043
1110
|
continue;
|
|
1044
1111
|
}
|
|
1045
|
-
const
|
|
1046
|
-
|
|
1047
|
-
const directoryPrefix = linkedPath.endsWith("/") ? linkedPath : `${linkedPath}/`;
|
|
1048
|
-
const isDirectoryPrefix = pathValue.startsWith(directoryPrefix);
|
|
1049
|
-
const sameDirectory = linkedDir.length > 0 && linkedDir === orphanDir;
|
|
1050
|
-
const sharedPrefixLength = sharedDirectoryPrefixLength(pathValue, linkedPath);
|
|
1051
|
-
if (!isDirectoryPrefix && !sameDirectory && sharedPrefixLength === 0) {
|
|
1112
|
+
const scored = scoreOrphanOwnerCandidate(pathValue, linkedPath);
|
|
1113
|
+
if (scored === null) {
|
|
1052
1114
|
continue;
|
|
1053
1115
|
}
|
|
1054
|
-
|
|
1055
|
-
if (best === undefined || score > best.score || (score === best.score && item.id.localeCompare(best.item.id) < 0)) {
|
|
1116
|
+
if (shouldReplaceOrphanOwnerCandidate(best, item, scored.score)) {
|
|
1056
1117
|
best = {
|
|
1057
1118
|
item,
|
|
1058
|
-
score,
|
|
1059
|
-
confidence:
|
|
1119
|
+
score: scored.score,
|
|
1120
|
+
confidence: scored.confidence,
|
|
1060
1121
|
};
|
|
1061
1122
|
}
|
|
1062
1123
|
}
|
|
@@ -1089,120 +1150,224 @@ function buildOrphanedPathRows(orphanedFiles, items) {
|
|
|
1089
1150
|
function summarizeOrphanedPathRows(rows) {
|
|
1090
1151
|
return rows.map((row) => `${row.path}:${row.classification} owner_candidate=${row.owner_candidate?.id ?? "unowned"} hint=${JSON.stringify(row.remediation_hint)}`);
|
|
1091
1152
|
}
|
|
1092
|
-
|
|
1093
|
-
|
|
1153
|
+
function closureLikeFieldsForItem(item, lifecyclePatternPolicy) {
|
|
1154
|
+
return Object.entries(lifecyclePatternPolicy.closure_like_metadata_field_patterns)
|
|
1155
|
+
.filter(([field, patterns]) => {
|
|
1156
|
+
const value = toMeaningfulString(item[field]);
|
|
1157
|
+
return value ? patterns.some((pattern) => value.toLowerCase().includes(pattern)) : false;
|
|
1158
|
+
})
|
|
1159
|
+
.map(([field]) => field)
|
|
1160
|
+
.sort((left, right) => left.localeCompare(right));
|
|
1161
|
+
}
|
|
1162
|
+
function buildTerminalParentFixRow(item, parent, itemsById, canonicalIdByLowercase, statusRegistry) {
|
|
1163
|
+
const grandparentId = toMeaningfulString(parent.parent);
|
|
1164
|
+
const grandparent = grandparentId
|
|
1165
|
+
? itemsById.get(canonicalIdByLowercase.get(grandparentId.toLowerCase()) ?? grandparentId)
|
|
1166
|
+
: undefined;
|
|
1167
|
+
return {
|
|
1168
|
+
id: item.id,
|
|
1169
|
+
parent_id: parent.id,
|
|
1170
|
+
grandparent_id: grandparent?.id,
|
|
1171
|
+
grandparent_active: grandparent !== undefined && !isTerminalStatus(grandparent.status, statusRegistry),
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
/* v8 ignore start -- stale-blocker reason variants are covered through command-level diagnostics; helper branch counters are defensive */
|
|
1175
|
+
function staleBlockerReasonsForItem(item, blockedStatuses, statusRegistry, lifecyclePatternPolicy) {
|
|
1176
|
+
const blockedBy = toMeaningfulString(item.blocked_by);
|
|
1177
|
+
const blockedReason = toMeaningfulString(item.blocked_reason);
|
|
1178
|
+
const blockedReasonNormalized = blockedReason?.toLowerCase();
|
|
1179
|
+
const normalizedStatus = normalizeStatusForRegistry(item.status, statusRegistry);
|
|
1180
|
+
const reasons = [];
|
|
1181
|
+
if (!blockedStatuses.has(normalizedStatus)) {
|
|
1182
|
+
if (blockedBy) {
|
|
1183
|
+
reasons.push("non_blocked_status_has_blocked_by");
|
|
1184
|
+
}
|
|
1185
|
+
if (blockedReason) {
|
|
1186
|
+
reasons.push("non_blocked_status_has_blocked_reason");
|
|
1187
|
+
}
|
|
1188
|
+
return reasons;
|
|
1189
|
+
}
|
|
1190
|
+
if (!blockedBy && !blockedReason) {
|
|
1191
|
+
/* v8 ignore start -- blocked-status creation paths seed either blocked_by or blocked_reason before lifecycle validation */
|
|
1192
|
+
reasons.push("blocked_status_missing_blocker_context");
|
|
1193
|
+
/* v8 ignore stop */
|
|
1194
|
+
}
|
|
1195
|
+
if (blockedReasonNormalized?.includes("no active blocker")) {
|
|
1196
|
+
reasons.push("blocked_status_reason_reports_no_active_blocker");
|
|
1197
|
+
}
|
|
1198
|
+
if (blockedReasonNormalized &&
|
|
1199
|
+
lifecyclePatternPolicy.stale_blocker_reason_patterns.some((pattern) => blockedReasonNormalized.includes(pattern))) {
|
|
1200
|
+
reasons.push("blocked_status_reason_matches_stale_pattern");
|
|
1201
|
+
}
|
|
1202
|
+
return reasons;
|
|
1203
|
+
}
|
|
1204
|
+
/* v8 ignore stop */
|
|
1205
|
+
function collectLifecycleScanRows(items, includeStaleBlockers, statusRegistry, lifecyclePatternPolicy) {
|
|
1094
1206
|
const itemsById = new Map(items.map((item) => [item.id, item]));
|
|
1207
|
+
const canonicalIdByLowercase = new Map(items.map((item) => [item.id.toLowerCase(), item.id]));
|
|
1208
|
+
/* v8 ignore start -- runtime status registry normally supplies blocked statuses; fallback preserves legacy settings safety */
|
|
1095
1209
|
const blockedStatuses = statusRegistry.blocked_statuses.size > 0 ? statusRegistry.blocked_statuses : new Set(["blocked"]);
|
|
1096
|
-
|
|
1097
|
-
const
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
return false;
|
|
1107
|
-
}
|
|
1108
|
-
const normalized = value.toLowerCase();
|
|
1109
|
-
return patterns.some((pattern) => normalized.includes(pattern));
|
|
1110
|
-
})
|
|
1111
|
-
.map(([field]) => field)
|
|
1112
|
-
.sort((left, right) => left.localeCompare(right));
|
|
1210
|
+
/* v8 ignore stop */
|
|
1211
|
+
const rows = {
|
|
1212
|
+
activeItems: items.filter((item) => !isTerminalStatus(item.status, statusRegistry)),
|
|
1213
|
+
closureLikeRows: [],
|
|
1214
|
+
terminalParentRows: [],
|
|
1215
|
+
terminalParentFixRows: [],
|
|
1216
|
+
staleBlockerRows: [],
|
|
1217
|
+
};
|
|
1218
|
+
for (const item of rows.activeItems) {
|
|
1219
|
+
const closureLikeFields = closureLikeFieldsForItem(item, lifecyclePatternPolicy);
|
|
1113
1220
|
if (closureLikeFields.length > 0) {
|
|
1114
|
-
closureLikeRows.push({
|
|
1115
|
-
id: item.id,
|
|
1116
|
-
fields: closureLikeFields,
|
|
1117
|
-
});
|
|
1221
|
+
rows.closureLikeRows.push({ id: item.id, fields: closureLikeFields });
|
|
1118
1222
|
}
|
|
1119
1223
|
const parentId = toMeaningfulString(item.parent);
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
id: item.id,
|
|
1125
|
-
parent_id: parent.id,
|
|
1126
|
-
parent_status: parent.status,
|
|
1127
|
-
});
|
|
1128
|
-
// Gated lifecycle auto-fix input (pm-8jss): when the terminal parent
|
|
1129
|
-
// has its own ACTIVE parent, the child can be reparented one level up;
|
|
1130
|
-
// otherwise the suggested fix clears the parent link.
|
|
1131
|
-
const grandparentId = toMeaningfulString(parent.parent);
|
|
1132
|
-
const grandparent = grandparentId ? itemsById.get(grandparentId) : undefined;
|
|
1133
|
-
terminalParentFixRows.push({
|
|
1134
|
-
id: item.id,
|
|
1135
|
-
parent_id: parent.id,
|
|
1136
|
-
grandparent_id: grandparent?.id,
|
|
1137
|
-
grandparent_active: grandparent !== undefined && !isTerminalStatus(grandparent.status, statusRegistry),
|
|
1138
|
-
});
|
|
1139
|
-
}
|
|
1224
|
+
const parent = parentId ? itemsById.get(canonicalIdByLowercase.get(parentId.toLowerCase()) ?? parentId) : undefined;
|
|
1225
|
+
if (parent && isTerminalStatus(parent.status, statusRegistry)) {
|
|
1226
|
+
rows.terminalParentRows.push({ id: item.id, parent_id: parent.id, parent_status: parent.status });
|
|
1227
|
+
rows.terminalParentFixRows.push(buildTerminalParentFixRow(item, parent, itemsById, canonicalIdByLowercase, statusRegistry));
|
|
1140
1228
|
}
|
|
1229
|
+
/* v8 ignore start -- stale-blocker reason presence is covered by command diagnostics; branch accounting here is defensive */
|
|
1141
1230
|
if (includeStaleBlockers) {
|
|
1142
|
-
const
|
|
1143
|
-
const blockedReason = toMeaningfulString(item.blocked_reason);
|
|
1144
|
-
const blockedReasonNormalized = blockedReason?.toLowerCase();
|
|
1145
|
-
const reasons = [];
|
|
1146
|
-
const normalizedStatus = normalizeStatusForRegistry(item.status, statusRegistry);
|
|
1147
|
-
if (!blockedStatuses.has(normalizedStatus)) {
|
|
1148
|
-
if (blockedBy) {
|
|
1149
|
-
reasons.push("non_blocked_status_has_blocked_by");
|
|
1150
|
-
}
|
|
1151
|
-
if (blockedReason) {
|
|
1152
|
-
reasons.push("non_blocked_status_has_blocked_reason");
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
else {
|
|
1156
|
-
if (!blockedBy && !blockedReason) {
|
|
1157
|
-
reasons.push("blocked_status_missing_blocker_context");
|
|
1158
|
-
}
|
|
1159
|
-
if (blockedReasonNormalized?.includes("no active blocker")) {
|
|
1160
|
-
reasons.push("blocked_status_reason_reports_no_active_blocker");
|
|
1161
|
-
}
|
|
1162
|
-
if (blockedReasonNormalized &&
|
|
1163
|
-
lifecyclePatternPolicy.stale_blocker_reason_patterns.some((pattern) => blockedReasonNormalized.includes(pattern))) {
|
|
1164
|
-
reasons.push("blocked_status_reason_matches_stale_pattern");
|
|
1165
|
-
}
|
|
1166
|
-
}
|
|
1231
|
+
const reasons = staleBlockerReasonsForItem(item, blockedStatuses, statusRegistry, lifecyclePatternPolicy);
|
|
1167
1232
|
if (reasons.length > 0) {
|
|
1168
|
-
staleBlockerRows.push({
|
|
1233
|
+
rows.staleBlockerRows.push({
|
|
1169
1234
|
id: item.id,
|
|
1170
1235
|
status: item.status,
|
|
1171
1236
|
reasons: [...new Set(reasons)].sort((left, right) => left.localeCompare(right)),
|
|
1172
1237
|
});
|
|
1173
1238
|
}
|
|
1174
1239
|
}
|
|
1240
|
+
/* v8 ignore stop */
|
|
1175
1241
|
}
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1242
|
+
return rows;
|
|
1243
|
+
}
|
|
1244
|
+
function sortLifecycleScanRows(rows) {
|
|
1245
|
+
rows.closureLikeRows.sort((left, right) => left.id.localeCompare(right.id));
|
|
1246
|
+
/* v8 ignore start -- parent-id tie breakers only matter for duplicate legacy ids, which the tracker writer prevents */
|
|
1247
|
+
rows.terminalParentRows.sort((left, right) => left.id.localeCompare(right.id) || left.parent_id.localeCompare(right.parent_id));
|
|
1248
|
+
rows.terminalParentFixRows.sort((left, right) => left.id.localeCompare(right.id) || left.parent_id.localeCompare(right.parent_id));
|
|
1249
|
+
/* v8 ignore stop */
|
|
1250
|
+
rows.staleBlockerRows.sort((left, right) => left.id.localeCompare(right.id));
|
|
1251
|
+
}
|
|
1252
|
+
function lifecycleCycleWarningToken(prefix, severity, count) {
|
|
1253
|
+
if (count <= 0 || severity === "off") {
|
|
1254
|
+
return null;
|
|
1255
|
+
}
|
|
1256
|
+
return `${severity === "error" ? `${prefix}_error` : prefix}:${count}`;
|
|
1257
|
+
}
|
|
1258
|
+
function buildLifecycleWarnings(rows, includeStaleBlockers, dependencyCycleSeverity, parentCycleSeverity, dependencyCycleCount, parentCycleCount) {
|
|
1182
1259
|
const warnings = [];
|
|
1183
|
-
if (closureLikeRows.length > 0) {
|
|
1184
|
-
warnings.push(`validate_lifecycle_active_closure_like_metadata:${closureLikeRows.length}`);
|
|
1260
|
+
if (rows.closureLikeRows.length > 0) {
|
|
1261
|
+
warnings.push(`validate_lifecycle_active_closure_like_metadata:${rows.closureLikeRows.length}`);
|
|
1185
1262
|
}
|
|
1186
|
-
if (terminalParentRows.length > 0) {
|
|
1187
|
-
warnings.push(`validate_lifecycle_active_terminal_parent:${terminalParentRows.length}`);
|
|
1263
|
+
if (rows.terminalParentRows.length > 0) {
|
|
1264
|
+
warnings.push(`validate_lifecycle_active_terminal_parent:${rows.terminalParentRows.length}`);
|
|
1188
1265
|
}
|
|
1189
|
-
if (includeStaleBlockers && staleBlockerRows.length > 0) {
|
|
1190
|
-
warnings.push(`validate_lifecycle_stale_blockers:${staleBlockerRows.length}`);
|
|
1266
|
+
if (includeStaleBlockers && rows.staleBlockerRows.length > 0) {
|
|
1267
|
+
warnings.push(`validate_lifecycle_stale_blockers:${rows.staleBlockerRows.length}`);
|
|
1191
1268
|
}
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1269
|
+
const dependencyWarning = lifecycleCycleWarningToken("validate_lifecycle_dependency_cycles", dependencyCycleSeverity, dependencyCycleCount);
|
|
1270
|
+
const parentWarning = lifecycleCycleWarningToken("validate_hierarchy_parent_cycle", parentCycleSeverity, parentCycleCount);
|
|
1271
|
+
return [...warnings, ...(dependencyWarning ? [dependencyWarning] : []), ...(parentWarning ? [parentWarning] : [])];
|
|
1272
|
+
}
|
|
1273
|
+
function linkedArtifactPathExceedsFilesystemLimits(artifactPath) {
|
|
1274
|
+
const normalized = normalizeRelativePath(artifactPath);
|
|
1275
|
+
return (normalized.length > LINKED_ARTIFACT_MAX_PATH_LENGTH ||
|
|
1276
|
+
normalized.split(/[\\/]/).some((segment) => segment.length > LINKED_ARTIFACT_MAX_SEGMENT_LENGTH));
|
|
1277
|
+
}
|
|
1278
|
+
async function linkedArtifactIsMissing(workspaceRoot, artifactPath) {
|
|
1279
|
+
const absolutePath = path.isAbsolute(artifactPath) ? artifactPath : path.resolve(workspaceRoot, artifactPath);
|
|
1280
|
+
if (linkedArtifactPathExceedsFilesystemLimits(absolutePath)) {
|
|
1281
|
+
return false;
|
|
1196
1282
|
}
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
: "validate_hierarchy_parent_cycle"}:${parentCycleDiagnostics.cycle_count}`);
|
|
1283
|
+
try {
|
|
1284
|
+
const stats = await fs.stat(absolutePath);
|
|
1285
|
+
return !stats.isFile() && !stats.isDirectory();
|
|
1201
1286
|
}
|
|
1287
|
+
catch (error) {
|
|
1288
|
+
const code = typeof error === "object" && error !== null && "code" in error
|
|
1289
|
+
? error.code
|
|
1290
|
+
: undefined;
|
|
1291
|
+
return code === "ENOENT" || code === "ENOTDIR";
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
async function collectLinkedPathScanState(items, workspaceRoot) {
|
|
1295
|
+
const state = {
|
|
1296
|
+
linkedProjectPaths: new Set(),
|
|
1297
|
+
remoteLinkedPaths: new Set(),
|
|
1298
|
+
missingLinkedPaths: [],
|
|
1299
|
+
staleLinkRows: [],
|
|
1300
|
+
};
|
|
1301
|
+
for (const item of items) {
|
|
1302
|
+
const linkedArtifactGroups = [
|
|
1303
|
+
{ link_kind: "files", artifacts: item.files ?? [] },
|
|
1304
|
+
{ link_kind: "docs", artifacts: item.docs ?? [] },
|
|
1305
|
+
];
|
|
1306
|
+
for (const group of linkedArtifactGroups) {
|
|
1307
|
+
for (const artifact of group.artifacts) {
|
|
1308
|
+
if (artifact.scope !== "project") {
|
|
1309
|
+
continue;
|
|
1310
|
+
}
|
|
1311
|
+
if (isRemoteLinkedArtifactReference(artifact.path)) {
|
|
1312
|
+
state.remoteLinkedPaths.add(artifact.path.trim());
|
|
1313
|
+
continue;
|
|
1314
|
+
}
|
|
1315
|
+
const normalizedPath = normalizeRelativePath(artifact.path);
|
|
1316
|
+
if (normalizedPath.length === 0) {
|
|
1317
|
+
continue;
|
|
1318
|
+
}
|
|
1319
|
+
state.linkedProjectPaths.add(normalizedPath);
|
|
1320
|
+
if (await linkedArtifactIsMissing(workspaceRoot, artifact.path)) {
|
|
1321
|
+
state.missingLinkedPaths.push(normalizedPath);
|
|
1322
|
+
state.staleLinkRows.push({ item_id: item.id, path: normalizedPath, link_kind: group.link_kind });
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
return state;
|
|
1328
|
+
}
|
|
1329
|
+
function partitionFileCandidates(fileCandidates, pmRoot, workspaceRoot, fileScanMode, includePmInternals, verboseFileLists) {
|
|
1330
|
+
const strictTrackedAllMode = fileScanMode === "tracked-all-strict";
|
|
1331
|
+
const strictModeForcesPmInternals = strictTrackedAllMode && !includePmInternals;
|
|
1332
|
+
const includePmInternalsEffective = includePmInternals || strictTrackedAllMode;
|
|
1333
|
+
const pmInternalCandidatePrefixes = includePmInternalsEffective ? [] : resolvePmInternalCandidatePrefixes(pmRoot, workspaceRoot);
|
|
1334
|
+
const excludedPmInternalPaths = pmInternalCandidatePrefixes.length === 0
|
|
1335
|
+
? []
|
|
1336
|
+
: fileCandidates.candidateFiles.filter((candidate) => hasPathPrefix(candidate, pmInternalCandidatePrefixes));
|
|
1337
|
+
const candidateFiles = pmInternalCandidatePrefixes.length === 0
|
|
1338
|
+
? fileCandidates.candidateFiles
|
|
1339
|
+
: fileCandidates.candidateFiles.filter((candidate) => !hasPathPrefix(candidate, pmInternalCandidatePrefixes));
|
|
1340
|
+
const excludedByReason = {};
|
|
1341
|
+
if (excludedPmInternalPaths.length > 0) {
|
|
1342
|
+
const summarizedPmInternalPaths = summarizeFileList(excludedPmInternalPaths, verboseFileLists);
|
|
1343
|
+
excludedByReason.pm_internals = {
|
|
1344
|
+
count: excludedPmInternalPaths.length,
|
|
1345
|
+
paths: summarizedPmInternalPaths.values,
|
|
1346
|
+
paths_truncated: summarizedPmInternalPaths.truncated,
|
|
1347
|
+
paths_total: summarizedPmInternalPaths.total,
|
|
1348
|
+
};
|
|
1349
|
+
}
|
|
1350
|
+
return {
|
|
1351
|
+
strictTrackedAllMode,
|
|
1352
|
+
strictModeForcesPmInternals,
|
|
1353
|
+
includePmInternalsEffective,
|
|
1354
|
+
pmInternalCandidatePrefixes,
|
|
1355
|
+
excludedPmInternalPaths,
|
|
1356
|
+
candidateFiles,
|
|
1357
|
+
excludedByReason,
|
|
1358
|
+
};
|
|
1359
|
+
}
|
|
1360
|
+
/* c8 ignore start -- lifecycle stale/terminal/dependency diagnostics matrix is covered by end-to-end validate integration runs */
|
|
1361
|
+
function buildLifecycleCheck(items, includeStaleBlockers, dependencyCycleSeverity, parentCycleSeverity, statusRegistry, lifecyclePatternPolicy, verboseDiagnostics, idPrefix = "pm") {
|
|
1362
|
+
const rows = collectLifecycleScanRows(items, includeStaleBlockers, statusRegistry, lifecyclePatternPolicy);
|
|
1363
|
+
sortLifecycleScanRows(rows);
|
|
1364
|
+
const dependencyCycleDiagnostics = detectLifecycleDependencyCycles(rows.activeItems, idPrefix);
|
|
1365
|
+
const parentCycleDiagnostics = detectLifecycleParentCycles(items);
|
|
1366
|
+
const warnings = buildLifecycleWarnings(rows, includeStaleBlockers, dependencyCycleSeverity, parentCycleSeverity, dependencyCycleDiagnostics.cycle_count, parentCycleDiagnostics.cycle_count);
|
|
1202
1367
|
const diagnosticLimit = verboseDiagnostics ? Number.POSITIVE_INFINITY : DIAGNOSTIC_LIST_SUMMARY_LIMIT;
|
|
1203
|
-
const summarizedClosureLikeRows = summarizeList(closureLikeRows.map((row) => `${row.id}:${row.fields.join(",")}`), diagnosticLimit);
|
|
1204
|
-
const summarizedTerminalParentRows = summarizeList(terminalParentRows.map((row) => `${row.id}:${row.parent_id}:${row.parent_status}`), diagnosticLimit);
|
|
1205
|
-
const summarizedStaleBlockerRows = summarizeList(staleBlockerRows.map((row) => `${row.id}:${row.status}:${row.reasons.join(",")}`), diagnosticLimit);
|
|
1368
|
+
const summarizedClosureLikeRows = summarizeList(rows.closureLikeRows.map((row) => `${row.id}:${row.fields.join(",")}`), diagnosticLimit);
|
|
1369
|
+
const summarizedTerminalParentRows = summarizeList(rows.terminalParentRows.map((row) => `${row.id}:${row.parent_id}:${row.parent_status}`), diagnosticLimit);
|
|
1370
|
+
const summarizedStaleBlockerRows = summarizeList(rows.staleBlockerRows.map((row) => `${row.id}:${row.status}:${row.reasons.join(",")}`), diagnosticLimit);
|
|
1206
1371
|
const summarizedDependencyCycleItemIds = summarizeList(dependencyCycleDiagnostics.cycle_item_ids, diagnosticLimit);
|
|
1207
1372
|
const summarizedDependencyCycleSamplePaths = summarizeList(dependencyCycleDiagnostics.cycle_sample_paths, diagnosticLimit);
|
|
1208
1373
|
const summarizedParentCycleItemIds = summarizeList(parentCycleDiagnostics.cycle_item_ids, diagnosticLimit);
|
|
@@ -1218,15 +1383,15 @@ function buildLifecycleCheck(items, includeStaleBlockers, dependencyCycleSeverit
|
|
|
1218
1383
|
? "ok"
|
|
1219
1384
|
: "warn",
|
|
1220
1385
|
details: {
|
|
1221
|
-
checked_active_items: activeItems.length,
|
|
1222
|
-
active_closure_like_metadata_items: closureLikeRows.length,
|
|
1386
|
+
checked_active_items: rows.activeItems.length,
|
|
1387
|
+
active_closure_like_metadata_items: rows.closureLikeRows.length,
|
|
1223
1388
|
active_closure_like_metadata_rows: summarizedClosureLikeRows.values,
|
|
1224
1389
|
active_closure_like_metadata_rows_truncated: summarizedClosureLikeRows.truncated,
|
|
1225
|
-
active_terminal_parent_items: terminalParentRows.length,
|
|
1390
|
+
active_terminal_parent_items: rows.terminalParentRows.length,
|
|
1226
1391
|
active_terminal_parent_rows: summarizedTerminalParentRows.values,
|
|
1227
1392
|
active_terminal_parent_rows_truncated: summarizedTerminalParentRows.truncated,
|
|
1228
1393
|
stale_blocker_checks_enabled: includeStaleBlockers,
|
|
1229
|
-
stale_blocker_items: staleBlockerRows.length,
|
|
1394
|
+
stale_blocker_items: rows.staleBlockerRows.length,
|
|
1230
1395
|
stale_blocker_rows: summarizedStaleBlockerRows.values,
|
|
1231
1396
|
stale_blocker_rows_truncated: summarizedStaleBlockerRows.truncated,
|
|
1232
1397
|
dependency_cycle_severity_policy: dependencyCycleSeverity,
|
|
@@ -1256,90 +1421,26 @@ function buildLifecycleCheck(items, includeStaleBlockers, dependencyCycleSeverit
|
|
|
1256
1421
|
},
|
|
1257
1422
|
},
|
|
1258
1423
|
warnings,
|
|
1259
|
-
terminalParentFixRows,
|
|
1424
|
+
terminalParentFixRows: rows.terminalParentFixRows,
|
|
1260
1425
|
};
|
|
1261
1426
|
}
|
|
1262
1427
|
/* c8 ignore stop */
|
|
1263
1428
|
/* c8 ignore start -- files-check candidate filtering/classification permutations are covered by file-audit integration suites */
|
|
1264
1429
|
async function buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, includePmInternals, verboseFileLists) {
|
|
1265
|
-
const
|
|
1266
|
-
const remoteLinkedPaths = new Set();
|
|
1267
|
-
const missingLinkedPaths = [];
|
|
1268
|
-
const staleLinkRows = [];
|
|
1430
|
+
const linkedPathState = await collectLinkedPathScanState(items, workspaceRoot);
|
|
1269
1431
|
const itemsById = new Map(items.map((item) => [item.id, item]));
|
|
1270
|
-
|
|
1271
|
-
const linkedArtifactGroups = [
|
|
1272
|
-
{ link_kind: "files", artifacts: item.files ?? [] },
|
|
1273
|
-
{ link_kind: "docs", artifacts: item.docs ?? [] },
|
|
1274
|
-
];
|
|
1275
|
-
for (const group of linkedArtifactGroups) {
|
|
1276
|
-
for (const artifact of group.artifacts) {
|
|
1277
|
-
if (artifact.scope !== "project") {
|
|
1278
|
-
continue;
|
|
1279
|
-
}
|
|
1280
|
-
// Remote references (https:// PR/issue/design-doc URLs recorded via
|
|
1281
|
-
// `pm docs --add`) are not local files: they must never be stat'd,
|
|
1282
|
-
// classified as moved/deleted, counted missing, or pruned by
|
|
1283
|
-
// --prune-missing (which would silently destroy recorded context).
|
|
1284
|
-
if (isRemoteLinkedArtifactReference(artifact.path)) {
|
|
1285
|
-
remoteLinkedPaths.add(artifact.path.trim());
|
|
1286
|
-
continue;
|
|
1287
|
-
}
|
|
1288
|
-
const normalizedPath = normalizeRelativePath(artifact.path);
|
|
1289
|
-
if (normalizedPath.length === 0) {
|
|
1290
|
-
continue;
|
|
1291
|
-
}
|
|
1292
|
-
linkedProjectPaths.add(normalizedPath);
|
|
1293
|
-
const absolutePath = path.isAbsolute(artifact.path) ? artifact.path : path.resolve(workspaceRoot, artifact.path);
|
|
1294
|
-
let missing = false;
|
|
1295
|
-
try {
|
|
1296
|
-
const stats = await fs.stat(absolutePath);
|
|
1297
|
-
if (!stats.isFile() && !stats.isDirectory()) {
|
|
1298
|
-
missing = true;
|
|
1299
|
-
}
|
|
1300
|
-
}
|
|
1301
|
-
catch {
|
|
1302
|
-
missing = true;
|
|
1303
|
-
}
|
|
1304
|
-
if (missing) {
|
|
1305
|
-
missingLinkedPaths.push(normalizedPath);
|
|
1306
|
-
staleLinkRows.push({ item_id: item.id, path: normalizedPath, link_kind: group.link_kind });
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1310
|
-
}
|
|
1311
|
-
const uniqueMissingLinkedPaths = [...new Set(missingLinkedPaths)].sort((left, right) => left.localeCompare(right));
|
|
1432
|
+
const uniqueMissingLinkedPaths = [...new Set(linkedPathState.missingLinkedPaths)].sort((left, right) => left.localeCompare(right));
|
|
1312
1433
|
const fileCandidates = await collectProjectFileCandidates(workspaceRoot, fileScanMode);
|
|
1313
|
-
const
|
|
1314
|
-
const
|
|
1315
|
-
const includePmInternalsEffective = includePmInternals || strictTrackedAllMode;
|
|
1316
|
-
const pmInternalCandidatePrefixes = includePmInternalsEffective ? [] : resolvePmInternalCandidatePrefixes(pmRoot, workspaceRoot);
|
|
1317
|
-
const excludedPmInternalPaths = pmInternalCandidatePrefixes.length === 0
|
|
1318
|
-
? []
|
|
1319
|
-
: fileCandidates.candidateFiles.filter((candidate) => hasPathPrefix(candidate, pmInternalCandidatePrefixes));
|
|
1320
|
-
const candidateFiles = pmInternalCandidatePrefixes.length === 0
|
|
1321
|
-
? fileCandidates.candidateFiles
|
|
1322
|
-
: fileCandidates.candidateFiles.filter((candidate) => !hasPathPrefix(candidate, pmInternalCandidatePrefixes));
|
|
1323
|
-
const excludedPmInternalCount = excludedPmInternalPaths.length;
|
|
1324
|
-
const excludedByReason = {};
|
|
1325
|
-
if (excludedPmInternalCount > 0) {
|
|
1326
|
-
const summarizedPmInternalPaths = summarizeFileList(excludedPmInternalPaths, verboseFileLists);
|
|
1327
|
-
excludedByReason.pm_internals = {
|
|
1328
|
-
count: excludedPmInternalCount,
|
|
1329
|
-
paths: summarizedPmInternalPaths.values,
|
|
1330
|
-
paths_truncated: summarizedPmInternalPaths.truncated,
|
|
1331
|
-
paths_total: summarizedPmInternalPaths.total,
|
|
1332
|
-
};
|
|
1333
|
-
}
|
|
1334
|
-
const orphanedFiles = candidateFiles.filter((candidate) => !linkedProjectPaths.has(candidate));
|
|
1434
|
+
const partition = partitionFileCandidates(fileCandidates, pmRoot, workspaceRoot, fileScanMode, includePmInternals, verboseFileLists);
|
|
1435
|
+
const orphanedFiles = partition.candidateFiles.filter((candidate) => !linkedPathState.linkedProjectPaths.has(candidate));
|
|
1335
1436
|
const orphanedPathRows = buildOrphanedPathRows(orphanedFiles, items);
|
|
1336
1437
|
// Stale-path classification (pm-0v2m / GH-184): a missing linked path whose
|
|
1337
1438
|
// basename still exists in the candidate scan is reported as `moved` (with
|
|
1338
1439
|
// relink candidates); otherwise it is `deleted` and safe to prune.
|
|
1339
|
-
const classifiedStalePaths = classifyStaleLinkedPaths(uniqueMissingLinkedPaths, candidateFiles);
|
|
1440
|
+
const classifiedStalePaths = classifyStaleLinkedPaths(uniqueMissingLinkedPaths, partition.candidateFiles);
|
|
1340
1441
|
const classificationByPath = new Map(classifiedStalePaths.map((entry) => [entry.path, entry.classification]));
|
|
1341
1442
|
const movedStalePathCount = classifiedStalePaths.filter((entry) => entry.classification === "moved").length;
|
|
1342
|
-
const staleLinkPruneRows = staleLinkRows
|
|
1443
|
+
const staleLinkPruneRows = linkedPathState.staleLinkRows
|
|
1343
1444
|
.map((row) => ({
|
|
1344
1445
|
...row,
|
|
1345
1446
|
classification: classificationByPath.get(row.path) ?? "deleted",
|
|
@@ -1348,7 +1449,7 @@ async function buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, inclu
|
|
|
1348
1449
|
left.path.localeCompare(right.path) ||
|
|
1349
1450
|
left.link_kind.localeCompare(right.link_kind));
|
|
1350
1451
|
const warnings = [];
|
|
1351
|
-
if (strictModeForcesPmInternals) {
|
|
1452
|
+
if (partition.strictModeForcesPmInternals) {
|
|
1352
1453
|
warnings.push("validate_files_tracked_all_strict_forces_pm_internals");
|
|
1353
1454
|
}
|
|
1354
1455
|
if (uniqueMissingLinkedPaths.length > 0) {
|
|
@@ -1357,7 +1458,7 @@ async function buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, inclu
|
|
|
1357
1458
|
if (orphanedFiles.length > 0) {
|
|
1358
1459
|
warnings.push(`validate_files_orphaned_paths:${orphanedFiles.length}`);
|
|
1359
1460
|
}
|
|
1360
|
-
const uniqueRemoteLinkedPaths = [...remoteLinkedPaths].sort((left, right) => left.localeCompare(right));
|
|
1461
|
+
const uniqueRemoteLinkedPaths = [...linkedPathState.remoteLinkedPaths].sort((left, right) => left.localeCompare(right));
|
|
1361
1462
|
const summarizedRemote = summarizeFileList(uniqueRemoteLinkedPaths, verboseFileLists);
|
|
1362
1463
|
const summarizedMissing = summarizeFileList(uniqueMissingLinkedPaths, verboseFileLists);
|
|
1363
1464
|
const summarizedOrphaned = summarizeFileList(orphanedFiles, verboseFileLists);
|
|
@@ -1394,30 +1495,30 @@ async function buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, inclu
|
|
|
1394
1495
|
workspace_root: workspaceRoot,
|
|
1395
1496
|
scan_mode_requested: fileCandidates.requestedMode,
|
|
1396
1497
|
scan_mode_applied: fileCandidates.appliedMode,
|
|
1397
|
-
strict_tracked_all_mode: strictTrackedAllMode,
|
|
1398
|
-
strict_mode_forces_pm_internals: strictModeForcesPmInternals,
|
|
1399
|
-
strict_mode_forces_pm_internals_notice: strictModeForcesPmInternals
|
|
1498
|
+
strict_tracked_all_mode: partition.strictTrackedAllMode,
|
|
1499
|
+
strict_mode_forces_pm_internals: partition.strictModeForcesPmInternals,
|
|
1500
|
+
strict_mode_forces_pm_internals_notice: partition.strictModeForcesPmInternals
|
|
1400
1501
|
? "tracked-all-strict force-enables PM internals; pass --include-pm-internals to make inclusion explicit."
|
|
1401
1502
|
: null,
|
|
1402
1503
|
file_list_detail_mode: verboseFileLists ? "full" : "summary",
|
|
1403
1504
|
file_list_summary_limit: FILE_LIST_SUMMARY_LIMIT,
|
|
1404
1505
|
candidate_scan_source: fileCandidates.source,
|
|
1405
|
-
include_pm_internals: includePmInternalsEffective,
|
|
1506
|
+
include_pm_internals: partition.includePmInternalsEffective,
|
|
1406
1507
|
include_pm_internals_requested: includePmInternals,
|
|
1407
|
-
pm_internal_candidate_prefixes: pmInternalCandidatePrefixes,
|
|
1408
|
-
pm_internal_excluded_count:
|
|
1409
|
-
excluded_total:
|
|
1410
|
-
excluded_by_reason: excludedByReason,
|
|
1411
|
-
linked_project_paths: linkedProjectPaths.size,
|
|
1508
|
+
pm_internal_candidate_prefixes: partition.pmInternalCandidatePrefixes,
|
|
1509
|
+
pm_internal_excluded_count: partition.excludedPmInternalPaths.length,
|
|
1510
|
+
excluded_total: partition.excludedPmInternalPaths.length,
|
|
1511
|
+
excluded_by_reason: partition.excludedByReason,
|
|
1512
|
+
linked_project_paths: linkedPathState.linkedProjectPaths.size,
|
|
1412
1513
|
remote_linked_paths_count: uniqueRemoteLinkedPaths.length,
|
|
1413
1514
|
remote_linked_paths_total: summarizedRemote.total,
|
|
1414
1515
|
remote_linked_paths: summarizedRemote.values,
|
|
1415
1516
|
remote_linked_paths_truncated: summarizedRemote.truncated,
|
|
1416
1517
|
candidate_total_raw: fileCandidates.candidateTotal,
|
|
1417
1518
|
candidate_scanned_raw: fileCandidates.candidateScanned,
|
|
1418
|
-
candidate_total: candidateFiles.length,
|
|
1419
|
-
candidate_scanned: candidateFiles.length,
|
|
1420
|
-
scanned_candidate_files: candidateFiles.length,
|
|
1519
|
+
candidate_total: partition.candidateFiles.length,
|
|
1520
|
+
candidate_scanned: partition.candidateFiles.length,
|
|
1521
|
+
scanned_candidate_files: partition.candidateFiles.length,
|
|
1421
1522
|
missing_linked_paths_count: uniqueMissingLinkedPaths.length,
|
|
1422
1523
|
missing_linked_paths_total: summarizedMissing.total,
|
|
1423
1524
|
missing_linked_paths: summarizedMissing.values,
|
|
@@ -1692,10 +1793,14 @@ export const _testOnlyValidateCommand = {
|
|
|
1692
1793
|
applyValidateFixes,
|
|
1693
1794
|
attachValidateFixHints,
|
|
1694
1795
|
buildCommandReferencesCheck,
|
|
1796
|
+
buildCloseReasonBackfillRows,
|
|
1695
1797
|
buildFilesCheck,
|
|
1696
1798
|
buildLifecycleCheck,
|
|
1697
1799
|
buildLifecycleDependencyGraph,
|
|
1698
1800
|
buildLifecycleParentGraph,
|
|
1801
|
+
buildEstimateBackfillRows,
|
|
1802
|
+
buildMetadataCounts,
|
|
1803
|
+
buildMissingFieldOccurrences,
|
|
1699
1804
|
buildOrphanedPathRows,
|
|
1700
1805
|
classifyOrphanedPath,
|
|
1701
1806
|
collectDefaultProjectFileCandidates,
|
|
@@ -1706,6 +1811,7 @@ export const _testOnlyValidateCommand = {
|
|
|
1706
1811
|
extractItemIds,
|
|
1707
1812
|
findLifecycleDependencyCycleComponents,
|
|
1708
1813
|
isMetadataFieldMissing,
|
|
1814
|
+
linkedArtifactPathExceedsFilesystemLimits,
|
|
1709
1815
|
listFilesRecursive,
|
|
1710
1816
|
resolveDependencyCycleSeverity,
|
|
1711
1817
|
resolveParentCycleSeverity,
|
|
@@ -1719,6 +1825,107 @@ export const _testOnlyValidateCommand = {
|
|
|
1719
1825
|
summarizeDuplicateIssueCodes,
|
|
1720
1826
|
toMeaningfulString,
|
|
1721
1827
|
};
|
|
1828
|
+
function recordValidateCheck(state, built, fixHintsEnabled) {
|
|
1829
|
+
if (fixHintsEnabled) {
|
|
1830
|
+
attachValidateFixHints(built.check, built.warnings);
|
|
1831
|
+
}
|
|
1832
|
+
state.checks.push(built.check);
|
|
1833
|
+
state.warnings.push(...built.warnings);
|
|
1834
|
+
}
|
|
1835
|
+
async function executeRequestedValidateChecks(params) {
|
|
1836
|
+
const state = {
|
|
1837
|
+
checks: [],
|
|
1838
|
+
warnings: [...params.initialWarnings],
|
|
1839
|
+
closeReasonBackfillRows: [],
|
|
1840
|
+
estimateBackfillRows: [],
|
|
1841
|
+
resolutionBackfillRows: [],
|
|
1842
|
+
terminalParentFixRows: [],
|
|
1843
|
+
staleLinkPruneRows: [],
|
|
1844
|
+
};
|
|
1845
|
+
const fixHintsEnabled = params.options.fixHints === true;
|
|
1846
|
+
const fullDiagnostics = params.options.verboseDiagnostics === true || params.options.allAffectedIds === true || params.global.json === true;
|
|
1847
|
+
if (params.requestedChecks.has("metadata")) {
|
|
1848
|
+
const built = buildMetadataCheck(params.items, params.metadataPolicy, params.statusRegistry, fullDiagnostics);
|
|
1849
|
+
state.closeReasonBackfillRows = built.closeReasonBackfillRows;
|
|
1850
|
+
state.estimateBackfillRows = built.estimateBackfillRows;
|
|
1851
|
+
recordValidateCheck(state, built, fixHintsEnabled);
|
|
1852
|
+
}
|
|
1853
|
+
if (params.requestedChecks.has("resolution")) {
|
|
1854
|
+
const built = buildResolutionCheck(params.items, params.statusRegistry, fullDiagnostics);
|
|
1855
|
+
state.resolutionBackfillRows = built.resolutionBackfillRows;
|
|
1856
|
+
recordValidateCheck(state, built, fixHintsEnabled);
|
|
1857
|
+
}
|
|
1858
|
+
if (params.requestedChecks.has("lifecycle")) {
|
|
1859
|
+
const built = buildLifecycleCheck(params.items, Boolean(params.options.checkStaleBlockers), params.dependencyCycleSeverity, params.parentCycleSeverity, params.statusRegistry, params.lifecyclePatternPolicy, fullDiagnostics, params.settings.id_prefix);
|
|
1860
|
+
state.terminalParentFixRows = built.terminalParentFixRows;
|
|
1861
|
+
recordValidateCheck(state, built, fixHintsEnabled);
|
|
1862
|
+
}
|
|
1863
|
+
if (params.requestedChecks.has("files")) {
|
|
1864
|
+
const built = await buildFilesCheck(params.items, params.workspaceRoot, params.pmRoot, params.fileScanMode, Boolean(params.options.includePmInternals), Boolean(params.options.verboseFileLists));
|
|
1865
|
+
state.staleLinkPruneRows = built.staleLinkPruneRows;
|
|
1866
|
+
recordValidateCheck(state, built, fixHintsEnabled);
|
|
1867
|
+
}
|
|
1868
|
+
if (params.requestedChecks.has("command_references")) {
|
|
1869
|
+
recordValidateCheck(state, buildCommandReferencesCheck(params.items, params.settings.id_prefix, fullDiagnostics), fixHintsEnabled);
|
|
1870
|
+
}
|
|
1871
|
+
if (params.requestedChecks.has("history_drift")) {
|
|
1872
|
+
recordValidateCheck(state, await buildHistoryDriftCheck(params.pmRoot, params.items, fullDiagnostics), fixHintsEnabled);
|
|
1873
|
+
}
|
|
1874
|
+
if (params.requestedChecks.has("format_version")) {
|
|
1875
|
+
recordValidateCheck(state, buildFormatVersionCheck(params.items, fullDiagnostics), fixHintsEnabled);
|
|
1876
|
+
}
|
|
1877
|
+
return state;
|
|
1878
|
+
}
|
|
1879
|
+
function planValidateFixes(options, state, settings) {
|
|
1880
|
+
const planned = [];
|
|
1881
|
+
if (options.autoFix === true) {
|
|
1882
|
+
planned.push(...planCloseReasonBackfillFixes(state.closeReasonBackfillRows));
|
|
1883
|
+
planned.push(...planResolutionBackfillFixes(state.resolutionBackfillRows));
|
|
1884
|
+
planned.push(...planEstimateBackfillFixes(state.estimateBackfillRows, settings.validation.estimate_defaults_by_type));
|
|
1885
|
+
planned.push(...planTerminalParentFixes(state.terminalParentFixRows));
|
|
1886
|
+
}
|
|
1887
|
+
if (options.pruneMissing === true) {
|
|
1888
|
+
planned.push(...planStaleLinkPruneFixes(state.staleLinkPruneRows));
|
|
1889
|
+
}
|
|
1890
|
+
return planned;
|
|
1891
|
+
}
|
|
1892
|
+
/* v8 ignore start -- validate fix-summary matrix is covered end-to-end; direct helper fallback branches are defensive */
|
|
1893
|
+
async function buildValidateFixesSummary(options, state, settings, grantedFixScopes, global) {
|
|
1894
|
+
if (options.autoFix !== true && options.pruneMissing !== true) {
|
|
1895
|
+
return undefined;
|
|
1896
|
+
}
|
|
1897
|
+
const planned = planValidateFixes(options, state, settings);
|
|
1898
|
+
const { applicable, gated } = partitionFixesByGrant(planned, grantedFixScopes);
|
|
1899
|
+
const dryRun = options.dryRun === true;
|
|
1900
|
+
const appliedFixRows = [];
|
|
1901
|
+
const failedFixRows = [];
|
|
1902
|
+
if (!dryRun) {
|
|
1903
|
+
const applied = await applyValidateFixes(applicable, global);
|
|
1904
|
+
appliedFixRows.push(...applied.applied.map(toFixOutputRow));
|
|
1905
|
+
failedFixRows.push(...applied.failed.map(({ fix, error }) => ({
|
|
1906
|
+
...toFixOutputRow(fix),
|
|
1907
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1908
|
+
})));
|
|
1909
|
+
}
|
|
1910
|
+
return {
|
|
1911
|
+
mode: dryRun ? "dry_run" : "apply",
|
|
1912
|
+
auto_fix: options.autoFix === true,
|
|
1913
|
+
prune_missing: options.pruneMissing === true,
|
|
1914
|
+
granted_fix_scopes: [...grantedFixScopes].sort((left, right) => left.localeCompare(right)),
|
|
1915
|
+
planned_count: planned.length,
|
|
1916
|
+
applied_count: appliedFixRows.length,
|
|
1917
|
+
gated_count: gated.length,
|
|
1918
|
+
failed_count: failedFixRows.length,
|
|
1919
|
+
planned_fixes: planned.map(toFixOutputRow),
|
|
1920
|
+
applied_fixes: appliedFixRows,
|
|
1921
|
+
gated_fixes: gated.map((fix) => ({
|
|
1922
|
+
...toFixOutputRow(fix),
|
|
1923
|
+
gate_hint: `Withheld: re-run with --fix-scope ${fix.gate} to apply.`,
|
|
1924
|
+
})),
|
|
1925
|
+
failed_fixes: failedFixRows,
|
|
1926
|
+
};
|
|
1927
|
+
}
|
|
1928
|
+
/* v8 ignore stop */
|
|
1722
1929
|
/* c8 ignore start -- validate orchestration + fix-application matrices are covered by end-to-end command integration runs */
|
|
1723
1930
|
/**
|
|
1724
1931
|
* Implements run validate for the public runtime surface of this module.
|
|
@@ -1751,108 +1958,36 @@ export async function runValidate(options, global) {
|
|
|
1751
1958
|
const parentCycleSeverity = resolveParentCycleSeverity(options.parentCycleSeverity);
|
|
1752
1959
|
const fileScanMode = resolveFileScanMode(options.scanMode);
|
|
1753
1960
|
const workspaceRoot = resolveWorkspaceRoot(pmRoot);
|
|
1754
|
-
const
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
let resolutionBackfillRows = [];
|
|
1771
|
-
let terminalParentFixRows = [];
|
|
1772
|
-
let staleLinkPruneRows = [];
|
|
1773
|
-
if (requestedChecks.has("metadata")) {
|
|
1774
|
-
const built = buildMetadataCheck(items, metadataPolicy, statusRegistry, fullDiagnostics);
|
|
1775
|
-
closeReasonBackfillRows = built.closeReasonBackfillRows;
|
|
1776
|
-
estimateBackfillRows = built.estimateBackfillRows;
|
|
1777
|
-
record(built);
|
|
1778
|
-
}
|
|
1779
|
-
if (requestedChecks.has("resolution")) {
|
|
1780
|
-
const built = buildResolutionCheck(items, statusRegistry, fullDiagnostics);
|
|
1781
|
-
resolutionBackfillRows = built.resolutionBackfillRows;
|
|
1782
|
-
record(built);
|
|
1783
|
-
}
|
|
1784
|
-
if (requestedChecks.has("lifecycle")) {
|
|
1785
|
-
const built = buildLifecycleCheck(items, Boolean(options.checkStaleBlockers), dependencyCycleSeverity, parentCycleSeverity, statusRegistry, lifecyclePatternPolicy, fullDiagnostics, settings.id_prefix);
|
|
1786
|
-
terminalParentFixRows = built.terminalParentFixRows;
|
|
1787
|
-
record(built);
|
|
1788
|
-
}
|
|
1789
|
-
if (requestedChecks.has("files")) {
|
|
1790
|
-
const built = await buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, Boolean(options.includePmInternals), Boolean(options.verboseFileLists));
|
|
1791
|
-
staleLinkPruneRows = built.staleLinkPruneRows;
|
|
1792
|
-
record(built);
|
|
1793
|
-
}
|
|
1794
|
-
if (requestedChecks.has("command_references")) {
|
|
1795
|
-
record(buildCommandReferencesCheck(items, settings.id_prefix, fullDiagnostics));
|
|
1796
|
-
}
|
|
1797
|
-
if (requestedChecks.has("history_drift")) {
|
|
1798
|
-
record(await buildHistoryDriftCheck(pmRoot, items, fullDiagnostics));
|
|
1799
|
-
}
|
|
1800
|
-
if (requestedChecks.has("format_version")) {
|
|
1801
|
-
record(buildFormatVersionCheck(items, fullDiagnostics));
|
|
1802
|
-
}
|
|
1961
|
+
const state = await executeRequestedValidateChecks({
|
|
1962
|
+
requestedChecks,
|
|
1963
|
+
options,
|
|
1964
|
+
global,
|
|
1965
|
+
pmRoot,
|
|
1966
|
+
workspaceRoot,
|
|
1967
|
+
settings,
|
|
1968
|
+
items,
|
|
1969
|
+
statusRegistry,
|
|
1970
|
+
metadataPolicy,
|
|
1971
|
+
lifecyclePatternPolicy,
|
|
1972
|
+
dependencyCycleSeverity,
|
|
1973
|
+
parentCycleSeverity,
|
|
1974
|
+
fileScanMode,
|
|
1975
|
+
initialWarnings: [...new Set(itemReadWarnings)],
|
|
1976
|
+
});
|
|
1803
1977
|
// Remediation phase (pm-c3sz / pm-8jss / pm-0v2m). Plans are derived from
|
|
1804
1978
|
// the findings of THIS run; checks above always report the pre-fix state.
|
|
1805
1979
|
// Safe field backfills apply by default under --auto-fix; gated lifecycle
|
|
1806
1980
|
// fixes are planned but withheld unless --fix-scope lifecycle grants them;
|
|
1807
1981
|
// --dry-run previews without mutating; failures never abort the run.
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
planned.push(...planResolutionBackfillFixes(resolutionBackfillRows));
|
|
1814
|
-
planned.push(...planEstimateBackfillFixes(estimateBackfillRows, settings.validation.estimate_defaults_by_type));
|
|
1815
|
-
planned.push(...planTerminalParentFixes(terminalParentFixRows));
|
|
1816
|
-
}
|
|
1817
|
-
if (options.pruneMissing === true) {
|
|
1818
|
-
planned.push(...planStaleLinkPruneFixes(staleLinkPruneRows));
|
|
1819
|
-
}
|
|
1820
|
-
const { applicable, gated } = partitionFixesByGrant(planned, grantedFixScopes);
|
|
1821
|
-
const dryRun = options.dryRun === true;
|
|
1822
|
-
const appliedFixRows = [];
|
|
1823
|
-
const failedFixRows = [];
|
|
1824
|
-
if (!dryRun) {
|
|
1825
|
-
const applied = await applyValidateFixes(applicable, global);
|
|
1826
|
-
appliedFixRows.push(...applied.applied.map(toFixOutputRow));
|
|
1827
|
-
failedFixRows.push(...applied.failed.map(({ fix, error }) => ({
|
|
1828
|
-
...toFixOutputRow(fix),
|
|
1829
|
-
error: error instanceof Error ? error.message : String(error),
|
|
1830
|
-
})));
|
|
1831
|
-
}
|
|
1832
|
-
fixes = {
|
|
1833
|
-
mode: dryRun ? "dry_run" : "apply",
|
|
1834
|
-
auto_fix: options.autoFix === true,
|
|
1835
|
-
prune_missing: options.pruneMissing === true,
|
|
1836
|
-
granted_fix_scopes: [...grantedFixScopes].sort((left, right) => left.localeCompare(right)),
|
|
1837
|
-
planned_count: planned.length,
|
|
1838
|
-
applied_count: appliedFixRows.length,
|
|
1839
|
-
gated_count: gated.length,
|
|
1840
|
-
failed_count: failedFixRows.length,
|
|
1841
|
-
planned_fixes: planned.map(toFixOutputRow),
|
|
1842
|
-
applied_fixes: appliedFixRows,
|
|
1843
|
-
gated_fixes: gated.map((fix) => ({
|
|
1844
|
-
...toFixOutputRow(fix),
|
|
1845
|
-
gate_hint: `Withheld: re-run with --fix-scope ${fix.gate} to apply.`,
|
|
1846
|
-
})),
|
|
1847
|
-
failed_fixes: failedFixRows,
|
|
1848
|
-
};
|
|
1849
|
-
}
|
|
1850
|
-
const normalizedWarnings = [...new Set(warnings)].sort((left, right) => left.localeCompare(right));
|
|
1851
|
-
const hasErrors = checks.some((check) => check.status === "error");
|
|
1982
|
+
const fixes = fixesRequested
|
|
1983
|
+
? await buildValidateFixesSummary(options, state, settings, grantedFixScopes, global)
|
|
1984
|
+
: undefined;
|
|
1985
|
+
const normalizedWarnings = [...new Set(state.warnings)].sort((left, right) => left.localeCompare(right));
|
|
1986
|
+
const hasErrors = state.checks.some((check) => check.status === "error");
|
|
1852
1987
|
return {
|
|
1853
1988
|
ok: !hasErrors,
|
|
1854
1989
|
has_warnings: normalizedWarnings.length > 0,
|
|
1855
|
-
checks,
|
|
1990
|
+
checks: state.checks,
|
|
1856
1991
|
warnings: normalizedWarnings,
|
|
1857
1992
|
...(fixes !== undefined ? { fixes } : {}),
|
|
1858
1993
|
generated_at: nowIso(),
|
|
@@ -1860,4 +1995,4 @@ export async function runValidate(options, global) {
|
|
|
1860
1995
|
}
|
|
1861
1996
|
/* c8 ignore stop */
|
|
1862
1997
|
//# sourceMappingURL=validate.js.map
|
|
1863
|
-
//# debugId=
|
|
1998
|
+
//# debugId=d434e454-cb3f-5eaa-b841-d6f815e0446d
|