Add Nix development environment and Claude guidance file
Change-Id: I4b3e2f0020409ee3f8b9e75633c901de94bd78d7 Signed-off-by: Thomas Kosiewski <tk@coder.com>
This commit is contained in:
parent
8639be0766
commit
46362efe73
6 changed files with 224 additions and 2 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -32,3 +32,7 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||||
|
|
||||||
# Finder (MacOS) folder config
|
# Finder (MacOS) folder config
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
.direnv
|
||||||
|
.envrc
|
||||||
|
.claude
|
||||||
|
|
|
||||||
67
CLAUDE.md
Normal file
67
CLAUDE.md
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
anyclaude is a proxy wrapper for Claude Code that enables using alternative LLM providers (OpenAI, Google, xAI, Azure) through the Anthropic API format. It intercepts Anthropic API calls and translates them to/from the Vercel AI SDK format for the specified provider.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
The proxy works by:
|
||||||
|
|
||||||
|
1. Spawning a local HTTP server that mimics the Anthropic API
|
||||||
|
2. Intercepting `/v1/messages` requests containing `<provider>/<model>` format
|
||||||
|
3. Converting Anthropic message format to AI SDK format
|
||||||
|
4. Routing to the appropriate provider (OpenAI, Google, xAI, Azure)
|
||||||
|
5. Converting responses back to Anthropic format
|
||||||
|
6. Setting `ANTHROPIC_BASE_URL` to point Claude Code at the proxy
|
||||||
|
|
||||||
|
Key components:
|
||||||
|
|
||||||
|
- `src/main.ts`: Entry point that sets up providers and spawns Claude with proxy
|
||||||
|
- `src/anthropic-proxy.ts`: HTTP server that handles request/response translation
|
||||||
|
- `src/convert-anthropic-messages.ts`: Bidirectional message format conversion
|
||||||
|
- `src/convert-to-anthropic-stream.ts`: Stream response conversion
|
||||||
|
- `src/json-schema.ts`: Schema adaptation for different providers
|
||||||
|
|
||||||
|
## Development Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies
|
||||||
|
bun install
|
||||||
|
|
||||||
|
# Build the project (creates dist/main.js with shebang)
|
||||||
|
bun run build
|
||||||
|
|
||||||
|
# The build command:
|
||||||
|
# 1. Compiles TypeScript to CommonJS for Node.js compatibility
|
||||||
|
# 2. Adds Node shebang for CLI execution
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
Test the proxy manually:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run in proxy-only mode to get the URL
|
||||||
|
PROXY_ONLY=true bun run src/main.ts
|
||||||
|
|
||||||
|
# Test with a provider
|
||||||
|
OPENAI_API_KEY=your-key bun run src/main.ts --model openai/gpt-4
|
||||||
|
```
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
Required for each provider:
|
||||||
|
|
||||||
|
- `OPENAI_API_KEY` + optional `OPENAI_API_URL` for OpenAI/OpenRouter
|
||||||
|
- `GOOGLE_API_KEY` + optional `GOOGLE_API_URL` for Google
|
||||||
|
- `XAI_API_KEY` + optional `XAI_API_URL` for xAI
|
||||||
|
- `AZURE_API_KEY` + optional `AZURE_API_URL` for Azure
|
||||||
|
- `ANTHROPIC_API_KEY` + optional `ANTHROPIC_API_URL` for Anthropic passthrough
|
||||||
|
|
||||||
|
Special modes:
|
||||||
|
|
||||||
|
- `PROXY_ONLY=true`: Run proxy server without spawning Claude Code
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@ Use Claude Code with OpenAI, Google, xAI, and other providers.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Use your favorite package manager (bun, pnpm, and npm are supported)
|
# Use your favorite package manager (bun, pnpm, and npm are supported)
|
||||||
$ pnpm install -g anyclaude
|
$ pnpm install -g anyclaude
|
||||||
|
|
||||||
# anyclaude is a wrapper for the Claude CLI
|
# anyclaude is a wrapper for the Claude CLI
|
||||||
# `openai/`, `google/`, `xai/`, and `anthropic/` are supported
|
# `openai/`, `google/`, `xai/`, and `anthropic/` are supported
|
||||||
|
|
|
||||||
96
flake.lock
generated
Normal file
96
flake.lock
generated
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1754498491,
|
||||||
|
"narHash": "sha256-erbiH2agUTD0Z30xcVSFcDHzkRvkRXOQ3lb887bcVrs=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "c2ae88e026f9525daf89587f3cbee584b92b6134",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1754340878,
|
||||||
|
"narHash": "sha256-lgmUyVQL9tSnvvIvBp7x1euhkkCho7n3TMzgjdvgPoU=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "cab778239e705082fe97bb4990e0d24c50924c04",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"treefmt-nix": "treefmt-nix"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"treefmt-nix": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1754492133,
|
||||||
|
"narHash": "sha256-B+3g9+76KlGe34Yk9za8AF3RL+lnbHXkLiVHLjYVOAc=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "treefmt-nix",
|
||||||
|
"rev": "1298185c05a56bff66383a20be0b41a307f52228",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "treefmt-nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
55
flake.nix
Normal file
55
flake.nix
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
{
|
||||||
|
description = "AnyClaude development environment";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
treefmt-nix.url = "github:numtide/treefmt-nix";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, flake-utils, treefmt-nix }:
|
||||||
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
|
let
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
|
||||||
|
treefmt = treefmt-nix.lib.evalModule pkgs {
|
||||||
|
projectRootFile = "flake.nix";
|
||||||
|
programs = {
|
||||||
|
nixpkgs-fmt.enable = true;
|
||||||
|
shfmt.enable = true;
|
||||||
|
shellcheck.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Format the source tree
|
||||||
|
formatter = treefmt.config.build.wrapper;
|
||||||
|
|
||||||
|
# Check formatting
|
||||||
|
checks.formatting = treefmt.config.build.check self;
|
||||||
|
|
||||||
|
devShells.default = pkgs.mkShell {
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
# Primary runtime and package manager
|
||||||
|
bun
|
||||||
|
|
||||||
|
# Node.js for compatibility (required by some tools)
|
||||||
|
nodejs_22
|
||||||
|
|
||||||
|
# Code quality tools (already included by treefmt)
|
||||||
|
treefmt.config.build.wrapper
|
||||||
|
|
||||||
|
# Version control
|
||||||
|
git
|
||||||
|
|
||||||
|
# Utilities
|
||||||
|
jq
|
||||||
|
ripgrep
|
||||||
|
bat
|
||||||
|
];
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
NODE_ENV = "development";
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -32,4 +32,4 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "bun build --target node --outfile dist/main.js ./src/main.ts --format cjs && sed -i '0,/^/s//#!\\/usr\\/bin\\/env node\\n/' ./dist/main.js"
|
"build": "bun build --target node --outfile dist/main.js ./src/main.ts --format cjs && sed -i '0,/^/s//#!\\/usr\\/bin\\/env node\\n/' ./dist/main.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue