---
description: "Internal vs public repo and publishing process"
globs:
alwaysApply: false
---

# Publishing: Internal vs Public Repos

## Repository Structure

**Two repositories with different purposes:**

### `{{GITHUB_ORG}}/{{INTERNAL_REPO_NAME}}` (Internal)
- **Purpose:** Product development (source of truth)
- **Audience:** {{ORG_NAME}} team only
- **Contains:** All development files, scripts, tests, internal docs
- **Location:** All work happens here

### `{{GITHUB_ORG}}/{{PUBLIC_REPO_NAME}}` (Public)
- **Purpose:** Customer-facing distribution
- **Audience:** Customers who install via git submodule
- **Contains:** Published subset of files (not everything)
- **Location:** Customers install as `.{{PROJECT_SHORTNAME}}/` submodule

---

## What Gets Published

**Published to `{{PUBLIC_REPO_NAME}}` repo:**
- ✅ `dist/` - Compiled/processed files
- ✅ `commands/` - Customer-facing commands (excludes `00-internal/`)
- ✅ `templates/` - Template files for customer use
- ✅ `rules/` - Cursor rules for customers
- ✅ Legal docs (LICENSE, CLA.md, CONTRIBUTING.md, LICENSE-COMMERCIAL)
- ✅ Installation scripts (install.cjs, setup.sh)
- ✅ README.md (customer documentation)
- ✅ package.json (customer version)

**Stays in `{{INTERNAL_REPO_NAME}}` only:**
- ❌ Development scripts (scripts/ directory)
- ❌ Internal documentation
- ❌ Test files
- ❌ Build infrastructure
- ❌ Team-specific configs
- ❌ Internal commands (`.cursor/commands/00-internal/`)

---

## Publishing Process

**Single unified approach:**

### GitHub API Publishing (PR-Based)
- **Method:** GitHub API-driven workflow with PR creation, CI validation, and release generation
- **Command:** `npx tsx scripts/publish-distribution.ts --push`
- **Environment:** Requires `GITHUB_TOKEN` with repo scope
- **Stats:** ~566 compiled files in dist/
- **Speed:** Moderate (GitHub API latency)
- **Reliability:** High (API-based, auditable, PR-based workflow)
- **Use cases:** 
  - Local development publishing
  - CI/CD automated publishing
  - Multi-team environments
- **Workflow Phases:**
  1. Run pre-publish audit
  2. Verify distribution is built and ready
  3. Build distribution (compile TypeScript utilities)
  4. Create working branch via GitHub API
  5. Batch file updates with rate limit delays
  6. Commit changes
  7. Create pull request
  8. Poll CI status
  9. Generate release
- **Location:** `scripts/utils/publish-distribution-command.ts`

**Flags:**
- `--push` - Push changes to GitHub after validation (default: false)
- `--force` - Override pre-publish audit warnings (not recommended)
- `--dry-run` - Preview only (shows PR title and body without creating)

---

## Pre-Publish Validation

**Critical step before any publishing:**

The publishing process runs a pre-publish audit that validates:
- Repository is in valid state
- Required files exist
- No breaking changes detected
- Build passes linting and tests

**Command:** `npm run pre-publish-audit`

**If audit fails:**
- Publishing stops with error message
- Fix issues and retry
- Use `--force` flag to override warnings (not recommended)

```bash
# Normal publish (with audit)
npx tsx scripts/publish-distribution.ts --push

# Preview only (no changes)
npx tsx scripts/publish-distribution.ts --dry-run

# Override audit warnings (use carefully)
npx tsx scripts/publish-distribution.ts --force --push
```

---

## Build & Compilation Step

**Before publishing, TypeScript utilities must be compiled:**

The `build-distribution.sh` script:
1. Compiles TypeScript source files to JavaScript
2. Copies compiled files to `dist/scripts/utils/`
3. Adds version headers to each compiled file
4. Verifies imports work correctly

**Automatic:** The publishing script runs this automatically if needed

**Manual build:**
```bash
npm run build
# or
./scripts/build-distribution.sh
```

**Output:** 
- Compiled `.js` files in `dist/scripts/utils/`
- Source maps (`.js.map`) for debugging
- Version headers (comments) added to each file

---

## Publishing Workflow

1. **Develop in `{{INTERNAL_REPO_NAME}}`**
   - All work on `dev` branch
   - Tests pass
   - PR merged to `dev`

2. **Prepare for release**
   - Version bump in package.json
   - Changelog updated
   - Build compiles TypeScript to JavaScript

3. **Run pre-publish audit**
   - `npm run pre-publish-audit`
   - Validates repository state
   - Checks for breaking changes

4. **Publish to `{{PUBLIC_REPO_NAME}}`**
   - Run publishing script via GitHub API
   - Creates PR with distribution changes
   - Validates CI checks pass
   - Merges PR and creates release

5. **Customer updates**
   - Customers run `git submodule update` to fetch
   - They control when to update (version pinning)

---

## GitHub API Publishing Details

**What happens in the GitHub API workflow:**

1. **Verification Phase:**
   - Pre-publish audit runs and must pass
   - Distribution files checked for completeness
   - File count and size verified

2. **Build Phase:**
   - TypeScript compiled if needed
   - Output placed in `dist/scripts/utils/`
   - Verification of imports

3. **API Sync Phase:**
   - Create new working branch on public repo
   - Batch file updates with 1-second delays between batches
   - Handles GitHub rate limits gracefully (5000 req/hour)
   - Only uploads changed files (delta sync)

4. **Commit & PR Phase:**
   - All changes committed with descriptive message
   - GitHub PR created to `main` branch
   - PR title includes version information
   - PR body includes file list and change summary

5. **CI Polling Phase:**
   - Continuously polls PR status
   - Waits for GitHub Actions CI to complete
   - Displays test results

6. **Release Generation Phase:**
   - After PR approval and merge
   - Creates GitHub release with auto-generated notes
   - Tags with semantic version
   - Adds release description

---

## Environment Setup

**Required for publishing:**

```bash
# Set GitHub token (must have repo scope)
export GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx

# Verify token works
curl -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/user

# Then publish
npx tsx scripts/publish-distribution.ts --push
```

**Token scopes required:**
- `repo` - Full control of repositories
- `workflows` - Manage GitHub Actions (optional, for CI polling)

---

## Rate Limiting & Delays

**GitHub API rate limits:**
- Authenticated: 5,000 requests/hour
- Publishing batches: 1-second delay between batches
- Large distribution (~560 files): Automatically handles batching

**The script automatically:**
- Batches file uploads (50 files per batch)
- Delays 1 second between batches
- Checks remaining rate limit before continuing
- Warns if rate limit is low

---

## Key Constraints

**Never:**
- Publish internal implementation details
- Include team-specific configurations
- Publish untested code to `{{PUBLIC_REPO_NAME}}`
- Break customer installations
- Publish internal commands (00-internal/)
- Use personal/expired GitHub tokens
- Publish without running pre-audit

**Always:**
- Run `npm run pre-publish-audit` before publishing
- Use `--dry-run` to preview changes first
- Set `GITHUB_TOKEN` environment variable
- Verify CI checks pass before merging PR
- Document breaking changes
- Provide migration guides for major changes
- Ensure TypeScript is compiled before publish

---

## Related Files

- **Publishing scripts:** 
  - `scripts/publish-distribution.ts` - Main publication orchestrator
  - `scripts/utils/publish-distribution-command.ts` - GitHub API publishing logic
  - `scripts/publish-now.mjs` - Quick publish wrapper
  - `scripts/build-distribution.sh` - TypeScript compilation
- **Published commands:** `.cursor/commands/07-publish/` 
  - `/build-distribution` - Build distribution locally
  - `/publish-distribution` - Publish to {{PUBLIC_REPO_NAME}} repo
  - `/pre-publish-checklist` - Pre-publication validation
- **GitHub API usage:** See `03-github.mdc`
- **Deployment modes:** See `09-mode-routing.mdc`
