@unbrained/pm-cli 2026.7.13 → 2026.7.14
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 +2 -2
- package/CHANGELOG.md +28 -0
- package/dist/cli/commands/aggregate.d.ts +1 -1
- package/dist/cli/commands/aggregate.js +18 -6
- package/dist/cli/commands/aggregate.js.map +1 -1
- package/dist/cli/commands/context.d.ts +16 -1
- package/dist/cli/commands/context.js +98 -16
- package/dist/cli/commands/context.js.map +1 -1
- package/dist/cli/commands/create.d.ts +1 -1
- package/dist/cli/commands/create.js +11 -7
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/deps.d.ts +6 -96
- package/dist/cli/commands/deps.js +4 -214
- package/dist/cli/commands/deps.js.map +1 -1
- package/dist/cli/commands/docs.d.ts +2 -44
- package/dist/cli/commands/docs.js +8 -13
- package/dist/cli/commands/docs.js.map +1 -1
- package/dist/cli/commands/files.d.ts +6 -134
- package/dist/cli/commands/files.js +4 -294
- package/dist/cli/commands/files.js.map +1 -1
- package/dist/cli/commands/get.js +15 -2
- package/dist/cli/commands/get.js.map +1 -1
- package/dist/cli/commands/list.js +5 -6
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/next.d.ts +3 -1
- package/dist/cli/commands/next.js +77 -20
- package/dist/cli/commands/next.js.map +1 -1
- package/dist/cli/commands/update-many.js +6 -3
- package/dist/cli/commands/update-many.js.map +1 -1
- package/dist/cli/commands/update.js +14 -7
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/commands/validate.d.ts +1 -1
- package/dist/cli/commands/validate.js +32 -35
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/main.d.ts +2 -14
- package/dist/cli/main.js +27 -8
- package/dist/cli/main.js.map +1 -1
- package/dist/cli-bundle/chunks/append-DYQWQK2J.js +11 -0
- package/dist/cli-bundle/chunks/{append-2FS6MVG7.js → append-PVZJDM6J.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-J2WAWP4U.js → chunk-2FNWQXZ2.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-YFGYDZRP.js → chunk-2GA3NK35.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-XFEIASAC.js → chunk-2QIQGYPW.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-3WCGYH5Q.js → chunk-3CMRNVTO.js} +7 -7
- package/dist/cli-bundle/chunks/chunk-3HKUXVKV.js +9 -0
- package/dist/cli-bundle/chunks/{chunk-VDAZPPRU.js → chunk-3I3LRT2G.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-3P3RFJIQ.js → chunk-3TL7WOEF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-4SHJ5JS3.js → chunk-44LNIULG.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-QFOAWBOB.js → chunk-4DY4KPQI.js} +11 -10
- package/dist/cli-bundle/chunks/{chunk-QFOAWBOB.js.map → chunk-4DY4KPQI.js.map} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BVCF4ULV.js → chunk-4RXTMU57.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-XMI2TRY5.js → chunk-4WREH7RT.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-JYUGUXFW.js → chunk-5CT5BW6E.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-NA5SBIB4.js → chunk-5URI7TPJ.js} +44 -44
- package/dist/cli-bundle/chunks/chunk-5URI7TPJ.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-QGH6WL6L.js → chunk-655STMGA.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-DGKBWCMA.js → chunk-6IIVBC56.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-SRQLQUO6.js → chunk-6MHSBDGD.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-SRQLQUO6.js.map → chunk-6MHSBDGD.js.map} +2 -2
- package/dist/cli-bundle/chunks/{chunk-D4GPNYYP.js → chunk-6OTZMORS.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-JVRVXO6M.js → chunk-6PKA3SJQ.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-2PR4ZTRO.js → chunk-6TTOHMTB.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-2PR4ZTRO.js.map → chunk-6TTOHMTB.js.map} +1 -1
- package/dist/cli-bundle/chunks/chunk-6X5MZ5R2.js +9 -0
- package/dist/cli-bundle/chunks/chunk-76UBY2EE.js +5 -0
- package/dist/cli-bundle/chunks/{chunk-ZS2KPCJN.js → chunk-7QDSYUMF.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-Z7TFPIJ6.js → chunk-7TQMR6LK.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-AHA4POA6.js → chunk-ABRCOSDC.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-XY3CC3EM.js → chunk-AFWZRL7M.js} +59 -53
- package/dist/cli-bundle/chunks/chunk-AFWZRL7M.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-KQJVTQVK.js → chunk-ANSJHDOZ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-OMT4NO7T.js → chunk-B5DZYTT3.js} +113 -24
- package/dist/cli-bundle/chunks/chunk-B5DZYTT3.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-B7SWOIP6.js +5 -0
- package/dist/cli-bundle/chunks/{chunk-D2LXG7WX.js → chunk-BN62TO2S.js} +5 -5
- package/dist/cli-bundle/chunks/chunk-BN62TO2S.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-ZTSV7P2T.js → chunk-BPD26E3P.js} +357 -42
- package/dist/cli-bundle/chunks/chunk-BPD26E3P.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-RKGFUC4O.js → chunk-CDJYP7OQ.js} +36 -14
- package/dist/cli-bundle/chunks/chunk-CDJYP7OQ.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-VLFLRFJP.js → chunk-CIOZ376P.js} +20 -13
- package/dist/cli-bundle/chunks/chunk-CIOZ376P.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-HXTCZSAI.js → chunk-DBZVUJTK.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-2QNOWOIB.js → chunk-DO5RGJXT.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-MKONZ4UO.js → chunk-DRNJPEPQ.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-XDT2PSXA.js → chunk-DVOLZJ3C.js} +12 -11
- package/dist/cli-bundle/chunks/{chunk-XDT2PSXA.js.map → chunk-DVOLZJ3C.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-H36FXA7B.js → chunk-DYEX6NFH.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-G3IB5GTD.js → chunk-E2WC6S4P.js} +15 -11
- package/dist/cli-bundle/chunks/chunk-E2WC6S4P.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-GAJ7U7B4.js → chunk-ERL2YFJ2.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-FPEYOFEF.js → chunk-F7PSHRNO.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-UH7OLT6F.js → chunk-FDSBDNYE.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-DGJF32JF.js → chunk-FIGXOCEQ.js} +66 -21
- package/dist/cli-bundle/chunks/chunk-FIGXOCEQ.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-RQAY7C5T.js → chunk-FJZDA6MS.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-B4TVNGRX.js → chunk-FO7GMJKG.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-FRQ63VPB.js +5 -0
- package/dist/cli-bundle/chunks/{chunk-UTYNQ2WH.js → chunk-FS6UM5WH.js} +48 -27
- package/dist/cli-bundle/chunks/chunk-FS6UM5WH.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-U252II47.js → chunk-FTQLW4JD.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-TNGLCRKS.js → chunk-GSEADLRH.js} +1821 -1809
- package/dist/cli-bundle/chunks/chunk-GSEADLRH.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-TGG7YGMC.js → chunk-GXXC7QSK.js} +53 -47
- package/dist/cli-bundle/chunks/chunk-GXXC7QSK.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-AGD4VZXH.js → chunk-H2QBAKLQ.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-CJVQ4XIG.js → chunk-HAMLIWAF.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-56DX6QYG.js → chunk-HL7V2PHX.js} +19 -13
- package/dist/cli-bundle/chunks/chunk-HL7V2PHX.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-7QOIQTPB.js → chunk-HLHSQ5CA.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-AHC7J6XD.js → chunk-IA3YFTXT.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-5ZCVF4WF.js → chunk-IAPHYPRL.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-OCSQWIOW.js → chunk-IFZA4VB5.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-6O2HJENY.js → chunk-IGED7NH2.js} +61 -48
- package/dist/cli-bundle/chunks/chunk-IGED7NH2.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-RPCCQDG2.js → chunk-ILLUE5DI.js} +36 -14
- package/dist/cli-bundle/chunks/chunk-ILLUE5DI.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-4WMFM77X.js → chunk-J4NZOP3I.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-57JVERX3.js → chunk-JAF4TUQ7.js} +4 -4
- package/dist/cli-bundle/chunks/chunk-JAF4TUQ7.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-MTNKSSSO.js → chunk-JL7WZ4O2.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-AZ52LTCY.js → chunk-K7WNZ7KD.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-2OLSXXIV.js → chunk-KADLSPIU.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-RQKORMM4.js → chunk-KB726FMH.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-WKSFBBZT.js → chunk-L24HCJFC.js} +114 -25
- package/dist/cli-bundle/chunks/chunk-L24HCJFC.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-LDO24J5I.js → chunk-LWTIRS3Y.js} +365 -43
- package/dist/cli-bundle/chunks/chunk-LWTIRS3Y.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-TZTQ4TVV.js → chunk-M6ASXYCU.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-WDDOAU7Z.js → chunk-M7EWN4TF.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-327DSGW2.js → chunk-MD6ULIPJ.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-OKDBHOON.js → chunk-MKL4CP2I.js} +61 -48
- package/dist/cli-bundle/chunks/chunk-MKL4CP2I.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-M52DG2QJ.js → chunk-MQZ3PLCF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-GQ2CQNGI.js → chunk-N3CMP4NI.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-J7SBFUZC.js → chunk-NAQYVWSQ.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-U2GMYP3L.js → chunk-NKW36AMT.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-5WEYOVZ7.js → chunk-OBDLEQG5.js} +19 -12
- package/dist/cli-bundle/chunks/chunk-OBDLEQG5.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-VL4LYTJN.js → chunk-OI4S4KCI.js} +18 -12
- package/dist/cli-bundle/chunks/chunk-OI4S4KCI.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-FCVVMAEX.js → chunk-P6MYFH6K.js} +60 -22
- package/dist/cli-bundle/chunks/chunk-P6MYFH6K.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-FTQQAPRX.js → chunk-PHKP3AGR.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-WVUXNIYO.js → chunk-Q37E63AM.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-JVXV7ANV.js → chunk-Q7E6OYZK.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-WVUYATII.js → chunk-QABYZYLU.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-QRRUGIJN.js → chunk-QASRVKUQ.js} +45 -45
- package/dist/cli-bundle/chunks/chunk-QASRVKUQ.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-L4262MFB.js → chunk-QK2ZN6UL.js} +14 -5
- package/dist/cli-bundle/chunks/{chunk-L4262MFB.js.map → chunk-QK2ZN6UL.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-7TQPV7HR.js → chunk-QSPARJWF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-GTKILM6F.js → chunk-QZ7LT3XE.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-L3VKY6R6.js → chunk-RA5AIAMP.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-BJS27ALI.js → chunk-RGXD5JJR.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-TSEPW2P6.js → chunk-RMF3IOYQ.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-QXYKH56X.js → chunk-T4BRCB6Z.js} +1894 -1875
- package/dist/cli-bundle/chunks/chunk-T4BRCB6Z.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-TGGTXC52.js → chunk-TH7U4KLY.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-LP4UATP6.js → chunk-TWLDBKQU.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-OTZ3C2NE.js → chunk-TZ2PSLLT.js} +49 -28
- package/dist/cli-bundle/chunks/chunk-TZ2PSLLT.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-UK222BHQ.js → chunk-TZRTLMWM.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-6E6S2X6S.js → chunk-UB2QYSTO.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-S6CXUSYC.js → chunk-UGTVWL3E.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-BNS6QHTZ.js → chunk-UJ4HJYWL.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BYVOEJPQ.js → chunk-UKUIIBDW.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-SGDBVR7X.js → chunk-UVBA6F5A.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-DZRZMBBF.js → chunk-VJTAEIPC.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-74PWVJON.js → chunk-W6HZ55JO.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-HR2MQAO5.js → chunk-WD6MSYMP.js} +13 -4
- package/dist/cli-bundle/chunks/{chunk-HR2MQAO5.js.map → chunk-WD6MSYMP.js.map} +2 -2
- package/dist/cli-bundle/chunks/{chunk-P7IFURWH.js → chunk-WPAWZW7S.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-36LEOWSX.js → chunk-WQUEHPZB.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-FCKJF7G2.js → chunk-WRKB56FC.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-KR5EHAN4.js → chunk-X3GYR4P2.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-J567OZJY.js → chunk-X6BVXQ52.js} +16 -12
- package/dist/cli-bundle/chunks/chunk-X6BVXQ52.js.map +1 -0
- package/dist/cli-bundle/chunks/chunk-Y72FV7RM.js +178 -0
- package/dist/cli-bundle/chunks/chunk-Y72FV7RM.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-OWW2KXOV.js → chunk-YQYG2V23.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-G2SCT7BC.js → chunk-YVKE5ZDM.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-QHIN4UTF.js → chunk-ZAYYDNB3.js} +4 -4
- package/dist/cli-bundle/chunks/chunk-ZHBI2AP7.js +9 -0
- package/dist/cli-bundle/chunks/chunk-ZNP64HOW.js +175 -0
- package/dist/cli-bundle/chunks/chunk-ZNP64HOW.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-GNVBUNJQ.js → chunk-ZTRBSABY.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-PY32KGQU.js → chunk-ZUKSZVBW.js} +5 -5
- package/dist/cli-bundle/chunks/{close-CU56F47E.js → close-LZECOMHO.js} +5 -5
- package/dist/cli-bundle/chunks/close-RI4JQQHU.js +12 -0
- package/dist/cli-bundle/chunks/close-many-LY2XJ52M.js +21 -0
- package/dist/cli-bundle/chunks/{close-many-ZQ2WP67J.js → close-many-ZHI6A5TN.js} +12 -12
- package/dist/cli-bundle/chunks/comments-35M273DN.js +13 -0
- package/dist/cli-bundle/chunks/{comments-UDUMKXL6.js → comments-AJWRTFZ5.js} +7 -7
- package/dist/cli-bundle/chunks/{copy-VFHECFBV.js → copy-GMXYKBXT.js} +4 -4
- package/dist/cli-bundle/chunks/copy-NPYM7M7U.js +9 -0
- package/dist/cli-bundle/chunks/create-F53OBTOU.js +27 -0
- package/dist/cli-bundle/chunks/{create-CE2X3SGF.js → create-HU4Q7RJX.js} +11 -9
- package/dist/cli-bundle/chunks/{delete-2JXQCHHT.js → delete-GSDZLTRC.js} +4 -4
- package/dist/cli-bundle/chunks/delete-ODRWJWAM.js +10 -0
- package/dist/cli-bundle/chunks/deps-U57I7EAK.js +16 -0
- package/dist/cli-bundle/chunks/{deps-FPXNLO6C.js → deps-WWB7P2GT.js} +7 -4
- package/dist/cli-bundle/chunks/docs-G7N4E2JO.js +14 -0
- package/dist/cli-bundle/chunks/{docs-AMAR4OHU.js → docs-MQIY2ZQS.js} +7 -7
- package/dist/cli-bundle/chunks/files-TBZD7V6H.js +18 -0
- package/dist/cli-bundle/chunks/{files-JFHN7DYM.js → files-TTY6N2AV.js} +7 -7
- package/dist/cli-bundle/chunks/focus-U5TRVCRS.js +10 -0
- package/dist/cli-bundle/chunks/{focus-QFN2RRZ7.js → focus-XT6YVFFX.js} +5 -5
- package/dist/cli-bundle/chunks/{history-compact-G34XMABV.js → history-compact-KKVUWB4V.js} +8 -8
- package/dist/cli-bundle/chunks/{history-compact-SAHT5D46.js → history-compact-M7GHYVFN.js} +8 -8
- package/dist/cli-bundle/chunks/{history-redact-IFJDNKLZ.js → history-redact-3DVZOILD.js} +6 -6
- package/dist/cli-bundle/chunks/history-redact-JIHZLHDP.js +16 -0
- package/dist/cli-bundle/chunks/{history-repair-NXLQTCVN.js → history-repair-ITDUMK4N.js} +8 -8
- package/dist/cli-bundle/chunks/history-repair-NAFCHLH7.js +18 -0
- package/dist/cli-bundle/chunks/{learnings-5CZKAMBS.js → learnings-FGO3NSFW.js} +7 -7
- package/dist/cli-bundle/chunks/learnings-SONGPSHI.js +13 -0
- package/dist/cli-bundle/chunks/notes-BSD53H2W.js +13 -0
- package/dist/cli-bundle/chunks/{notes-POMK37UI.js → notes-NQ6RXVW6.js} +7 -7
- package/dist/cli-bundle/chunks/{plan-YBNYNT3A.js → plan-2NNEO46V.js} +10 -10
- package/dist/cli-bundle/chunks/plan-AWLYGBNV.js +24 -0
- package/dist/cli-bundle/chunks/{profile-JNKSU6EQ.js → profile-AAQUU6T3.js} +9 -9
- package/dist/cli-bundle/chunks/{profile-A2WPVG6I.js → profile-U725ATWZ.js} +9 -9
- package/dist/cli-bundle/chunks/{register-list-query-UG4ZA5AU.js → register-list-query-BUWCYHBT.js} +14 -13
- package/dist/cli-bundle/chunks/{register-list-query-UG4ZA5AU.js.map → register-list-query-BUWCYHBT.js.map} +1 -1
- package/dist/cli-bundle/chunks/{register-list-query-KJULL4W3.js → register-list-query-KTZ6AGE7.js} +16 -15
- package/dist/cli-bundle/chunks/{register-list-query-KJULL4W3.js.map → register-list-query-KTZ6AGE7.js.map} +1 -1
- package/dist/cli-bundle/chunks/{register-mutation-3OXYXBKH.js → register-mutation-4FMGJJF7.js} +29 -29
- package/dist/cli-bundle/chunks/{register-mutation-WK265BM7.js → register-mutation-UELYYOR7.js} +29 -29
- package/dist/cli-bundle/chunks/{register-operations-C5SQH3FJ.js → register-operations-ISUX6LY5.js} +33 -29
- package/dist/cli-bundle/chunks/{register-operations-C5SQH3FJ.js.map → register-operations-ISUX6LY5.js.map} +1 -1
- package/dist/cli-bundle/chunks/{register-operations-FH3PBHYN.js → register-operations-JVW24J2Y.js} +35 -31
- package/dist/cli-bundle/chunks/{register-operations-FH3PBHYN.js.map → register-operations-JVW24J2Y.js.map} +1 -1
- package/dist/cli-bundle/chunks/{register-setup-CCK7CJVR.js → register-setup-5XNGKJ22.js} +15 -15
- package/dist/cli-bundle/chunks/{register-setup-CPZBGSOJ.js → register-setup-ZTNY6S7R.js} +15 -15
- package/dist/cli-bundle/chunks/restore-66GLMHIX.js +14 -0
- package/dist/cli-bundle/chunks/{restore-IVS5XGYR.js → restore-B3BAB6X2.js} +6 -6
- package/dist/cli-bundle/chunks/{schema-P2MF23JO.js → schema-LZNUYHDB.js} +6 -6
- package/dist/cli-bundle/chunks/schema-LZNUYHDB.js.map +7 -0
- package/dist/cli-bundle/chunks/{schema-R3U2REY4.js → schema-U7IM2DXV.js} +6 -6
- package/dist/cli-bundle/chunks/schema-U7IM2DXV.js.map +1 -0
- package/dist/cli-bundle/chunks/update-2XGHIVQ2.js +21 -0
- package/dist/cli-bundle/chunks/update-2XGHIVQ2.js.map +7 -0
- package/dist/cli-bundle/chunks/{update-YBIQESMH.js → update-Q3UCILNR.js} +12 -12
- package/dist/cli-bundle/chunks/update-Q3UCILNR.js.map +1 -0
- package/dist/cli-bundle/chunks/{update-many-F3CIV5SQ.js → update-many-75K57FS3.js} +19 -19
- package/dist/cli-bundle/chunks/update-many-75K57FS3.js.map +1 -0
- package/dist/cli-bundle/chunks/update-many-U42YA445.js +30 -0
- package/dist/cli-bundle/chunks/update-many-U42YA445.js.map +7 -0
- package/dist/cli-bundle/main.js +39 -16
- package/dist/cli-bundle/main.js.map +2 -2
- package/dist/cli-bundle/sdk-runtime.js +56 -53
- package/dist/cli-bundle/sdk-testing.js +6 -6
- package/dist/cli-bundle/sdk.js +115 -55
- package/dist/cli-bundle/sdk.js.map +2 -2
- package/dist/core/extensions/command-hook-context.d.ts +40 -0
- package/dist/core/extensions/command-hook-context.js +14 -0
- package/dist/core/extensions/command-hook-context.js.map +1 -0
- package/dist/core/extensions/index.d.ts +1 -0
- package/dist/core/extensions/index.js +4 -3
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/item/parse.d.ts +2 -0
- package/dist/core/item/parse.js +11 -2
- package/dist/core/item/parse.js.map +1 -1
- package/dist/core/store/paths.d.ts +2 -0
- package/dist/core/store/paths.js +10 -2
- package/dist/core/store/paths.js.map +1 -1
- package/dist/mcp/tool-definitions.js +12 -2
- package/dist/mcp/tool-definitions.js.map +1 -1
- package/dist/sdk/context-packing.d.ts +114 -0
- package/dist/sdk/context-packing.js +219 -0
- package/dist/sdk/context-packing.js.map +1 -0
- package/dist/sdk/context-relevance.d.ts +1 -1
- package/dist/sdk/context-relevance.js +4 -2
- package/dist/sdk/context-relevance.js.map +1 -1
- package/dist/sdk/context-usage.d.ts +79 -0
- package/dist/sdk/context-usage.js +193 -0
- package/dist/sdk/context-usage.js.map +1 -0
- package/dist/sdk/dependencies.d.ts +145 -0
- package/dist/sdk/dependencies.js +327 -0
- package/dist/sdk/dependencies.js.map +1 -0
- package/dist/sdk/docs.d.ts +48 -0
- package/dist/sdk/docs.js +15 -0
- package/dist/sdk/docs.js.map +1 -0
- package/dist/sdk/files.d.ts +135 -0
- package/dist/sdk/files.js +320 -0
- package/dist/sdk/files.js.map +1 -0
- package/dist/sdk/index.d.ts +6 -0
- package/dist/sdk/index.js +8 -2
- package/dist/sdk/index.js.map +1 -1
- package/dist/{cli/commands → sdk}/linked-artifacts.d.ts +11 -5
- package/dist/{cli/commands → sdk}/linked-artifacts.js +49 -25
- package/dist/sdk/linked-artifacts.js.map +1 -0
- package/dist/sdk/runtime.d.ts +4 -4
- package/dist/sdk/runtime.js +7 -4
- package/dist/sdk/runtime.js.map +1 -1
- package/dist/sdk/workspace.js +3 -2
- package/dist/sdk/workspace.js.map +1 -1
- package/docs/AGENT_GUIDE.md +1 -1
- package/docs/CONFIGURATION.md +1 -0
- package/docs/PR_REVIEW_LOOP.md +21 -11
- package/docs/SDK.md +94 -0
- package/marketplace.json +2 -2
- package/package.json +1 -1
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/dist/cli/commands/linked-artifacts.js.map +0 -1
- package/dist/cli-bundle/chunks/append-CTKFDEAX.js +0 -11
- package/dist/cli-bundle/chunks/chunk-56DX6QYG.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-57JVERX3.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-5WEYOVZ7.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-6O2HJENY.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-CCAGZCZK.js +0 -17
- package/dist/cli-bundle/chunks/chunk-CCAGZCZK.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-D2LXG7WX.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-DGJF32JF.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-FCVVMAEX.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-FUOK7JZ6.js +0 -14
- package/dist/cli-bundle/chunks/chunk-FUOK7JZ6.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-G3IB5GTD.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-J567OZJY.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-LDO24J5I.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-NA5SBIB4.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-OKDBHOON.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-OMT4NO7T.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-OTZ3C2NE.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-QRRUGIJN.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-QXYKH56X.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-RKGFUC4O.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-RPCCQDG2.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-TGG7YGMC.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-TNGLCRKS.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-UTYNQ2WH.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-VL4LYTJN.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-VLFLRFJP.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-WKSFBBZT.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-XY3CC3EM.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-ZTSV7P2T.js.map +0 -1
- package/dist/cli-bundle/chunks/close-BWM7FTF4.js +0 -12
- package/dist/cli-bundle/chunks/close-many-AUHTVFUQ.js +0 -21
- package/dist/cli-bundle/chunks/comments-7D5VPBZI.js +0 -13
- package/dist/cli-bundle/chunks/copy-QJ6ZVWZV.js +0 -9
- package/dist/cli-bundle/chunks/create-FGMTTYOI.js +0 -25
- package/dist/cli-bundle/chunks/delete-L2GMMMPR.js +0 -10
- package/dist/cli-bundle/chunks/deps-KTFI4RWD.js +0 -13
- package/dist/cli-bundle/chunks/docs-VNURA275.js +0 -14
- package/dist/cli-bundle/chunks/files-UNFPZLTG.js +0 -18
- package/dist/cli-bundle/chunks/focus-MI2UHBP4.js +0 -10
- package/dist/cli-bundle/chunks/history-redact-VAHGBUHI.js +0 -16
- package/dist/cli-bundle/chunks/history-repair-DDYQXR43.js +0 -18
- package/dist/cli-bundle/chunks/learnings-VWJEKHEO.js +0 -13
- package/dist/cli-bundle/chunks/notes-NGVJJJQO.js +0 -13
- package/dist/cli-bundle/chunks/plan-U6SQJUFI.js +0 -24
- package/dist/cli-bundle/chunks/restore-AX6ZMGHZ.js +0 -14
- package/dist/cli-bundle/chunks/update-XYHF3YZF.js +0 -21
- package/dist/cli-bundle/chunks/update-many-5HKVHFUL.js +0 -30
- /package/dist/cli-bundle/chunks/{append-CTKFDEAX.js.map → append-DYQWQK2J.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{append-2FS6MVG7.js.map → append-PVZJDM6J.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-J2WAWP4U.js.map → chunk-2FNWQXZ2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-YFGYDZRP.js.map → chunk-2GA3NK35.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-XFEIASAC.js.map → chunk-2QIQGYPW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-3WCGYH5Q.js.map → chunk-3CMRNVTO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-BWM7FTF4.js.map → chunk-3HKUXVKV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-VDAZPPRU.js.map → chunk-3I3LRT2G.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-3P3RFJIQ.js.map → chunk-3TL7WOEF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-4SHJ5JS3.js.map → chunk-44LNIULG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-BVCF4ULV.js.map → chunk-4RXTMU57.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-XMI2TRY5.js.map → chunk-4WREH7RT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-JYUGUXFW.js.map → chunk-5CT5BW6E.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-QGH6WL6L.js.map → chunk-655STMGA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-DGKBWCMA.js.map → chunk-6IIVBC56.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-D4GPNYYP.js.map → chunk-6OTZMORS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-JVRVXO6M.js.map → chunk-6PKA3SJQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-many-AUHTVFUQ.js.map → chunk-6X5MZ5R2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-CU56F47E.js.map → chunk-76UBY2EE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-ZS2KPCJN.js.map → chunk-7QDSYUMF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-Z7TFPIJ6.js.map → chunk-7TQMR6LK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-AHA4POA6.js.map → chunk-ABRCOSDC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-KQJVTQVK.js.map → chunk-ANSJHDOZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-many-ZQ2WP67J.js.map → chunk-B7SWOIP6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-HXTCZSAI.js.map → chunk-DBZVUJTK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-2QNOWOIB.js.map → chunk-DO5RGJXT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-MKONZ4UO.js.map → chunk-DRNJPEPQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-H36FXA7B.js.map → chunk-DYEX6NFH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GAJ7U7B4.js.map → chunk-ERL2YFJ2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-FPEYOFEF.js.map → chunk-F7PSHRNO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UH7OLT6F.js.map → chunk-FDSBDNYE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-RQAY7C5T.js.map → chunk-FJZDA6MS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-B4TVNGRX.js.map → chunk-FO7GMJKG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{comments-UDUMKXL6.js.map → chunk-FRQ63VPB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-U252II47.js.map → chunk-FTQLW4JD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-AGD4VZXH.js.map → chunk-H2QBAKLQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-CJVQ4XIG.js.map → chunk-HAMLIWAF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-7QOIQTPB.js.map → chunk-HLHSQ5CA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-AHC7J6XD.js.map → chunk-IA3YFTXT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-5ZCVF4WF.js.map → chunk-IAPHYPRL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-OCSQWIOW.js.map → chunk-IFZA4VB5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-4WMFM77X.js.map → chunk-J4NZOP3I.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-MTNKSSSO.js.map → chunk-JL7WZ4O2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-AZ52LTCY.js.map → chunk-K7WNZ7KD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-2OLSXXIV.js.map → chunk-KADLSPIU.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-RQKORMM4.js.map → chunk-KB726FMH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-TZTQ4TVV.js.map → chunk-M6ASXYCU.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-WDDOAU7Z.js.map → chunk-M7EWN4TF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-327DSGW2.js.map → chunk-MD6ULIPJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-M52DG2QJ.js.map → chunk-MQZ3PLCF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GQ2CQNGI.js.map → chunk-N3CMP4NI.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-J7SBFUZC.js.map → chunk-NAQYVWSQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-U2GMYP3L.js.map → chunk-NKW36AMT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-FTQQAPRX.js.map → chunk-PHKP3AGR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-WVUXNIYO.js.map → chunk-Q37E63AM.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-JVXV7ANV.js.map → chunk-Q7E6OYZK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-WVUYATII.js.map → chunk-QABYZYLU.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-7TQPV7HR.js.map → chunk-QSPARJWF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GTKILM6F.js.map → chunk-QZ7LT3XE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-L3VKY6R6.js.map → chunk-RA5AIAMP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-BJS27ALI.js.map → chunk-RGXD5JJR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-TSEPW2P6.js.map → chunk-RMF3IOYQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-TGGTXC52.js.map → chunk-TH7U4KLY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-LP4UATP6.js.map → chunk-TWLDBKQU.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UK222BHQ.js.map → chunk-TZRTLMWM.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-6E6S2X6S.js.map → chunk-UB2QYSTO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-S6CXUSYC.js.map → chunk-UGTVWL3E.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-BNS6QHTZ.js.map → chunk-UJ4HJYWL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-BYVOEJPQ.js.map → chunk-UKUIIBDW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-SGDBVR7X.js.map → chunk-UVBA6F5A.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-DZRZMBBF.js.map → chunk-VJTAEIPC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-74PWVJON.js.map → chunk-W6HZ55JO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-P7IFURWH.js.map → chunk-WPAWZW7S.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-36LEOWSX.js.map → chunk-WQUEHPZB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-FCKJF7G2.js.map → chunk-WRKB56FC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-KR5EHAN4.js.map → chunk-X3GYR4P2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-OWW2KXOV.js.map → chunk-YQYG2V23.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-G2SCT7BC.js.map → chunk-YVKE5ZDM.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-QHIN4UTF.js.map → chunk-ZAYYDNB3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{comments-7D5VPBZI.js.map → chunk-ZHBI2AP7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GNVBUNJQ.js.map → chunk-ZTRBSABY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-PY32KGQU.js.map → chunk-ZUKSZVBW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{copy-VFHECFBV.js.map → close-LZECOMHO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{copy-QJ6ZVWZV.js.map → close-RI4JQQHU.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-FGMTTYOI.js.map → close-many-LY2XJ52M.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-CE2X3SGF.js.map → close-many-ZHI6A5TN.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{delete-L2GMMMPR.js.map → comments-35M273DN.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{delete-2JXQCHHT.js.map → comments-AJWRTFZ5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-FPXNLO6C.js.map → copy-GMXYKBXT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-KTFI4RWD.js.map → copy-NPYM7M7U.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{docs-VNURA275.js.map → create-F53OBTOU.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{docs-AMAR4OHU.js.map → create-HU4Q7RJX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{files-JFHN7DYM.js.map → delete-GSDZLTRC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{files-UNFPZLTG.js.map → delete-ODRWJWAM.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{focus-MI2UHBP4.js.map → deps-U57I7EAK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{focus-QFN2RRZ7.js.map → deps-WWB7P2GT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-compact-SAHT5D46.js.map → docs-G7N4E2JO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-compact-G34XMABV.js.map → docs-MQIY2ZQS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-redact-VAHGBUHI.js.map → files-TBZD7V6H.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-redact-IFJDNKLZ.js.map → files-TTY6N2AV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-repair-DDYQXR43.js.map → focus-U5TRVCRS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-repair-NXLQTCVN.js.map → focus-XT6YVFFX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{learnings-5CZKAMBS.js.map → history-compact-KKVUWB4V.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{learnings-VWJEKHEO.js.map → history-compact-M7GHYVFN.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{notes-POMK37UI.js.map → history-redact-3DVZOILD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{notes-NGVJJJQO.js.map → history-redact-JIHZLHDP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{plan-YBNYNT3A.js.map → history-repair-ITDUMK4N.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{plan-U6SQJUFI.js.map → history-repair-NAFCHLH7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{profile-JNKSU6EQ.js.map → learnings-FGO3NSFW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{profile-A2WPVG6I.js.map → learnings-SONGPSHI.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{restore-AX6ZMGHZ.js.map → notes-BSD53H2W.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{restore-IVS5XGYR.js.map → notes-NQ6RXVW6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{schema-R3U2REY4.js.map → plan-2NNEO46V.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{schema-P2MF23JO.js.map → plan-AWLYGBNV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-YBIQESMH.js.map → profile-AAQUU6T3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-XYHF3YZF.js.map → profile-U725ATWZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-mutation-3OXYXBKH.js.map → register-mutation-4FMGJJF7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-mutation-WK265BM7.js.map → register-mutation-UELYYOR7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-setup-CCK7CJVR.js.map → register-setup-5XNGKJ22.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-setup-CPZBGSOJ.js.map → register-setup-ZTNY6S7R.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-5HKVHFUL.js.map → restore-66GLMHIX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-F3CIV5SQ.js.map → restore-B3BAB6X2.js.map} +0 -0
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Official marketplace for pm CLI — native git-based project management for Claude Code and AI coding agents.",
|
|
9
|
-
"version": "2026.7.
|
|
9
|
+
"version": "2026.7.14"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "pm-claude",
|
|
14
14
|
"source": "./plugins/pm-claude",
|
|
15
15
|
"description": "Native pm CLI integration for Claude Code — 28 MCP tools, 5 workflow skills, 14 slash commands, 4 subagents, hybrid TUI task tracking, session context injection, and coordination subagents for git-based project management without leaving Claude Code.",
|
|
16
|
-
"version": "2026.7.
|
|
16
|
+
"version": "2026.7.14",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "unbrained",
|
|
19
19
|
"url": "https://github.com/unbraind/pm-cli"
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026.7.14 - 2026-07-14
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Context usage feedback signal: served-then-acted-on outcomes strengthen relevance scoring (retrieval-practice effect) ([pm-uwfs](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/features/pm-uwfs.toon))
|
|
8
|
+
- GH-544: linked-file path anchoring — files/docs add/glob/discover/validate-paths resolve at process.cwd() while validate --check-files anchors at the workspace root ([pm-chyh](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-chyh.toon))
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Replace obsolete front-matter vocabulary with item metadata terminology ([pm-hq28](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/tasks/pm-hq28.toon))
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- GH-533: create/update accept empty --title — required-title contract inconsistent between omitted and empty string ([pm-7je0](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-7je0.toon))
|
|
17
|
+
- GH-535: pm deps omits dangling parent references (missing_count:0, missing:false) contradicting validate's dangling_reference_count ([pm-p9sc](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-p9sc.toon))
|
|
18
|
+
- GH-542: MCP pm_copy nests title/message under options while sibling tools declare flat camelCase params — own suite triggers unexpected-arg warnings ([pm-hno5](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-hno5.toon))
|
|
19
|
+
- GH-532: --estimated-minutes accepts negative numbers and floats — missing non-negative-integer range validation ([pm-jh9t](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-jh9t.toon))
|
|
20
|
+
- GH-534: no-op update reports phantom changed_fields in --json while TOON reports empty, and changed_field_count is always null in JSON ([pm-45mb](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-45mb.toon))
|
|
21
|
+
- GH-526: aggregate --sum/--avg accept unknown field names and silently report 0 ([pm-96vo](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-96vo.toon))
|
|
22
|
+
- GH-530: list --status <invalid\> silently returns count 0 — validate against the status domain like --type and search status: ([pm-kj4k](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-kj4k.toon))
|
|
23
|
+
- Separate active dangling dependency warnings from terminal historical reference diagnostics ([pm-2ler](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-2ler.toon))
|
|
24
|
+
|
|
25
|
+
### Other
|
|
26
|
+
|
|
27
|
+
- PR review helper: watch GitHub checks and enforce thread-scoped replies ([pm-0fxa](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/tasks/pm-0fxa.toon))
|
|
28
|
+
- Token-budget context packer: diversity-aware selection, projection degradation, and bounded output for pm context/next ([pm-55ra](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/tasks/pm-55ra.toon))
|
|
29
|
+
- Complete public linked-resource SDK primitives and actionable dependency governance ([pm-jcvg](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/tasks/pm-jcvg.toon))
|
|
30
|
+
|
|
3
31
|
## 2026.7.13 - 2026-07-13
|
|
4
32
|
|
|
5
33
|
### Added
|
|
@@ -120,7 +120,7 @@ interface NumericAggregation {
|
|
|
120
120
|
sum: boolean;
|
|
121
121
|
avg: boolean;
|
|
122
122
|
}
|
|
123
|
-
declare function parseNumericAggregation(options: AggregateOptions): NumericAggregation | null;
|
|
123
|
+
declare function parseNumericAggregation(options: AggregateOptions, allowedFields?: readonly string[]): NumericAggregation | null;
|
|
124
124
|
declare function parseGroupBy(raw: string | undefined): AggregateGroupField[];
|
|
125
125
|
declare function normalizeTagGroupValue(tags: string[]): string | null;
|
|
126
126
|
declare function resolveGroupValue(field: AggregateGroupField, item: AggregateListedItem): AggregateGroupValue;
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
* Implements the pm aggregate 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]="fce074e9-e105-530a-a070-9a99c71b043d")}catch(e){}}();
|
|
8
8
|
import { EXIT_CODE } from "../../core/shared/constants.js";
|
|
9
9
|
import { PmCliError } from "../../core/shared/errors.js";
|
|
10
10
|
import { splitCommaList } from "../../core/shared/split-comma-list.js";
|
|
11
11
|
import { nowIso } from "../../core/shared/time.js";
|
|
12
12
|
import { normalizeStatusInput } from "../../core/item/status.js";
|
|
13
13
|
import { parseStatusFilterCsv } from "../../core/item/status-filter.js";
|
|
14
|
-
import { resolveRuntimeStatusRegistry, } from "../../core/schema/runtime-schema.js";
|
|
14
|
+
import { resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, } from "../../core/schema/runtime-schema.js";
|
|
15
15
|
import { resolvePmRoot } from "../../core/store/paths.js";
|
|
16
16
|
import { readSettings } from "../../core/store/settings.js";
|
|
17
17
|
import { buildListQueryFilters } from "./list-filter-shared.js";
|
|
@@ -39,7 +39,7 @@ function parseStatus(raw, statusRegistry) {
|
|
|
39
39
|
}
|
|
40
40
|
return statuses[0];
|
|
41
41
|
}
|
|
42
|
-
function parseNumericAggregation(options) {
|
|
42
|
+
function parseNumericAggregation(options, allowedFields = ["estimate", "estimated_minutes", "priority"]) {
|
|
43
43
|
const sumField = options.sum?.trim();
|
|
44
44
|
const avgField = options.avg?.trim();
|
|
45
45
|
const normalizedSum = sumField && sumField.length > 0 ? sumField : undefined;
|
|
@@ -50,8 +50,12 @@ function parseNumericAggregation(options) {
|
|
|
50
50
|
if (normalizedSum && normalizedAvg && normalizedSum !== normalizedAvg) {
|
|
51
51
|
throw new PmCliError("Aggregate --sum and --avg must target the same numeric field", EXIT_CODE.USAGE);
|
|
52
52
|
}
|
|
53
|
+
const field = normalizedSum ?? normalizedAvg;
|
|
54
|
+
if (!allowedFields.includes(field)) {
|
|
55
|
+
throw new PmCliError(`Aggregate numeric field "${field}" is not registered. Allowed: ${allowedFields.join(", ")}`, EXIT_CODE.USAGE);
|
|
56
|
+
}
|
|
53
57
|
return {
|
|
54
|
-
field
|
|
58
|
+
field,
|
|
55
59
|
sum: normalizedSum !== undefined,
|
|
56
60
|
avg: normalizedAvg !== undefined,
|
|
57
61
|
};
|
|
@@ -305,9 +309,17 @@ export async function runAggregate(options, global) {
|
|
|
305
309
|
const pmRoot = resolvePmRoot(process.cwd(), global.path);
|
|
306
310
|
const settings = await readSettings(pmRoot);
|
|
307
311
|
const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
|
|
312
|
+
const numericFields = [
|
|
313
|
+
"estimate",
|
|
314
|
+
"estimated_minutes",
|
|
315
|
+
"priority",
|
|
316
|
+
...resolveRuntimeFieldRegistry(settings.schema).definitions
|
|
317
|
+
.filter((definition) => definition.type === "number")
|
|
318
|
+
.map((definition) => definition.metadata_key),
|
|
319
|
+
];
|
|
308
320
|
const groupBy = parseGroupBy(options.groupBy);
|
|
309
321
|
const status = parseStatus(options.status, statusRegistry);
|
|
310
|
-
const numericAggregation = parseNumericAggregation(options);
|
|
322
|
+
const numericAggregation = parseNumericAggregation(options, [...new Set(numericFields)].sort((left, right) => left.localeCompare(right)));
|
|
311
323
|
const includeCompletion = options.completion === true;
|
|
312
324
|
const includeUnparented = options.includeUnparented === true;
|
|
313
325
|
const listed = await runList(status, buildListQueryFilters(options), global);
|
|
@@ -386,4 +398,4 @@ export const _testOnlyAggregateCommand = {
|
|
|
386
398
|
updateCompletionCounts,
|
|
387
399
|
};
|
|
388
400
|
//# sourceMappingURL=aggregate.js.map
|
|
389
|
-
//# debugId=
|
|
401
|
+
//# debugId=fce074e9-e105-530a-a070-9a99c71b043d
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aggregate.js","sources":["cli/commands/aggregate.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module cli/commands/aggregate\n *\n * Implements the pm aggregate command surface and its agent-facing runtime behavior.\n */\nimport { EXIT_CODE } from \"../../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../../core/shared/command-types.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport { splitCommaList } from \"../../core/shared/split-comma-list.js\";\nimport { nowIso } from \"../../core/shared/time.js\";\nimport { normalizeStatusInput } from \"../../core/item/status.js\";\nimport { parseStatusFilterCsv } from \"../../core/item/status-filter.js\";\nimport {\n resolveRuntimeStatusRegistry,\n type RuntimeStatusRegistry,\n} from \"../../core/schema/runtime-schema.js\";\nimport { resolvePmRoot } from \"../../core/store/paths.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\nimport { type ItemStatus } from \"../../types/index.js\";\nimport { buildListQueryFilters } from \"./list-filter-shared.js\";\nimport { runList } from \"./list.js\";\n\ntype AggregateGroupField =\n | \"parent\"\n | \"type\"\n | \"priority\"\n | \"status\"\n | \"assignee\"\n | \"tags\"\n | \"sprint\"\n | \"release\";\ntype AggregateGroupValue = string | number | null;\ntype AggregateGroupRecord = Partial<\n Record<AggregateGroupField, AggregateGroupValue>\n>;\ntype AggregateListedItem = {\n type: string;\n status: ItemStatus;\n priority: number;\n parent?: string;\n assignee?: string;\n tags: string[];\n sprint?: string;\n release?: string;\n};\n\nconst AGGREGATE_GROUP_FIELDS: AggregateGroupField[] = [\n \"parent\",\n \"type\",\n \"priority\",\n \"status\",\n \"assignee\",\n \"tags\",\n \"sprint\",\n \"release\",\n];\n\n/** Documents the aggregate options payload exchanged by command, SDK, and package integrations. */\nexport interface AggregateOptions {\n /** Value that configures or reports group by for this contract. */\n groupBy?: string;\n /** Value that configures or reports count for this contract. */\n count?: boolean;\n /** Value that configures or reports completion for this contract. */\n completion?: boolean;\n /** Value that configures or reports sum for this contract. */\n sum?: string;\n /** Value that configures or reports avg for this contract. */\n avg?: string;\n /** Value that configures or reports include unparented for this contract. */\n includeUnparented?: boolean;\n /** Lifecycle state reported for status. */\n status?: string;\n /** Schema type that determines the shape and validation rules for this value. */\n type?: string;\n /** Value that configures or reports tag for this contract. */\n tag?: string;\n /** Value that configures or reports priority for this contract. */\n priority?: string;\n /** Value that configures or reports deadline before for this contract. */\n deadlineBefore?: string;\n /** Value that configures or reports deadline after for this contract. */\n deadlineAfter?: string;\n /** Value that configures or reports assignee for this contract. */\n assignee?: string;\n /** Value that configures or reports assignee filter for this contract. */\n assigneeFilter?: string;\n /** Value that configures or reports parent for this contract. */\n parent?: string;\n /** Value that configures or reports sprint for this contract. */\n sprint?: string;\n /** Value that configures or reports release for this contract. */\n release?: string;\n}\n\n/** Documents the aggregate row payload exchanged by command, SDK, and package integrations. */\nexport interface AggregateRow {\n /** Value that configures or reports group for this contract. */\n group: AggregateGroupRecord;\n /** Human-readable display label for this group. Blank/null group values render with an explicit \"(unassigned)\"-style label (per dimension) so terminal and grep-based consumers are never faced with an ambiguous empty key. The structured `group` record keeps the raw null for machine consumers. */\n group_label: string;\n /** Value that configures or reports count for this contract. */\n count: number;\n /** Value that configures or reports open for this contract. */\n open?: number;\n /** Value that configures or reports in progress for this contract. */\n in_progress?: number;\n /** Value that configures or reports closed for this contract. */\n closed?: number;\n /** Value that configures or reports other for this contract. */\n other?: number;\n /** Value that configures or reports completion pct for this contract. */\n completion_pct?: number;\n /** Number of null entries represented by this result. */\n null_count?: number;\n /** Value that configures or reports sum for this contract. */\n sum?: number | null;\n /** Value that configures or reports avg for this contract. */\n avg?: number | null;\n}\n\n/** Documents the aggregate result payload exchanged by command, SDK, and package integrations. */\nexport interface AggregateResult {\n /** Value that configures or reports groups for this contract. */\n groups: AggregateRow[];\n /** Value that configures or reports count for this contract. */\n count: number;\n /** Value that configures or reports totals for this contract. */\n totals: {\n items_considered: number;\n items_grouped: number;\n items_skipped_unparented: number;\n };\n /** Value that configures or reports filters for this contract. */\n filters: {\n group_by: AggregateGroupField[];\n count: boolean;\n completion: boolean;\n sum?: string | null;\n avg?: string | null;\n numeric_field?: string | null;\n include_unparented: boolean;\n status: ItemStatus | null;\n type: string | null;\n tag: string | null;\n priority: string | null;\n deadline_before: string | null;\n deadline_after: string | null;\n assignee: string | null;\n assignee_filter: string | null;\n parent: string | null;\n sprint: string | null;\n release: string | null;\n };\n /** Value that configures or reports now for this contract. */\n now: string;\n /** Value that configures or reports warnings for this contract. */\n warnings?: string[];\n}\n\nfunction parseStatus(\n raw: string | undefined,\n statusRegistry: RuntimeStatusRegistry,\n): ItemStatus | undefined {\n const statuses = parseStatusFilterCsv(raw, statusRegistry, {\n strict: true,\n flagLabel: \"--status\",\n });\n if (!statuses || statuses.length === 0) {\n return undefined;\n }\n if (statuses.length > 1) {\n throw new PmCliError(\n 'Aggregate --status accepts one status, or the standalone \"all\" sentinel.',\n EXIT_CODE.USAGE,\n );\n }\n return statuses[0];\n}\n\ninterface NumericAggregation {\n field: string;\n sum: boolean;\n avg: boolean;\n}\n\nfunction parseNumericAggregation(\n options: AggregateOptions,\n): NumericAggregation | null {\n const sumField = options.sum?.trim();\n const avgField = options.avg?.trim();\n const normalizedSum = sumField && sumField.length > 0 ? sumField : undefined;\n const normalizedAvg = avgField && avgField.length > 0 ? avgField : undefined;\n if (!normalizedSum && !normalizedAvg) {\n return null;\n }\n if (normalizedSum && normalizedAvg && normalizedSum !== normalizedAvg) {\n throw new PmCliError(\n \"Aggregate --sum and --avg must target the same numeric field\",\n EXIT_CODE.USAGE,\n );\n }\n return {\n field: normalizedSum ?? normalizedAvg!,\n sum: normalizedSum !== undefined,\n avg: normalizedAvg !== undefined,\n };\n}\n\nfunction parseGroupBy(raw: string | undefined): AggregateGroupField[] {\n const value = raw?.trim() ?? \"status\";\n if (value.length === 0) {\n throw new PmCliError(\n \"--group-by requires at least one field name\",\n EXIT_CODE.USAGE,\n );\n }\n const requested = splitCommaList(value);\n if (requested.length === 0) {\n throw new PmCliError(\n \"--group-by requires a comma-separated list of fields\",\n EXIT_CODE.USAGE,\n );\n }\n for (const field of requested) {\n if (!AGGREGATE_GROUP_FIELDS.includes(field as AggregateGroupField)) {\n throw new PmCliError(\n `Aggregate group fields must be one of ${AGGREGATE_GROUP_FIELDS.join(\"|\")}; received \"${field}\"`,\n EXIT_CODE.USAGE,\n );\n }\n }\n return requested as AggregateGroupField[];\n}\n\nfunction normalizeTagGroupValue(tags: string[]): string | null {\n const normalized = [\n ...new Set(\n tags\n .map((tag) => tag.trim().toLowerCase())\n .filter((tag) => tag.length > 0),\n ),\n ].sort((left, right) => left.localeCompare(right));\n if (normalized.length === 0) {\n return null;\n }\n return normalized.join(\",\");\n}\n\nfunction resolveGroupValue(\n field: AggregateGroupField,\n item: AggregateListedItem,\n): AggregateGroupValue {\n switch (field) {\n case \"parent\":\n return item.parent ?? null;\n case \"type\":\n return item.type;\n case \"priority\":\n return item.priority;\n case \"status\":\n return item.status;\n case \"assignee\":\n return item.assignee ?? null;\n case \"tags\":\n return normalizeTagGroupValue(item.tags);\n case \"sprint\":\n return item.sprint ?? null;\n case \"release\":\n return item.release ?? null;\n default:\n return null;\n }\n}\n\nfunction compareNullableGroupValue(\n left: AggregateGroupValue | undefined,\n right: AggregateGroupValue | undefined,\n): number {\n const leftValue = left ?? null;\n const rightValue = right ?? null;\n if (leftValue === rightValue) {\n return 0;\n }\n if (leftValue === null) {\n return 1;\n }\n if (rightValue === null) {\n return -1;\n }\n if (typeof leftValue === \"number\" && typeof rightValue === \"number\") {\n return leftValue - rightValue;\n }\n return String(leftValue).localeCompare(String(rightValue));\n}\n\nfunction buildGroupKey(\n groupBy: AggregateGroupField[],\n group: AggregateGroupRecord,\n): string {\n return groupBy\n .map((field) => `${field}:${JSON.stringify(group[field] ?? null)}`)\n .join(\"|\");\n}\n\n/** Explicit display label for an empty/blank group value, keyed by dimension. */\nconst EMPTY_AGGREGATE_GROUP_LABELS: Record<AggregateGroupField, string> = {\n parent: \"(unparented)\",\n type: \"(untyped)\",\n priority: \"(no priority)\",\n status: \"(no status)\",\n assignee: \"(unassigned)\",\n tags: \"(untagged)\",\n sprint: \"(no sprint)\",\n release: \"(no release)\",\n};\n\n/** Render a single group field's value, substituting an explicit label for null. */\nfunction formatGroupFieldLabel(\n field: AggregateGroupField,\n value: AggregateGroupValue | undefined,\n): string {\n if (value === null || value === undefined || value === \"\") {\n return EMPTY_AGGREGATE_GROUP_LABELS[field];\n }\n return String(value);\n}\n\n/** Build the human-readable label for an aggregate row. Single-field grouping yields the bare (possibly substituted) value; multi-field grouping joins each \"field=value\" pair so composite groups stay unambiguous. */\nfunction buildGroupLabel(\n groupBy: AggregateGroupField[],\n group: AggregateGroupRecord,\n): string {\n if (groupBy.length === 1) {\n return formatGroupFieldLabel(groupBy[0], group[groupBy[0]]);\n }\n return groupBy\n .map((field) => `${field}=${formatGroupFieldLabel(field, group[field])}`)\n .join(\" | \");\n}\n\nfunction compareAggregateRows(\n left: AggregateRow,\n right: AggregateRow,\n groupBy: AggregateGroupField[],\n): number {\n for (const field of groupBy) {\n const byField = compareNullableGroupValue(\n left.group[field],\n right.group[field],\n );\n if (byField !== 0) {\n return byField;\n }\n }\n return 0;\n}\n\nfunction readNumericAggregateValue(\n item: AggregateListedItem,\n field: string,\n): number | null {\n const source = item as unknown as Record<string, unknown>;\n const raw = source[field];\n if (typeof raw === \"number\" && Number.isFinite(raw)) {\n return raw;\n }\n if (typeof raw === \"string\") {\n const trimmed = raw.trim();\n if (trimmed.length === 0) {\n return null;\n }\n const parsed = Number(trimmed);\n if (Number.isFinite(parsed)) {\n return parsed;\n }\n }\n return null;\n}\n\ninterface AggregateAccumulator {\n /** group_label is derived once at finalization, so the accumulator omits it. */\n row: Omit<AggregateRow, \"group_label\">;\n numeric_count: number;\n numeric_sum: number;\n null_count: number;\n open_count: number;\n in_progress_count: number;\n closed_count: number;\n other_count: number;\n}\n\nfunction completionPct(closed: number, total: number): number {\n if (total <= 0) {\n return 0;\n }\n return Math.round((closed / total) * 10000) / 100;\n}\n\nfunction updateCompletionCounts(\n accumulator: AggregateAccumulator,\n status: ItemStatus,\n statusRegistry: RuntimeStatusRegistry,\n): void {\n const normalizedStatus =\n normalizeStatusInput(String(status), statusRegistry) ?? status;\n if (normalizedStatus === statusRegistry.open_status) {\n accumulator.open_count += 1;\n return;\n }\n if (\n normalizedStatus === \"in_progress\" ||\n (statusRegistry.active_statuses.has(normalizedStatus) &&\n normalizedStatus !== statusRegistry.open_status)\n ) {\n accumulator.in_progress_count += 1;\n return;\n }\n if (\n statusRegistry.terminal_done_statuses.has(normalizedStatus) ||\n normalizedStatus === statusRegistry.close_status\n ) {\n accumulator.closed_count += 1;\n return;\n }\n accumulator.other_count += 1;\n}\n\nfunction createAggregateAccumulator(\n group: AggregateGroupRecord,\n numericValue: number | null,\n): AggregateAccumulator {\n return {\n row: {\n group,\n count: 1,\n },\n numeric_count: numericValue === null ? 0 : 1,\n numeric_sum: numericValue ?? 0,\n null_count: numericValue === null ? 1 : 0,\n open_count: 0,\n in_progress_count: 0,\n closed_count: 0,\n other_count: 0,\n };\n}\n\nfunction updateNumericAggregation(\n accumulator: AggregateAccumulator,\n numericValue: number | null,\n): void {\n if (numericValue === null) {\n accumulator.null_count += 1;\n return;\n }\n accumulator.numeric_count += 1;\n accumulator.numeric_sum += numericValue;\n}\n\nfunction updateAggregateAccumulator(params: {\n accumulator: AggregateAccumulator;\n item: AggregateListedItem;\n statusRegistry: RuntimeStatusRegistry;\n includeCompletion: boolean;\n numericAggregation: NumericAggregation | null;\n numericValue: number | null;\n}): void {\n params.accumulator.row.count += 1;\n if (params.includeCompletion) {\n updateCompletionCounts(\n params.accumulator,\n params.item.status,\n params.statusRegistry,\n );\n }\n if (params.numericAggregation !== null) {\n updateNumericAggregation(params.accumulator, params.numericValue);\n }\n}\n\nfunction buildAggregateGroup(\n groupBy: AggregateGroupField[],\n item: AggregateListedItem,\n): AggregateGroupRecord {\n const group: AggregateGroupRecord = {};\n for (const field of groupBy) {\n group[field] = resolveGroupValue(field, item);\n }\n return group;\n}\n\nfunction finalizeAggregateRow(\n entry: AggregateAccumulator,\n groupBy: AggregateGroupField[],\n includeCompletion: boolean,\n numericAggregation: NumericAggregation | null,\n): AggregateRow {\n const row: AggregateRow = {\n ...entry.row,\n group_label: buildGroupLabel(groupBy, entry.row.group),\n };\n if (includeCompletion) {\n row.open = entry.open_count;\n row.in_progress = entry.in_progress_count;\n row.closed = entry.closed_count;\n row.other = entry.other_count;\n row.completion_pct = completionPct(entry.closed_count, entry.row.count);\n }\n if (numericAggregation !== null) {\n row.null_count = entry.null_count;\n if (numericAggregation.sum) {\n row.sum = entry.numeric_sum;\n }\n if (numericAggregation.avg) {\n row.avg =\n entry.numeric_count === 0\n ? null\n : entry.numeric_sum / entry.numeric_count;\n }\n }\n return row;\n}\n\nfunction buildAggregateFilters(params: {\n groupBy: AggregateGroupField[];\n includeCompletion: boolean;\n includeUnparented: boolean;\n status: ItemStatus | undefined;\n options: AggregateOptions;\n numericAggregation: NumericAggregation | null;\n}): AggregateResult[\"filters\"] {\n return {\n group_by: params.groupBy,\n count: true,\n completion: params.includeCompletion,\n include_unparented: params.includeUnparented,\n status: params.status ?? null,\n type: params.options.type ?? null,\n tag: params.options.tag ?? null,\n priority: params.options.priority ?? null,\n deadline_before: params.options.deadlineBefore ?? null,\n deadline_after: params.options.deadlineAfter ?? null,\n assignee: params.options.assignee ?? null,\n assignee_filter: params.options.assigneeFilter ?? null,\n parent: params.options.parent ?? null,\n sprint: params.options.sprint ?? null,\n release: params.options.release ?? null,\n ...(params.numericAggregation !== null\n ? {\n sum: params.options.sum ?? null,\n avg: params.options.avg ?? null,\n numeric_field: params.numericAggregation.field,\n }\n : {}),\n };\n}\n\n/** Implements run aggregate for the public runtime surface of this module. */\nexport async function runAggregate(\n options: AggregateOptions,\n global: GlobalOptions,\n): Promise<AggregateResult> {\n if (options.count === false) {\n throw new PmCliError(\n \"Aggregate grouped counts are always enabled; omit count=false.\",\n EXIT_CODE.USAGE,\n );\n }\n\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n const settings = await readSettings(pmRoot);\n const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);\n const groupBy = parseGroupBy(options.groupBy);\n const status = parseStatus(options.status, statusRegistry);\n const numericAggregation = parseNumericAggregation(options);\n const includeCompletion = options.completion === true;\n const includeUnparented = options.includeUnparented === true;\n\n const listed = await runList(status, buildListQueryFilters(options), global);\n\n const grouped = new Map<string, AggregateAccumulator>();\n let skippedUnparented = 0;\n let groupedItemCount = 0;\n\n for (const listedItem of listed.items) {\n const item = listedItem as AggregateListedItem;\n const group = buildAggregateGroup(groupBy, item);\n if (\n groupBy.includes(\"parent\") &&\n group.parent === null &&\n !includeUnparented\n ) {\n skippedUnparented += 1;\n continue;\n }\n const key = buildGroupKey(groupBy, group);\n const existing = grouped.get(key);\n const numericValue =\n numericAggregation === null\n ? null\n : readNumericAggregateValue(item, numericAggregation.field);\n if (existing) {\n updateAggregateAccumulator({\n accumulator: existing,\n item,\n statusRegistry,\n includeCompletion,\n numericAggregation,\n numericValue,\n });\n } else {\n const accumulator = createAggregateAccumulator(group, numericValue);\n if (includeCompletion) {\n updateCompletionCounts(accumulator, item.status, statusRegistry);\n }\n grouped.set(key, accumulator);\n }\n groupedItemCount += 1;\n }\n\n const groups = [...grouped.values()]\n .map((entry) =>\n finalizeAggregateRow(\n entry,\n groupBy,\n includeCompletion,\n numericAggregation,\n ),\n )\n .sort((left, right) => compareAggregateRows(left, right, groupBy));\n const warnings =\n listed.warnings && listed.warnings.length > 0 ? listed.warnings : undefined;\n\n return {\n groups,\n count: groups.length,\n totals: {\n items_considered: listed.items.length,\n items_grouped: groupedItemCount,\n items_skipped_unparented: skippedUnparented,\n },\n filters: buildAggregateFilters({\n groupBy,\n includeCompletion,\n includeUnparented,\n status,\n options,\n numericAggregation,\n }),\n now: nowIso(),\n ...(warnings ? { warnings } : {}),\n };\n}\n\n/** Public contract for test only aggregate command, shared by SDK and presentation-layer consumers. */\nexport const _testOnlyAggregateCommand = {\n buildGroupKey,\n compareAggregateRows,\n compareNullableGroupValue,\n completionPct,\n normalizeTagGroupValue,\n parseGroupBy,\n parseNumericAggregation,\n parseStatus,\n readNumericAggregateValue,\n resolveGroupValue,\n updateCompletionCounts,\n};\n"],"names":[],"mappings":"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","debugId":"91c3695d-ea52-548f-967f-491f656c3ec3"}
|
|
1
|
+
{"version":3,"file":"aggregate.js","sources":["cli/commands/aggregate.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module cli/commands/aggregate\n *\n * Implements the pm aggregate command surface and its agent-facing runtime behavior.\n */\nimport { EXIT_CODE } from \"../../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../../core/shared/command-types.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport { splitCommaList } from \"../../core/shared/split-comma-list.js\";\nimport { nowIso } from \"../../core/shared/time.js\";\nimport { normalizeStatusInput } from \"../../core/item/status.js\";\nimport { parseStatusFilterCsv } from \"../../core/item/status-filter.js\";\nimport {\n resolveRuntimeFieldRegistry,\n resolveRuntimeStatusRegistry,\n type RuntimeStatusRegistry,\n} from \"../../core/schema/runtime-schema.js\";\nimport { resolvePmRoot } from \"../../core/store/paths.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\nimport { type ItemStatus } from \"../../types/index.js\";\nimport { buildListQueryFilters } from \"./list-filter-shared.js\";\nimport { runList } from \"./list.js\";\n\ntype AggregateGroupField =\n | \"parent\"\n | \"type\"\n | \"priority\"\n | \"status\"\n | \"assignee\"\n | \"tags\"\n | \"sprint\"\n | \"release\";\ntype AggregateGroupValue = string | number | null;\ntype AggregateGroupRecord = Partial<\n Record<AggregateGroupField, AggregateGroupValue>\n>;\ntype AggregateListedItem = {\n type: string;\n status: ItemStatus;\n priority: number;\n parent?: string;\n assignee?: string;\n tags: string[];\n sprint?: string;\n release?: string;\n};\n\nconst AGGREGATE_GROUP_FIELDS: AggregateGroupField[] = [\n \"parent\",\n \"type\",\n \"priority\",\n \"status\",\n \"assignee\",\n \"tags\",\n \"sprint\",\n \"release\",\n];\n\n/** Documents the aggregate options payload exchanged by command, SDK, and package integrations. */\nexport interface AggregateOptions {\n /** Value that configures or reports group by for this contract. */\n groupBy?: string;\n /** Value that configures or reports count for this contract. */\n count?: boolean;\n /** Value that configures or reports completion for this contract. */\n completion?: boolean;\n /** Value that configures or reports sum for this contract. */\n sum?: string;\n /** Value that configures or reports avg for this contract. */\n avg?: string;\n /** Value that configures or reports include unparented for this contract. */\n includeUnparented?: boolean;\n /** Lifecycle state reported for status. */\n status?: string;\n /** Schema type that determines the shape and validation rules for this value. */\n type?: string;\n /** Value that configures or reports tag for this contract. */\n tag?: string;\n /** Value that configures or reports priority for this contract. */\n priority?: string;\n /** Value that configures or reports deadline before for this contract. */\n deadlineBefore?: string;\n /** Value that configures or reports deadline after for this contract. */\n deadlineAfter?: string;\n /** Value that configures or reports assignee for this contract. */\n assignee?: string;\n /** Value that configures or reports assignee filter for this contract. */\n assigneeFilter?: string;\n /** Value that configures or reports parent for this contract. */\n parent?: string;\n /** Value that configures or reports sprint for this contract. */\n sprint?: string;\n /** Value that configures or reports release for this contract. */\n release?: string;\n}\n\n/** Documents the aggregate row payload exchanged by command, SDK, and package integrations. */\nexport interface AggregateRow {\n /** Value that configures or reports group for this contract. */\n group: AggregateGroupRecord;\n /** Human-readable display label for this group. Blank/null group values render with an explicit \"(unassigned)\"-style label (per dimension) so terminal and grep-based consumers are never faced with an ambiguous empty key. The structured `group` record keeps the raw null for machine consumers. */\n group_label: string;\n /** Value that configures or reports count for this contract. */\n count: number;\n /** Value that configures or reports open for this contract. */\n open?: number;\n /** Value that configures or reports in progress for this contract. */\n in_progress?: number;\n /** Value that configures or reports closed for this contract. */\n closed?: number;\n /** Value that configures or reports other for this contract. */\n other?: number;\n /** Value that configures or reports completion pct for this contract. */\n completion_pct?: number;\n /** Number of null entries represented by this result. */\n null_count?: number;\n /** Value that configures or reports sum for this contract. */\n sum?: number | null;\n /** Value that configures or reports avg for this contract. */\n avg?: number | null;\n}\n\n/** Documents the aggregate result payload exchanged by command, SDK, and package integrations. */\nexport interface AggregateResult {\n /** Value that configures or reports groups for this contract. */\n groups: AggregateRow[];\n /** Value that configures or reports count for this contract. */\n count: number;\n /** Value that configures or reports totals for this contract. */\n totals: {\n items_considered: number;\n items_grouped: number;\n items_skipped_unparented: number;\n };\n /** Value that configures or reports filters for this contract. */\n filters: {\n group_by: AggregateGroupField[];\n count: boolean;\n completion: boolean;\n sum?: string | null;\n avg?: string | null;\n numeric_field?: string | null;\n include_unparented: boolean;\n status: ItemStatus | null;\n type: string | null;\n tag: string | null;\n priority: string | null;\n deadline_before: string | null;\n deadline_after: string | null;\n assignee: string | null;\n assignee_filter: string | null;\n parent: string | null;\n sprint: string | null;\n release: string | null;\n };\n /** Value that configures or reports now for this contract. */\n now: string;\n /** Value that configures or reports warnings for this contract. */\n warnings?: string[];\n}\n\nfunction parseStatus(\n raw: string | undefined,\n statusRegistry: RuntimeStatusRegistry,\n): ItemStatus | undefined {\n const statuses = parseStatusFilterCsv(raw, statusRegistry, {\n strict: true,\n flagLabel: \"--status\",\n });\n if (!statuses || statuses.length === 0) {\n return undefined;\n }\n if (statuses.length > 1) {\n throw new PmCliError(\n 'Aggregate --status accepts one status, or the standalone \"all\" sentinel.',\n EXIT_CODE.USAGE,\n );\n }\n return statuses[0];\n}\n\ninterface NumericAggregation {\n field: string;\n sum: boolean;\n avg: boolean;\n}\n\nfunction parseNumericAggregation(\n options: AggregateOptions,\n allowedFields: readonly string[] = [\"estimate\", \"estimated_minutes\", \"priority\"],\n): NumericAggregation | null {\n const sumField = options.sum?.trim();\n const avgField = options.avg?.trim();\n const normalizedSum = sumField && sumField.length > 0 ? sumField : undefined;\n const normalizedAvg = avgField && avgField.length > 0 ? avgField : undefined;\n if (!normalizedSum && !normalizedAvg) {\n return null;\n }\n if (normalizedSum && normalizedAvg && normalizedSum !== normalizedAvg) {\n throw new PmCliError(\n \"Aggregate --sum and --avg must target the same numeric field\",\n EXIT_CODE.USAGE,\n );\n }\n const field = normalizedSum ?? normalizedAvg!;\n if (!allowedFields.includes(field)) {\n throw new PmCliError(\n `Aggregate numeric field \"${field}\" is not registered. Allowed: ${allowedFields.join(\", \")}`,\n EXIT_CODE.USAGE,\n );\n }\n return {\n field,\n sum: normalizedSum !== undefined,\n avg: normalizedAvg !== undefined,\n };\n}\n\nfunction parseGroupBy(raw: string | undefined): AggregateGroupField[] {\n const value = raw?.trim() ?? \"status\";\n if (value.length === 0) {\n throw new PmCliError(\n \"--group-by requires at least one field name\",\n EXIT_CODE.USAGE,\n );\n }\n const requested = splitCommaList(value);\n if (requested.length === 0) {\n throw new PmCliError(\n \"--group-by requires a comma-separated list of fields\",\n EXIT_CODE.USAGE,\n );\n }\n for (const field of requested) {\n if (!AGGREGATE_GROUP_FIELDS.includes(field as AggregateGroupField)) {\n throw new PmCliError(\n `Aggregate group fields must be one of ${AGGREGATE_GROUP_FIELDS.join(\"|\")}; received \"${field}\"`,\n EXIT_CODE.USAGE,\n );\n }\n }\n return requested as AggregateGroupField[];\n}\n\nfunction normalizeTagGroupValue(tags: string[]): string | null {\n const normalized = [\n ...new Set(\n tags\n .map((tag) => tag.trim().toLowerCase())\n .filter((tag) => tag.length > 0),\n ),\n ].sort((left, right) => left.localeCompare(right));\n if (normalized.length === 0) {\n return null;\n }\n return normalized.join(\",\");\n}\n\nfunction resolveGroupValue(\n field: AggregateGroupField,\n item: AggregateListedItem,\n): AggregateGroupValue {\n switch (field) {\n case \"parent\":\n return item.parent ?? null;\n case \"type\":\n return item.type;\n case \"priority\":\n return item.priority;\n case \"status\":\n return item.status;\n case \"assignee\":\n return item.assignee ?? null;\n case \"tags\":\n return normalizeTagGroupValue(item.tags);\n case \"sprint\":\n return item.sprint ?? null;\n case \"release\":\n return item.release ?? null;\n default:\n return null;\n }\n}\n\nfunction compareNullableGroupValue(\n left: AggregateGroupValue | undefined,\n right: AggregateGroupValue | undefined,\n): number {\n const leftValue = left ?? null;\n const rightValue = right ?? null;\n if (leftValue === rightValue) {\n return 0;\n }\n if (leftValue === null) {\n return 1;\n }\n if (rightValue === null) {\n return -1;\n }\n if (typeof leftValue === \"number\" && typeof rightValue === \"number\") {\n return leftValue - rightValue;\n }\n return String(leftValue).localeCompare(String(rightValue));\n}\n\nfunction buildGroupKey(\n groupBy: AggregateGroupField[],\n group: AggregateGroupRecord,\n): string {\n return groupBy\n .map((field) => `${field}:${JSON.stringify(group[field] ?? null)}`)\n .join(\"|\");\n}\n\n/** Explicit display label for an empty/blank group value, keyed by dimension. */\nconst EMPTY_AGGREGATE_GROUP_LABELS: Record<AggregateGroupField, string> = {\n parent: \"(unparented)\",\n type: \"(untyped)\",\n priority: \"(no priority)\",\n status: \"(no status)\",\n assignee: \"(unassigned)\",\n tags: \"(untagged)\",\n sprint: \"(no sprint)\",\n release: \"(no release)\",\n};\n\n/** Render a single group field's value, substituting an explicit label for null. */\nfunction formatGroupFieldLabel(\n field: AggregateGroupField,\n value: AggregateGroupValue | undefined,\n): string {\n if (value === null || value === undefined || value === \"\") {\n return EMPTY_AGGREGATE_GROUP_LABELS[field];\n }\n return String(value);\n}\n\n/** Build the human-readable label for an aggregate row. Single-field grouping yields the bare (possibly substituted) value; multi-field grouping joins each \"field=value\" pair so composite groups stay unambiguous. */\nfunction buildGroupLabel(\n groupBy: AggregateGroupField[],\n group: AggregateGroupRecord,\n): string {\n if (groupBy.length === 1) {\n return formatGroupFieldLabel(groupBy[0], group[groupBy[0]]);\n }\n return groupBy\n .map((field) => `${field}=${formatGroupFieldLabel(field, group[field])}`)\n .join(\" | \");\n}\n\nfunction compareAggregateRows(\n left: AggregateRow,\n right: AggregateRow,\n groupBy: AggregateGroupField[],\n): number {\n for (const field of groupBy) {\n const byField = compareNullableGroupValue(\n left.group[field],\n right.group[field],\n );\n if (byField !== 0) {\n return byField;\n }\n }\n return 0;\n}\n\nfunction readNumericAggregateValue(\n item: AggregateListedItem,\n field: string,\n): number | null {\n const source = item as unknown as Record<string, unknown>;\n const raw = source[field];\n if (typeof raw === \"number\" && Number.isFinite(raw)) {\n return raw;\n }\n if (typeof raw === \"string\") {\n const trimmed = raw.trim();\n if (trimmed.length === 0) {\n return null;\n }\n const parsed = Number(trimmed);\n if (Number.isFinite(parsed)) {\n return parsed;\n }\n }\n return null;\n}\n\ninterface AggregateAccumulator {\n /** group_label is derived once at finalization, so the accumulator omits it. */\n row: Omit<AggregateRow, \"group_label\">;\n numeric_count: number;\n numeric_sum: number;\n null_count: number;\n open_count: number;\n in_progress_count: number;\n closed_count: number;\n other_count: number;\n}\n\nfunction completionPct(closed: number, total: number): number {\n if (total <= 0) {\n return 0;\n }\n return Math.round((closed / total) * 10000) / 100;\n}\n\nfunction updateCompletionCounts(\n accumulator: AggregateAccumulator,\n status: ItemStatus,\n statusRegistry: RuntimeStatusRegistry,\n): void {\n const normalizedStatus =\n normalizeStatusInput(String(status), statusRegistry) ?? status;\n if (normalizedStatus === statusRegistry.open_status) {\n accumulator.open_count += 1;\n return;\n }\n if (\n normalizedStatus === \"in_progress\" ||\n (statusRegistry.active_statuses.has(normalizedStatus) &&\n normalizedStatus !== statusRegistry.open_status)\n ) {\n accumulator.in_progress_count += 1;\n return;\n }\n if (\n statusRegistry.terminal_done_statuses.has(normalizedStatus) ||\n normalizedStatus === statusRegistry.close_status\n ) {\n accumulator.closed_count += 1;\n return;\n }\n accumulator.other_count += 1;\n}\n\nfunction createAggregateAccumulator(\n group: AggregateGroupRecord,\n numericValue: number | null,\n): AggregateAccumulator {\n return {\n row: {\n group,\n count: 1,\n },\n numeric_count: numericValue === null ? 0 : 1,\n numeric_sum: numericValue ?? 0,\n null_count: numericValue === null ? 1 : 0,\n open_count: 0,\n in_progress_count: 0,\n closed_count: 0,\n other_count: 0,\n };\n}\n\nfunction updateNumericAggregation(\n accumulator: AggregateAccumulator,\n numericValue: number | null,\n): void {\n if (numericValue === null) {\n accumulator.null_count += 1;\n return;\n }\n accumulator.numeric_count += 1;\n accumulator.numeric_sum += numericValue;\n}\n\nfunction updateAggregateAccumulator(params: {\n accumulator: AggregateAccumulator;\n item: AggregateListedItem;\n statusRegistry: RuntimeStatusRegistry;\n includeCompletion: boolean;\n numericAggregation: NumericAggregation | null;\n numericValue: number | null;\n}): void {\n params.accumulator.row.count += 1;\n if (params.includeCompletion) {\n updateCompletionCounts(\n params.accumulator,\n params.item.status,\n params.statusRegistry,\n );\n }\n if (params.numericAggregation !== null) {\n updateNumericAggregation(params.accumulator, params.numericValue);\n }\n}\n\nfunction buildAggregateGroup(\n groupBy: AggregateGroupField[],\n item: AggregateListedItem,\n): AggregateGroupRecord {\n const group: AggregateGroupRecord = {};\n for (const field of groupBy) {\n group[field] = resolveGroupValue(field, item);\n }\n return group;\n}\n\nfunction finalizeAggregateRow(\n entry: AggregateAccumulator,\n groupBy: AggregateGroupField[],\n includeCompletion: boolean,\n numericAggregation: NumericAggregation | null,\n): AggregateRow {\n const row: AggregateRow = {\n ...entry.row,\n group_label: buildGroupLabel(groupBy, entry.row.group),\n };\n if (includeCompletion) {\n row.open = entry.open_count;\n row.in_progress = entry.in_progress_count;\n row.closed = entry.closed_count;\n row.other = entry.other_count;\n row.completion_pct = completionPct(entry.closed_count, entry.row.count);\n }\n if (numericAggregation !== null) {\n row.null_count = entry.null_count;\n if (numericAggregation.sum) {\n row.sum = entry.numeric_sum;\n }\n if (numericAggregation.avg) {\n row.avg =\n entry.numeric_count === 0\n ? null\n : entry.numeric_sum / entry.numeric_count;\n }\n }\n return row;\n}\n\nfunction buildAggregateFilters(params: {\n groupBy: AggregateGroupField[];\n includeCompletion: boolean;\n includeUnparented: boolean;\n status: ItemStatus | undefined;\n options: AggregateOptions;\n numericAggregation: NumericAggregation | null;\n}): AggregateResult[\"filters\"] {\n return {\n group_by: params.groupBy,\n count: true,\n completion: params.includeCompletion,\n include_unparented: params.includeUnparented,\n status: params.status ?? null,\n type: params.options.type ?? null,\n tag: params.options.tag ?? null,\n priority: params.options.priority ?? null,\n deadline_before: params.options.deadlineBefore ?? null,\n deadline_after: params.options.deadlineAfter ?? null,\n assignee: params.options.assignee ?? null,\n assignee_filter: params.options.assigneeFilter ?? null,\n parent: params.options.parent ?? null,\n sprint: params.options.sprint ?? null,\n release: params.options.release ?? null,\n ...(params.numericAggregation !== null\n ? {\n sum: params.options.sum ?? null,\n avg: params.options.avg ?? null,\n numeric_field: params.numericAggregation.field,\n }\n : {}),\n };\n}\n\n/** Implements run aggregate for the public runtime surface of this module. */\nexport async function runAggregate(\n options: AggregateOptions,\n global: GlobalOptions,\n): Promise<AggregateResult> {\n if (options.count === false) {\n throw new PmCliError(\n \"Aggregate grouped counts are always enabled; omit count=false.\",\n EXIT_CODE.USAGE,\n );\n }\n\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n const settings = await readSettings(pmRoot);\n const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);\n const numericFields = [\n \"estimate\",\n \"estimated_minutes\",\n \"priority\",\n ...resolveRuntimeFieldRegistry(settings.schema).definitions\n .filter((definition) => definition.type === \"number\")\n .map((definition) => definition.metadata_key),\n ];\n const groupBy = parseGroupBy(options.groupBy);\n const status = parseStatus(options.status, statusRegistry);\n const numericAggregation = parseNumericAggregation(\n options,\n [...new Set(numericFields)].sort((left, right) => left.localeCompare(right)),\n );\n const includeCompletion = options.completion === true;\n const includeUnparented = options.includeUnparented === true;\n\n const listed = await runList(status, buildListQueryFilters(options), global);\n\n const grouped = new Map<string, AggregateAccumulator>();\n let skippedUnparented = 0;\n let groupedItemCount = 0;\n\n for (const listedItem of listed.items) {\n const item = listedItem as AggregateListedItem;\n const group = buildAggregateGroup(groupBy, item);\n if (\n groupBy.includes(\"parent\") &&\n group.parent === null &&\n !includeUnparented\n ) {\n skippedUnparented += 1;\n continue;\n }\n const key = buildGroupKey(groupBy, group);\n const existing = grouped.get(key);\n const numericValue =\n numericAggregation === null\n ? null\n : readNumericAggregateValue(item, numericAggregation.field);\n if (existing) {\n updateAggregateAccumulator({\n accumulator: existing,\n item,\n statusRegistry,\n includeCompletion,\n numericAggregation,\n numericValue,\n });\n } else {\n const accumulator = createAggregateAccumulator(group, numericValue);\n if (includeCompletion) {\n updateCompletionCounts(accumulator, item.status, statusRegistry);\n }\n grouped.set(key, accumulator);\n }\n groupedItemCount += 1;\n }\n\n const groups = [...grouped.values()]\n .map((entry) =>\n finalizeAggregateRow(\n entry,\n groupBy,\n includeCompletion,\n numericAggregation,\n ),\n )\n .sort((left, right) => compareAggregateRows(left, right, groupBy));\n const warnings =\n listed.warnings && listed.warnings.length > 0 ? listed.warnings : undefined;\n\n return {\n groups,\n count: groups.length,\n totals: {\n items_considered: listed.items.length,\n items_grouped: groupedItemCount,\n items_skipped_unparented: skippedUnparented,\n },\n filters: buildAggregateFilters({\n groupBy,\n includeCompletion,\n includeUnparented,\n status,\n options,\n numericAggregation,\n }),\n now: nowIso(),\n ...(warnings ? { warnings } : {}),\n };\n}\n\n/** Public contract for test only aggregate command, shared by SDK and presentation-layer consumers. */\nexport const _testOnlyAggregateCommand = {\n buildGroupKey,\n compareAggregateRows,\n compareNullableGroupValue,\n completionPct,\n normalizeTagGroupValue,\n parseGroupBy,\n parseNumericAggregation,\n parseStatus,\n readNumericAggregateValue,\n resolveGroupValue,\n updateCompletionCounts,\n};\n"],"names":[],"mappings":"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","debugId":"fce074e9-e105-530a-a070-9a99c71b043d"}
|
|
@@ -4,6 +4,7 @@ import type { ContextDepth, ContextSectionName, ContextSettings, ItemMetadata, I
|
|
|
4
4
|
import { type CalendarRow } from "./calendar.js";
|
|
5
5
|
import { type CompactActivityEntry } from "./activity.js";
|
|
6
6
|
import { type ContextRelevanceCandidate, type ContextRelevanceContributions, type ContextRelevanceReport, type ContextRelevanceSignalName } from "../../sdk/context-relevance.js";
|
|
7
|
+
import { type ContextPackingReport } from "../../sdk/context-packing.js";
|
|
7
8
|
/** Supported values accepted by the context output contract. */
|
|
8
9
|
export declare const CONTEXT_OUTPUT_VALUES: readonly ["markdown", "toon", "json"];
|
|
9
10
|
/** Restricts context output format values accepted by command, SDK, and storage contracts. */
|
|
@@ -309,6 +310,8 @@ export interface ContextResult {
|
|
|
309
310
|
warnings?: string[];
|
|
310
311
|
/** Value that configures or reports ranking for this contract. */
|
|
311
312
|
ranking?: ContextRankingSummary;
|
|
313
|
+
/** Token-budget selection and projection accounting for ranked focus rows. */
|
|
314
|
+
packing?: ContextPackingSummary;
|
|
312
315
|
/** Whether additional ranked focus rows remain after this page. */
|
|
313
316
|
has_more?: boolean;
|
|
314
317
|
/** Opaque continuation cursor for the next ranked focus page. */
|
|
@@ -318,6 +321,14 @@ export interface ContextResult {
|
|
|
318
321
|
/** Explicit marker that focus rows were bounded. */
|
|
319
322
|
truncated?: true;
|
|
320
323
|
}
|
|
324
|
+
/** Compact token-budget accounting shared by context and next results. */
|
|
325
|
+
export type ContextPackingSummary = Omit<ContextPackingReport<unknown>, "included"> & {
|
|
326
|
+
included: Array<{
|
|
327
|
+
id: string;
|
|
328
|
+
projection: string;
|
|
329
|
+
tokens: number;
|
|
330
|
+
}>;
|
|
331
|
+
};
|
|
321
332
|
/** Compact explainability envelope shared by context and next JSON results. */
|
|
322
333
|
export interface ContextRankingSummary {
|
|
323
334
|
/** Value that configures or reports model for this contract. */
|
|
@@ -382,7 +393,11 @@ declare function normalizedParentId(value: unknown): string | null;
|
|
|
382
393
|
*/
|
|
383
394
|
export declare function compareCriticalItems(left: ItemMetadata, right: ItemMetadata, statusRegistry: RuntimeStatusRegistry): number;
|
|
384
395
|
/** Derives the metadata signals currently available on compact item rows. More expensive history/index/semantic signals can be added by an extension scorer without changing the public candidate contract. */
|
|
385
|
-
export declare function buildItemContextRelevanceCandidates(items: readonly ItemMetadata[], statusRegistry: RuntimeStatusRegistry, now: string, author: string | undefined): ContextRelevanceCandidate<ItemMetadata>[];
|
|
396
|
+
export declare function buildItemContextRelevanceCandidates(items: readonly ItemMetadata[], statusRegistry: RuntimeStatusRegistry, now: string, author: string | undefined, usageAffinity?: Readonly<Record<string, number>>): ContextRelevanceCandidate<ItemMetadata>[];
|
|
397
|
+
/** Packs a relevance report with monotone identity, summary, and full item projections. */
|
|
398
|
+
export declare function packRankedContextItems(report: ContextRelevanceReport<ItemMetadata>, tokenBudget: number, requiredIds?: ReadonlySet<string>, profile?: "context" | "next"): ContextPackingReport<ItemMetadata>;
|
|
399
|
+
/** Projects the SDK packer report onto the stable low-token command envelope. */
|
|
400
|
+
export declare function toContextPackingSummary(report: ContextPackingReport<ItemMetadata>): ContextPackingSummary;
|
|
386
401
|
/** Project a full scorer report onto the low-token command explanation shape. */
|
|
387
402
|
export declare function toContextRankingSummary<TItem>(report: ContextRelevanceReport<TItem>): ContextRankingSummary;
|
|
388
403
|
declare function completionPct(closed: number, total: number): number;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm context 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]="7563a6df-9229-5af9-9849-85a058c01a46")}catch(e){}}();
|
|
8
8
|
import { SETTINGS_DEFAULTS, EXIT_CODE } from "../../core/shared/constants.js";
|
|
9
9
|
import { PmCliError } from "../../core/shared/errors.js";
|
|
10
10
|
import { compareTimestampStrings, nowIso } from "../../core/shared/time.js";
|
|
@@ -19,6 +19,8 @@ import { runList } from "./list.js";
|
|
|
19
19
|
import { runActivity } from "./activity.js";
|
|
20
20
|
import { scoreContextCandidatesWithActiveExtensions, } from "../../sdk/context-relevance.js";
|
|
21
21
|
import { createQueryFingerprint, encodeQueryCursor, resolveQueryCursorStart, } from "../../sdk/pagination.js";
|
|
22
|
+
import { packContextCandidates, } from "../../sdk/context-packing.js";
|
|
23
|
+
import { readContextUsageAffinity, recordContextUsageServing, } from "../../sdk/context-usage.js";
|
|
22
24
|
// ---------------------------------------------------------------------------
|
|
23
25
|
// Output format
|
|
24
26
|
// ---------------------------------------------------------------------------
|
|
@@ -451,11 +453,12 @@ function buildItemContextRelevanceCandidate(item, params) {
|
|
|
451
453
|
deadline_pressure: resolveDeadlinePressure(item.deadline, params.nowMs),
|
|
452
454
|
knowledge_density: Math.min(knowledgeEntries / 5, 1),
|
|
453
455
|
author_affinity: assignedToAuthor ? 1 : 0,
|
|
456
|
+
usage_affinity: params.usageAffinity?.[item.id],
|
|
454
457
|
},
|
|
455
458
|
};
|
|
456
459
|
}
|
|
457
460
|
/** Derives the metadata signals currently available on compact item rows. More expensive history/index/semantic signals can be added by an extension scorer without changing the public candidate contract. */
|
|
458
|
-
export function buildItemContextRelevanceCandidates(items, statusRegistry, now, author) {
|
|
461
|
+
export function buildItemContextRelevanceCandidates(items, statusRegistry, now, author, usageAffinity) {
|
|
459
462
|
const recencyOrder = [...items].sort((left, right) => compareTimestampStrings(sortableTimestamp(right.updated_at), sortableTimestamp(left.updated_at)) || left.id.localeCompare(right.id));
|
|
460
463
|
const recencyRank = new Map(recencyOrder.map((item, index) => [item.id, index]));
|
|
461
464
|
const recencyDenominator = Math.max(items.length - 1, 1);
|
|
@@ -468,8 +471,46 @@ export function buildItemContextRelevanceCandidates(items, statusRegistry, now,
|
|
|
468
471
|
recencyRank,
|
|
469
472
|
recencyDenominator,
|
|
470
473
|
itemCount: items.length,
|
|
474
|
+
usageAffinity,
|
|
471
475
|
}));
|
|
472
476
|
}
|
|
477
|
+
function estimateJsonTokens(value) {
|
|
478
|
+
return Math.max(1, Math.ceil(Buffer.byteLength(JSON.stringify(value), "utf8") / 4));
|
|
479
|
+
}
|
|
480
|
+
/** Packs a relevance report with monotone identity, summary, and full item projections. */
|
|
481
|
+
export function packRankedContextItems(report, tokenBudget, requiredIds = new Set(), profile = "context") {
|
|
482
|
+
return packContextCandidates(report.ranked.map((entry) => ({
|
|
483
|
+
id: entry.id,
|
|
484
|
+
item: entry.item,
|
|
485
|
+
rank: entry.rank,
|
|
486
|
+
score: entry.score,
|
|
487
|
+
required: requiredIds.has(entry.id),
|
|
488
|
+
cluster: entry.item.parent?.trim() || entry.item.type,
|
|
489
|
+
token_costs: {
|
|
490
|
+
identity: estimateJsonTokens({ id: entry.id, title: entry.item.title }),
|
|
491
|
+
summary: estimateJsonTokens({
|
|
492
|
+
id: entry.id,
|
|
493
|
+
title: entry.item.title,
|
|
494
|
+
type: entry.item.type,
|
|
495
|
+
status: entry.item.status,
|
|
496
|
+
priority: entry.item.priority,
|
|
497
|
+
parent: entry.item.parent,
|
|
498
|
+
}),
|
|
499
|
+
full: estimateJsonTokens(entry.item),
|
|
500
|
+
},
|
|
501
|
+
})), { tokenBudget, profile, latencyBudgetMs: 25 });
|
|
502
|
+
}
|
|
503
|
+
/** Projects the SDK packer report onto the stable low-token command envelope. */
|
|
504
|
+
export function toContextPackingSummary(report) {
|
|
505
|
+
return {
|
|
506
|
+
...report,
|
|
507
|
+
included: report.included.map((entry) => ({
|
|
508
|
+
id: entry.id,
|
|
509
|
+
projection: entry.projection,
|
|
510
|
+
tokens: entry.tokens,
|
|
511
|
+
})),
|
|
512
|
+
};
|
|
513
|
+
}
|
|
473
514
|
/** Project a full scorer report onto the low-token command explanation shape. */
|
|
474
515
|
export function toContextRankingSummary(report) {
|
|
475
516
|
return {
|
|
@@ -1195,38 +1236,51 @@ function resolveContextSubtreeIds(parentScope, fullCorpus) {
|
|
|
1195
1236
|
}
|
|
1196
1237
|
return subtree.ids;
|
|
1197
1238
|
}
|
|
1198
|
-
async function resolveContextFocusGroups(listedItemMetadata, allItems, statusRegistry, sectionsIncluded, limit, now, author, cursor, cursorFingerprint, useBoundedPage) {
|
|
1239
|
+
async function resolveContextFocusGroups(listedItemMetadata, allItems, statusRegistry, sectionsIncluded, limit, now, author, cursor, cursorFingerprint, useBoundedPage, pmRoot) {
|
|
1199
1240
|
const structural = [...listedItemMetadata].sort((left, right) => compareCriticalItems(left, right, statusRegistry));
|
|
1200
|
-
const
|
|
1241
|
+
const usage = await readContextUsageAffinity({
|
|
1242
|
+
pmRoot,
|
|
1243
|
+
author,
|
|
1244
|
+
enabled: process.env.PM_CONTEXT_USAGE_DISABLED !== "1",
|
|
1245
|
+
});
|
|
1246
|
+
const ranking = await scoreContextCandidatesWithActiveExtensions("context", buildItemContextRelevanceCandidates(structural, statusRegistry, now, author, usage.affinity));
|
|
1201
1247
|
const ranked = ranking.ranked.map((entry) => entry.item);
|
|
1202
1248
|
const activeStatuses = statusRegistry.active_statuses;
|
|
1203
|
-
const
|
|
1249
|
+
const rankedActiveItems = ranked.filter((item) => activeStatuses.has(normalizeStatusForRegistry(item.status, statusRegistry)));
|
|
1204
1250
|
const pageStart = useBoundedPage
|
|
1205
|
-
? resolveQueryCursorStart(
|
|
1251
|
+
? resolveQueryCursorStart(rankedActiveItems, cursor, cursorFingerprint, (item) => item.id)
|
|
1206
1252
|
: 0;
|
|
1207
1253
|
const focusPage = useBoundedPage
|
|
1208
|
-
?
|
|
1209
|
-
:
|
|
1254
|
+
? rankedActiveItems.slice(pageStart, pageStart + limit)
|
|
1255
|
+
: rankedActiveItems;
|
|
1210
1256
|
const hasMore = useBoundedPage &&
|
|
1211
1257
|
focusPage.length > 0 &&
|
|
1212
|
-
pageStart + focusPage.length <
|
|
1258
|
+
pageStart + focusPage.length < rankedActiveItems.length;
|
|
1213
1259
|
const nextCursor = hasMore && focusPage.length > 0
|
|
1214
1260
|
? encodeQueryCursor(cursorFingerprint, focusPage[focusPage.length - 1].id, pageStart + focusPage.length - 1)
|
|
1215
1261
|
: undefined;
|
|
1216
|
-
const
|
|
1262
|
+
const rankedBlockedItems = ranked.filter((item) => statusRegistry.blocked_statuses.has(normalizeStatusForRegistry(item.status, statusRegistry)));
|
|
1263
|
+
const packingIds = new Set([
|
|
1264
|
+
...focusPage.map((item) => item.id),
|
|
1265
|
+
...rankedBlockedItems.slice(0, limit).map((item) => item.id),
|
|
1266
|
+
]);
|
|
1267
|
+
const packing = packRankedContextItems({ ...ranking, ranked: ranking.ranked.filter((entry) => packingIds.has(entry.id)) }, Math.max(256, limit * 160));
|
|
1268
|
+
const packedItems = packing.included.map((entry) => entry.item);
|
|
1269
|
+
const activeItems = packedItems.filter((item) => activeStatuses.has(normalizeStatusForRegistry(item.status, statusRegistry)));
|
|
1270
|
+
const blockedItems = packedItems.filter((item) => statusRegistry.blocked_statuses.has(normalizeStatusForRegistry(item.status, statusRegistry)));
|
|
1217
1271
|
const childrenByParent = buildChildrenByParent(allItems);
|
|
1218
1272
|
const focusChildrenByParent = contextNeedsAllItems(sectionsIncluded)
|
|
1219
1273
|
? childrenByParent
|
|
1220
1274
|
: undefined;
|
|
1221
|
-
const highLevel =
|
|
1275
|
+
const highLevel = activeItems
|
|
1222
1276
|
.filter((item) => HIGH_LEVEL_TYPES.has(item.type))
|
|
1223
1277
|
.slice(0, useBoundedPage ? focusPage.length : limit)
|
|
1224
1278
|
.map((item) => toContextFocusItem(item, statusRegistry, focusChildrenByParent));
|
|
1225
|
-
const lowLevel =
|
|
1279
|
+
const lowLevel = activeItems
|
|
1226
1280
|
.filter((item) => !HIGH_LEVEL_TYPES.has(item.type))
|
|
1227
1281
|
.slice(0, useBoundedPage ? focusPage.length : limit)
|
|
1228
1282
|
.map((item) => toContextFocusItem(item, statusRegistry, focusChildrenByParent));
|
|
1229
|
-
const blockedFallbackUsed =
|
|
1283
|
+
const blockedFallbackUsed = rankedActiveItems.length === 0;
|
|
1230
1284
|
return {
|
|
1231
1285
|
activeItems,
|
|
1232
1286
|
blockedItems,
|
|
@@ -1239,6 +1293,7 @@ async function resolveContextFocusGroups(listedItemMetadata, allItems, statusReg
|
|
|
1239
1293
|
: [],
|
|
1240
1294
|
blockedFallbackUsed,
|
|
1241
1295
|
ranking,
|
|
1296
|
+
packing,
|
|
1242
1297
|
pageExtras: {
|
|
1243
1298
|
...(useBoundedPage ? { applied_limit: limit } : {}),
|
|
1244
1299
|
...(hasMore ? { has_more: true, truncated: true } : {}),
|
|
@@ -1382,15 +1437,39 @@ function maybeAttachEmptyContextSuggestions(result, activeItems, blockedItems) {
|
|
|
1382
1437
|
"pm aggregate for a full project status overview",
|
|
1383
1438
|
];
|
|
1384
1439
|
}
|
|
1440
|
+
async function attachContextUsageFeedback(result, focusGroups, pmRoot, author) {
|
|
1441
|
+
try {
|
|
1442
|
+
const included = new Set(focusGroups.packing.included.map((entry) => entry.id));
|
|
1443
|
+
await recordContextUsageServing({
|
|
1444
|
+
pmRoot,
|
|
1445
|
+
author,
|
|
1446
|
+
surface: "context",
|
|
1447
|
+
profile: focusGroups.packing.profile,
|
|
1448
|
+
rows: focusGroups.ranking.ranked.map((entry) => ({
|
|
1449
|
+
id: entry.id,
|
|
1450
|
+
rank: entry.rank,
|
|
1451
|
+
included: included.has(entry.id),
|
|
1452
|
+
})),
|
|
1453
|
+
enabled: process.env.PM_CONTEXT_USAGE_DISABLED !== "1",
|
|
1454
|
+
});
|
|
1455
|
+
}
|
|
1456
|
+
catch {
|
|
1457
|
+
result.warnings = mergeSortedWarnings(result.warnings, [
|
|
1458
|
+
"context_usage_feedback_write_failed",
|
|
1459
|
+
]);
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1385
1462
|
/** Implements run context for the public runtime surface of this module. */
|
|
1386
1463
|
export async function runContext(options, global) {
|
|
1464
|
+
const pmRoot = resolvePmRoot(process.cwd(), global.path);
|
|
1387
1465
|
const resolvedRuntime = await resolveContextRuntime(options, global);
|
|
1388
1466
|
const corpus = await loadContextCorpus(options, global, resolvedRuntime);
|
|
1389
1467
|
const runtime = {
|
|
1390
1468
|
...resolvedRuntime,
|
|
1391
1469
|
limit: resolveContextLimitAtScale(resolvedRuntime.limit, corpus.fullCorpus.length),
|
|
1392
1470
|
};
|
|
1393
|
-
const
|
|
1471
|
+
const author = process.env.PM_AUTHOR ?? runtime.settings.author_default;
|
|
1472
|
+
const focusGroups = await resolveContextFocusGroups(corpus.listedItemMetadata, corpus.allItems, runtime.statusRegistry, runtime.sectionsIncluded, runtime.limit, nowIso(), author, options.after, buildContextCursorFingerprint(options), shouldPageContextFocus(options, corpus.fullCorpus.length), pmRoot);
|
|
1394
1473
|
const agendaContext = await buildContextAgenda(options, global, runtime, corpus.subtreeIds);
|
|
1395
1474
|
const warnings = mergeSortedWarnings(corpus.listed.warnings, agendaContext.agenda.warnings, focusGroups.ranking.warnings);
|
|
1396
1475
|
const inProgressCount = countContextStatus(focusGroups.activeItems, normalizeStatusInput("in_progress", runtime.statusRegistry), runtime.statusRegistry);
|
|
@@ -1453,13 +1532,16 @@ export async function runContext(options, global) {
|
|
|
1453
1532
|
...focusGroups.pageExtras,
|
|
1454
1533
|
};
|
|
1455
1534
|
attachOptionalContextSections(result, sections);
|
|
1456
|
-
if (options.explainRanking === true)
|
|
1535
|
+
if (options.explainRanking === true) {
|
|
1457
1536
|
result.ranking = toContextRankingSummary(focusGroups.ranking);
|
|
1537
|
+
result.packing = toContextPackingSummary(focusGroups.packing);
|
|
1538
|
+
}
|
|
1458
1539
|
applyContextFocusProjection(result, runtime.focusFields);
|
|
1459
1540
|
if (warnings.length > 0)
|
|
1460
1541
|
result.warnings = warnings;
|
|
1461
1542
|
maybeAttachEmptyContextSuggestions(result, focusGroups.activeItems, focusGroups.blockedItems);
|
|
1543
|
+
await attachContextUsageFeedback(result, focusGroups, pmRoot, author);
|
|
1462
1544
|
return result;
|
|
1463
1545
|
}
|
|
1464
1546
|
//# sourceMappingURL=context.js.map
|
|
1465
|
-
//# debugId=
|
|
1547
|
+
//# debugId=7563a6df-9229-5af9-9849-85a058c01a46
|