{
  "id": "mail-deduplicate",
  "name": "Mail Deduplicate",
  "homepage": "https://kdeldycke.github.io/mail-deduplicate/",
  "description": "Remove duplicate emails from your mailboxes.",
  "executables": [
    "mdedup"
  ],
  "dotfiles": {
    "paths": [
      "[appData]/mdedup/",
      "[configHome]/mdedup/"
    ],
    "secret": []
  },
  "commands": {
    "format": 1,
    "label": "Deduplicate mailboxes",
    "description": "Find duplicate mails across one or more mailboxes, pick which copy to keep with a strategy, then act on the result. The default action only copies the selection to a new box. Hash tuning, thresholds and the regexp-based strategies are left out.",
    "quality": "ai-draft",
    "parser": {
      "end_of_options": "--",
      "interleave": "permute",
      "long_equals": true,
      "short_attached": true,
      "short_bundles": false
    },
    "source": [
      {
        "id": "help",
        "kind": "help",
        "url": "https://kdeldycke.github.io/mail-deduplicate/cli.html",
        "revision": "2026-10-27",
        "evidence": "Usage: mdedup [OPTIONS] MAIL_SOURCE_1 MAIL_SOURCE_2 ...\n  -i, --input-format [maildir|mbox|mh|babyl|mmdf|eml]\n  -b, --hash-body [skip|raw|normalized]\n  --cache / --no-cache\n  -s, --strategy [select-older|select-oldest|select-newer|select-newest|discard-newest|discard-newer|discard-oldest|discard-older|select-smaller|select-smallest|select-bigger|select-biggest|discard-biggest|discard-bigger|discard-smallest|discard-smaller|select-matching-path|select-non-matching-path|discard-non-matching-path|discard-matching-path|select-one|select-all-but-one|discard-all-but-one|discard-one]\n  -a, --action [copy-selected|copy-discarded|move-selected|move-discarded|delete-selected|delete-discarded|hardlink-discarded]\n  -E, --export MAIL_BOX_PATH\n  -e, --export-format [maildir|mbox|mh|babyl|mmdf|eml]\n  --export-append\n  -n, --dry-run\n  -H, --hash-only\n"
      }
    ],
    "field": [
      {
        "id": "sources",
        "label": "Mail sources",
        "description": "Mailboxes (maildir, mbox, ...) or mail files to deduplicate.",
        "type": "path",
        "path": {
          "kind": "any",
          "role": "input"
        },
        "position": 0,
        "multiple": true,
        "min": 1,
        "sources": [
          "help"
        ]
      },
      {
        "id": "strategy",
        "label": "Selection strategy",
        "description": "Which copy of each duplicate set is selected. Without one, nothing is selected and no action is taken.",
        "type": "string",
        "option": [
          "--strategy",
          "-s"
        ],
        "suggestions": [
          {
            "value": "select-oldest",
            "label": "Select oldest"
          },
          {
            "value": "select-newest",
            "label": "Select newest"
          },
          {
            "value": "select-biggest",
            "label": "Select biggest"
          },
          {
            "value": "select-smallest",
            "label": "Select smallest"
          },
          {
            "value": "select-one",
            "label": "Select one copy"
          },
          {
            "value": "select-all-but-one",
            "label": "Select all but one"
          }
        ],
        "sources": [
          "help"
        ]
      },
      {
        "id": "action",
        "label": "Action",
        "description": "Default copy-selected only reads the sources and writes a new box. The delete-* and move-* actions change the sources; rehearse with Dry run.",
        "type": "enum",
        "option": [
          "--action",
          "-a"
        ],
        "choices": [
          {
            "value": "copy-selected",
            "label": "Copy selected"
          },
          {
            "value": "copy-discarded",
            "label": "Copy discarded"
          },
          {
            "value": "move-selected",
            "label": "Move selected"
          },
          {
            "value": "move-discarded",
            "label": "Move discarded"
          },
          {
            "value": "delete-selected",
            "label": "Delete selected"
          },
          {
            "value": "delete-discarded",
            "label": "Delete discarded"
          },
          {
            "value": "hardlink-discarded",
            "label": "Hardlink discarded"
          }
        ],
        "sources": [
          "help"
        ]
      },
      {
        "id": "export",
        "label": "Destination mailbox",
        "description": "Required by the copy and move actions.",
        "type": "path",
        "option": [
          "--export",
          "-E"
        ],
        "path": {
          "kind": "any",
          "role": "output",
          "must_exist": false
        },
        "effect": "overwrite",
        "sources": [
          "help"
        ]
      },
      {
        "id": "export_format",
        "label": "Destination format",
        "type": "enum",
        "option": [
          "--export-format",
          "-e"
        ],
        "choices": [
          {
            "value": "maildir",
            "label": "Maildir"
          },
          {
            "value": "mbox",
            "label": "mbox"
          },
          {
            "value": "mh",
            "label": "MH"
          },
          {
            "value": "babyl",
            "label": "Babyl"
          },
          {
            "value": "mmdf",
            "label": "MMDF"
          },
          {
            "value": "eml",
            "label": "eml files"
          }
        ],
        "observed_default": "mbox",
        "sources": [
          "help"
        ]
      },
      {
        "id": "export_append",
        "label": "Append to existing destination",
        "type": "boolean",
        "option": [
          "--export-append"
        ],
        "sources": [
          "help"
        ]
      },
      {
        "id": "input_format",
        "label": "Force input format",
        "description": "Leave unset to auto-detect maildir, mbox and eml.",
        "type": "enum",
        "option": [
          "--input-format",
          "-i"
        ],
        "choices": [
          {
            "value": "maildir",
            "label": "Maildir"
          },
          {
            "value": "mbox",
            "label": "mbox"
          },
          {
            "value": "mh",
            "label": "MH"
          },
          {
            "value": "babyl",
            "label": "Babyl"
          },
          {
            "value": "mmdf",
            "label": "MMDF"
          },
          {
            "value": "eml",
            "label": "eml files"
          }
        ],
        "sources": [
          "help"
        ]
      },
      {
        "id": "hash_body",
        "label": "Hash mail bodies",
        "type": "enum",
        "option": [
          "--hash-body",
          "-b"
        ],
        "choices": [
          {
            "value": "skip",
            "label": "Skip (headers only)"
          },
          {
            "value": "raw",
            "label": "Raw"
          },
          {
            "value": "normalized",
            "label": "Normalized"
          }
        ],
        "observed_default": "skip",
        "sources": [
          "help"
        ]
      },
      {
        "id": "cache",
        "label": "Reuse hash cache",
        "type": "boolean",
        "option": [
          "--cache"
        ],
        "false_option": "--no-cache",
        "sources": [
          "help"
        ]
      },
      {
        "id": "dry_run",
        "label": "Dry run",
        "description": "Report what would be done without doing it.",
        "type": "boolean",
        "option": [
          "--dry-run",
          "-n"
        ],
        "sources": [
          "help"
        ]
      }
    ],
    "task": [
      {
        "id": "merge",
        "label": "Merge into a new mailbox",
        "fields": [
          "sources",
          "strategy",
          "export",
          "dry_run"
        ],
        "required": [
          "sources",
          "strategy",
          "export"
        ],
        "set": {
          "strategy": [
            "select-one"
          ]
        }
      },
      {
        "id": "rehearse_delete",
        "label": "Rehearse deleting duplicates",
        "fields": [
          "sources",
          "strategy",
          "action",
          "dry_run"
        ],
        "required": [
          "sources",
          "strategy",
          "action",
          "dry_run"
        ],
        "set": {
          "strategy": [
            "select-one"
          ],
          "action": [
            "delete-discarded"
          ],
          "dry_run": [
            true
          ]
        }
      }
    ],
    "group": [
      {
        "id": "basic",
        "label": "Basic",
        "fields": [
          "sources",
          "strategy",
          "action",
          "export",
          "dry_run"
        ]
      },
      {
        "id": "advanced",
        "label": "Advanced",
        "fields": [
          "export_format",
          "export_append",
          "input_format",
          "hash_body",
          "cache"
        ]
      }
    ]
  }
}
