Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 51 additions & 28 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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

Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ dist/
bin/
package-lock.json
pnpm-lock.yaml
skills-lock.json
51 changes: 40 additions & 11 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand All @@ -25,23 +26,35 @@ weavefox-cli/
│ └── format.ts # Output: JSON mode / human mode
├── scripts/
│ └── build-bin.sh # Bun cross-compile (5 platforms + SHA256)
├── 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
```

## CLI Subcommands
Expand All @@ -54,6 +67,20 @@ pnpm clean # rm -rf dist bin
| `call <toolName> [--kv ...]` | Invoke a tool (`key=value` scalars, `key:=value` JSON) |
| `config [--set-url ...] [--set-auth-header ...]` | View / modify configuration |

Global options: `--json`, `--url <url>`, `--auth-header <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. `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

No manual tagging or scripts needed.

## Key Design

### Transport: StreamableHTTP
Expand All @@ -63,7 +90,7 @@ Server uses `WebStandardStreamableHTTPServerTransport`. Client matches with `Str
### Auth: Configurable

- Default: `Authorization: Bearer <key>`
- 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`

Expand All @@ -73,7 +100,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)

Expand All @@ -84,7 +111,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
Expand All @@ -97,8 +124,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<ReturnType<...>>` 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
23 changes: 16 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand Down
23 changes: 16 additions & 7 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@

通过 MCP 协议调用 WeaveFox 服务端开放能力的命令行工具,面向开发者和 AI Agent。

> 开发指南请参阅 [AGENTS.md](./AGENTS.md) 了解项目结构、构建命令和编码规范。
>
> [English](./README.md)
[English](./README.md)

## 安装

Expand All @@ -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

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
Loading