From addb57b05c8ce1624c5fcdb0ae56d3cf8bbfb14d Mon Sep 17 00:00:00 2001 From: wang1212 Date: Thu, 27 Aug 2026 13:51:42 +0800 Subject: [PATCH 1/8] docs: add full platform binary install instructions, remove AGENTS.md reference --- .gitignore | 1 + README.md | 23 ++++++++++++++++------- README.zh-CN.md | 23 ++++++++++++++++------- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 51b13d6..7b2fcf7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ dist/ bin/ package-lock.json pnpm-lock.yaml +skills-lock.json diff --git a/README.md b/README.md index 6bdc044..9dc681c 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,7 @@ A CLI tool for calling WeaveFox server-side open capabilities via the MCP protocol. Built for developers and AI agents. -> For development guide, see [AGENTS.md](./AGENTS.md) for project structure, build commands, and coding conventions. -> -> [中文文档](./README.zh-CN.md) +[中文文档](./README.zh-CN.md) ## Install @@ -30,12 +28,23 @@ npm i -g @weavefox/cli Download from [GitHub Release](https://github.com/weavefox/weavefox-cli/releases) for your platform: ```bash -# macOS Apple Silicon -curl -fsSL https://github.com/weavefox/weavefox-cli/releases/latest/download/wf-darwin-arm64 -o wf -chmod +x wf && ./wf tools +# macOS (Apple Silicon) +curl -fsSL https://github.com/weavefox/weavefox-cli/releases/latest/download/wf-darwin-arm64 -o /usr/local/bin/wf + +# macOS (Intel) +curl -fsSL https://github.com/weavefox/weavefox-cli/releases/latest/download/wf-darwin-x64 -o /usr/local/bin/wf + +# Linux (x64) +curl -fsSL https://github.com/weavefox/weavefox-cli/releases/latest/download/wf-linux-x64 -o /usr/local/bin/wf + +# Linux (ARM64) +curl -fsSL https://github.com/weavefox/weavefox-cli/releases/latest/download/wf-linux-arm64 -o /usr/local/bin/wf + +chmod +x /usr/local/bin/wf +wf tools ``` -Platforms: `darwin-arm64` `darwin-x64` `linux-x64` `linux-arm64` `windows-x64.exe` +Windows: download `wf-windows-x64.exe` from [Releases](https://github.com/weavefox/weavefox-cli/releases). ### AI Agent Skill diff --git a/README.zh-CN.md b/README.zh-CN.md index f0a68e3..1982b15 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -9,9 +9,7 @@ 通过 MCP 协议调用 WeaveFox 服务端开放能力的命令行工具,面向开发者和 AI Agent。 -> 开发指南请参阅 [AGENTS.md](./AGENTS.md) 了解项目结构、构建命令和编码规范。 -> -> [English](./README.md) +[English](./README.md) ## 安装 @@ -30,12 +28,23 @@ npm i -g @weavefox/cli 从 [GitHub Release](https://github.com/weavefox/weavefox-cli/releases) 下载对应平台: ```bash -# macOS Apple Silicon -curl -fsSL https://github.com/weavefox/weavefox-cli/releases/latest/download/wf-darwin-arm64 -o wf -chmod +x wf && ./wf tools +# macOS (Apple Silicon) +curl -fsSL https://github.com/weavefox/weavefox-cli/releases/latest/download/wf-darwin-arm64 -o /usr/local/bin/wf + +# macOS (Intel) +curl -fsSL https://github.com/weavefox/weavefox-cli/releases/latest/download/wf-darwin-x64 -o /usr/local/bin/wf + +# Linux (x64) +curl -fsSL https://github.com/weavefox/weavefox-cli/releases/latest/download/wf-linux-x64 -o /usr/local/bin/wf + +# Linux (ARM64) +curl -fsSL https://github.com/weavefox/weavefox-cli/releases/latest/download/wf-linux-arm64 -o /usr/local/bin/wf + +chmod +x /usr/local/bin/wf +wf tools ``` -平台: `darwin-arm64` `darwin-x64` `linux-x64` `linux-arm64` `windows-x64.exe` +Windows: 从 [Releases](https://github.com/weavefox/weavefox-cli/releases) 下载 `wf-windows-x64.exe`。 ### AI Agent Skill From b4c9a76dd66b22e2a48b50e1463fa1ad9725e25b Mon Sep 17 00:00:00 2001 From: wang1212 Date: Thu, 27 Aug 2026 13:55:02 +0800 Subject: [PATCH 2/8] fix: release script works with protected main branch --- scripts/release.sh | 70 ++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/scripts/release.sh b/scripts/release.sh index 0d25702..c3d99e5 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -1,59 +1,49 @@ #!/usr/bin/env bash # -# Bump version, commit, tag, and push. -# This triggers the GitHub Actions release pipeline (NPM OIDC + binary + GitHub Release). +# Create release tag from the current commit on main. +# Run this AFTER the version change has been merged to main via PR. +# +# Prerequisites: +# 1. Version in package.json was bumped and merged to main via PR +# 2. You are on the main branch, up to date with origin # # Usage: -# bash scripts/release.sh patch # 0.0.1 -> 0.0.2 -# bash scripts/release.sh minor # 0.0.1 -> 0.1.0 -# bash scripts/release.sh major # 0.0.1 -> 1.0.0 -# bash scripts/release.sh 1.2.3 # explicit version +# bash scripts/release.sh # tag current version from package.json +# bash scripts/release.sh 0.0.2 # explicit version # set -euo pipefail -BUMP="${1:-patch}" PKG_FILE="package.json" -# Read current version -CURRENT=$(node -p "require('./$PKG_FILE').version") - -# Calculate next version -if [[ "$BUMP" == "patch" || "$BUMP" == "minor" || "$BUMP" == "major" ]]; then - NEXT=$(node -e " - const semver = require('./$PKG_FILE').version.split('.'); - const map = { patch: 2, minor: 1, major: 0 }; - const idx = map['$BUMP']; - semver[idx] = (parseInt(semver[idx]) + 1).toString(); - for (let i = idx + 1; i < 3; i++) semver[i] = '0'; - console.log(semver.join('.')); - ") -else - NEXT="$BUMP" +# Verify we're on main +BRANCH=$(git branch --show-current) +if [ "$BRANCH" != "main" ]; then + echo "Error: must be on main (currently on '$BRANCH')" + echo "Run: git checkout main && git pull" + exit 1 fi -echo "Releasing: $CURRENT -> $NEXT" +# Determine version +VERSION="${1:-$(node -p "require('./$PKG_FILE').version")}" +TAG="v${VERSION}" # Validate format -if ! [[ "$NEXT" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "Invalid version: $NEXT" +if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Invalid version: $VERSION" + exit 1 +fi + +# Check tag doesn't already exist +if git rev-parse "$TAG" >/dev/null 2>&1; then + echo "Error: tag $TAG already exists" exit 1 fi -# Update package.json -node -e " - const fs = require('fs'); - const pkg = JSON.parse(fs.readFileSync('$PKG_FILE', 'utf-8')); - pkg.version = '$NEXT'; - fs.writeFileSync('$PKG_FILE', JSON.stringify(pkg, null, 2) + '\n'); -" - -# Commit + tag + push -git add "$PKG_FILE" -git commit -m "chore: release v$NEXT" -git tag "v$NEXT" -git push origin main -git push origin "v$NEXT" +echo "Creating tag $TAG for version $VERSION..." + +git tag "$TAG" +git push origin "$TAG" echo "" -echo "Done. v$NEXT pushed. GitHub Actions release pipeline will start automatically." +echo "Done. $TAG pushed. Release pipeline will start automatically." echo "Check: https://github.com/weavefox/weavefox-cli/actions/workflows/release.yml" From 41f5efc7d5e7f7329dd389db9567a3edb40b30e7 Mon Sep 17 00:00:00 2001 From: wang1212 Date: Thu, 27 Aug 2026 14:00:49 +0800 Subject: [PATCH 3/8] fix: restore release script command --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index ae87b3c..a082cd7 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,8 @@ "lint:fix": "tsc --noEmit", "clean": "rm -rf dist bin", "clean:deps": "rm -rf node_modules", - "prepare": "husky" + "prepare": "husky", + "release": "bash scripts/release.sh" }, "dependencies": { "@modelcontextprotocol/sdk": "^1.30.0", From 754301f74030cf9c22b01ef7a83cf59cec3a429a Mon Sep 17 00:00:00 2001 From: wang1212 Date: Thu, 27 Aug 2026 14:07:25 +0800 Subject: [PATCH 4/8] docs: update AGENTS.md with release process, skills, husky, pnpm v12 --- AGENTS.md | 58 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 5ef1060..1b1651e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ ## Overview -`@weavefox/cli` is a generic MCP client CLI. Connects to any MCP server over Streamable HTTP, supports Bearer/custom-header auth or no auth. Dual-channel distribution (npm + standalone binary). +`@weavefox/cli` is a generic MCP client CLI. Connects to any MCP server over Streamable HTTP, supports Bearer/custom-header auth or no auth. Dual-channel distribution (npm + standalone binary). Includes an AI Agent skill for cross-platform agent integration. ## Tech Stack @@ -13,6 +13,7 @@ - npm build: tsup - Binary build: bun build --compile (cross-compile 5 platforms) - Dev runner: tsx (no compilation needed) +- Commit lint: commitlint + husky (conventional commits) ## Directory Structure @@ -24,36 +25,65 @@ weavefox-cli/ │ ├── mcp-client.ts # MCP client (StreamableHTTP + configurable auth + errors) │ └── format.ts # Output: JSON mode / human mode ├── scripts/ -│ └── build-bin.sh # Bun cross-compile (5 platforms + SHA256) +│ ├── build-bin.sh # Bun cross-compile (5 platforms + SHA256) +│ └── release.sh # Tag current version and push (triggers release pipeline) +├── skills/ +│ └── weavefox/ +│ ├── SKILL.md # AI Agent skill (install via skills.sh) +│ └── scripts/ +│ └── install.sh ├── .github/workflows/ │ ├── ci.yml # CI: type check + build + binary smoke test │ └── release.yml # Release: NPM OIDC + GitHub Release +├── .husky/ +│ └── commit-msg # commitlint hook +├── pnpm-workspace.yaml # pnpm v12 config (allowBuilds: esbuild) +├── commitlint.config.mjs ├── tsup.config.ts ├── tsconfig.json -└── package.json +├── package.json +├── README.md +├── README.zh-CN.md +└── AGENTS.md ``` ## Commands ```bash -pnpm dev # tsx runs TS directly -pnpm lint # tsc --noEmit -pnpm build # tsup -> dist/index.js -pnpm build:bin # Bun binary (current platform) -pnpm build:bin:all # Bash script: cross-compile 5 platforms -pnpm clean # rm -rf dist bin +pnpm dev # tsx runs TS directly +pnpm lint # tsc --noEmit +pnpm build # tsup -> dist/index.js +pnpm build:bin # Bun binary (current platform) +pnpm build:bin:all # Cross-compile 5 platforms +pnpm clean # rm -rf dist bin +pnpm release # Tag current version and push (run on main after pull) ``` ## CLI Subcommands | Command | Description | -| --------- | ------------- | +|---------|-------------| | `login --key ` | Persist API Key | | `logout [--purge]` | Clear credentials / remove config dir | | `tools` | List MCP tools + schemas | | `call [--kv ...]` | Invoke a tool (`key=value` scalars, `key:=value` JSON) | | `config [--set-url ...] [--set-auth-header ...]` | View / modify configuration | +Global options: `--json`, `--url `, `--auth-header
`, `--version` + +## Release Process + +Main branch is protected — all changes go through PR. + +1. Bump version in `package.json`, commit, push to a branch, create PR +2. Merge PR to main +3. `git checkout main && git pull` +4. `pnpm release` — tags current version and pushes tag +5. Tag push triggers `release.yml`: + - NPM publish via OIDC -> binary cross-compile -> GitHub Release + +Manual alternative: `git tag v0.0.2 && git push origin v0.0.2` + ## Key Design ### Transport: StreamableHTTP @@ -63,7 +93,7 @@ Server uses `WebStandardStreamableHTTPServerTransport`. Client matches with `Str ### Auth: Configurable - Default: `Authorization: Bearer ` -- Custom: `wf config --set-auth-header "X-API-Key"` → key sent as-is +- Custom: `wf config --set-auth-header "X-API-Key"` or `--auth-header` global option - No key: no auth header sent at all (public MCPs work out of the box) - Env: `WEAVEFOX_API_KEY`, `WEAVEFOX_MCP_URL`, `WEAVEFOX_AUTH_HEADER` @@ -73,7 +103,7 @@ Server uses `WebStandardStreamableHTTPServerTransport`. Client matches with `Str Env vars > Config file > Defaults ``` -`--url` and `--json` are per-invocation overrides, don't write to file. +`--url`, `--auth-header`, `--json` are per-invocation overrides, don't write to file. ### --kv Syntax (httpie-style) @@ -84,7 +114,7 @@ Env vars > Config file > Defaults | Channel | Output | Target | |---------|--------|--------| -| npm (`pnpm build`) | `dist/index.js` 9.4KB | Node developers, npx | +| npm (`pnpm build`) | `dist/index.js` 11KB | Node developers, npx | | Binary (`pnpm build:bin:all`) | 5 platform standalone binaries | No Node.js environment | ### CI/CD: OIDC Trusted Publishing @@ -97,8 +127,10 @@ Env vars > Config file > Defaults ## Coding Conventions - ESM imports must include `.js` suffix: `import { getConfig } from './config.js'` +- JSON imports use `with { type: 'json' }` (not deprecated `assert`) - Keep imports in sync with code changes (lint removes unused imports) - SDK return types: `Awaited>` inference, not direct Schema types - Errors: `WeaveFoxCliError` with `code` field; no `process.exit()` except login - Comments: only document WHY, never restate WHAT (function names already do that) - `withClient()` closure manages MCP client lifecycle (create -> fn -> close) +- Commit messages: conventional commits (`feat:`, `fix:`, `docs:`, `chore:`), enforced by husky + commitlint From 62e4424d8fc4c16ee21ea0b8f9cd4005472ed7fb Mon Sep 17 00:00:00 2001 From: wang1212 Date: Thu, 27 Aug 2026 14:14:21 +0800 Subject: [PATCH 5/8] feat: auto-release on merge to main when version changes --- .github/workflows/release.yml | 79 ++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b3f7d0d..420b109 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,42 +1,66 @@ # Release Pipeline # -# Triggered by pushing a v* git tag. +# Triggered on push to main. Checks if the version in package.json has a +# corresponding git tag; if not, publishes npm + binaries + GitHub Release. # -# Runs sequentially: npm publish -> binary build -> GitHub Release. -# This ordering ensures npm succeeds before creating a GitHub Release, -# preventing "Release exists on GitHub but npm version is missing" mismatches. +# Flow (single workflow, no tag-triggered loop): +# push to main -> check new version -> npm publish -> tag + binaries + release # # Security: OIDC Trusted Publishing, zero long-lived secrets. # Provenance: --provenance generates SLSA L3 attestation, publicly verifiable. -# -# Usage: -# git tag v1.0.0 -# git push origin v1.0.0 name: Release on: push: - tags: - - 'v*' + branches: + - main permissions: contents: read concurrency: - group: release-${{ github.ref }} + group: release-main cancel-in-progress: false jobs: # ─────────────────────────────────────────────────────────────── - # Job 1: NPM publish (OIDC Trusted Publishing + Provenance) + # Job 1: Check if this is a new release + # ─────────────────────────────────────────────────────────────── + check-version: + name: Check Version + runs-on: ubuntu-latest + outputs: + should-release: ${{ steps.check.outputs.should-release }} + version: ${{ steps.check.outputs.version }} + steps: + - uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - id: check + run: | + VERSION=$(node -p "require('./package.json').version") + if git rev-parse "v${VERSION}" >/dev/null 2>&1; then + echo "Tag v${VERSION} already exists, skipping release" + echo "should-release=false" >> $GITHUB_OUTPUT + else + echo "New version detected: ${VERSION}" + echo "should-release=true" >> $GITHUB_OUTPUT + echo "version=${VERSION}" >> $GITHUB_OUTPUT + fi + + # ─────────────────────────────────────────────────────────────── + # Job 2: NPM publish (OIDC Trusted Publishing + Provenance) # ─────────────────────────────────────────────────────────────── publish-npm: name: Publish to NPM + needs: check-version + if: needs.check-version.outputs.should-release == 'true' runs-on: ubuntu-latest permissions: contents: read - id-token: write # OIDC: allows GitHub to mint short-lived ID-Token + id-token: write # OIDC steps: - uses: actions/checkout@v7 @@ -49,17 +73,6 @@ jobs: - run: pnpm install - # Verify git tag version matches package.json version - - name: Verify version matches tag - run: | - TAG="${GITHUB_REF_NAME#v}" - PKG=$(node -p "require('./package.json').version") - if [ "$TAG" != "$PKG" ]; then - echo "Version mismatch: tag=$TAG package.json=$PKG" - exit 1 - fi - echo "Version OK: $PKG" - - name: Type check run: pnpm lint @@ -70,15 +83,17 @@ jobs: run: npm publish --provenance --access public # ─────────────────────────────────────────────────────────────── - # Job 2: Binary cross-compilation + GitHub Release + # Job 3: Binary cross-compile + tag + GitHub Release # Depends on publish-npm success to ensure version consistency. # ─────────────────────────────────────────────────────────────── - build-binaries: + build-and-release: name: Build & Release Binaries needs: publish-npm runs-on: ubuntu-latest permissions: - contents: write # Create GitHub Release + contents: write # Create tag + GitHub Release + env: + VERSION: ${{ needs.check-version.outputs.version }} steps: - uses: actions/checkout@v7 @@ -106,10 +121,18 @@ jobs: cat bin/checksums-sha256.txt >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY + - name: Create git tag + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git tag "v${VERSION}" + git push origin "v${VERSION}" + - name: Create GitHub Release uses: softprops/action-gh-release@v3 with: - name: ${{ github.ref_name }} + tag: v${{ env.VERSION }} + name: v${{ env.VERSION }} generate_release_notes: true files: | bin/wf-darwin-arm64 From 0407d07f6e07a6ed079dd08b50787a38017aff73 Mon Sep 17 00:00:00 2001 From: wang1212 Date: Thu, 27 Aug 2026 14:15:00 +0800 Subject: [PATCH 6/8] chore: bump version to 0.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a082cd7..9db7f51 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@weavefox/cli", - "version": "0.0.1", + "version": "0.0.2", "description": "WeaveFox CLI - Call server-side open capabilities via MCP protocol, for developers and AI agents", "license": "MIT", "repository": { From a0460ccebe3700a2873c33f374d70ea525cc5912 Mon Sep 17 00:00:00 2001 From: wang1212 Date: Thu, 27 Aug 2026 14:18:24 +0800 Subject: [PATCH 7/8] chore: remove release script, auto-release on merge --- AGENTS.md | 2 +- package.json | 3 +-- scripts/release.sh | 49 ---------------------------------------------- 3 files changed, 2 insertions(+), 52 deletions(-) delete mode 100755 scripts/release.sh diff --git a/AGENTS.md b/AGENTS.md index 1b1651e..5a7d85e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -62,7 +62,7 @@ pnpm release # Tag current version and push (run on main after pull) ## CLI Subcommands | Command | Description | -|---------|-------------| +| --------- | ------------- | | `login --key ` | Persist API Key | | `logout [--purge]` | Clear credentials / remove config dir | | `tools` | List MCP tools + schemas | diff --git a/package.json b/package.json index 9db7f51..de47364 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,7 @@ "lint:fix": "tsc --noEmit", "clean": "rm -rf dist bin", "clean:deps": "rm -rf node_modules", - "prepare": "husky", - "release": "bash scripts/release.sh" + "prepare": "husky" }, "dependencies": { "@modelcontextprotocol/sdk": "^1.30.0", diff --git a/scripts/release.sh b/scripts/release.sh deleted file mode 100755 index c3d99e5..0000000 --- a/scripts/release.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env bash -# -# Create release tag from the current commit on main. -# Run this AFTER the version change has been merged to main via PR. -# -# Prerequisites: -# 1. Version in package.json was bumped and merged to main via PR -# 2. You are on the main branch, up to date with origin -# -# Usage: -# bash scripts/release.sh # tag current version from package.json -# bash scripts/release.sh 0.0.2 # explicit version -# -set -euo pipefail - -PKG_FILE="package.json" - -# Verify we're on main -BRANCH=$(git branch --show-current) -if [ "$BRANCH" != "main" ]; then - echo "Error: must be on main (currently on '$BRANCH')" - echo "Run: git checkout main && git pull" - exit 1 -fi - -# Determine version -VERSION="${1:-$(node -p "require('./$PKG_FILE').version")}" -TAG="v${VERSION}" - -# Validate format -if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "Invalid version: $VERSION" - exit 1 -fi - -# Check tag doesn't already exist -if git rev-parse "$TAG" >/dev/null 2>&1; then - echo "Error: tag $TAG already exists" - exit 1 -fi - -echo "Creating tag $TAG for version $VERSION..." - -git tag "$TAG" -git push origin "$TAG" - -echo "" -echo "Done. $TAG pushed. Release pipeline will start automatically." -echo "Check: https://github.com/weavefox/weavefox-cli/actions/workflows/release.yml" From d7873c582ec41f3c12ad74fa04512a8b17c491d7 Mon Sep 17 00:00:00 2001 From: wang1212 Date: Thu, 27 Aug 2026 14:21:20 +0800 Subject: [PATCH 8/8] docs: update AGENTS.md for auto-release, remove release script --- AGENTS.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 5a7d85e..62e0e8a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -25,8 +25,7 @@ weavefox-cli/ │ ├── mcp-client.ts # MCP client (StreamableHTTP + configurable auth + errors) │ └── format.ts # Output: JSON mode / human mode ├── scripts/ -│ ├── build-bin.sh # Bun cross-compile (5 platforms + SHA256) -│ └── release.sh # Tag current version and push (triggers release pipeline) +│ └── build-bin.sh # Bun cross-compile (5 platforms + SHA256) ├── skills/ │ └── weavefox/ │ ├── SKILL.md # AI Agent skill (install via skills.sh) @@ -56,7 +55,6 @@ pnpm build # tsup -> dist/index.js pnpm build:bin # Bun binary (current platform) pnpm build:bin:all # Cross-compile 5 platforms pnpm clean # rm -rf dist bin -pnpm release # Tag current version and push (run on main after pull) ``` ## CLI Subcommands @@ -77,12 +75,11 @@ Main branch is protected — all changes go through PR. 1. Bump version in `package.json`, commit, push to a branch, create PR 2. Merge PR to main -3. `git checkout main && git pull` -4. `pnpm release` — tags current version and pushes tag -5. Tag push triggers `release.yml`: - - NPM publish via OIDC -> binary cross-compile -> GitHub Release +3. `release.yml` auto-triggers: checks if tag `v{version}` exists +4. If new version: npm publish (OIDC) -> binary cross-compile -> create tag -> GitHub Release +5. If no version change: skips release entirely -Manual alternative: `git tag v0.0.2 && git push origin v0.0.2` +No manual tagging or scripts needed. ## Key Design