def compare_semver(a, b):
    # Split into version and prerelease
    a_parts = a.split('-', 1)
    b_parts = b.split('-', 1)
    a_ver = a_parts[0].split('.')
    b_ver = b_parts[0].split('.')
    a_pre = a_parts[1] if len(a_parts) > 1 else None
    b_pre = b_parts[1] if len(b_parts) > 1 else None

    # Compare MAJOR.MINOR.PATCH numerically
    for i in range(3):
        av = int(a_ver[i])
        bv = int(b_ver[i])
        if av != bv:
            return -1 if av < bv else 1

    # Version cores are equal; handle prerelease
    if a_pre is None and b_pre is None:
        return 0
    if a_pre is None:
        return 1  # release > prerelease
    if b_pre is None:
        return -1  # release > prerelease

    # Both have prerelease; compare dot-separated identifiers
    a_ids = a_pre.split('.')
    b_ids = b_pre.split('.')
    for i in range(max(len(a_ids), len(b_ids))):
        if i >= len(a_ids):
            return -1  # shorter is less
        if i >= len(b_ids):
            return 1  # shorter is less
        ai = a_ids[i]
        bi = b_ids[i]
        a_num = ai.isdigit()
        b_num = bi.isdigit()
        if a_num and b_num:
            av = int(ai)
            bv = int(bi)
            if av != bv:
                return -1 if av < bv else 1
        elif a_num and not b_num:
            return -1  # numeric < non-numeric
        elif not a_num and b_num:
            return 1   # numeric < non-numeric
        else:
            if ai != bi:
                return -1 if ai < bi else 1
    return 0
