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
264 changes: 160 additions & 104 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ on:
workflow_dispatch:
inputs:
version:
description: "Version to publish (e.g., 0.1.0)"
description: 'Package version to publish (e.g., 0.1.4)'
required: true
type: string
claude_code_version:
description: 'Claude Code CLI version to bundle (e.g., 2.0.0 or latest)'
required: false
type: string
default: 'latest'
jobs:
test:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -56,114 +61,165 @@ jobs:
run: |
mypy src/

publish:
build-wheels:
needs: [test, lint]
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
permissions:
contents: write
pull-requests: write

steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0 # Fetch all history including tags (necessary for changelog generation)

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Set version
id: version
run: |
VERSION="${{ github.event.inputs.version }}"
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "version=$VERSION" >> $GITHUB_OUTPUT
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history including tags (necessary for changelog generation)

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build twine
shell: bash

- name: Build wheel with bundled CLI
run: |
python scripts/build_wheel.py \
--version "${{ github.event.inputs.version }}" \
--cli-version "${{ github.event.inputs.claude_code_version }}" \
--skip-sdist \
--clean
shell: bash

- name: Upload wheel artifact
uses: actions/upload-artifact@v4
with:
name: wheel-${{ matrix.os }}
path: dist/*.whl
if-no-files-found: error

- name: Update version
run: |
python scripts/update_version.py "${{ env.VERSION }}"

- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build twine

- name: Build package
run: python -m build

- name: Check package
run: twine check dist/*

- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
twine upload dist/*
echo "Package published to PyPI"
echo "Install with: pip install claude-agent-sdk==${{ env.VERSION }}"

- name: Get previous release tag
id: previous_tag
run: |
PREVIOUS_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
echo "previous_tag=$PREVIOUS_TAG" >> $GITHUB_OUTPUT
echo "Previous release: $PREVIOUS_TAG"

- name: Create release branch and commit version changes
run: |
# Create a new branch for the version update
BRANCH_NAME="release/v${{ env.VERSION }}"
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV

# Configure git
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"

# Create and switch to new branch
git checkout -b "$BRANCH_NAME"

# Commit version changes
git add pyproject.toml src/claude_agent_sdk/_version.py
git commit -m "chore: bump version to ${{ env.VERSION }}"

- name: Update changelog with Claude
continue-on-error: true
uses: anthropics/claude-code-action@v1
with:
prompt: "/generate-changelog new version: ${{ env.VERSION }}, old version: ${{ steps.previous_tag.outputs.previous_tag }}"
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
claude_args: |
--allowedTools 'Bash(git add:*),Bash(git commit:*),Edit'

- name: Push branch and create PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Push the branch with all commits
git push origin "${{ env.BRANCH_NAME }}"

# Create PR using GitHub CLI
PR_BODY="This PR updates the version to ${{ env.VERSION }} after publishing to PyPI.

## Changes
- Updated version in \`pyproject.toml\`
- Updated version in \`src/claude_agent_sdk/_version.py\`
- Updated \`CHANGELOG.md\` with release notes

## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/${{ env.VERSION }}/
- Install with: \`pip install claude-agent-sdk==${{ env.VERSION }}\`

🤖 Generated by GitHub Actions"

PR_URL=$(gh pr create \
--title "chore: release v${{ env.VERSION }}" \
--body "$PR_BODY" \
--base main \
--head "${{ env.BRANCH_NAME }}")
publish:
needs: [build-wheels]
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write

echo "PR created: $PR_URL"
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Set version
id: version
run: |
VERSION="${{ github.event.inputs.version }}"
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "version=$VERSION" >> $GITHUB_OUTPUT

- name: Update version
run: |
python scripts/update_version.py "${{ env.VERSION }}"

- name: Update CLI version
run: |
python scripts/update_cli_version.py "${{ github.event.inputs.claude_code_version }}"

- name: Download all wheel artifacts
uses: actions/download-artifact@v4
with:
path: dist
pattern: wheel-*
merge-multiple: true

- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build twine

- name: Build source distribution
run: python -m build --sdist

- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
twine upload dist/*
echo "Package published to PyPI"
echo "Install with: pip install claude-agent-sdk==${{ env.VERSION }}"

- name: Get previous release tag
id: previous_tag
run: |
PREVIOUS_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
echo "previous_tag=$PREVIOUS_TAG" >> $GITHUB_OUTPUT
echo "Previous release: $PREVIOUS_TAG"

- name: Create release branch and commit version changes
run: |
# Create a new branch for the version update
BRANCH_NAME="release/v${{ env.VERSION }}"
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV

# Configure git
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"

# Create and switch to new branch
git checkout -b "$BRANCH_NAME"

# Commit version changes
git add pyproject.toml src/claude_agent_sdk/_version.py src/claude_agent_sdk/_cli_version.py
git commit -m "chore: bump version to ${{ env.VERSION }} with CLI ${{ github.event.inputs.claude_code_version }}"

- name: Update changelog with Claude
continue-on-error: true
uses: anthropics/claude-code-action@v1
with:
prompt: "/generate-changelog new version: ${{ env.VERSION }}, old version: ${{ steps.previous_tag.outputs.previous_tag }}"
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
claude_args: |
--allowedTools 'Bash(git add:*),Bash(git commit:*),Edit'

- name: Push branch and create PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Push the branch with all commits
git push origin "${{ env.BRANCH_NAME }}"

# Create PR using GitHub CLI
PR_BODY="This PR updates the version to ${{ env.VERSION }} after publishing to PyPI.

## Changes
- Updated version in \`pyproject.toml\` to ${{ env.VERSION }}
- Updated version in \`src/claude_agent_sdk/_version.py\` to ${{ env.VERSION }}
- Updated bundled CLI version in \`src/claude_agent_sdk/_cli_version.py\` to ${{ github.event.inputs.claude_code_version }}
- Updated \`CHANGELOG.md\` with release notes

## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/${{ env.VERSION }}/
- Bundled CLI version: ${{ github.event.inputs.claude_code_version }}
- Install with: \`pip install claude-agent-sdk==${{ env.VERSION }}\`

🤖 Generated by GitHub Actions"

PR_URL=$(gh pr create \
--title "chore: release v${{ env.VERSION }}" \
--body "$PR_BODY" \
--base main \
--head "${{ env.BRANCH_NAME }}")

echo "PR created: $PR_URL"
71 changes: 66 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ pip install claude-agent-sdk
```

**Prerequisites:**

- Python 3.10+
- Node.js
- Claude Code 2.0.0+: `npm install -g @anthropic-ai/claude-code`

**Note:** The Claude Code CLI is automatically bundled with the package - no separate installation required! The SDK will use the bundled CLI by default. If you prefer to use a system-wide installation or a specific version, you can:

- Install Claude Code separately: `curl -fsSL https://claude.ai/install.sh | bash`
- Specify a custom path: `ClaudeAgentOptions(cli_path="/path/to/claude")`

## Quick Start

Expand Down Expand Up @@ -179,7 +183,7 @@ options = ClaudeAgentOptions(

### Hooks

A **hook** is a Python function that the Claude Code *application* (*not* Claude) invokes at specific points of the Claude agent loop. Hooks can provide deterministic processing and automated feedback for Claude. Read more in [Claude Code Hooks Reference](https://docs.anthropic.com/en/docs/claude-code/hooks).
A **hook** is a Python function that the Claude Code _application_ (_not_ Claude) invokes at specific points of the Claude agent loop. Hooks can provide deterministic processing and automated feedback for Claude. Read more in [Claude Code Hooks Reference](https://docs.anthropic.com/en/docs/claude-code/hooks).

For more examples, see examples/hooks.py.

Expand Down Expand Up @@ -229,10 +233,10 @@ async with ClaudeSDKClient(options=options) as client:
print(msg)
```


## Types

See [src/claude_agent_sdk/types.py](src/claude_agent_sdk/types.py) for complete type definitions:

- `ClaudeAgentOptions` - Configuration options
- `AssistantMessage`, `UserMessage`, `SystemMessage`, `ResultMessage` - Message types
- `TextBlock`, `ToolUseBlock`, `ToolResultBlock` - Content blocks
Expand All @@ -259,7 +263,7 @@ except CLIJSONDecodeError as e:
print(f"Failed to parse response: {e}")
```

See [src/claude_agent_sdk/_errors.py](src/claude_agent_sdk/_errors.py) for all error types.
See [src/claude_agent_sdk/\_errors.py](src/claude_agent_sdk/_errors.py) for all error types.

## Available Tools

Expand Down Expand Up @@ -290,6 +294,63 @@ If you're contributing to this project, run the initial setup script to install

This installs a pre-push hook that runs lint checks before pushing, matching the CI workflow. To skip the hook temporarily, use `git push --no-verify`.

### Building Wheels Locally

To build wheels with the bundled Claude Code CLI:

```bash
# Install build dependencies
pip install build twine

# Build wheel with bundled CLI
python scripts/build_wheel.py

# Build with specific version
python scripts/build_wheel.py --version 0.1.4

# Build with specific CLI version
python scripts/build_wheel.py --cli-version 2.0.0

# Clean bundled CLI after building
python scripts/build_wheel.py --clean

# Skip CLI download (use existing)
python scripts/build_wheel.py --skip-download
```

The build script:

1. Downloads Claude Code CLI for your platform
2. Bundles it in the wheel
3. Builds both wheel and source distribution
4. Checks the package with twine

See `python scripts/build_wheel.py --help` for all options.

### Release Workflow

The package is published to PyPI via the GitHub Actions workflow in `.github/workflows/publish.yml`. To create a new release:

1. **Trigger the workflow** manually from the Actions tab with two inputs:
- `version`: The package version to publish (e.g., `0.1.5`)
- `claude_code_version`: The Claude Code CLI version to bundle (e.g., `2.0.0` or `latest`)

2. **The workflow will**:
- Build platform-specific wheels for macOS, Linux, and Windows
- Bundle the specified Claude Code CLI version in each wheel
- Build a source distribution
- Publish all artifacts to PyPI
- Create a release branch with version updates
- Open a PR to main with:
- Updated `pyproject.toml` version
- Updated `src/claude_agent_sdk/_version.py`
- Updated `src/claude_agent_sdk/_cli_version.py` with bundled CLI version
- Auto-generated `CHANGELOG.md` entry

3. **Review and merge** the release PR to update main with the new version information

The workflow tracks both the package version and the bundled CLI version separately, allowing you to release a new package version with an updated CLI without code changes.

## License

MIT
Loading
Loading