#!/bin/bash
set -e

# =============================================================================
# VERSION BUMP SCRIPT FOR BEADS
# =============================================================================
#
# This script handles all version bumping and local installation for beads
# releases. It updates version numbers across all components and can install
# everything locally for testing before pushing.
#
# QUICK START (for typical release):
#
#   # 1. Update CHANGELOG.md and cmd/bd/info.go with release notes (manual)
#   # 2. Run version bump with chaos tests and all local installations:
#   ./scripts/bump-version.sh X.Y.Z --run-chaos-tests --commit --tag --push --all
#
# Or step by step:
#   ./scripts/bump-version.sh X.Y.Z --run-chaos-tests  # Run chaos tests first
#   ./scripts/bump-version.sh X.Y.Z --commit --all     # Commit and install
#   git push origin main && git push origin vX.Y.Z     # Push
#
# WHAT --all DOES:
#   --install          - Build bd and install to ~/go/bin AND ~/.local/bin
#   --mcp-local        - Install beads-mcp from local source via uv/pip
#   --restart-daemons  - Restart all bd daemons to pick up new version
#
# MOLECULE WORKFLOW (Alternative):
#   For guided, resumable releases with multiple agents:
#   bd template instantiate bd-6s61 --var version=X.Y.Z --assignee <identity>
#
# IMPORTANT: In Gas Town, run from mayor/rig to avoid git conflicts with bd sync
# =============================================================================
#
# Gas Town agents share a beads database at mayor/rig/.beads/. The bd sync
# command commits from that clone. Running version bumps from a different
# clone (e.g., crew/dave) causes push conflicts when bd sync tries to push.
#
# Always run releases from the rig root:
#
#   cd ~/gt/beads/mayor/rig && ./scripts/bump-version.sh X.Y.Z --commit --tag --push --all
#
# =============================================================================

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Usage message
usage() {
    echo "Usage: $0 <version> [--commit] [--tag] [--push] [--install] [--upgrade-mcp] [--mcp-local] [--restart-daemons] [--run-chaos-tests] [--publish-npm] [--publish-pypi] [--publish-all] [--all] [--allow-staged]"
    echo ""
    echo "Bump version across all beads components."
    echo ""
    echo "Arguments:"
    echo "  <version>        Semantic version (e.g., 0.9.3, 1.0.0)"
    echo "  --commit         Automatically create a git commit (optional)"
    echo "  --tag            Create annotated git tag after commit (requires --commit)"
    echo "  --push           Push commit and tag to origin (requires --commit and --tag)"
    echo "  --install        Rebuild and install bd binary to GOPATH/bin AND ~/.local/bin"
    echo "  --upgrade-mcp    Upgrade local beads-mcp installation via pip after version bump"
    echo "  --mcp-local      Install beads-mcp from local source (for pre-PyPI testing)"
    echo "  --restart-daemons  Restart all bd daemons to pick up new version"
    echo "  --run-chaos-tests  Run chaos/corruption recovery tests before tagging"
    echo "  --publish-npm    Publish npm package to registry (requires npm login)"
    echo "  --publish-pypi   Publish beads-mcp to PyPI (requires TWINE credentials)"
    echo "  --publish-all    Shorthand for --publish-npm --publish-pypi"
    echo "  --all            Shorthand for --install --mcp-local --restart-daemons"
    echo "  --allow-staged   Allow pre-staged release files (CHANGELOG.md, info.go)"
    echo ""
    echo "Examples:"
    echo "  $0 0.9.3                            # Update versions and show diff"
    echo "  $0 0.9.3 --install                  # Update versions and rebuild/install bd"
    echo "  $0 0.9.3 --upgrade-mcp              # Update versions and upgrade beads-mcp from PyPI"
    echo "  $0 0.9.3 --mcp-local                # Update versions and install beads-mcp from local source"
    echo "  $0 0.9.3 --commit                   # Update versions and commit"
    echo "  $0 0.9.3 --commit --tag             # Update, commit, and tag"
    echo "  $0 0.9.3 --commit --tag --push      # Full release preparation"
    echo "  $0 0.9.3 --all                      # Install bd, local MCP, and restart daemons"
    echo "  $0 0.9.3 --commit --all             # Commit and install everything locally"
    echo "  $0 0.9.3 --run-chaos-tests          # Run chaos tests before proceeding"
    echo "  $0 0.9.3 --publish-all              # Publish to npm and PyPI"
    echo "  $0 0.9.3 --allow-staged --commit    # With pre-staged CHANGELOG.md/info.go"
    echo ""
    echo "Pre-staged release notes workflow:"
    echo "  # 1. Edit CHANGELOG.md and cmd/bd/info.go with release notes"
    echo "  # 2. Stage them: git add CHANGELOG.md cmd/bd/info.go"
    echo "  # 3. Run: $0 X.Y.Z --allow-staged --commit --tag --push --all"
    echo ""
    echo "Recommended release command (includes chaos testing):"
    echo "  $0 X.Y.Z --run-chaos-tests --commit --tag --push --all"
    exit 1
}

# Validate semantic versioning
validate_version() {
    local version=$1
    if ! [[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
        echo -e "${RED}Error: Invalid version format '$version'${NC}"
        echo "Expected semantic version format: MAJOR.MINOR.PATCH (e.g., 0.9.3)"
        exit 1
    fi
}

# Get current version from version.go
get_current_version() {
    grep 'Version = ' cmd/bd/version.go | sed 's/.*"\(.*\)".*/\1/'
}

# Check if all uncommitted changes are to release-related files
# Returns 0 if all changes are release files, 1 otherwise
check_release_files_only() {
    local changed_files
    changed_files=$(git diff --name-only HEAD 2>/dev/null)

    if [ -z "$changed_files" ]; then
        return 0  # No changes
    fi

    # List of expected release files
    local release_files="CHANGELOG.md cmd/bd/info.go"

    for file in $changed_files; do
        local is_release_file=false
        for rf in $release_files; do
            if [ "$file" = "$rf" ]; then
                is_release_file=true
                break
            fi
        done
        if [ "$is_release_file" = false ]; then
            return 1  # Found a non-release file
        fi
    done

    return 0  # All files are release files
}

# Update a file with sed (cross-platform compatible)
update_file() {
    local file=$1
    local old_pattern=$2
    local new_text=$3

    if [[ "$OSTYPE" == "darwin"* ]]; then
        # macOS requires -i ''
        sed -i '' "s|$old_pattern|$new_text|g" "$file"
    else
        # Linux
        sed -i "s|$old_pattern|$new_text|g" "$file"
    fi
}

# Update CHANGELOG.md: move [Unreleased] to [version] and create new [Unreleased]
update_changelog() {
    local version=$1
    local date=$(date +%Y-%m-%d)

    if [ ! -f "CHANGELOG.md" ]; then
        echo -e "${YELLOW}Warning: CHANGELOG.md not found, skipping${NC}"
        return
    fi

    # Check if there's an [Unreleased] section
    if ! grep -q "## \[Unreleased\]" CHANGELOG.md; then
        echo -e "${YELLOW}Warning: No [Unreleased] section in CHANGELOG.md${NC}"
        echo -e "${YELLOW}You may need to manually update CHANGELOG.md${NC}"
        return
    fi

    # Create a temporary file with the updated changelog
    if [[ "$OSTYPE" == "darwin"* ]]; then
        # macOS
        sed -i '' "s/## \[Unreleased\]/## [Unreleased]\n\n## [$version] - $date/" CHANGELOG.md
    else
        # Linux
        sed -i "s/## \[Unreleased\]/## [Unreleased]\n\n## [$version] - $date/" CHANGELOG.md
    fi
}

# Main script
main() {
    # Check arguments
    if [ $# -lt 1 ]; then
        usage
    fi

    NEW_VERSION=$1
    AUTO_COMMIT=false
    AUTO_TAG=false
    AUTO_PUSH=false
    AUTO_INSTALL=false
    AUTO_UPGRADE_MCP=false
    AUTO_MCP_LOCAL=false
    AUTO_RESTART_DAEMONS=false
    AUTO_PUBLISH_NPM=false
    AUTO_PUBLISH_PYPI=false
    AUTO_RUN_CHAOS_TESTS=false
    ALLOW_STAGED=false

    # Parse flags
    shift  # Remove version argument
    while [ $# -gt 0 ]; do
        case "$1" in
            --commit)
                AUTO_COMMIT=true
                ;;
            --tag)
                AUTO_TAG=true
                ;;
            --push)
                AUTO_PUSH=true
                ;;
            --install)
                AUTO_INSTALL=true
                ;;
            --upgrade-mcp)
                AUTO_UPGRADE_MCP=true
                ;;
            --mcp-local)
                AUTO_MCP_LOCAL=true
                ;;
            --restart-daemons)
                AUTO_RESTART_DAEMONS=true
                ;;
            --publish-npm)
                AUTO_PUBLISH_NPM=true
                ;;
            --publish-pypi)
                AUTO_PUBLISH_PYPI=true
                ;;
            --publish-all)
                AUTO_PUBLISH_NPM=true
                AUTO_PUBLISH_PYPI=true
                ;;
            --run-chaos-tests)
                AUTO_RUN_CHAOS_TESTS=true
                ;;
            --allow-staged)
                ALLOW_STAGED=true
                ;;
            --all)
                AUTO_INSTALL=true
                AUTO_MCP_LOCAL=true
                AUTO_RESTART_DAEMONS=true
                ;;
            *)
                echo -e "${RED}Error: Unknown option '$1'${NC}"
                usage
                ;;
        esac
        shift
    done

    # Validate flag dependencies
    if [ "$AUTO_TAG" = true ] && [ "$AUTO_COMMIT" = false ]; then
        echo -e "${RED}Error: --tag requires --commit${NC}"
        exit 1
    fi
    if [ "$AUTO_PUSH" = true ] && [ "$AUTO_TAG" = false ]; then
        echo -e "${RED}Error: --push requires --tag${NC}"
        exit 1
    fi

    # Validate version format
    validate_version "$NEW_VERSION"

    # Get current version
    CURRENT_VERSION=$(get_current_version)

    echo -e "${YELLOW}Bumping version: $CURRENT_VERSION → $NEW_VERSION${NC}"
    echo ""

    # Check if we're in the repo root
    if [ ! -f "cmd/bd/version.go" ]; then
        echo -e "${RED}Error: Must run from repository root${NC}"
        exit 1
    fi

    # Check for uncommitted changes
    PRE_STAGED_RELEASE_FILES=false
    if ! git diff-index --quiet HEAD --; then
        if [ "$ALLOW_STAGED" = true ] && check_release_files_only; then
            # Pre-staged release files (CHANGELOG.md, info.go) - this is expected workflow
            echo -e "${GREEN}✓ Detected pre-staged release files (CHANGELOG.md and/or info.go)${NC}"
            PRE_STAGED_RELEASE_FILES=true
        else
            echo -e "${YELLOW}Warning: You have uncommitted changes${NC}"
            if [ "$AUTO_COMMIT" = true ]; then
                if [ "$ALLOW_STAGED" = true ]; then
                    echo -e "${RED}Error: --allow-staged only permits CHANGELOG.md and info.go${NC}"
                    echo "Changed files:"
                    git diff --name-only HEAD
                else
                    echo -e "${RED}Error: Cannot auto-commit with existing uncommitted changes${NC}"
                    echo -e "${YELLOW}Tip: Use --allow-staged if changes are to CHANGELOG.md/info.go${NC}"
                fi
                exit 1
            fi
            read -p "Continue anyway? (y/N) " -n 1 -r
            echo
            if [[ ! $REPLY =~ ^[Yy]$ ]]; then
                exit 1
            fi
        fi
    fi

    echo "Updating version files..."

    # 1. Update cmd/bd/version.go
    echo "  • cmd/bd/version.go"
    update_file "cmd/bd/version.go" \
        "Version = \"$CURRENT_VERSION\"" \
        "Version = \"$NEW_VERSION\""

    # 2. Update .claude-plugin/plugin.json
    echo "  • .claude-plugin/plugin.json"
    update_file ".claude-plugin/plugin.json" \
        "\"version\": \"$CURRENT_VERSION\"" \
        "\"version\": \"$NEW_VERSION\""

    # 3. Update .claude-plugin/marketplace.json
    echo "  • .claude-plugin/marketplace.json"
    update_file ".claude-plugin/marketplace.json" \
        "\"version\": \"$CURRENT_VERSION\"" \
        "\"version\": \"$NEW_VERSION\""

    # 4. Update integrations/beads-mcp/pyproject.toml
    echo "  • integrations/beads-mcp/pyproject.toml"
    update_file "integrations/beads-mcp/pyproject.toml" \
        "version = \"$CURRENT_VERSION\"" \
        "version = \"$NEW_VERSION\""

    # 5. Update integrations/beads-mcp/src/beads_mcp/__init__.py
    echo "  • integrations/beads-mcp/src/beads_mcp/__init__.py"
    update_file "integrations/beads-mcp/src/beads_mcp/__init__.py" \
        "__version__ = \"$CURRENT_VERSION\"" \
        "__version__ = \"$NEW_VERSION\""

    # 6. Update README.md
    echo "  • README.md"
    update_file "README.md" \
        "Alpha (v$CURRENT_VERSION)" \
        "Alpha (v$NEW_VERSION)"

    # 7. Update PLUGIN.md version requirements (if exists)
    if [ -f "PLUGIN.md" ]; then
        echo "  • PLUGIN.md"
        update_file "PLUGIN.md" \
            "Plugin $CURRENT_VERSION requires bd CLI $CURRENT_VERSION+" \
            "Plugin $NEW_VERSION requires bd CLI $NEW_VERSION+"
    fi

    # 8. Update npm-package/package.json
    echo "  • npm-package/package.json"
    update_file "npm-package/package.json" \
        "\"version\": \"$CURRENT_VERSION\"" \
        "\"version\": \"$NEW_VERSION\""

    # 9. Update hook templates
    echo "  • cmd/bd/templates/hooks/*"
    HOOK_FILES=("pre-commit" "post-merge" "pre-push" "post-checkout")
    for hook in "${HOOK_FILES[@]}"; do
        update_file "cmd/bd/templates/hooks/$hook" \
            "# bd-hooks-version: $CURRENT_VERSION" \
            "# bd-hooks-version: $NEW_VERSION"
    done

    # 10. Update CHANGELOG.md
    echo "  • CHANGELOG.md"
    update_changelog "$NEW_VERSION"

    echo ""
    echo -e "${GREEN}✓ Version updated to $NEW_VERSION${NC}"
    echo ""

    # Show diff
    echo "Changed files:"
    git diff --stat
    echo ""

    # Verify all versions match
    echo "Verifying version consistency..."
    VERSIONS=(
        "$(grep 'Version = ' cmd/bd/version.go | sed 's/.*"\(.*\)".*/\1/')"
        "$(jq -r '.version' .claude-plugin/plugin.json)"
        "$(jq -r '.plugins[0].version' .claude-plugin/marketplace.json)"
        "$(grep 'version = ' integrations/beads-mcp/pyproject.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')"
        "$(grep '__version__ = ' integrations/beads-mcp/src/beads_mcp/__init__.py | sed 's/.*"\(.*\)".*/\1/')"
        "$(jq -r '.version' npm-package/package.json)"
        "$(grep '# bd-hooks-version: ' cmd/bd/templates/hooks/pre-commit | sed 's/.*: \(.*\)/\1/')"
    )

    ALL_MATCH=true
    for v in "${VERSIONS[@]}"; do
        if [ "$v" != "$NEW_VERSION" ]; then
            ALL_MATCH=false
            echo -e "${RED}✗ Version mismatch found: $v${NC}"
        fi
    done

    if [ "$ALL_MATCH" = true ]; then
        echo -e "${GREEN}✓ All versions match: $NEW_VERSION${NC}"
    else
        echo -e "${RED}✗ Version mismatch detected!${NC}"
        exit 1
    fi

    echo ""

    # Auto-install if requested
    if [ "$AUTO_INSTALL" = true ]; then
        echo "Rebuilding and installing bd..."
        GOPATH_BIN="$(go env GOPATH)/bin"
        LOCAL_BIN="$HOME/.local/bin"

        # Build the binary
        if ! go build -o /tmp/bd-new ./cmd/bd; then
            echo -e "${RED}✗ go build failed${NC}"
            exit 1
        fi

        # Codesign the binary on macOS (required to avoid "Killed: 9")
        if [[ "$OSTYPE" == "darwin"* ]]; then
            xattr -cr /tmp/bd-new 2>/dev/null
            codesign -f -s - /tmp/bd-new 2>/dev/null
            echo -e "${GREEN}✓ bd codesigned for macOS${NC}"
        fi

        # Install to GOPATH/bin (typically ~/go/bin)
        cp /tmp/bd-new "$GOPATH_BIN/bd"
        if [[ "$OSTYPE" == "darwin"* ]]; then
            codesign -f -s - "$GOPATH_BIN/bd" 2>/dev/null
        fi
        echo -e "${GREEN}✓ bd installed to $GOPATH_BIN/bd${NC}"

        # Install to ~/.local/bin if it exists or we can create it
        if [ -d "$LOCAL_BIN" ] || mkdir -p "$LOCAL_BIN" 2>/dev/null; then
            cp /tmp/bd-new "$LOCAL_BIN/bd"
            if [[ "$OSTYPE" == "darwin"* ]]; then
                codesign -f -s - "$LOCAL_BIN/bd" 2>/dev/null
            fi
            echo -e "${GREEN}✓ bd installed to $LOCAL_BIN/bd${NC}"
        else
            echo -e "${YELLOW}⚠ Could not install to $LOCAL_BIN (directory doesn't exist)${NC}"
        fi

        # Clean up temp file
        rm -f /tmp/bd-new

        # Verify installation
        echo ""
        echo "Verifying installed versions..."
        if [ -f "$GOPATH_BIN/bd" ]; then
            GOPATH_VERSION=$("$GOPATH_BIN/bd" --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
            if [ "$GOPATH_VERSION" = "$NEW_VERSION" ]; then
                echo -e "${GREEN}✓ $GOPATH_BIN/bd reports $GOPATH_VERSION${NC}"
            else
                echo -e "${YELLOW}⚠ $GOPATH_BIN/bd reports $GOPATH_VERSION (expected $NEW_VERSION)${NC}"
            fi
        fi
        if [ -f "$LOCAL_BIN/bd" ]; then
            LOCAL_VERSION=$("$LOCAL_BIN/bd" --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
            if [ "$LOCAL_VERSION" = "$NEW_VERSION" ]; then
                echo -e "${GREEN}✓ $LOCAL_BIN/bd reports $LOCAL_VERSION${NC}"
            else
                echo -e "${YELLOW}⚠ $LOCAL_BIN/bd reports $LOCAL_VERSION (expected $NEW_VERSION)${NC}"
            fi
        fi
        echo ""
    fi

    # Auto-upgrade MCP if requested
    if [ "$AUTO_UPGRADE_MCP" = true ]; then
        echo "Upgrading local beads-mcp installation..."

        # Try pip first (most common)
        if command -v pip &> /dev/null; then
            if pip install --upgrade beads-mcp; then
                echo -e "${GREEN}✓ beads-mcp upgraded via pip${NC}"
                echo ""
                INSTALLED_MCP_VERSION=$(pip show beads-mcp 2>/dev/null | grep Version | awk '{print $2}')
                if [ "$INSTALLED_MCP_VERSION" = "$NEW_VERSION" ]; then
                    echo -e "${GREEN}✓ Verified: beads-mcp version is $INSTALLED_MCP_VERSION${NC}"
                    echo -e "${YELLOW}  Note: Restart Claude Code or MCP session to use the new version${NC}"
                else
                    echo -e "${YELLOW}⚠ Warning: beads-mcp version is $INSTALLED_MCP_VERSION (expected $NEW_VERSION)${NC}"
                    echo -e "${YELLOW}  This is normal - PyPI package may not be published yet${NC}"
                    echo -e "${YELLOW}  The local source version in pyproject.toml is $NEW_VERSION${NC}"
                fi
            else
                echo -e "${YELLOW}⚠ pip upgrade failed or beads-mcp not installed via pip${NC}"
                echo -e "${YELLOW}  You may need to upgrade manually after publishing to PyPI${NC}"
            fi
        # Try uv tool as fallback
        elif command -v uv &> /dev/null; then
            if uv tool list | grep -q beads-mcp; then
                if uv tool upgrade beads-mcp; then
                    echo -e "${GREEN}✓ beads-mcp upgraded via uv tool${NC}"
                    echo -e "${YELLOW}  Note: Restart Claude Code or MCP session to use the new version${NC}"
                else
                    echo -e "${RED}✗ uv tool upgrade failed${NC}"
                fi
            else
                echo -e "${YELLOW}⚠ beads-mcp not installed via uv tool${NC}"
                echo -e "${YELLOW}  Install with: uv tool install beads-mcp${NC}"
            fi
        else
            echo -e "${YELLOW}⚠ Neither pip nor uv found${NC}"
            echo -e "${YELLOW}  Install beads-mcp with: pip install beads-mcp${NC}"
        fi
        echo ""
    fi

    # Install MCP from local source if requested
    if [ "$AUTO_MCP_LOCAL" = true ]; then
        echo "Installing beads-mcp from local source..."
        MCP_DIR="integrations/beads-mcp"

        if [ ! -d "$MCP_DIR" ]; then
            echo -e "${RED}✗ MCP directory not found: $MCP_DIR${NC}"
            exit 1
        fi

        # Use uv tool for installation (preferred for CLI tools)
        if command -v uv &> /dev/null; then
            if uv tool install --reinstall "./$MCP_DIR"; then
                echo -e "${GREEN}✓ beads-mcp installed from local source via uv${NC}"

                # Verify the installed version
                if command -v beads-mcp &> /dev/null; then
                    LOCAL_MCP_VERSION=$(python -c "import beads_mcp; print(beads_mcp.__version__)" 2>/dev/null || echo "unknown")
                    if [ "$LOCAL_MCP_VERSION" = "$NEW_VERSION" ]; then
                        echo -e "${GREEN}✓ Verified: beads-mcp version is $LOCAL_MCP_VERSION${NC}"
                    else
                        echo -e "${YELLOW}⚠ beads-mcp version is $LOCAL_MCP_VERSION (expected $NEW_VERSION)${NC}"
                    fi
                fi
            else
                echo -e "${RED}✗ uv tool install failed${NC}"
                echo -e "${YELLOW}  Try manually: uv tool install --reinstall ./$MCP_DIR${NC}"
            fi
        # Fallback to pip
        elif command -v pip &> /dev/null; then
            if pip install -e "./$MCP_DIR"; then
                echo -e "${GREEN}✓ beads-mcp installed from local source via pip${NC}"
                INSTALLED_MCP_VERSION=$(pip show beads-mcp 2>/dev/null | grep Version | awk '{print $2}')
                if [ "$INSTALLED_MCP_VERSION" = "$NEW_VERSION" ]; then
                    echo -e "${GREEN}✓ Verified: beads-mcp version is $INSTALLED_MCP_VERSION${NC}"
                else
                    echo -e "${YELLOW}⚠ beads-mcp version is $INSTALLED_MCP_VERSION (expected $NEW_VERSION)${NC}"
                fi
            else
                echo -e "${RED}✗ pip install failed${NC}"
            fi
        else
            echo -e "${YELLOW}⚠ Neither uv nor pip found${NC}"
            echo -e "${YELLOW}  Install uv: curl -LsSf https://astral.sh/uv/install.sh | sh${NC}"
        fi
        echo ""
    fi

    # Restart daemons if requested
    if [ "$AUTO_RESTART_DAEMONS" = true ]; then
        echo "Restarting bd daemons..."

        # Use the bd that was just installed (prefer GOPATH/bin which should be in PATH)
        BD_CMD="bd"
        if [ "$AUTO_INSTALL" = true ]; then
            # Use the freshly installed binary
            BD_CMD="$(go env GOPATH)/bin/bd"
        fi

        if command -v "$BD_CMD" &> /dev/null || [ -x "$BD_CMD" ]; then
            if "$BD_CMD" daemons killall --json 2>/dev/null; then
                echo -e "${GREEN}✓ All bd daemons killed (will auto-restart on next bd command)${NC}"
            else
                echo -e "${YELLOW}⚠ No daemons running or daemon killall failed${NC}"
            fi
        else
            echo -e "${YELLOW}⚠ bd command not found, cannot restart daemons${NC}"
        fi
        echo ""
    fi

    # Publish to npm if requested
    if [ "$AUTO_PUBLISH_NPM" = true ]; then
        echo "Publishing npm package..."
        NPM_DIR="npm-package"

        if [ ! -d "$NPM_DIR" ]; then
            echo -e "${RED}✗ npm package directory not found: $NPM_DIR${NC}"
            exit 1
        fi

        cd "$NPM_DIR"

        # Check if logged in
        if ! npm whoami &>/dev/null; then
            echo -e "${YELLOW}⚠ Not logged into npm. Run 'npm adduser' first.${NC}"
            cd ..
            exit 1
        fi

        if npm publish --access public; then
            echo -e "${GREEN}✓ Published @beads/bd@$NEW_VERSION to npm${NC}"
        else
            echo -e "${RED}✗ npm publish failed${NC}"
            cd ..
            exit 1
        fi

        cd ..
        echo ""
    fi

    # Publish to PyPI if requested
    if [ "$AUTO_PUBLISH_PYPI" = true ]; then
        echo "Publishing beads-mcp to PyPI..."
        MCP_DIR="integrations/beads-mcp"

        if [ ! -d "$MCP_DIR" ]; then
            echo -e "${RED}✗ MCP directory not found: $MCP_DIR${NC}"
            exit 1
        fi

        cd "$MCP_DIR"

        # Clean previous builds
        rm -rf dist/ build/ *.egg-info

        # Build the package
        echo "  Building package..."
        if command -v uv &> /dev/null; then
            if ! uv build; then
                echo -e "${RED}✗ uv build failed${NC}"
                cd ../..
                exit 1
            fi
        elif command -v python3 &> /dev/null; then
            if ! python3 -m build; then
                echo -e "${RED}✗ python build failed${NC}"
                cd ../..
                exit 1
            fi
        else
            echo -e "${RED}✗ Neither uv nor python3 found${NC}"
            cd ../..
            exit 1
        fi

        # Upload to PyPI
        echo "  Uploading to PyPI..."
        if command -v uv &> /dev/null; then
            if uv tool run twine upload dist/*; then
                echo -e "${GREEN}✓ Published beads-mcp@$NEW_VERSION to PyPI${NC}"
            else
                echo -e "${RED}✗ PyPI upload failed${NC}"
                echo -e "${YELLOW}  Ensure TWINE_USERNAME and TWINE_PASSWORD are set${NC}"
                echo -e "${YELLOW}  Or configure ~/.pypirc with credentials${NC}"
                cd ../..
                exit 1
            fi
        elif command -v twine &> /dev/null; then
            if twine upload dist/*; then
                echo -e "${GREEN}✓ Published beads-mcp@$NEW_VERSION to PyPI${NC}"
            else
                echo -e "${RED}✗ PyPI upload failed${NC}"
                cd ../..
                exit 1
            fi
        else
            echo -e "${RED}✗ twine not found. Install with: pip install twine${NC}"
            cd ../..
            exit 1
        fi

        cd ../..
        echo ""
    fi

    # Run chaos tests if requested (before commit/tag to catch issues early)
    if [ "$AUTO_RUN_CHAOS_TESTS" = true ]; then
        echo "Running chaos/corruption recovery tests..."
        echo "  (This tests database corruption recovery, may take a few minutes)"
        echo ""

        # Run chaos tests with the chaos build tag
        if go test -tags=chaos -timeout=10m ./cmd/bd/...; then
            echo -e "${GREEN}✓ Chaos tests passed${NC}"
            echo ""
        else
            echo -e "${RED}✗ Chaos tests failed${NC}"
            echo -e "${YELLOW}  Fix the failures before releasing.${NC}"
            exit 1
        fi

        # Also run E2E tests if available
        echo "Running E2E tests..."
        if go test -tags=e2e -timeout=10m ./cmd/bd/...; then
            echo -e "${GREEN}✓ E2E tests passed${NC}"
            echo ""
        else
            echo -e "${RED}✗ E2E tests failed${NC}"
            echo -e "${YELLOW}  Fix the failures before releasing.${NC}"
            exit 1
        fi
    fi

    # Check if cmd/bd/info.go has been updated with the new version
    if ! grep -q "\"$NEW_VERSION\"" cmd/bd/info.go; then
        echo -e "${YELLOW}Warning: cmd/bd/info.go does not contain an entry for $NEW_VERSION${NC}"
        echo -e "${YELLOW}  Please update versionChanges in cmd/bd/info.go with release notes${NC}"
        if [ "$AUTO_COMMIT" = true ]; then
             echo -e "${RED}Error: Cannot auto-commit without updating cmd/bd/info.go${NC}"
             exit 1
        fi
    fi

    # Auto-commit if requested
    if [ "$AUTO_COMMIT" = true ]; then
        echo "Creating git commit..."

        git add cmd/bd/version.go \
                .claude-plugin/plugin.json \
                .claude-plugin/marketplace.json \
                integrations/beads-mcp/pyproject.toml \
                integrations/beads-mcp/src/beads_mcp/__init__.py \
                npm-package/package.json \
                README.md \
                cmd/bd/templates/hooks/*

        # Add PLUGIN.md if it exists
        if [ -f "PLUGIN.md" ]; then
            git add PLUGIN.md
        fi

        # Add CHANGELOG.md if it exists
        if [ -f "CHANGELOG.md" ]; then
            git add CHANGELOG.md
        fi

        # Add pre-staged release files (info.go with release notes)
        if [ "$PRE_STAGED_RELEASE_FILES" = true ]; then
            echo -e "${GREEN}  Including pre-staged release files in commit${NC}"
            git add cmd/bd/info.go 2>/dev/null || true
        fi

        git commit -m "chore: Bump version to $NEW_VERSION

Updated all component versions:
- bd CLI: $CURRENT_VERSION → $NEW_VERSION
- Plugin: $CURRENT_VERSION → $NEW_VERSION
- MCP server: $CURRENT_VERSION → $NEW_VERSION
- npm package: $CURRENT_VERSION → $NEW_VERSION
- Documentation: $CURRENT_VERSION → $NEW_VERSION

Generated by scripts/bump-version.sh"

        echo -e "${GREEN}✓ Commit created${NC}"
        echo ""

        # Auto-tag if requested
        if [ "$AUTO_TAG" = true ]; then
            echo "Creating git tag v$NEW_VERSION..."
            git tag -a "v$NEW_VERSION" -m "Release v$NEW_VERSION"
            echo -e "${GREEN}✓ Tag created${NC}"
            echo ""
        fi

        # Auto-push if requested
        if [ "$AUTO_PUSH" = true ]; then
            echo "Pushing to origin..."
            git push origin main
            git push origin "v$NEW_VERSION"
            echo -e "${GREEN}✓ Pushed to origin${NC}"
            echo ""
            echo -e "${GREEN}Release v$NEW_VERSION initiated!${NC}"
            echo "GitHub Actions will build artifacts in ~5-10 minutes."
            echo "Monitor: https://github.com/steveyegge/beads/actions"
        elif [ "$AUTO_TAG" = true ]; then
            echo "Next steps:"
            if [ "$AUTO_INSTALL" = false ]; then
                echo -e "  ${YELLOW}--install${NC}  # Install bd to ~/go/bin AND ~/.local/bin"
            fi
            if [ "$AUTO_MCP_LOCAL" = false ]; then
                echo -e "  ${YELLOW}--mcp-local${NC}  # Install beads-mcp from local source"
            fi
            if [ "$AUTO_RESTART_DAEMONS" = false ]; then
                echo -e "  ${YELLOW}--restart-daemons${NC}  # Restart daemons to pick up new version"
            fi
            echo "  git push origin main"
            echo "  git push origin v$NEW_VERSION"
        else
            echo "Next steps:"
            if [ "$AUTO_INSTALL" = false ]; then
                echo -e "  ${YELLOW}--install${NC}  # Install bd to ~/go/bin AND ~/.local/bin"
            fi
            if [ "$AUTO_MCP_LOCAL" = false ]; then
                echo -e "  ${YELLOW}--mcp-local${NC}  # Install beads-mcp from local source"
            fi
            if [ "$AUTO_RESTART_DAEMONS" = false ]; then
                echo -e "  ${YELLOW}--restart-daemons${NC}  # Restart daemons to pick up new version"
            fi
            echo "  git push origin main"
            echo "  git tag -a v$NEW_VERSION -m 'Release v$NEW_VERSION'"
            echo "  git push origin v$NEW_VERSION"
        fi
    else
        echo "Review the changes above."
        echo ""
        echo "Quick local setup (use --all for all local steps):"
        echo -e "  $0 $NEW_VERSION ${YELLOW}--all${NC}"
        echo ""
        echo "Or step by step:"
        if [ "$AUTO_INSTALL" = false ]; then
            echo -e "  ${YELLOW}--install${NC}         # Install bd to ~/go/bin AND ~/.local/bin"
        fi
        if [ "$AUTO_MCP_LOCAL" = false ]; then
            echo -e "  ${YELLOW}--mcp-local${NC}       # Install beads-mcp from local source"
        fi
        if [ "$AUTO_RESTART_DAEMONS" = false ]; then
            echo -e "  ${YELLOW}--restart-daemons${NC} # Restart daemons to pick up new version"
        fi
        echo ""
        echo "Publishing (after tag is pushed, CI handles this automatically):"
        echo -e "  ${YELLOW}--publish-npm${NC}     # Publish @beads/bd to npm"
        echo -e "  ${YELLOW}--publish-pypi${NC}    # Publish beads-mcp to PyPI"
        echo -e "  ${YELLOW}--publish-all${NC}     # Publish to both npm and PyPI"
        echo ""
        echo "Full release (with git commit/tag/push):"
        echo "  $0 $NEW_VERSION --commit --tag --push --all"
        echo ""
        echo "Note: npm/PyPI publishing happens automatically via GitHub Actions"
        echo "when a tag is pushed. Use --publish-* only for manual releases."
    fi
}

main "$@"
