---
name: version-bump
description: Bump the package version across all versioned filenames, imports, READMEs, HTML files, and package.json exports in the Cahir project.
---

# version-bump

This skill handles version bumping across the Cahir project — a task that involves renaming ~19 versioned files, updating ~18 files with version strings in their content, rebuilding dist/, and syncing static/js/ copies.

## When to Use

Use this skill when:
- A **patch**, **minor**, or **major** version bump is needed
- The user says something like "bump version", "update version to X.Y.Z", "prepare release"
- A new version is being prepared for `npm publish`

## How It Works

The project uses **version-stamped filenames** for better CDN UX (e.g., `simple-chat.0.0.10.es.js`). On each version bump, all these filenames and internal references must be updated consistently.

A companion bash script handles this automatically:

```
scripts/version-bump.sh
```

## Steps

### 1. Dry-run first (recommended)

Always preview what will happen before making changes:

```bash
bash scripts/version-bump.sh <NEW_VERSION> --dry-run
```

This walks through ALL phases showing exactly what would happen — backup targets, npm version changes, mini-diffs for every content change (line-by-line before→after), file renames, build, and static sync — without modifying anything.

### 2. Run the bump

```bash
bash scripts/version-bump.sh <NEW_VERSION>
```

The script will:
1. Read the current version from `package.json`
2. Discover all versioned files dynamically (via `find` and `grep`)
3. Show a summary and ask for confirmation
4. **Phase 0:** Back up all affected files to `olderVersions/` (skip with `--no-backup`)
5. **Phase 0.5:** `npm version <NEW> --no-git-tag-version` to update `package.json` version field + `package-lock.json`
6. **Phase 1:** `sed -i` replace old version → new version in file contents (export paths, imports, READMEs, etc.) + `git add`. `package-lock.json` is never touched by sed.
7. **Phase 2:** `git mv` all versioned filenames to new version (or `mv` + `git add` for untracked)
8. **Phase 3:** Run `npm run build` to regenerate `dist/` files (aborts on failure)
9. **Phase 4:** Copy fresh builds to `static/js/` + clean up old copies
10. **Phase 5:** Verify no stale old-version references remain

### 3. Review and commit

```bash
git diff --staged
git commit -m "chore: bump version to <NEW_VERSION>"
git tag v<NEW_VERSION>  # optional
npm publish
```

## What Gets Changed

### Files RENAMED (dynamically discovered — new components auto-included):

**dist/** — 6 files (also regenerated by `npm run build`):
- `cahir.<VERSION>.evergreen.es.js`
- `cahir.<VERSION>.evergreen.es.min.js`
- `cahir.<VERSION>.evergreen.umd.cjs`
- `cahir.<VERSION>.evergreen.umd.js`
- `cahir.<VERSION>.evergreen.umd.min.cjs`
- `cahir.<VERSION>.evergreen.umd.min.js`

**collections/DOM/** — 3 files:
- `ch.<VERSION>.cjs`
- `ch.<VERSION>.es.js`
- `ch.<VERSION>.js`

**components/\*/** — 2 files per component (`.es.js` + `.js`):
- `<component-name>.<VERSION>.es.js`
- `<component-name>.<VERSION>.js`

**static/js/** — 2 files (copies for GitHub Pages):
- `cahir.<VERSION>.evergreen.umd.js`
- `ch.<VERSION>.js`

### Files with CONTENT updates (dynamically discovered):

- `package.json` — version field (via `npm version`) + exports paths (via `sed`)
- `README.md` — CDN URLs and file references
- `index.html` — script src tags
- `components/examples/index.html` — script src tags
- `components/*/README.md` — CDN URLs in each component's docs
- `collections/DOM/ch.es.js` + `ch.<VERSION>.es.js` — import paths
- `components/*/*.es.js` + `*.<VERSION>.es.js` — import paths

### Files that are NOT touched:
- `.cjs` files — no version strings inside
- Non-ES `.js` component files (e.g., `simple-chat.js`) — no version strings inside
- `rollup.config.evergreen.js` — reads version from env dynamically
- `CHANGELOG.md` — excluded from automated replacement (update manually)
- `package-lock.json` — managed by `npm version`, never touched by `sed`
- `src/` — source files rebuilt via `npm run build` using `npm_package_version` env var
- `debug/` — not committed (in `.gitignore`)

## Adding New Components

When a new component is added under `components/`:

1. Follow the existing naming convention:
   - `components/<componentName>/<component-name>.<VERSION>.es.js`
   - `components/<componentName>/<component-name>.<VERSION>.js`
   - `components/<componentName>/<component-name>.es.js` (versionless copy)
   - `components/<componentName>/<component-name>.js` (versionless copy)

2. The `.es.js` files should import from `../../collections/DOM/ch.<VERSION>.es.js`

3. Add the component to `package.json` exports:
   ```json
   "./components/<componentName>": {
     "browser": "./components/<componentName>/<component-name>.<VERSION>.js",
     "import": "./components/<componentName>/<component-name>.<VERSION>.es.js"
   }
   ```

4. Add the component script tag to `components/examples/index.html`

5. **The bash script will automatically discover the new component** on the next version bump — no script changes needed, as it uses `find` and `grep` to dynamically locate versioned files.

## Flags

| Flag | Description |
|------|-------------|
| `--dry-run` | Walk through all phases showing exactly what would change (mini-diffs, renames, etc.) without modifying anything |
| `--yes` or `-y` | Skip confirmation prompt (for CI/automation) |
| `--no-backup` | Skip the pre-change backup to `olderVersions/` |

## Safety

- The script only operates within the git project root
- Validates semver format before proceeding
- Backs up all affected files to `olderVersions/backup-{VERSION}-{TIMESTAMP}/` before changes
- Shows a full summary before making any changes
- Uses `git mv` for better rename tracking (smaller diffs)
- Stages all version-bumped files (`git add`) for commit
- Aborts if `npm run build` fails
- Verifies no stale references remain after completion
- Excludes `CHANGELOG.md` from automated replacement and content discovery (update manually)
- Excludes `src/`, `debug/`, `olderVersions/` from scanning
- Auto-excludes gitignored paths via `git check-ignore` (second pass on top of manual exclusions)
- All `grep` calls use `-F` (fixed-string mode) so dots in version strings are literal, not regex wildcards
- `sed` escapes dots in version strings for regex safety (`0.0.10` → `0\.0\.10`)
- Phase 5 verifies both file contents AND filenames for stale old-version references
- Dry-run walks through every phase with full reporting (not just a summary)
- Mini-diffs show every line that will change, before and after, with line numbers
