* Compute label mutations for the current issue state. * * @param {{currentLabels: Set |string[], desiredType: string|null, desiredDomainLabels: string[], syncDomains: boolean, overrideType: boolean}} params * @returns {{toAdd: string[], toRemove: string[]}}
(params)
| 582 | * @returns {{toAdd: string[], toRemove: string[]}} |
| 583 | */ |
| 584 | function planIssueLabelChanges(params) { |
| 585 | const { |
| 586 | currentLabels, |
| 587 | desiredType, |
| 588 | desiredDomainLabels, |
| 589 | syncDomains, |
| 590 | overrideType, |
| 591 | } = params; |
| 592 | |
| 593 | const current = currentLabels instanceof Set ? currentLabels : new Set(currentLabels || []); |
| 594 | const toAdd = new Set(); |
| 595 | const toRemove = new Set(); |
| 596 | |
| 597 | // Type: only apply when desiredType exists. |
| 598 | // Safety: by default, do NOT override existing type labels to avoid reverting manual triage. |
| 599 | if (desiredType) { |
| 600 | const currentType = [...current].filter((l) => TYPE_LABEL_SET.has(l)); |
| 601 | const shouldApplyType = overrideType || currentType.length === 0; |
| 602 | if (shouldApplyType) { |
| 603 | if (!current.has(desiredType)) { |
| 604 | toAdd.add(desiredType); |
| 605 | } |
| 606 | for (const t of currentType) { |
| 607 | if (t !== desiredType) toRemove.add(t); |
| 608 | } |
| 609 | } |
| 610 | } |
| 611 | |
| 612 | // Domain: add-only by default; strict sync via --sync-domains. |
| 613 | const desiredDomains = new Set(desiredDomainLabels || []); |
| 614 | for (const d of desiredDomains) { |
| 615 | if (!current.has(d)) toAdd.add(d); |
| 616 | } |
| 617 | |
| 618 | // Safety: only remove domains when we can positively match at least one domain. |
| 619 | if (syncDomains && desiredDomains.size > 0) { |
| 620 | for (const d of current) { |
| 621 | if (DOMAIN_LABEL_SET.has(d) && !desiredDomains.has(d)) { |
| 622 | toRemove.add(d); |
| 623 | } |
| 624 | } |
| 625 | } |
| 626 | |
| 627 | return { |
| 628 | toAdd: [...toAdd], |
| 629 | toRemove: [...toRemove], |
| 630 | }; |
| 631 | } |
| 632 | |
| 633 | /** |
| 634 | * Parse CLI arguments into runtime options. |