@unbrained/pm-cli 2026.7.16 → 2026.7.17
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 +17 -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/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/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/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 +140 -133
- package/dist/cli/main.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 +341 -341
- 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-WT3ZEOGH.js → chunk-23TCGBRK.js} +16 -7
- package/dist/cli-bundle/chunks/{chunk-WT3ZEOGH.js.map → chunk-23TCGBRK.js.map} +1 -1
- 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-J6364LFM.js → chunk-2MPMKJF2.js} +9 -18
- package/dist/cli-bundle/chunks/{chunk-J6364LFM.js.map → chunk-2MPMKJF2.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-GM5QHQU6.js → chunk-2XOSFSTH.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-K3WII2ME.js → chunk-37DRDP2B.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-2WSE6PO2.js → chunk-37V5MXAU.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-UWQHLMEB.js → chunk-3D4YVTNG.js} +8 -8
- 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-ONG5V5CI.js → chunk-6XAZB6SE.js} +97 -69
- package/dist/cli-bundle/chunks/chunk-6XAZB6SE.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-PENXZX3U.js → chunk-74FKFFXO.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-LPYWLWDS.js → chunk-7CTQ7WW5.js} +37 -37
- package/dist/cli-bundle/chunks/chunk-7CTQ7WW5.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-HO4KXD6I.js → chunk-7H5NNCJ5.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-XXXF6PAQ.js → chunk-7LTCLTRG.js} +69 -61
- package/dist/cli-bundle/chunks/chunk-7LTCLTRG.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-TQSZFPIS.js → chunk-AFGKSHAM.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-JXQUXVMI.js → chunk-AFSV5HBB.js} +77 -7
- package/dist/cli-bundle/chunks/{chunk-JXQUXVMI.js.map → chunk-AFSV5HBB.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-6N2VXVTQ.js → chunk-ARGDWQ4J.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-3U7ZR6M4.js → chunk-B57RJHBZ.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-7B67ZL4N.js → chunk-B6SH2YNN.js} +75 -5
- package/dist/cli-bundle/chunks/{chunk-7B67ZL4N.js.map → chunk-B6SH2YNN.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-YCQET3OT.js → chunk-BAP7G3N2.js} +2 -2
- 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-YBLZ2VE7.js → chunk-CFSUNEL7.js} +320 -239
- package/dist/cli-bundle/chunks/chunk-CFSUNEL7.js.map +7 -0
- 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-E2OJMKML.js → chunk-DCC2AQBD.js} +18 -9
- package/dist/cli-bundle/chunks/{chunk-E2OJMKML.js.map → chunk-DCC2AQBD.js.map} +1 -1
- 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-IG3SWA4A.js → chunk-EHJFUOXL.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-ONREO4ST.js → chunk-EY7ZE3TG.js} +3 -3
- 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-EACOH7AU.js → chunk-FZGM3PNA.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-FNSPG7MU.js → chunk-G6KM4YKY.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-AHVTB5I5.js → chunk-G6MYGULG.js} +4 -4
- 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-5ZSLZLDN.js → chunk-HF63SBLC.js} +585 -456
- package/dist/cli-bundle/chunks/chunk-HF63SBLC.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-SELVXEZK.js → chunk-HO4DLBNK.js} +2 -2
- 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-CRVF2JDM.js → chunk-HXVHBERL.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-NU3IMIEA.js → chunk-I7DIDUSP.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-2NCIPMQP.js → chunk-I7GY4X6Y.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-JYFOV7FC.js → chunk-IE5KRAKN.js} +4 -4
- 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-J6EY5V4N.js → chunk-KOEZCHRF.js} +9 -9
- 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-LSG2U345.js → chunk-L6FVNR7X.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-ILX33QXL.js → chunk-LLODAQMP.js} +706 -532
- package/dist/cli-bundle/chunks/chunk-LLODAQMP.js.map +7 -0
- 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-MNV226E4.js +834 -0
- package/dist/cli-bundle/chunks/chunk-MNV226E4.js.map +1 -0
- 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-BKVG6XOA.js → chunk-MSGETE6I.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-3WM75PWC.js → chunk-N33FD2UI.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-UFXU44HV.js → chunk-N7I2DGLP.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-3S5QVM5H.js → chunk-NCAFUBJX.js} +13 -13
- package/dist/cli-bundle/chunks/chunk-NCAFUBJX.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-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-NLDFBC6J.js → chunk-P56LKFQX.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-NVPZIJVR.js → chunk-PT7MCCGD.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-P74IZQ7A.js → chunk-QKVVV6QO.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-5JLUII3O.js → chunk-QNUAZYGW.js} +321 -240
- package/dist/cli-bundle/chunks/chunk-QNUAZYGW.js.map +1 -0
- 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-HYB5AZ63.js → chunk-S46R2M3W.js} +117 -71
- package/dist/cli-bundle/chunks/chunk-S46R2M3W.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-H5APFTHZ.js → chunk-S6FF7VW6.js} +18 -18
- package/dist/cli-bundle/chunks/chunk-S6FF7VW6.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-UXONS674.js → chunk-SIJV365F.js} +54 -55
- package/dist/cli-bundle/chunks/chunk-SIJV365F.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-7Z4LKRS4.js → chunk-SPFZV2GR.js} +9 -9
- package/dist/cli-bundle/chunks/{chunk-ULTHRDBP.js → chunk-TM5CIO3F.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-4XQ3BDV4.js → chunk-V3VBXQQV.js} +36 -36
- package/dist/cli-bundle/chunks/chunk-V3VBXQQV.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-YAROI3PD.js → chunk-V7MP6YTN.js} +7 -7
- 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-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-J5AOEGDC.js → chunk-XNPMDSQQ.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-K2X6U4UA.js → chunk-XXLXJL7V.js} +4 -4
- package/dist/cli-bundle/chunks/chunk-XYJK6GIQ.js +851 -0
- package/dist/cli-bundle/chunks/chunk-XYJK6GIQ.js.map +7 -0
- 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-JFTKLTEF.js → chunk-YQCWK2MB.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-EYLCSJAI.js → chunk-YQEZWI3R.js} +2 -2
- package/dist/cli-bundle/chunks/close-BEP7MHF3.js +12 -0
- package/dist/cli-bundle/chunks/{close-CWODTPKG.js → close-Y6QFUJQN.js} +5 -5
- package/dist/cli-bundle/chunks/{close-many-CQFUY7MR.js → close-many-JJFW7KTT.js} +14 -14
- package/dist/cli-bundle/chunks/close-many-QJ6FKJUE.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-OA26IS25.js → deps-5NC4IZH7.js} +5 -5
- package/dist/cli-bundle/chunks/{deps-JZ7TMVCB.js → deps-EVTOQMKW.js} +5 -5
- 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-IVXQEL3D.js → profile-AGUKS52S.js} +9 -9
- package/dist/cli-bundle/chunks/{profile-FAU7NZML.js → profile-U2B6Y7GE.js} +9 -9
- package/dist/cli-bundle/chunks/{register-list-query-UL4UKBBN.js → register-list-query-A5KRJ5J2.js} +16 -16
- package/dist/cli-bundle/chunks/{register-list-query-DKA3EH5D.js → register-list-query-NEYP3TXO.js} +16 -16
- package/dist/cli-bundle/chunks/{register-mutation-RBBJ52DK.js → register-mutation-6LOPBAHC.js} +29 -29
- package/dist/cli-bundle/chunks/{register-mutation-ARFHRW55.js → register-mutation-GCZOALNJ.js} +29 -29
- package/dist/cli-bundle/chunks/{register-operations-ZIBBRSED.js → register-operations-6ZZIF27A.js} +35 -35
- package/dist/cli-bundle/chunks/{register-operations-ZUJ5JWPE.js → register-operations-REDIAEGI.js} +35 -35
- package/dist/cli-bundle/chunks/{register-setup-TDCGWIOS.js → register-setup-BHPMN5SK.js} +15 -15
- package/dist/cli-bundle/chunks/{register-setup-BCVLFEYS.js → register-setup-J3JS2ZVT.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-PQQHLYCC.js +21 -0
- package/dist/cli-bundle/chunks/{update-XHSIAIXE.js → update-SA6AG23P.js} +12 -12
- package/dist/cli-bundle/chunks/update-many-RQVTFJPD.js +36 -0
- package/dist/cli-bundle/chunks/update-many-TV3L3KBX.js +32 -0
- package/dist/cli-bundle/main.js +153 -855
- package/dist/cli-bundle/main.js.map +4 -4
- package/dist/cli-bundle/sdk-runtime.js +54 -54
- package/dist/cli-bundle/sdk-testing.js +6 -6
- package/dist/cli-bundle/sdk.js +195 -59
- package/dist/cli-bundle/sdk.js.map +3 -3
- package/dist/core/extensions/item-fields.js +2 -2
- package/dist/core/extensions/item-fields.js.map +1 -1
- 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/eval.d.ts +66 -0
- package/dist/sdk/eval.js +186 -0
- package/dist/sdk/eval.js.map +1 -0
- package/dist/sdk/index.d.ts +16 -4
- package/dist/sdk/index.js +18 -6
- 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 +254 -0
- package/dist/sdk/query/list.js +1073 -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/runtime.d.ts +7 -7
- package/dist/sdk/runtime.js +13 -7
- 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/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/SDK.md +122 -0
- 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-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-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-LPYWLWDS.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-ONG5V5CI.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/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/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-2WSE6PO2.js.map → chunk-37V5MXAU.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UWQHLMEB.js.map → chunk-3D4YVTNG.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-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-EACOH7AU.js.map → chunk-FZGM3PNA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-FNSPG7MU.js.map → chunk-G6KM4YKY.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-3CLU2XZO.js.map → chunk-HSYV4ZYT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-CRVF2JDM.js.map → chunk-HXVHBERL.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-2NCIPMQP.js.map → chunk-I7GY4X6Y.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-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-J6EY5V4N.js.map → chunk-KOEZCHRF.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-BKVG6XOA.js.map → chunk-MSGETE6I.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-UFXU44HV.js.map → chunk-N7I2DGLP.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-NLDFBC6J.js.map → chunk-P56LKFQX.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-P74IZQ7A.js.map → chunk-QKVVV6QO.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-7Z4LKRS4.js.map → chunk-SPFZV2GR.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-YAROI3PD.js.map → chunk-V7MP6YTN.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-J5AOEGDC.js.map → chunk-XNPMDSQQ.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-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-JFTKLTEF.js.map → chunk-YQCWK2MB.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-BEP7MHF3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-CWODTPKG.js.map → close-Y6QFUJQN.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-many-CQFUY7MR.js.map → close-many-JJFW7KTT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-many-DLDDVSH5.js.map → close-many-QJ6FKJUE.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-OA26IS25.js.map → deps-5NC4IZH7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-JZ7TMVCB.js.map → deps-EVTOQMKW.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-IVXQEL3D.js.map → profile-AGUKS52S.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{profile-FAU7NZML.js.map → profile-U2B6Y7GE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-list-query-UL4UKBBN.js.map → register-list-query-A5KRJ5J2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-list-query-DKA3EH5D.js.map → register-list-query-NEYP3TXO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-mutation-RBBJ52DK.js.map → register-mutation-6LOPBAHC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-mutation-ARFHRW55.js.map → register-mutation-GCZOALNJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-operations-ZIBBRSED.js.map → register-operations-6ZZIF27A.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-operations-ZUJ5JWPE.js.map → register-operations-REDIAEGI.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-setup-TDCGWIOS.js.map → register-setup-BHPMN5SK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-setup-BCVLFEYS.js.map → register-setup-J3JS2ZVT.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-WWBYOPXO.js.map → update-PQQHLYCC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-XHSIAIXE.js.map → update-SA6AG23P.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-TA7NGQBO.js.map → update-many-RQVTFJPD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-OUGIU5SF.js.map → update-many-TV3L3KBX.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 = {
|