Split the one-shot label backfill into reusable, mode-selected operations while
preserving the original default behavior:
- --create-labels : idempotent label creation only (create_labels()).
- --apply-mapping : one-off MAPPING labeling only (apply_mapping(); PUT replaces
each issue's set).
- --add-label <issue> <label> : ad-hoc single-issue labeling (add_label(); POST
appends the label, does not replace; refuses an undefined label).
- default (no mode) : create labels then apply MAPPING — identical to the prior
behavior. --dry (and --dry-run) still print without writing.
Extracted create_labels / apply_mapping / add_label / _labels_by_name helpers;
LABELS, MAPPING, and the api() wrapper are unchanged. No auth/network behavior
change; MAPPING remains the same one-off backfill data.
Tests: extend tests/test_manage_labels.py with a TestModes suite — create-only
(no PUT), apply-only (no label creation), add-label appends (POST, not PUT),
unknown-label no-op, dry no-op, non-numeric issue exits. Existing default/dry/
mapping/constant tests unchanged and still pass.
py_compile clean; full suite 319 passed / 0 failures; git diff --check clean;
no secrets.
Closes#6.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>