duplicatecode 0.3.0__py3-none-win_amd64.whl → 0.3.1__py3-none-win_amd64.whl
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.
- {duplicatecode-0.3.0.data → duplicatecode-0.3.1.data}/scripts/duplicatecode.exe +0 -0
- {duplicatecode-0.3.0.dist-info → duplicatecode-0.3.1.dist-info}/METADATA +14 -7
- duplicatecode-0.3.1.dist-info/RECORD +5 -0
- {duplicatecode-0.3.0.dist-info → duplicatecode-0.3.1.dist-info}/sboms/duplicatecode.cyclonedx.json +14 -14
- duplicatecode-0.3.0.dist-info/RECORD +0 -5
- {duplicatecode-0.3.0.dist-info → duplicatecode-0.3.1.dist-info}/WHEEL +0 -0
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: duplicatecode
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Classifier: Programming Language :: Rust
|
|
5
5
|
Classifier: Environment :: Console
|
|
6
6
|
Summary: Static (LLM-free) detection of duplicate/similar code in Python, TypeScript/JavaScript, SQL and C#
|
|
@@ -10,7 +10,7 @@ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
|
10
10
|
|
|
11
11
|
# duplicatecode
|
|
12
12
|
|
|
13
|
-
Static (LLM-free) detection of duplicate / similar code in Python, TypeScript/JavaScript (TSX/JSX), SQL and C#,
|
|
13
|
+
Static by default (LLM-free, no network unless `--embed*` is used) detection of duplicate / similar code in Python, TypeScript/JavaScript (TSX/JSX), SQL and C#,
|
|
14
14
|
aimed at catching an LLM re-implementing something that already exists. Input can be a git diff
|
|
15
15
|
checked against existing source.
|
|
16
16
|
|
|
@@ -66,7 +66,14 @@ duplicatecode find "retry with exponential backoff" src/ # does something like
|
|
|
66
66
|
|
|
67
67
|
## Embeddings (bring your own key)
|
|
68
68
|
|
|
69
|
-
Two optional signals, both off by default (the detector stays
|
|
69
|
+
Two optional signals, both off by default (the detector stays static and offline unless you ask).
|
|
70
|
+
|
|
71
|
+
> **Privacy warning.** `--embed openai`, `--embed cohere`, and `--embed-code` / `--embeddings` pointed at any
|
|
72
|
+
> hosted endpoint (OpenAI, Cohere, Azure, ...) **upload the source text of your units** to that provider
|
|
73
|
+
> (`--embeddings` sends identifier names only). `find` embeds **every unit under the given paths**, so
|
|
74
|
+
> `find ... --embed openai` uploads all of it. The local presets (`minilm`, `qwen3`, `potion`) are meant for a
|
|
75
|
+
> server on loopback (default `127.0.0.1:8099`; `DUPLICATECODE_EMBED_ENDPOINT` overrides it): pointing that
|
|
76
|
+
> variable at a remote host sends text there too. Do not use hosted embeddings on code you may not share.
|
|
70
77
|
|
|
71
78
|
- `--embeddings` embeds identifier *names* (cheap) as an extra name-similarity signal.
|
|
72
79
|
- `--embed <preset>` is the short form (`minilm`, `qwen3`, `potion`, `openai`, `cohere`; `qwen3` is about 5x slower than `minilm` on CPU, so use it with a GPU or prefer `minilm`) and implies
|
|
@@ -215,9 +222,9 @@ Self-scans of three internal repositories (Python + TypeScript), 189 pairs judge
|
|
|
215
222
|
before trusting them. A structure-heavy `--profile reimpl` exists for renamed re-implementations
|
|
216
223
|
(use with `--min-name 0`) but has no real-repo precision data yet.
|
|
217
224
|
|
|
218
|
-
### Fresh held-out check (copies profile, threshold 0.6)
|
|
225
|
+
### Fresh held-out check (copies profile, threshold 0.6 = the `copies` default for `scan`)
|
|
219
226
|
|
|
220
|
-
A third, untouched sample of 57 pairs (nothing was tuned on it): 30% true duplicates, 47% incl. partial
|
|
227
|
+
A third, untouched sample of 57 pairs (nothing was tuned on it; the `reimpl` profile has different defaults, 0.35 for `scan`, and is not covered by this sample): 30% true duplicates, 47% incl. partial
|
|
221
228
|
(OneSales 0/24, MDMApp 11/24, CCMT2 6/9 true). The 50%/76% above was optimistic because it was measured on the
|
|
222
229
|
pairs used to choose the weights. Test code is about half of the noise but also holds real copies
|
|
223
230
|
(25% true either way), so it is kept by default; `--skip-tests` drops it.
|
|
@@ -235,7 +242,7 @@ by Haiku and Sonnet without seeing the repo. Fraction where the original is foun
|
|
|
235
242
|
| 0.5 | 45% | 14% | 30% | 1% |
|
|
236
243
|
| 0.6 | 24% | 5% | 14% | 0% |
|
|
237
244
|
|
|
238
|
-
So `diff` (checking new code) defaults to threshold 0.4 while `scan` (existing copies) defaults to 0.6. About half of
|
|
245
|
+
So with the `copies` profile `diff` (checking new code) defaults to threshold 0.4 while `scan` (existing copies) defaults to 0.6; the `reimpl` profile has its own lower defaults (see above). About half of
|
|
239
246
|
independent re-implementations are caught; the rest are genuinely different code. The structure-heavy `reimpl`
|
|
240
247
|
profile is not better on this test.
|
|
241
248
|
|
|
@@ -252,7 +259,7 @@ read/grep, two with this CLI. All distinct groups (82) were then judged blind by
|
|
|
252
259
|
| OneSales, with CLI | 21 | 10 | 48% / 86% | 67% | 9 |
|
|
253
260
|
|
|
254
261
|
Only 18 of 82 groups were found by both, so the approaches are complementary. The agents' reports are capped at 30
|
|
255
|
-
groups, so the raw tool is a better measure of recall: `scan --threshold 0.6` (defaults) finds 38 of the 40 judged
|
|
262
|
+
groups, so the raw tool is a better measure of recall: `scan --threshold 0.6` (the `copies` defaults) finds 38 of the 40 judged
|
|
256
263
|
true duplicates (25/25 MDMApp, 13/15 OneSales) and 23 of the 25 that the LLM-only agents found independently.
|
|
257
264
|
What it still misses: a differently-written picker function (same purpose, different code) and a formatFileSize
|
|
258
265
|
variant with different constants. Fixed after this test: tiny same-name exact copies (`min_tokens` 20 -> 8, near-exact
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
duplicatecode-0.3.1.data/scripts/duplicatecode.exe,sha256=33sUDGbK4bx4ia2FRp7sr2VNCqXbDEv8d2PB-586Ydw,17516032
|
|
2
|
+
duplicatecode-0.3.1.dist-info/METADATA,sha256=O5SLA8he4Y3B-lFxwEAIERR0oQAO9uvq_FcKHJVVSMM,20682
|
|
3
|
+
duplicatecode-0.3.1.dist-info/WHEEL,sha256=8Aej0W0a6Cz6apA3IzJrTnxLRVLAt-w0Oh8SA3Con_c,94
|
|
4
|
+
duplicatecode-0.3.1.dist-info/sboms/duplicatecode.cyclonedx.json,sha256=XyVdeAxDdFGNhcXz_Jq2o4fltkDfZerwCTzRKtU6dSo,126750
|
|
5
|
+
duplicatecode-0.3.1.dist-info/RECORD,,
|
{duplicatecode-0.3.0.dist-info → duplicatecode-0.3.1.dist-info}/sboms/duplicatecode.cyclonedx.json
RENAMED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"bomFormat": "CycloneDX",
|
|
3
3
|
"specVersion": "1.5",
|
|
4
4
|
"version": 1,
|
|
5
|
-
"serialNumber": "urn:uuid:
|
|
5
|
+
"serialNumber": "urn:uuid:f5087dff-39cc-49e3-b7f1-add6f1b591d6",
|
|
6
6
|
"metadata": {
|
|
7
|
-
"timestamp": "2026-10-
|
|
7
|
+
"timestamp": "2026-10-07T09:33:02.890409000Z",
|
|
8
8
|
"tools": [
|
|
9
9
|
{
|
|
10
10
|
"vendor": "CycloneDX",
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
],
|
|
15
15
|
"component": {
|
|
16
16
|
"type": "application",
|
|
17
|
-
"bom-ref": "path+file:///D:/a/duplicatecode/duplicatecode/crates/duplicatecode-cli#duplicatecode@0.3.
|
|
17
|
+
"bom-ref": "path+file:///D:/a/duplicatecode/duplicatecode/crates/duplicatecode-cli#duplicatecode@0.3.1",
|
|
18
18
|
"name": "duplicatecode",
|
|
19
|
-
"version": "0.3.
|
|
19
|
+
"version": "0.3.1",
|
|
20
20
|
"description": "CLI to detect duplicate/similar code in Python and TypeScript",
|
|
21
21
|
"scope": "required",
|
|
22
22
|
"licenses": [
|
|
@@ -24,14 +24,14 @@
|
|
|
24
24
|
"expression": "MIT"
|
|
25
25
|
}
|
|
26
26
|
],
|
|
27
|
-
"purl": "pkg:cargo/duplicatecode@0.3.
|
|
27
|
+
"purl": "pkg:cargo/duplicatecode@0.3.1?download_url=file://.",
|
|
28
28
|
"components": [
|
|
29
29
|
{
|
|
30
30
|
"type": "application",
|
|
31
|
-
"bom-ref": "path+file:///D:/a/duplicatecode/duplicatecode/crates/duplicatecode-cli#duplicatecode@0.3.
|
|
31
|
+
"bom-ref": "path+file:///D:/a/duplicatecode/duplicatecode/crates/duplicatecode-cli#duplicatecode@0.3.1 bin-target-0",
|
|
32
32
|
"name": "duplicatecode",
|
|
33
|
-
"version": "0.3.
|
|
34
|
-
"purl": "pkg:cargo/duplicatecode@0.3.
|
|
33
|
+
"version": "0.3.1",
|
|
34
|
+
"purl": "pkg:cargo/duplicatecode@0.3.1?download_url=file://.#src/main.rs"
|
|
35
35
|
}
|
|
36
36
|
]
|
|
37
37
|
},
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"components": [
|
|
46
46
|
{
|
|
47
47
|
"type": "library",
|
|
48
|
-
"bom-ref": "path+file:///D:/a/duplicatecode/duplicatecode/crates/duplicatecode-engine#0.3.
|
|
48
|
+
"bom-ref": "path+file:///D:/a/duplicatecode/duplicatecode/crates/duplicatecode-engine#0.3.1",
|
|
49
49
|
"name": "duplicatecode-engine",
|
|
50
|
-
"version": "0.3.
|
|
50
|
+
"version": "0.3.1",
|
|
51
51
|
"description": "Static duplicate/similar code detection engine for Python, TypeScript/JavaScript, SQL and C#",
|
|
52
52
|
"scope": "required",
|
|
53
53
|
"licenses": [
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"expression": "MIT"
|
|
56
56
|
}
|
|
57
57
|
],
|
|
58
|
-
"purl": "pkg:cargo/duplicatecode-engine@0.3.
|
|
58
|
+
"purl": "pkg:cargo/duplicatecode-engine@0.3.1?download_url=file://..\\duplicatecode-engine"
|
|
59
59
|
},
|
|
60
60
|
{
|
|
61
61
|
"type": "library",
|
|
@@ -3324,11 +3324,11 @@
|
|
|
3324
3324
|
],
|
|
3325
3325
|
"dependencies": [
|
|
3326
3326
|
{
|
|
3327
|
-
"ref": "path+file:///D:/a/duplicatecode/duplicatecode/crates/duplicatecode-cli#duplicatecode@0.3.
|
|
3327
|
+
"ref": "path+file:///D:/a/duplicatecode/duplicatecode/crates/duplicatecode-cli#duplicatecode@0.3.1",
|
|
3328
3328
|
"dependsOn": [
|
|
3329
3329
|
"registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.104",
|
|
3330
3330
|
"registry+https://github.com/rust-lang/crates.io-index#clap@4.6.7",
|
|
3331
|
-
"path+file:///D:/a/duplicatecode/duplicatecode/crates/duplicatecode-engine#0.3.
|
|
3331
|
+
"path+file:///D:/a/duplicatecode/duplicatecode/crates/duplicatecode-engine#0.3.1",
|
|
3332
3332
|
"registry+https://github.com/rust-lang/crates.io-index#rayon@1.12.0",
|
|
3333
3333
|
"registry+https://github.com/rust-lang/crates.io-index#serde@1.0.229",
|
|
3334
3334
|
"registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.151",
|
|
@@ -3337,7 +3337,7 @@
|
|
|
3337
3337
|
]
|
|
3338
3338
|
},
|
|
3339
3339
|
{
|
|
3340
|
-
"ref": "path+file:///D:/a/duplicatecode/duplicatecode/crates/duplicatecode-engine#0.3.
|
|
3340
|
+
"ref": "path+file:///D:/a/duplicatecode/duplicatecode/crates/duplicatecode-engine#0.3.1",
|
|
3341
3341
|
"dependsOn": [
|
|
3342
3342
|
"registry+https://github.com/rust-lang/crates.io-index#ignore@0.4.33",
|
|
3343
3343
|
"registry+https://github.com/rust-lang/crates.io-index#serde@1.0.229",
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
duplicatecode-0.3.0.data/scripts/duplicatecode.exe,sha256=21yAmm_HzANC-d5pxUqpwsyxrAxL8PuGrK59ya4sodQ,17500672
|
|
2
|
-
duplicatecode-0.3.0.dist-info/METADATA,sha256=NatafxHYcIf4MIhEVtm-ioWP22fwXvQsBAzpc-SGRvI,19741
|
|
3
|
-
duplicatecode-0.3.0.dist-info/WHEEL,sha256=8Aej0W0a6Cz6apA3IzJrTnxLRVLAt-w0Oh8SA3Con_c,94
|
|
4
|
-
duplicatecode-0.3.0.dist-info/sboms/duplicatecode.cyclonedx.json,sha256=uPjugBPtNH7_f99oGPEDmrjDbAcAcj-bKIOlBsWrRgw,126750
|
|
5
|
-
duplicatecode-0.3.0.dist-info/RECORD,,
|
|
File without changes
|