# Design: BRAT-compatible packaging and releases

## Context

The obsidian-opencode plugin is currently in early development (v0.1.0). The repository contains `main.js` which is a build artifact, while `styles.css` is a static source file. Users must manually clone/build to install. This creates friction for beta testers and doesn't scale.

BRAT (Beta Reviewer's Auto-update Tool) is the community standard for beta plugin distribution. It works by monitoring GitHub releases and downloading `manifest.json`, `main.js`, and `styles.css` from release assets.

Current state:
- Uses Bun as package manager and build tool
- Has esbuild-based build system producing `main.js`
- Has CI workflow for testing but no release automation
- `manifest.json` exists but isn't synchronized with `package.json`
- `main.js` build artifact is already in `.gitignore`

## Goals / Non-Goals

**Goals:**
- Enable one-click installation via BRAT for beta testers
- Automate release creation on version tag push
- Ensure `manifest.json` version always matches release tag
- Remove build artifacts from git repository
- Provide simple version bumping commands for developers

**Non-Goals:**
- Marketplace submission (out of scope for this change)
- Automated changelog generation
- Multi-platform release assets (only JS/CSS files, no binaries)
- Version pinning or rollback mechanisms
- Signing or verification of releases

## Decisions

### 1. Use `bun pm version` for version management

**Rationale:** Bun's built-in version manager updates `package.json`, creates a git commit, and tags automatically. This is simpler than custom scripts and matches the existing Bun-based toolchain.

**Alternatives considered:**
- Custom Node.js script: More code to maintain, requires parsing JSON
- `standard-version` or `semantic-release`: Too complex for early-stage project
- Manual editing: Error-prone, inconsistent

### 2. Synchronized version updates: package.json + manifest.json

**Approach:** Use Bun's npm lifecycle scripts. When `bun pm version` runs, it executes the "version" script after updating package.json but before creating the commit. In this script, we read the new version from package.json and update manifest.json. Both files are then committed together with the same version.

**Rationale:** Keeps both files in sync at all times in the repository. The manifest.json always reflects the current package.json version, making it clear what version is being developed. This also simplifies the release workflow since manifest.json is already correct.

**Implementation:**
1. Add a "version" script to package.json that runs a sync script
2. The sync script reads package.json version and writes it to manifest.json
3. Stage manifest.json with `git add` so it's included in the version commit
4. `bun pm version` handles the commit and tag automatically

**Alternatives considered:**
- Two-stage (release-time sync): Manifest in repo stays out of sync with package.json, confusing during development
- Custom version script: Would lose Bun's built-in lifecycle management
- Pre-commit hook: Would run on every commit, not just version bumps

### 3. Tag-triggered GitHub Actions workflow

**Approach:** Workflow triggers on `v*` tag push (e.g., `v0.1.0`). This is explicit and intentional - releases happen only when a developer decides to tag.

**Rationale:** Prevents accidental releases from every commit. Tag-based triggers are standard for GitHub releases and integrate well with `bun pm version` which creates tags.

**Alternatives considered:**
- Manual workflow dispatch: More steps, easier to forget
- Release on every push to main: Too frequent, no control
- Release on merged PR: Good for continuous deployment, but we want explicit versioning

### 4. Mark all releases as `prerelease: true` during beta

**Approach:** The GitHub Actions workflow will always set `prerelease: true` on releases. This is hardcoded until we're ready for marketplace.

**Rationale:** Signals to users and BRAT that these are beta versions. Once we submit to marketplace, we'll change this to `prerelease: false` for stable releases.

**Alternatives considered:**
- Detect from version string (e.g., `-beta` suffix): More complex, inconsistent with BRAT expectations
- Manual toggle in workflow: Easy to forget

### 5. Build artifact (main.js) only in releases

**Approach:** `main.js` is already in `.gitignore`. The GitHub Actions workflow will build it and attach to releases. `styles.css` is a static source file and remains tracked in git.

**Rationale:** `main.js` is generated by esbuild and should not be in git. `styles.css` is hand-written and should be version controlled. Both are included in releases for BRAT distribution.

**Trade-off:** Repository won't have `main.js` after clone - developers must run `bun install && bun run build`. Acceptable since this is a development workflow.

## Risks / Trade-offs

| Risk | Mitigation |
|------|------------|
| Tag pushed but release fails | Workflow will fail visibly; developer can delete tag and retry, or manually create release |
| Version mismatch between package.json and manifest.json in release | Workflow enforces manifest.json version is updated from package.json before build |
| Users can't install from git clone anymore | Document that BRAT is the intended install method for users; git clone is for developers only |
| Build fails on CI but works locally | Existing CI already builds successfully; release workflow uses same build command |
| Forgetting to use `bun pm version` vs manual tag | Document in CONTRIBUTING.md; consider adding a check that verifies tag matches package.json version |

## Migration Plan

1. **Prepare repository:**
   - Verify `main.js` is in `.gitignore` (already done)
   - Keep `styles.css` tracked in git (it's a static source file)

2. **Add version scripts:**
   - Add `version:patch`, `version:minor`, `version:major` to package.json scripts

3. **Create release workflow:**
   - Add `.github/workflows/release.yml`

4. **Test release process:**
   - Run `bun run version:patch` locally
   - Verify tag is created
   - Push tag and verify workflow creates release
   - Test installing via BRAT

5. **Update documentation:**
   - Add BRAT installation section to README
   - Add release process to CONTRIBUTING.md

## Open Questions

_None at this time - design is ready for implementation._
