@unbrained/pm-cli 2026.7.16 → 2026.7.18
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 +30 -2
- package/CONTRIBUTING.md +2 -2
- package/dist/cli/bootstrap-args.d.ts +2 -115
- package/dist/cli/bootstrap-args.js +4 -831
- package/dist/cli/bootstrap-args.js.map +1 -1
- package/dist/cli/commands/close.d.ts +1 -1
- package/dist/cli/commands/close.js +3 -3
- package/dist/cli/commands/close.js.map +1 -1
- package/dist/cli/commands/completion.js +47 -5
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/context.d.ts +2 -2
- package/dist/cli/commands/context.js +42 -28
- package/dist/cli/commands/context.js.map +1 -1
- package/dist/cli/commands/contracts.js +5 -3
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/commands/eval.d.ts +4 -64
- package/dist/cli/commands/eval.js +4 -153
- package/dist/cli/commands/eval.js.map +1 -1
- package/dist/cli/commands/graph.d.ts +7 -0
- package/dist/cli/commands/graph.js +11 -0
- package/dist/cli/commands/graph.js.map +1 -0
- package/dist/cli/commands/index.d.ts +1 -0
- package/dist/cli/commands/index.js +3 -2
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/linked-test-entry.d.ts +6 -6
- package/dist/cli/commands/linked-test-entry.js +4 -65
- package/dist/cli/commands/linked-test-entry.js.map +1 -1
- package/dist/cli/commands/linked-test-parsers.d.ts +3 -45
- package/dist/cli/commands/linked-test-parsers.js +4 -516
- package/dist/cli/commands/linked-test-parsers.js.map +1 -1
- package/dist/cli/commands/list.d.ts +3 -210
- package/dist/cli/commands/list.js +4 -1068
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/next.d.ts +1 -1
- package/dist/cli/commands/next.js +3 -3
- package/dist/cli/commands/next.js.map +1 -1
- package/dist/cli/commands/search.d.ts +3 -464
- package/dist/cli/commands/search.js +4 -2236
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/stats.d.ts +6 -66
- package/dist/cli/commands/stats.js +4 -157
- package/dist/cli/commands/stats.js.map +1 -1
- package/dist/cli/commands/telemetry.d.ts +6 -14
- package/dist/cli/commands/telemetry.js +4 -349
- package/dist/cli/commands/telemetry.js.map +1 -1
- package/dist/cli/commands/test-all.d.ts +6 -95
- package/dist/cli/commands/test-all.js +4 -439
- package/dist/cli/commands/test-all.js.map +1 -1
- package/dist/cli/commands/test-runs.d.ts +6 -92
- package/dist/cli/commands/test-runs.js +4 -189
- package/dist/cli/commands/test-runs.js.map +1 -1
- package/dist/cli/commands/test.d.ts +6 -244
- package/dist/cli/commands/test.js +4 -1780
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/commands/update-many.d.ts +15 -29
- package/dist/cli/commands/update-many.js +355 -259
- package/dist/cli/commands/update-many.js.map +1 -1
- package/dist/cli/main.js +141 -133
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/register-list-query.js +49 -7
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.js +7 -3
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/search-refresh.js +4 -9
- package/dist/cli/search-refresh.js.map +1 -1
- package/dist/cli/shared-parsers.d.ts +6 -9
- package/dist/cli/shared-parsers.js +4 -37
- package/dist/cli/shared-parsers.js.map +1 -1
- package/dist/cli/telemetry-flush.js +4 -4
- package/dist/cli/telemetry-flush.js.map +1 -1
- package/dist/cli-bundle/bundle-manifest.json +334 -326
- package/dist/cli-bundle/chunks/{append-OJQFUQ4T.js → append-5YF3TO7I.js} +5 -5
- package/dist/cli-bundle/chunks/append-JHO5K6RP.js +11 -0
- package/dist/cli-bundle/chunks/{chunk-BCOFWYW4.js → chunk-2BX74BAS.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-APRVSW2O.js → chunk-2CXL335K.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-KG44YSKD.js → chunk-2FUOXSRN.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-HDH3JUGG.js → chunk-2IPNL3DR.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-GM5QHQU6.js → chunk-2XOSFSTH.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-UFXU44HV.js → chunk-35FHWD4C.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-2WSE6PO2.js.map → chunk-35FHWD4C.js.map} +1 -7
- package/dist/cli-bundle/chunks/{chunk-K3WII2ME.js → chunk-37DRDP2B.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-BKVG6XOA.js → chunk-3CUQZNQ6.js} +67 -509
- package/dist/cli-bundle/chunks/chunk-3CUQZNQ6.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-3QDR6ZLU.js +800 -0
- package/dist/cli-bundle/chunks/chunk-3QDR6ZLU.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-5JLUII3O.js → chunk-43UMFKCK.js} +321 -240
- package/dist/cli-bundle/chunks/chunk-43UMFKCK.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-PMOSXADO.js → chunk-47HXN6RX.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-6CFNAVTF.js → chunk-5HGZKQUL.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-2IFFUZLC.js → chunk-5UKQLQM2.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-DM4H7FP4.js → chunk-633PKXLT.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-XSJUSQAE.js → chunk-646MQXFW.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-ZI6VQWQ7.js → chunk-66MKH7SZ.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-S6MQESFR.js → chunk-67RO3H4N.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-34L5OT3Y.js → chunk-6DYOZS6C.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-RRM5JYJC.js → chunk-6O44IN44.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-5ZSLZLDN.js → chunk-6VHUGVNP.js} +608 -456
- package/dist/cli-bundle/chunks/chunk-6VHUGVNP.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-PENXZX3U.js → chunk-74FKFFXO.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-HO4KXD6I.js → chunk-7H5NNCJ5.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-7B67ZL4N.js → chunk-7R6UIHYY.js} +75 -5
- package/dist/cli-bundle/chunks/{chunk-7B67ZL4N.js.map → chunk-7R6UIHYY.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-3S5QVM5H.js → chunk-7UCY6DR5.js} +193 -22
- package/dist/cli-bundle/chunks/chunk-7UCY6DR5.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-WT3ZEOGH.js → chunk-ADXDCAKP.js} +16 -7
- package/dist/cli-bundle/chunks/{chunk-WT3ZEOGH.js.map → chunk-ADXDCAKP.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-TQSZFPIS.js → chunk-AFGKSHAM.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-6N2VXVTQ.js → chunk-ARGDWQ4J.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-XXXF6PAQ.js → chunk-AXRT7K5V.js} +83 -62
- package/dist/cli-bundle/chunks/chunk-AXRT7K5V.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-3U7ZR6M4.js → chunk-B57RJHBZ.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-YCQET3OT.js → chunk-BAP7G3N2.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-NLDFBC6J.js → chunk-BDA35QG5.js} +35 -5
- package/dist/cli-bundle/chunks/chunk-BDA35QG5.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-QKXHFPYM.js → chunk-BIRYX32V.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-RMLWNPH2.js → chunk-BVLOMU6O.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-2VPAVL7O.js → chunk-CKX4WOPC.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-TKOVBP6C.js → chunk-D52ZN3BF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-KPMKHGEA.js → chunk-D53RTYVI.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-ODALILG3.js → chunk-D5XHO4Q7.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-YAQEBNY7.js → chunk-DDFGYUCQ.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-EAB64KLB.js → chunk-DG2EQRIH.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-J6364LFM.js → chunk-DHNG452T.js} +9 -18
- package/dist/cli-bundle/chunks/{chunk-J6364LFM.js.map → chunk-DHNG452T.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-JXQUXVMI.js → chunk-E4FXM2XB.js} +77 -7
- package/dist/cli-bundle/chunks/{chunk-JXQUXVMI.js.map → chunk-E4FXM2XB.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-IG3SWA4A.js → chunk-EHJFUOXL.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-P74IZQ7A.js → chunk-EWIT5WIC.js} +7 -7
- package/dist/cli-bundle/chunks/chunk-EX7OQT3Y.js +783 -0
- package/dist/cli-bundle/chunks/chunk-EX7OQT3Y.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-ONREO4ST.js → chunk-EY7ZE3TG.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-ILX33QXL.js → chunk-F3VC3GOV.js} +669 -472
- package/dist/cli-bundle/chunks/chunk-F3VC3GOV.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-EJEXHTY5.js → chunk-FHOBCGQO.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-H3EIEWGR.js → chunk-FL4D53ND.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-WUJQK4YV.js → chunk-FVNWHUME.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-INU6DKT5.js → chunk-FXFCFL73.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-QEHQ2GVG.js → chunk-FY4RLHSC.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-AHVTB5I5.js → chunk-G6MYGULG.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-HYB5AZ63.js → chunk-GKPCTQYG.js} +1822 -72
- package/dist/cli-bundle/chunks/chunk-GKPCTQYG.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-TSMHDIW4.js → chunk-GLZKZON6.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-2JKGO6QX.js → chunk-H5IOT54C.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-SELVXEZK.js → chunk-HO4DLBNK.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-CRVF2JDM.js → chunk-HPAYDSR2.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-3CLU2XZO.js → chunk-HSYV4ZYT.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-EH2OPHBI.js → chunk-HTXXXF45.js} +23 -19
- package/dist/cli-bundle/chunks/chunk-HTXXXF45.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-J5AOEGDC.js → chunk-HYTOJW2Q.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-4XQ3BDV4.js → chunk-I3INI567.js} +536 -449
- package/dist/cli-bundle/chunks/chunk-I3INI567.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-NU3IMIEA.js → chunk-I7DIDUSP.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-JYFOV7FC.js → chunk-IE5KRAKN.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-YAROI3PD.js → chunk-IL5SPRMH.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-UY2ACEMF.js → chunk-ILVOOAT4.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-GOSLKLFE.js → chunk-KH6QAHME.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-QKECXBBG.js → chunk-KX62NMZC.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-QKECXBBG.js.map → chunk-KX62NMZC.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-WQPUU7XD.js → chunk-L337QKWJ.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-JFTKLTEF.js → chunk-L5BTTDU5.js} +68 -503
- package/dist/cli-bundle/chunks/chunk-L5BTTDU5.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-LSG2U345.js → chunk-L6FVNR7X.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-FMBNM2EN.js → chunk-LSOWTLEM.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-4223PVZT.js → chunk-M7MVOKVV.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-UMOPHQSU.js → chunk-MR4SHYR4.js} +41 -19
- package/dist/cli-bundle/chunks/chunk-MR4SHYR4.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-3WM75PWC.js → chunk-N33FD2UI.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-UXONS674.js → chunk-NCVT6XEL.js} +68 -56
- package/dist/cli-bundle/chunks/chunk-NCVT6XEL.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-6S3YSUYG.js → chunk-NNANAWFH.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-IJIICKVW.js → chunk-NTRQLE2R.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-SDQLJWBO.js → chunk-NVZ6NVHJ.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-E2OJMKML.js → chunk-OGVTB5VO.js} +47 -37
- package/dist/cli-bundle/chunks/chunk-OGVTB5VO.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-H2Z3FYXQ.js → chunk-OWP6QFBV.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-Q7A43DS4.js → chunk-P22HGFFI.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-NVPZIJVR.js → chunk-PT7MCCGD.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-ONG5V5CI.js → chunk-QPGQNLPI.js} +1751 -70
- package/dist/cli-bundle/chunks/chunk-QPGQNLPI.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-J6EY5V4N.js → chunk-QRZNCRNA.js} +9 -9
- package/dist/cli-bundle/chunks/{chunk-QIPLHNP7.js → chunk-QWBKN3QC.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-7PIWCHTW.js → chunk-R5XTTZSJ.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-JOUQZENX.js → chunk-RC4UOUXA.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-BEP7WJA2.js → chunk-RGMWJLXF.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-NP22ERDF.js → chunk-RTBX3C4C.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-FNSPG7MU.js → chunk-RXPQ5Q23.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-LPYWLWDS.js → chunk-SIPOACV5.js} +534 -447
- package/dist/cli-bundle/chunks/chunk-SIPOACV5.js.map +1 -0
- package/dist/cli-bundle/chunks/chunk-TGBTLGPX.js +851 -0
- package/dist/cli-bundle/chunks/chunk-TGBTLGPX.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-2WSE6PO2.js → chunk-TLWJP5BF.js} +5 -5
- package/dist/cli-bundle/chunks/chunk-TLWJP5BF.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-ULTHRDBP.js → chunk-TM5CIO3F.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-UWQHLMEB.js → chunk-TZAE66GQ.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-OW4JWD5M.js → chunk-VAHZIPWS.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-DYH63FX7.js → chunk-VE6ZSTQW.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-3AUGG2DP.js → chunk-W5E2UUSH.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-BSEQUTQP.js → chunk-WACRQ26A.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BSEQUTQP.js.map → chunk-WACRQ26A.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-UOHFKBUV.js → chunk-WL3SS45P.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-H5APFTHZ.js → chunk-WQXRZMFN.js} +204 -33
- package/dist/cli-bundle/chunks/chunk-WQXRZMFN.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-QKJGPFAF.js → chunk-WU3KAN6A.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-IA5FKNII.js → chunk-X2MGQMZO.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-TD3LVC7D.js → chunk-X5YCTFKT.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-B7PE22W6.js → chunk-XC2HEEOV.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-7Z4LKRS4.js → chunk-XPUTSGJU.js} +38 -37
- package/dist/cli-bundle/chunks/chunk-XPUTSGJU.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-YBLZ2VE7.js → chunk-XWBD6DSR.js} +320 -239
- package/dist/cli-bundle/chunks/chunk-XWBD6DSR.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-XWYQ2LT4.js +834 -0
- package/dist/cli-bundle/chunks/chunk-XWYQ2LT4.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-K2X6U4UA.js → chunk-XXLXJL7V.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-2NCIPMQP.js → chunk-YFE7JHX3.js} +27 -6
- package/dist/cli-bundle/chunks/chunk-YFE7JHX3.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-EACOH7AU.js → chunk-YIIIAKCE.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-RLCHOOHC.js → chunk-YJSURTBB.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-PGY23YTC.js → chunk-YKFHF37B.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-EYLCSJAI.js → chunk-YQEZWI3R.js} +2 -2
- package/dist/cli-bundle/chunks/close-GPD7DTJV.js +12 -0
- package/dist/cli-bundle/chunks/{close-CWODTPKG.js → close-X3CF6FQP.js} +5 -5
- package/dist/cli-bundle/chunks/{close-many-CQFUY7MR.js → close-many-J7A5EHOQ.js} +14 -14
- package/dist/cli-bundle/chunks/close-many-NQLYGPYW.js +23 -0
- package/dist/cli-bundle/chunks/comments-2AOZQ5D2.js +13 -0
- package/dist/cli-bundle/chunks/{comments-WGLHR7LB.js → comments-TMHMALA5.js} +7 -7
- package/dist/cli-bundle/chunks/{copy-LXVDXH7B.js → copy-FWQA5OU4.js} +4 -4
- package/dist/cli-bundle/chunks/copy-N3LCQBMC.js +9 -0
- package/dist/cli-bundle/chunks/{create-LBVCYMEG.js → create-AQ5SIGZC.js} +9 -9
- package/dist/cli-bundle/chunks/{create-J5U6ND4K.js → create-KOGQ3JKD.js} +9 -9
- package/dist/cli-bundle/chunks/delete-6G3MBZ6S.js +10 -0
- package/dist/cli-bundle/chunks/{delete-PMJBNY5G.js → delete-YYYFOSEA.js} +4 -4
- package/dist/cli-bundle/chunks/{deps-JZ7TMVCB.js → deps-MQ4ZIGZB.js} +16 -7
- package/dist/cli-bundle/chunks/deps-NIIKXLPB.js +28 -0
- package/dist/cli-bundle/chunks/{docs-FEWB2DQB.js → docs-53NUGMIQ.js} +6 -6
- package/dist/cli-bundle/chunks/docs-OWRGDMNY.js +14 -0
- package/dist/cli-bundle/chunks/{files-EFIWKFTM.js → files-3PXGXYDB.js} +6 -6
- package/dist/cli-bundle/chunks/{files-6YFBJRBG.js → files-EGLKHD7O.js} +6 -6
- package/dist/cli-bundle/chunks/focus-KZLIA6WS.js +10 -0
- package/dist/cli-bundle/chunks/{focus-4QJR7FOQ.js → focus-SRPASFTN.js} +5 -5
- package/dist/cli-bundle/chunks/{history-compact-CKRPDTJN.js → history-compact-G4DULDCX.js} +6 -6
- package/dist/cli-bundle/chunks/history-compact-HHIUOMZ7.js +16 -0
- package/dist/cli-bundle/chunks/{history-redact-BB3TGDAE.js → history-redact-IUSJ6X3E.js} +4 -4
- package/dist/cli-bundle/chunks/{history-redact-D225BHOZ.js → history-redact-THHGRQXV.js} +4 -4
- package/dist/cli-bundle/chunks/history-repair-KG7SWXI6.js +16 -0
- package/dist/cli-bundle/chunks/{history-repair-RQXKQHL4.js → history-repair-LUQWRS7X.js} +6 -6
- package/dist/cli-bundle/chunks/{learnings-JLNLCOL5.js → learnings-2MRNBFJF.js} +7 -7
- package/dist/cli-bundle/chunks/learnings-ZVHSALJY.js +13 -0
- package/dist/cli-bundle/chunks/{notes-GB47XXQQ.js → notes-73JWKWUD.js} +7 -7
- package/dist/cli-bundle/chunks/notes-BAKUL5DJ.js +13 -0
- package/dist/cli-bundle/chunks/{plan-VDCJ2PCN.js → plan-AZPMCG37.js} +10 -10
- package/dist/cli-bundle/chunks/plan-LEAGLPGP.js +24 -0
- package/dist/cli-bundle/chunks/{profile-FAU7NZML.js → profile-AVCIIZID.js} +9 -9
- package/dist/cli-bundle/chunks/{profile-IVXQEL3D.js → profile-LFYO3HHX.js} +9 -9
- package/dist/cli-bundle/chunks/{register-list-query-UL4UKBBN.js → register-list-query-MZUF2EEC.js} +50 -22
- package/dist/cli-bundle/chunks/register-list-query-MZUF2EEC.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-list-query-DKA3EH5D.js → register-list-query-UKMF55FT.js} +49 -21
- package/dist/cli-bundle/chunks/register-list-query-UKMF55FT.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-mutation-RBBJ52DK.js → register-mutation-2PBW2GEX.js} +35 -33
- package/dist/cli-bundle/chunks/register-mutation-2PBW2GEX.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-mutation-ARFHRW55.js → register-mutation-T6RVNJC4.js} +34 -32
- package/dist/cli-bundle/chunks/{register-mutation-ARFHRW55.js.map → register-mutation-T6RVNJC4.js.map} +2 -2
- package/dist/cli-bundle/chunks/{register-operations-ZIBBRSED.js → register-operations-KHZYR6MG.js} +35 -35
- package/dist/cli-bundle/chunks/{register-operations-ZUJ5JWPE.js → register-operations-WPQ2LWZJ.js} +35 -35
- package/dist/cli-bundle/chunks/{register-setup-BCVLFEYS.js → register-setup-PGDNOXDQ.js} +15 -15
- package/dist/cli-bundle/chunks/{register-setup-TDCGWIOS.js → register-setup-TDN7WAO6.js} +15 -15
- package/dist/cli-bundle/chunks/{restore-25DLT2Q2.js → restore-E3PRGDN3.js} +6 -6
- package/dist/cli-bundle/chunks/restore-KIUYTAEJ.js +14 -0
- package/dist/cli-bundle/chunks/{schema-FNU3WE4O.js → schema-5JNFQFUW.js} +6 -6
- package/dist/cli-bundle/chunks/{schema-NBCM3RAD.js → schema-TMIW4XZC.js} +6 -6
- package/dist/cli-bundle/chunks/{update-XHSIAIXE.js → update-SQYZA3ZW.js} +12 -12
- package/dist/cli-bundle/chunks/update-XZJYS5X7.js +21 -0
- package/dist/cli-bundle/chunks/update-many-R24B3GBK.js +36 -0
- package/dist/cli-bundle/chunks/update-many-WQ3R3J6N.js +32 -0
- package/dist/cli-bundle/main.js +170 -856
- package/dist/cli-bundle/main.js.map +4 -4
- package/dist/cli-bundle/sdk-runtime.js +57 -54
- package/dist/cli-bundle/sdk-testing.js +6 -6
- package/dist/cli-bundle/sdk.js +266 -340
- package/dist/cli-bundle/sdk.js.map +4 -4
- package/dist/core/extensions/item-fields.js +2 -2
- package/dist/core/extensions/item-fields.js.map +1 -1
- package/dist/core/item/actionability.d.ts +12 -0
- package/dist/core/item/actionability.js +39 -4
- package/dist/core/item/actionability.js.map +1 -1
- package/dist/core/sentry/instrument.d.ts +11 -0
- package/dist/core/sentry/instrument.js +21 -2
- package/dist/core/sentry/instrument.js.map +1 -1
- package/dist/mcp/server.d.ts +16 -18
- package/dist/mcp/server.js +84 -31
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-definitions.js +17 -4
- package/dist/mcp/tool-definitions.js.map +1 -1
- package/dist/sdk/actionability.d.ts +10 -0
- package/dist/sdk/actionability.js +14 -0
- package/dist/sdk/actionability.js.map +1 -0
- package/dist/sdk/cli-bootstrap.d.ts +122 -0
- package/dist/sdk/cli-bootstrap.js +879 -0
- package/dist/sdk/cli-bootstrap.js.map +1 -0
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +6 -2
- package/dist/sdk/cli-contracts/enum-contracts.js +19 -2
- package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -1
- package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +21 -2
- package/dist/sdk/cli-contracts/flag-contracts.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +2 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.js +16 -2
- package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +80 -3
- package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-schema.d.ts +20 -0
- package/dist/sdk/cli-contracts/tool-schema.js +97 -9
- package/dist/sdk/cli-contracts/tool-schema.js.map +1 -1
- package/dist/sdk/cli-contracts.d.ts +2 -2
- package/dist/sdk/cli-contracts.js +4 -4
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/sdk/dependencies.d.ts +42 -53
- package/dist/sdk/dependencies.js +177 -125
- package/dist/sdk/dependencies.js.map +1 -1
- package/dist/sdk/eval.d.ts +66 -0
- package/dist/sdk/eval.js +186 -0
- package/dist/sdk/eval.js.map +1 -0
- package/dist/sdk/governance/validate.js +3 -3
- package/dist/sdk/governance/validate.js.map +1 -1
- package/dist/sdk/graph/analytics.d.ts +124 -0
- package/dist/sdk/graph/analytics.js +464 -0
- package/dist/sdk/graph/analytics.js.map +1 -0
- package/dist/sdk/graph/assembly.d.ts +97 -0
- package/dist/sdk/graph/assembly.js +146 -0
- package/dist/sdk/graph/assembly.js.map +1 -0
- package/dist/sdk/graph/cache.d.ts +66 -0
- package/dist/sdk/graph/cache.js +148 -0
- package/dist/sdk/graph/cache.js.map +1 -0
- package/dist/sdk/graph/governance.d.ts +108 -0
- package/dist/sdk/graph/governance.js +360 -0
- package/dist/sdk/graph/governance.js.map +1 -0
- package/dist/sdk/graph/index.d.ts +16 -0
- package/dist/sdk/graph/index.js +20 -0
- package/dist/sdk/graph/index.js.map +1 -0
- package/dist/sdk/graph/remediation.d.ts +52 -0
- package/dist/sdk/graph/remediation.js +148 -0
- package/dist/sdk/graph/remediation.js.map +1 -0
- package/dist/sdk/graph/run.d.ts +295 -0
- package/dist/sdk/graph/run.js +468 -0
- package/dist/sdk/graph/run.js.map +1 -0
- package/dist/sdk/graph/traversal.d.ts +77 -0
- package/dist/sdk/graph/traversal.js +262 -0
- package/dist/sdk/graph/traversal.js.map +1 -0
- package/dist/sdk/index.d.ts +19 -5
- package/dist/sdk/index.js +21 -7
- package/dist/sdk/index.js.map +1 -1
- package/dist/{cli/commands → sdk/query}/item-filter-options.d.ts +1 -1
- package/dist/{cli/commands → sdk/query}/item-filter-options.js +3 -3
- package/dist/sdk/query/item-filter-options.js.map +1 -0
- package/dist/sdk/query/list.d.ts +262 -0
- package/dist/sdk/query/list.js +1089 -0
- package/dist/sdk/query/list.js.map +1 -0
- package/dist/sdk/query/parsers.d.ts +9 -0
- package/dist/sdk/query/parsers.js +45 -0
- package/dist/sdk/query/parsers.js.map +1 -0
- package/dist/{cli/commands → sdk/query}/search-pagination.js +4 -4
- package/dist/sdk/query/search-pagination.js.map +1 -0
- package/dist/{cli/commands → sdk/query}/search-rendering.js +3 -3
- package/dist/sdk/query/search-rendering.js.map +1 -0
- package/dist/sdk/query/search.d.ts +469 -0
- package/dist/sdk/query/search.js +2247 -0
- package/dist/sdk/query/search.js.map +1 -0
- package/dist/sdk/relationship-context.d.ts +42 -0
- package/dist/sdk/relationship-context.js +99 -20
- package/dist/sdk/relationship-context.js.map +1 -1
- package/dist/sdk/relationships.d.ts +13 -0
- package/dist/sdk/relationships.js +30 -2
- package/dist/sdk/relationships.js.map +1 -1
- package/dist/sdk/runtime-input.d.ts +41 -0
- package/dist/sdk/runtime-input.js +422 -2
- package/dist/sdk/runtime-input.js.map +1 -1
- package/dist/sdk/runtime.d.ts +19 -30
- package/dist/sdk/runtime.js +30 -376
- package/dist/sdk/runtime.js.map +1 -1
- package/dist/sdk/search-refresh-worker.d.ts +2 -0
- package/dist/sdk/search-refresh-worker.js +19 -0
- package/dist/sdk/search-refresh-worker.js.map +1 -0
- package/dist/sdk/stats.d.ts +66 -0
- package/dist/sdk/stats.js +151 -0
- package/dist/sdk/stats.js.map +1 -0
- package/dist/sdk/telemetry-flush.d.ts +2 -0
- package/dist/sdk/telemetry-flush.js +14 -0
- package/dist/sdk/telemetry-flush.js.map +1 -0
- package/dist/sdk/telemetry.d.ts +14 -0
- package/dist/sdk/telemetry.js +398 -0
- package/dist/sdk/telemetry.js.map +1 -0
- package/dist/sdk/test/batch.d.ts +94 -0
- package/dist/sdk/test/batch.js +492 -0
- package/dist/sdk/test/batch.js.map +1 -0
- package/dist/sdk/test/entry.d.ts +6 -0
- package/dist/sdk/test/entry.js +74 -0
- package/dist/sdk/test/entry.js.map +1 -0
- package/dist/sdk/test/execution.d.ts +282 -0
- package/dist/sdk/test/execution.js +1817 -0
- package/dist/sdk/test/execution.js.map +1 -0
- package/dist/sdk/test/linked-command-detection.js +12 -3
- package/dist/sdk/test/linked-command-detection.js.map +1 -1
- package/dist/sdk/test/parsers.d.ts +48 -0
- package/dist/sdk/test/parsers.js +522 -0
- package/dist/sdk/test/parsers.js.map +1 -0
- package/dist/sdk/test/runs.d.ts +92 -0
- package/dist/sdk/test/runs.js +195 -0
- package/dist/sdk/test/runs.js.map +1 -0
- package/docs/AGENT_GUIDE.md +1 -0
- package/docs/COMMANDS.md +19 -1
- package/docs/RELATIONSHIP_GRAPH.md +99 -3
- package/docs/SDK.md +139 -3
- package/docs/SDK_PRIMITIVE_INVENTORY.md +5 -3
- package/docs/examples/sdk-custom-tool/README.md +27 -0
- package/docs/examples/sdk-custom-tool/package.json +13 -0
- package/docs/examples/sdk-custom-tool/src/cli.ts +36 -0
- package/docs/examples/sdk-custom-tool/src/entry.ts +15 -0
- package/docs/examples/sdk-custom-tool/src/index.ts +223 -0
- package/marketplace.json +2 -2
- package/package.json +4 -4
- 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/extensions/governance-audit/comments-audit.ts +77 -57
- package/packages/pm-governance-audit/extensions/governance-audit/dedupe-audit.ts +202 -194
- package/packages/pm-governance-audit/extensions/governance-audit/dedupe-merge.ts +227 -153
- package/packages/pm-governance-audit/extensions/governance-audit/normalize.ts +169 -125
- package/packages/pm-governance-audit/extensions/governance-audit/runtime-utils.ts +130 -81
- package/packages/pm-governance-audit/extensions/governance-audit/sdk.ts +53 -4
- 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/item-filter-options.js.map +0 -1
- package/dist/cli/commands/search-pagination.js.map +0 -1
- package/dist/cli/commands/search-rendering.js.map +0 -1
- package/dist/cli-bundle/chunks/append-UZVHUO74.js +0 -11
- package/dist/cli-bundle/chunks/chunk-2NCIPMQP.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-3S5QVM5H.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-4XQ3BDV4.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-5JLUII3O.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-5ZSLZLDN.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-7Z4LKRS4.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-BKVG6XOA.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-E2OJMKML.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-EH2OPHBI.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-H5APFTHZ.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-HYB5AZ63.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-ILX33QXL.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-JFTKLTEF.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-LPYWLWDS.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-NLDFBC6J.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-ONG5V5CI.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-UFXU44HV.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-UMOPHQSU.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-UXONS674.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-XXXF6PAQ.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-YBLZ2VE7.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-YXSHIAUJ.js +0 -58
- package/dist/cli-bundle/chunks/chunk-YXSHIAUJ.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-ZKRZY773.js +0 -68
- package/dist/cli-bundle/chunks/chunk-ZKRZY773.js.map +0 -7
- package/dist/cli-bundle/chunks/close-W6LI2PKM.js +0 -12
- package/dist/cli-bundle/chunks/close-many-DLDDVSH5.js +0 -23
- package/dist/cli-bundle/chunks/comments-E3TNTK24.js +0 -13
- package/dist/cli-bundle/chunks/copy-Q5ZJPUKR.js +0 -9
- package/dist/cli-bundle/chunks/delete-WNHB3LYW.js +0 -10
- package/dist/cli-bundle/chunks/deps-OA26IS25.js +0 -19
- package/dist/cli-bundle/chunks/docs-HA2AIDBB.js +0 -14
- package/dist/cli-bundle/chunks/focus-POIW5LTJ.js +0 -10
- package/dist/cli-bundle/chunks/history-compact-FWG2C7FZ.js +0 -16
- package/dist/cli-bundle/chunks/history-repair-6GEAM7HE.js +0 -16
- package/dist/cli-bundle/chunks/learnings-RSNLSWDC.js +0 -13
- package/dist/cli-bundle/chunks/notes-2WDH6DXU.js +0 -13
- package/dist/cli-bundle/chunks/plan-DOVI2VMW.js +0 -24
- package/dist/cli-bundle/chunks/register-list-query-DKA3EH5D.js.map +0 -7
- package/dist/cli-bundle/chunks/register-list-query-UL4UKBBN.js.map +0 -1
- package/dist/cli-bundle/chunks/register-mutation-RBBJ52DK.js.map +0 -1
- package/dist/cli-bundle/chunks/restore-YPMVUUEX.js +0 -14
- package/dist/cli-bundle/chunks/update-WWBYOPXO.js +0 -21
- package/dist/cli-bundle/chunks/update-many-OUGIU5SF.js +0 -32
- package/dist/cli-bundle/chunks/update-many-TA7NGQBO.js +0 -36
- /package/dist/cli-bundle/chunks/{append-OJQFUQ4T.js.map → append-5YF3TO7I.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{append-UZVHUO74.js.map → append-JHO5K6RP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-BCOFWYW4.js.map → chunk-2BX74BAS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-APRVSW2O.js.map → chunk-2CXL335K.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-KG44YSKD.js.map → chunk-2FUOXSRN.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-HDH3JUGG.js.map → chunk-2IPNL3DR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GM5QHQU6.js.map → chunk-2XOSFSTH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-K3WII2ME.js.map → chunk-37DRDP2B.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-PMOSXADO.js.map → chunk-47HXN6RX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-6CFNAVTF.js.map → chunk-5HGZKQUL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-2IFFUZLC.js.map → chunk-5UKQLQM2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-DM4H7FP4.js.map → chunk-633PKXLT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-XSJUSQAE.js.map → chunk-646MQXFW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-ZI6VQWQ7.js.map → chunk-66MKH7SZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-S6MQESFR.js.map → chunk-67RO3H4N.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-34L5OT3Y.js.map → chunk-6DYOZS6C.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-RRM5JYJC.js.map → chunk-6O44IN44.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-PENXZX3U.js.map → chunk-74FKFFXO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-HO4KXD6I.js.map → chunk-7H5NNCJ5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-TQSZFPIS.js.map → chunk-AFGKSHAM.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-6N2VXVTQ.js.map → chunk-ARGDWQ4J.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-3U7ZR6M4.js.map → chunk-B57RJHBZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-YCQET3OT.js.map → chunk-BAP7G3N2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-QKXHFPYM.js.map → chunk-BIRYX32V.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-RMLWNPH2.js.map → chunk-BVLOMU6O.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-2VPAVL7O.js.map → chunk-CKX4WOPC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-TKOVBP6C.js.map → chunk-D52ZN3BF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-KPMKHGEA.js.map → chunk-D53RTYVI.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-ODALILG3.js.map → chunk-D5XHO4Q7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-YAQEBNY7.js.map → chunk-DDFGYUCQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-EAB64KLB.js.map → chunk-DG2EQRIH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-IG3SWA4A.js.map → chunk-EHJFUOXL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-P74IZQ7A.js.map → chunk-EWIT5WIC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-ONREO4ST.js.map → chunk-EY7ZE3TG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-EJEXHTY5.js.map → chunk-FHOBCGQO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-H3EIEWGR.js.map → chunk-FL4D53ND.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-WUJQK4YV.js.map → chunk-FVNWHUME.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-INU6DKT5.js.map → chunk-FXFCFL73.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-QEHQ2GVG.js.map → chunk-FY4RLHSC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-AHVTB5I5.js.map → chunk-G6MYGULG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-TSMHDIW4.js.map → chunk-GLZKZON6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-2JKGO6QX.js.map → chunk-H5IOT54C.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-SELVXEZK.js.map → chunk-HO4DLBNK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-CRVF2JDM.js.map → chunk-HPAYDSR2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-3CLU2XZO.js.map → chunk-HSYV4ZYT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-J5AOEGDC.js.map → chunk-HYTOJW2Q.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-NU3IMIEA.js.map → chunk-I7DIDUSP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-JYFOV7FC.js.map → chunk-IE5KRAKN.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-YAROI3PD.js.map → chunk-IL5SPRMH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UY2ACEMF.js.map → chunk-ILVOOAT4.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GOSLKLFE.js.map → chunk-KH6QAHME.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-WQPUU7XD.js.map → chunk-L337QKWJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-LSG2U345.js.map → chunk-L6FVNR7X.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-FMBNM2EN.js.map → chunk-LSOWTLEM.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-4223PVZT.js.map → chunk-M7MVOKVV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-3WM75PWC.js.map → chunk-N33FD2UI.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-6S3YSUYG.js.map → chunk-NNANAWFH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-IJIICKVW.js.map → chunk-NTRQLE2R.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-SDQLJWBO.js.map → chunk-NVZ6NVHJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-H2Z3FYXQ.js.map → chunk-OWP6QFBV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-Q7A43DS4.js.map → chunk-P22HGFFI.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-NVPZIJVR.js.map → chunk-PT7MCCGD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-J6EY5V4N.js.map → chunk-QRZNCRNA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-QIPLHNP7.js.map → chunk-QWBKN3QC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-7PIWCHTW.js.map → chunk-R5XTTZSJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-JOUQZENX.js.map → chunk-RC4UOUXA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-BEP7WJA2.js.map → chunk-RGMWJLXF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-NP22ERDF.js.map → chunk-RTBX3C4C.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-FNSPG7MU.js.map → chunk-RXPQ5Q23.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-ULTHRDBP.js.map → chunk-TM5CIO3F.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UWQHLMEB.js.map → chunk-TZAE66GQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-OW4JWD5M.js.map → chunk-VAHZIPWS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-DYH63FX7.js.map → chunk-VE6ZSTQW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-3AUGG2DP.js.map → chunk-W5E2UUSH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UOHFKBUV.js.map → chunk-WL3SS45P.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-QKJGPFAF.js.map → chunk-WU3KAN6A.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-IA5FKNII.js.map → chunk-X2MGQMZO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-TD3LVC7D.js.map → chunk-X5YCTFKT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-B7PE22W6.js.map → chunk-XC2HEEOV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-K2X6U4UA.js.map → chunk-XXLXJL7V.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-EACOH7AU.js.map → chunk-YIIIAKCE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-RLCHOOHC.js.map → chunk-YJSURTBB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-PGY23YTC.js.map → chunk-YKFHF37B.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-EYLCSJAI.js.map → chunk-YQEZWI3R.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-W6LI2PKM.js.map → close-GPD7DTJV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-CWODTPKG.js.map → close-X3CF6FQP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-many-CQFUY7MR.js.map → close-many-J7A5EHOQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-many-DLDDVSH5.js.map → close-many-NQLYGPYW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{comments-E3TNTK24.js.map → comments-2AOZQ5D2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{comments-WGLHR7LB.js.map → comments-TMHMALA5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{copy-LXVDXH7B.js.map → copy-FWQA5OU4.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{copy-Q5ZJPUKR.js.map → copy-N3LCQBMC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-LBVCYMEG.js.map → create-AQ5SIGZC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-J5U6ND4K.js.map → create-KOGQ3JKD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{delete-WNHB3LYW.js.map → delete-6G3MBZ6S.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{delete-PMJBNY5G.js.map → delete-YYYFOSEA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-JZ7TMVCB.js.map → deps-MQ4ZIGZB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-OA26IS25.js.map → deps-NIIKXLPB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{docs-FEWB2DQB.js.map → docs-53NUGMIQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{docs-HA2AIDBB.js.map → docs-OWRGDMNY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{files-EFIWKFTM.js.map → files-3PXGXYDB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{files-6YFBJRBG.js.map → files-EGLKHD7O.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{focus-POIW5LTJ.js.map → focus-KZLIA6WS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{focus-4QJR7FOQ.js.map → focus-SRPASFTN.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-compact-CKRPDTJN.js.map → history-compact-G4DULDCX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-compact-FWG2C7FZ.js.map → history-compact-HHIUOMZ7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-redact-BB3TGDAE.js.map → history-redact-IUSJ6X3E.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-redact-D225BHOZ.js.map → history-redact-THHGRQXV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-repair-6GEAM7HE.js.map → history-repair-KG7SWXI6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-repair-RQXKQHL4.js.map → history-repair-LUQWRS7X.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{learnings-JLNLCOL5.js.map → learnings-2MRNBFJF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{learnings-RSNLSWDC.js.map → learnings-ZVHSALJY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{notes-GB47XXQQ.js.map → notes-73JWKWUD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{notes-2WDH6DXU.js.map → notes-BAKUL5DJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{plan-VDCJ2PCN.js.map → plan-AZPMCG37.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{plan-DOVI2VMW.js.map → plan-LEAGLPGP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{profile-FAU7NZML.js.map → profile-AVCIIZID.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{profile-IVXQEL3D.js.map → profile-LFYO3HHX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-operations-ZIBBRSED.js.map → register-operations-KHZYR6MG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-operations-ZUJ5JWPE.js.map → register-operations-WPQ2LWZJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-setup-BCVLFEYS.js.map → register-setup-PGDNOXDQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-setup-TDCGWIOS.js.map → register-setup-TDN7WAO6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{restore-25DLT2Q2.js.map → restore-E3PRGDN3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{restore-YPMVUUEX.js.map → restore-KIUYTAEJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{schema-FNU3WE4O.js.map → schema-5JNFQFUW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{schema-NBCM3RAD.js.map → schema-TMIW4XZC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-XHSIAIXE.js.map → update-SQYZA3ZW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-WWBYOPXO.js.map → update-XZJYS5X7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-TA7NGQBO.js.map → update-many-R24B3GBK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-OUGIU5SF.js.map → update-many-WQ3R3J6N.js.map} +0 -0
- /package/dist/{cli/commands → sdk/query}/search-pagination.d.ts +0 -0
- /package/dist/{cli/commands → sdk/query}/search-rendering.d.ts +0 -0
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
runList,
|
|
16
16
|
type GlobalOptions,
|
|
17
17
|
type ItemStatus,
|
|
18
|
+
type ListedItem,
|
|
18
19
|
type RuntimeStatusRegistry,
|
|
19
20
|
} from "./sdk.ts";
|
|
20
21
|
import {
|
|
@@ -177,7 +178,8 @@ export interface DedupeAuditResult {
|
|
|
177
178
|
warnings?: string[];
|
|
178
179
|
}
|
|
179
180
|
|
|
180
|
-
|
|
181
|
+
const parseMode = (raw: string | undefined): DedupeAuditMode => {
|
|
182
|
+
/** Normalize the optional strategy name against the supported audit modes. */
|
|
181
183
|
const normalized = (raw ?? "title_exact").trim().toLowerCase();
|
|
182
184
|
if (!DEDUPE_AUDIT_MODES.includes(normalized as DedupeAuditMode)) {
|
|
183
185
|
throw new PmCliError(
|
|
@@ -186,7 +188,7 @@ function parseMode(raw: string | undefined): DedupeAuditMode {
|
|
|
186
188
|
);
|
|
187
189
|
}
|
|
188
190
|
return normalized as DedupeAuditMode;
|
|
189
|
-
}
|
|
191
|
+
};
|
|
190
192
|
|
|
191
193
|
let dedupeAllowedStatuses = new Set<string>([
|
|
192
194
|
"draft",
|
|
@@ -199,7 +201,8 @@ let dedupeAllowedStatuses = new Set<string>([
|
|
|
199
201
|
let dedupeTerminalStatuses = new Set<string>(["closed", "canceled"]);
|
|
200
202
|
let dedupeStatusRegistry: RuntimeStatusRegistry | null = null;
|
|
201
203
|
|
|
202
|
-
|
|
204
|
+
const parseStatus = (raw: string | undefined): ItemStatus | undefined => {
|
|
205
|
+
/** Normalize an optional status token against the active audit registry. */
|
|
203
206
|
if (raw === undefined) {
|
|
204
207
|
return undefined;
|
|
205
208
|
}
|
|
@@ -211,9 +214,10 @@ function parseStatus(raw: string | undefined): ItemStatus | undefined {
|
|
|
211
214
|
);
|
|
212
215
|
}
|
|
213
216
|
return normalized as ItemStatus;
|
|
214
|
-
}
|
|
217
|
+
};
|
|
215
218
|
|
|
216
|
-
|
|
219
|
+
const parseThreshold = (raw: string | undefined): number | undefined => {
|
|
220
|
+
/** Parse an optional fuzzy-match threshold on the inclusive zero-to-one scale. */
|
|
217
221
|
if (raw === undefined) {
|
|
218
222
|
return undefined;
|
|
219
223
|
}
|
|
@@ -225,20 +229,22 @@ function parseThreshold(raw: string | undefined): number | undefined {
|
|
|
225
229
|
);
|
|
226
230
|
}
|
|
227
231
|
return parsed;
|
|
228
|
-
}
|
|
232
|
+
};
|
|
229
233
|
|
|
230
|
-
|
|
234
|
+
const isTerminal = (status: ItemStatus): boolean => {
|
|
235
|
+
/** Resolve terminality through the active schema with a built-in fallback. */
|
|
231
236
|
if (dedupeStatusRegistry) {
|
|
232
237
|
return isTerminalStatus(status, dedupeStatusRegistry);
|
|
233
238
|
}
|
|
234
239
|
const normalized = normalizeStatusInput(status) ?? status;
|
|
235
240
|
return dedupeTerminalStatuses.has(normalized);
|
|
236
|
-
}
|
|
241
|
+
};
|
|
237
242
|
|
|
238
|
-
|
|
243
|
+
const compareCandidates = (
|
|
239
244
|
left: DedupeAuditPreparedCandidate,
|
|
240
245
|
right: DedupeAuditPreparedCandidate,
|
|
241
|
-
): number {
|
|
246
|
+
): number => {
|
|
247
|
+
/** Rank canonical candidates by lifecycle, priority, recency, and identity. */
|
|
242
248
|
const leftTerminal = isTerminal(left.status);
|
|
243
249
|
const rightTerminal = isTerminal(right.status);
|
|
244
250
|
if (leftTerminal !== rightTerminal) {
|
|
@@ -253,11 +259,12 @@ function compareCandidates(
|
|
|
253
259
|
return byUpdated;
|
|
254
260
|
}
|
|
255
261
|
return left.id.localeCompare(right.id);
|
|
256
|
-
}
|
|
262
|
+
};
|
|
257
263
|
|
|
258
|
-
|
|
264
|
+
const toCandidate = (
|
|
259
265
|
candidate: DedupeAuditPreparedCandidate,
|
|
260
|
-
): DedupeAuditCandidate {
|
|
266
|
+
): DedupeAuditCandidate => {
|
|
267
|
+
/** Project one prepared comparison record into the public candidate shape. */
|
|
261
268
|
return {
|
|
262
269
|
id: candidate.id,
|
|
263
270
|
title: candidate.title,
|
|
@@ -268,13 +275,14 @@ function toCandidate(
|
|
|
268
275
|
created_at: candidate.created_at,
|
|
269
276
|
updated_at: candidate.updated_at,
|
|
270
277
|
};
|
|
271
|
-
}
|
|
278
|
+
};
|
|
272
279
|
|
|
273
|
-
|
|
280
|
+
const toMergeSuggestion = (
|
|
274
281
|
duplicate: DedupeAuditPreparedCandidate,
|
|
275
282
|
canonical: DedupeAuditPreparedCandidate,
|
|
276
283
|
mode: DedupeAuditMode,
|
|
277
|
-
): DedupeMergeSuggestion {
|
|
284
|
+
): DedupeMergeSuggestion => {
|
|
285
|
+
/** Build an executable close recommendation for one duplicate candidate. */
|
|
278
286
|
const closeReason = `Duplicate of ${canonical.id}`;
|
|
279
287
|
const message = `Close ${duplicate.id} as duplicate of ${canonical.id} from pm dedupe-audit (${mode}).`;
|
|
280
288
|
const escapedReason = closeReason.replaceAll('"', '\\"');
|
|
@@ -286,15 +294,57 @@ function toMergeSuggestion(
|
|
|
286
294
|
suggested_message: message,
|
|
287
295
|
suggested_command: `pm close ${duplicate.id} "${escapedReason}" --message "${escapedMessage}"`,
|
|
288
296
|
};
|
|
289
|
-
}
|
|
297
|
+
};
|
|
290
298
|
|
|
291
|
-
|
|
299
|
+
const similarityScore = (
|
|
300
|
+
left: DedupeAuditPreparedCandidate,
|
|
301
|
+
right: DedupeAuditPreparedCandidate,
|
|
302
|
+
): number => {
|
|
303
|
+
/** Score exact normalized titles first, then fall back to token overlap. */
|
|
304
|
+
if (left.normalized_title === right.normalized_title) {
|
|
305
|
+
return 1;
|
|
306
|
+
}
|
|
307
|
+
return jaccardSimilarity(left.title_tokens, right.title_tokens);
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
const forEachCandidatePair = (
|
|
311
|
+
items: DedupeAuditPreparedCandidate[],
|
|
312
|
+
visit: (
|
|
313
|
+
left: DedupeAuditPreparedCandidate,
|
|
314
|
+
right: DedupeAuditPreparedCandidate,
|
|
315
|
+
leftIndex: number,
|
|
316
|
+
rightIndex: number,
|
|
317
|
+
) => void,
|
|
318
|
+
): void => {
|
|
319
|
+
/** Visit each unordered candidate pair exactly once. */
|
|
320
|
+
for (let leftIndex = 0; leftIndex < items.length; leftIndex += 1) {
|
|
321
|
+
for (
|
|
322
|
+
let rightIndex = leftIndex + 1;
|
|
323
|
+
rightIndex < items.length;
|
|
324
|
+
rightIndex += 1
|
|
325
|
+
) {
|
|
326
|
+
visit(items[leftIndex], items[rightIndex], leftIndex, rightIndex);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
const extremeOrDefault = (
|
|
332
|
+
values: number[],
|
|
333
|
+
select: (...candidates: number[]) => number,
|
|
334
|
+
fallback: number,
|
|
335
|
+
): number => {
|
|
336
|
+
/** Select one numeric extreme while preserving a deterministic empty fallback. */
|
|
337
|
+
return values.length === 0 ? fallback : select(...values);
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
const clusterFromMembers = (
|
|
292
341
|
mode: DedupeAuditMode,
|
|
293
342
|
key: string,
|
|
294
343
|
members: DedupeAuditPreparedCandidate[],
|
|
295
344
|
matchReason: string,
|
|
296
|
-
threshold
|
|
297
|
-
): DedupeAuditCluster {
|
|
345
|
+
threshold?: number,
|
|
346
|
+
): DedupeAuditCluster => {
|
|
347
|
+
/** Assemble one deterministic cluster and its optional similarity envelope. */
|
|
298
348
|
const sortedMembers = [...members].sort(compareCandidates);
|
|
299
349
|
const canonical = sortedMembers[0];
|
|
300
350
|
const duplicates = sortedMembers.slice(1);
|
|
@@ -311,125 +361,91 @@ function clusterFromMembers(
|
|
|
311
361
|
merge_suggestions: mergeSuggestions,
|
|
312
362
|
};
|
|
313
363
|
if (mode === "title_fuzzy") {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
let rightIndex = leftIndex + 1;
|
|
319
|
-
rightIndex < sortedMembers.length;
|
|
320
|
-
rightIndex += 1
|
|
321
|
-
) {
|
|
322
|
-
const score = similarityScore(
|
|
323
|
-
sortedMembers[leftIndex],
|
|
324
|
-
sortedMembers[rightIndex],
|
|
325
|
-
);
|
|
326
|
-
min = Math.min(min, score);
|
|
327
|
-
max = Math.max(max, score);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
if (!Number.isFinite(min)) {
|
|
331
|
-
min = 1;
|
|
332
|
-
}
|
|
333
|
-
if (!Number.isFinite(max)) {
|
|
334
|
-
max = 1;
|
|
335
|
-
}
|
|
364
|
+
const scores: number[] = [];
|
|
365
|
+
forEachCandidatePair(sortedMembers, (left, right) => {
|
|
366
|
+
scores.push(similarityScore(left, right));
|
|
367
|
+
});
|
|
336
368
|
cluster.similarity = {
|
|
337
369
|
metric: "token_jaccard",
|
|
338
370
|
threshold: threshold ?? 0.8,
|
|
339
|
-
min,
|
|
340
|
-
max,
|
|
371
|
+
min: extremeOrDefault(scores, Math.min, 1),
|
|
372
|
+
max: extremeOrDefault(scores, Math.max, 1),
|
|
341
373
|
};
|
|
342
374
|
}
|
|
343
375
|
return cluster;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
function similarityScore(
|
|
347
|
-
left: DedupeAuditPreparedCandidate,
|
|
348
|
-
right: DedupeAuditPreparedCandidate,
|
|
349
|
-
): number {
|
|
350
|
-
if (left.normalized_title === right.normalized_title) {
|
|
351
|
-
return 1;
|
|
352
|
-
}
|
|
353
|
-
return jaccardSimilarity(left.title_tokens, right.title_tokens);
|
|
354
|
-
}
|
|
376
|
+
};
|
|
355
377
|
|
|
356
|
-
|
|
378
|
+
const collectGroupedCandidates = (
|
|
357
379
|
items: DedupeAuditPreparedCandidate[],
|
|
358
|
-
|
|
359
|
-
|
|
380
|
+
keyFor: (item: DedupeAuditPreparedCandidate) => string | undefined,
|
|
381
|
+
): Map<string, DedupeAuditPreparedCandidate[]> => {
|
|
382
|
+
/** Group candidates by a caller-defined non-empty comparison key. */
|
|
383
|
+
const groups = new Map<string, DedupeAuditPreparedCandidate[]>();
|
|
360
384
|
for (const item of items) {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
existing.push(item);
|
|
367
|
-
} else {
|
|
368
|
-
byTitle.set(item.normalized_title, [item]);
|
|
369
|
-
}
|
|
385
|
+
const key = keyFor(item);
|
|
386
|
+
if (key === undefined) continue;
|
|
387
|
+
const members = groups.get(key) ?? [];
|
|
388
|
+
members.push(item);
|
|
389
|
+
groups.set(key, members);
|
|
370
390
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
),
|
|
391
|
+
return groups;
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
const clustersFromGroups = (
|
|
395
|
+
groups: Map<string, DedupeAuditPreparedCandidate[]>,
|
|
396
|
+
mode: DedupeAuditMode,
|
|
397
|
+
matchReason: string,
|
|
398
|
+
): DedupeAuditCluster[] => {
|
|
399
|
+
/** Convert non-singleton candidate groups into deterministic clusters. */
|
|
400
|
+
return [...groups.entries()]
|
|
401
|
+
.filter(([, members]) => members.length > 1)
|
|
402
|
+
.map(([key, members]) =>
|
|
403
|
+
clusterFromMembers(mode, key, members, matchReason),
|
|
384
404
|
);
|
|
385
|
-
|
|
386
|
-
return clusters;
|
|
387
|
-
}
|
|
405
|
+
};
|
|
388
406
|
|
|
389
|
-
|
|
407
|
+
const collectExactTitleClusters = (
|
|
390
408
|
items: DedupeAuditPreparedCandidate[],
|
|
391
|
-
): DedupeAuditCluster[] {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
);
|
|
419
|
-
}
|
|
420
|
-
return clusters;
|
|
421
|
-
}
|
|
409
|
+
): DedupeAuditCluster[] => {
|
|
410
|
+
/** Group candidates that share the same normalized title. */
|
|
411
|
+
const groups = collectGroupedCandidates(items, (item) =>
|
|
412
|
+
item.normalized_title.length === 0 ? undefined : item.normalized_title,
|
|
413
|
+
);
|
|
414
|
+
return clustersFromGroups(
|
|
415
|
+
groups,
|
|
416
|
+
"title_exact",
|
|
417
|
+
"exact_normalized_title_match",
|
|
418
|
+
);
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
const collectParentScopedClusters = (
|
|
422
|
+
items: DedupeAuditPreparedCandidate[],
|
|
423
|
+
): DedupeAuditCluster[] => {
|
|
424
|
+
/** Group normalized-title duplicates only when they share a parent. */
|
|
425
|
+
const groups = collectGroupedCandidates(items, (item) =>
|
|
426
|
+
item.parent && item.normalized_title.length > 0
|
|
427
|
+
? `${item.parent}|${item.normalized_title}`
|
|
428
|
+
: undefined,
|
|
429
|
+
);
|
|
430
|
+
return clustersFromGroups(
|
|
431
|
+
groups,
|
|
432
|
+
"parent_scope",
|
|
433
|
+
"same_parent_and_exact_normalized_title",
|
|
434
|
+
);
|
|
435
|
+
};
|
|
422
436
|
|
|
423
|
-
|
|
437
|
+
const findRoot = (parents: number[], index: number): number => {
|
|
438
|
+
/** Find and compress one disjoint-set root for fuzzy clustering. */
|
|
424
439
|
let current = index;
|
|
425
440
|
while (parents[current] !== current) {
|
|
426
441
|
parents[current] = parents[parents[current]];
|
|
427
442
|
current = parents[current];
|
|
428
443
|
}
|
|
429
444
|
return current;
|
|
430
|
-
}
|
|
445
|
+
};
|
|
431
446
|
|
|
432
|
-
|
|
447
|
+
const unionRoots = (parents: number[], left: number, right: number): void => {
|
|
448
|
+
/** Join two fuzzy-cluster roots under the lower deterministic index. */
|
|
433
449
|
const leftRoot = findRoot(parents, left);
|
|
434
450
|
const rightRoot = findRoot(parents, right);
|
|
435
451
|
if (leftRoot === rightRoot) {
|
|
@@ -440,77 +456,62 @@ function unionRoots(parents: number[], left: number, right: number): void {
|
|
|
440
456
|
} else {
|
|
441
457
|
parents[leftRoot] = rightRoot;
|
|
442
458
|
}
|
|
443
|
-
}
|
|
459
|
+
};
|
|
444
460
|
|
|
445
|
-
|
|
461
|
+
const collectFuzzyTitleClusters = (
|
|
446
462
|
items: DedupeAuditPreparedCandidate[],
|
|
447
463
|
threshold: number,
|
|
448
|
-
): DedupeAuditCluster[] {
|
|
449
|
-
|
|
450
|
-
return [];
|
|
451
|
-
}
|
|
464
|
+
): DedupeAuditCluster[] => {
|
|
465
|
+
/** Build transitive fuzzy-title clusters at the requested similarity floor. */
|
|
452
466
|
const parents = items.map((_item, index) => index);
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
rightIndex < items.length;
|
|
457
|
-
rightIndex += 1
|
|
458
|
-
) {
|
|
459
|
-
const score = similarityScore(items[leftIndex], items[rightIndex]);
|
|
460
|
-
if (score >= threshold) {
|
|
461
|
-
unionRoots(parents, leftIndex, rightIndex);
|
|
462
|
-
}
|
|
467
|
+
forEachCandidatePair(items, (left, right, leftIndex, rightIndex) => {
|
|
468
|
+
if (similarityScore(left, right) >= threshold) {
|
|
469
|
+
unionRoots(parents, leftIndex, rightIndex);
|
|
463
470
|
}
|
|
464
|
-
}
|
|
471
|
+
});
|
|
465
472
|
const groupedIndices = new Map<number, number[]>();
|
|
466
473
|
for (let index = 0; index < items.length; index += 1) {
|
|
467
474
|
const root = findRoot(parents, index);
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
} else {
|
|
472
|
-
groupedIndices.set(root, [index]);
|
|
473
|
-
}
|
|
475
|
+
const indices = groupedIndices.get(root) ?? [];
|
|
476
|
+
indices.push(index);
|
|
477
|
+
groupedIndices.set(root, indices);
|
|
474
478
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
`cluster-${clusters.length + 1}`;
|
|
485
|
-
clusters.push(
|
|
486
|
-
clusterFromMembers(
|
|
479
|
+
return [...groupedIndices.values()]
|
|
480
|
+
.filter((indices) => indices.length > 1)
|
|
481
|
+
.map((indices, clusterIndex) => {
|
|
482
|
+
const members = indices.map((index) => items[index]);
|
|
483
|
+
/* c8 ignore next -- production item ids are required; malformed helper fixtures retain a deterministic key. */
|
|
484
|
+
const canonicalKey =
|
|
485
|
+
[...members].sort(compareCandidates)[0]?.id ??
|
|
486
|
+
`cluster-${clusterIndex + 1}`;
|
|
487
|
+
return clusterFromMembers(
|
|
487
488
|
"title_fuzzy",
|
|
488
489
|
canonicalKey,
|
|
489
490
|
members,
|
|
490
491
|
"title_token_jaccard_above_threshold",
|
|
491
492
|
threshold,
|
|
492
|
-
)
|
|
493
|
-
);
|
|
494
|
-
|
|
495
|
-
return clusters;
|
|
496
|
-
}
|
|
493
|
+
);
|
|
494
|
+
});
|
|
495
|
+
};
|
|
497
496
|
|
|
498
|
-
|
|
497
|
+
const compareClusters = (
|
|
499
498
|
left: DedupeAuditCluster,
|
|
500
499
|
right: DedupeAuditCluster,
|
|
501
|
-
): number {
|
|
500
|
+
): number => {
|
|
501
|
+
/** Order larger clusters first and break ties by canonical identity. */
|
|
502
502
|
const bySize = right.cluster_size - left.cluster_size;
|
|
503
503
|
if (bySize !== 0) {
|
|
504
504
|
return bySize;
|
|
505
505
|
}
|
|
506
506
|
return left.canonical.id.localeCompare(right.canonical.id);
|
|
507
|
-
}
|
|
507
|
+
};
|
|
508
508
|
|
|
509
|
-
|
|
509
|
+
const collectDedupeClusters = (
|
|
510
510
|
mode: DedupeAuditMode,
|
|
511
511
|
prepared: DedupeAuditPreparedCandidate[],
|
|
512
512
|
fuzzyThreshold: number,
|
|
513
|
-
): DedupeAuditCluster[] {
|
|
513
|
+
): DedupeAuditCluster[] => {
|
|
514
|
+
/** Dispatch candidate collection to the selected comparison strategy. */
|
|
514
515
|
if (mode === "title_exact") {
|
|
515
516
|
return collectExactTitleClusters(prepared);
|
|
516
517
|
}
|
|
@@ -518,11 +519,12 @@ function collectDedupeClusters(
|
|
|
518
519
|
return collectParentScopedClusters(prepared);
|
|
519
520
|
}
|
|
520
521
|
return collectFuzzyTitleClusters(prepared, fuzzyThreshold);
|
|
521
|
-
}
|
|
522
|
+
};
|
|
522
523
|
|
|
523
|
-
|
|
524
|
-
item:
|
|
525
|
-
): DedupeAuditPreparedCandidate {
|
|
524
|
+
const toPreparedDedupeCandidate = (
|
|
525
|
+
item: ListedItem,
|
|
526
|
+
): DedupeAuditPreparedCandidate => {
|
|
527
|
+
/** Precompute normalized fields used by every dedupe comparison strategy. */
|
|
526
528
|
return {
|
|
527
529
|
id: item.id,
|
|
528
530
|
title: item.title,
|
|
@@ -535,38 +537,43 @@ function toPreparedDedupeCandidate(
|
|
|
535
537
|
normalized_title: normalizeLowercaseWhitespace(item.title),
|
|
536
538
|
title_tokens: tokenizeAlphaNumeric(item.title),
|
|
537
539
|
};
|
|
538
|
-
}
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
/** Preserve a defined filter value or project its absence as an explicit null. */
|
|
543
|
+
const toNullable = <Value>(value: Value | undefined): Value | null =>
|
|
544
|
+
value ?? null;
|
|
539
545
|
|
|
540
|
-
|
|
546
|
+
const buildDedupeAuditFilters = (params: {
|
|
541
547
|
mode: DedupeAuditMode;
|
|
542
548
|
status: ItemStatus | undefined;
|
|
543
549
|
options: DedupeAuditOptions;
|
|
544
550
|
limit: number | undefined;
|
|
545
551
|
fuzzyThreshold: number;
|
|
546
|
-
}): DedupeAuditResult["filters"] {
|
|
552
|
+
}): DedupeAuditResult["filters"] => {
|
|
553
|
+
/** Echo normalized audit filters in the stable public result shape. */
|
|
547
554
|
return {
|
|
548
555
|
mode: params.mode,
|
|
549
|
-
status: params.status
|
|
550
|
-
type: params.options.type
|
|
551
|
-
tag: params.options.tag
|
|
552
|
-
priority: params.options.priority
|
|
553
|
-
deadline_before: params.options.deadlineBefore
|
|
554
|
-
deadline_after: params.options.deadlineAfter
|
|
555
|
-
assignee: params.options.assignee
|
|
556
|
-
assignee_filter: params.options.assigneeFilter
|
|
557
|
-
parent: params.options.parent
|
|
558
|
-
sprint: params.options.sprint
|
|
559
|
-
release: params.options.release
|
|
560
|
-
limit: params.limit
|
|
556
|
+
status: toNullable(params.status),
|
|
557
|
+
type: toNullable(params.options.type),
|
|
558
|
+
tag: toNullable(params.options.tag),
|
|
559
|
+
priority: toNullable(params.options.priority),
|
|
560
|
+
deadline_before: toNullable(params.options.deadlineBefore),
|
|
561
|
+
deadline_after: toNullable(params.options.deadlineAfter),
|
|
562
|
+
assignee: toNullable(params.options.assignee),
|
|
563
|
+
assignee_filter: toNullable(params.options.assigneeFilter),
|
|
564
|
+
parent: toNullable(params.options.parent),
|
|
565
|
+
sprint: toNullable(params.options.sprint),
|
|
566
|
+
release: toNullable(params.options.release),
|
|
567
|
+
limit: toNullable(params.limit),
|
|
561
568
|
threshold: params.mode === "title_fuzzy" ? params.fuzzyThreshold : null,
|
|
562
569
|
};
|
|
563
|
-
}
|
|
570
|
+
};
|
|
564
571
|
|
|
565
572
|
/** Implements run dedupe audit for the public runtime surface of this module. */
|
|
566
|
-
export async
|
|
573
|
+
export const runDedupeAudit = async (
|
|
567
574
|
options: DedupeAuditOptions,
|
|
568
575
|
global: GlobalOptions,
|
|
569
|
-
): Promise<DedupeAuditResult> {
|
|
576
|
+
): Promise<DedupeAuditResult> => {
|
|
570
577
|
const pmRoot = resolvePmRoot(process.cwd(), global.path);
|
|
571
578
|
const settings = await readSettings(pmRoot);
|
|
572
579
|
const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
|
|
@@ -581,7 +588,11 @@ export async function runDedupeAudit(
|
|
|
581
588
|
const threshold = parseThreshold(options.threshold);
|
|
582
589
|
const fuzzyThreshold = threshold ?? 0.8;
|
|
583
590
|
|
|
584
|
-
const listed = await runList(
|
|
591
|
+
const listed = await runList(
|
|
592
|
+
status,
|
|
593
|
+
{ ...buildListQueryFilters(options), full: true as const },
|
|
594
|
+
global,
|
|
595
|
+
);
|
|
585
596
|
|
|
586
597
|
const prepared = listed.items.map((item) => toPreparedDedupeCandidate(item));
|
|
587
598
|
|
|
@@ -598,11 +609,7 @@ export async function runDedupeAudit(
|
|
|
598
609
|
(total, cluster) => total + cluster.merge_suggestions.length,
|
|
599
610
|
0,
|
|
600
611
|
);
|
|
601
|
-
|
|
602
|
-
const warnings =
|
|
603
|
-
listed.warnings && listed.warnings.length > 0 ? listed.warnings : undefined;
|
|
604
|
-
|
|
605
|
-
return {
|
|
612
|
+
const result: DedupeAuditResult = {
|
|
606
613
|
mode,
|
|
607
614
|
clusters: limitedClusters,
|
|
608
615
|
count: limitedClusters.length,
|
|
@@ -619,10 +626,11 @@ export async function runDedupeAudit(
|
|
|
619
626
|
fuzzyThreshold,
|
|
620
627
|
}),
|
|
621
628
|
now: nowIso(),
|
|
622
|
-
/* c8 ignore next -- warnings are omitted when undefined to keep stable result payloads. */
|
|
623
|
-
...(warnings ? { warnings } : {}),
|
|
624
629
|
};
|
|
625
|
-
|
|
630
|
+
/* c8 ignore next -- list warnings are normalized upstream in command-level tests. */
|
|
631
|
+
if (listed.warnings?.length) result.warnings = listed.warnings;
|
|
632
|
+
return result;
|
|
633
|
+
};
|
|
626
634
|
|
|
627
635
|
/** Public contract for test only, shared by SDK and presentation-layer consumers. */
|
|
628
636
|
export const _testOnly = {
|