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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ jobs:
run: |
./codes add --help
./codes select --help
./codes install --help
./codes completion --help
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ help:
@echo " clean - Clean build artifacts"
@echo " test - Test the build"
@echo " version - Show version"
@echo " install - Install codes to system"
@echo " install - Build and run init (install + setup)"
@echo ""
@echo "Usage: make [target]"

Expand All @@ -28,15 +28,15 @@ test:
@if [ -f "$(BINARY)" ]; then \
./$(BINARY) --help > /dev/null 2>&1 && echo "✓ Help works"; \
./$(BINARY) version && echo "✓ Version works"; \
./$(BINARY) install --help 2>/dev/null && echo "✓ Install command exists"; \
./$(BINARY) completion bash > /dev/null 2>&1 && echo "✓ Completion works"; \
else \
echo "✗ Not built"; \
fi

version:
@./$(BINARY) version 2>/dev/null || echo "Not built"

install:
install: build
@echo "Installing codes..."
@./$(BINARY) install
@./$(BINARY) init
@echo "Install completed"
89 changes: 59 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@ A powerful CLI tool for managing multiple Claude Code configurations with ease.
- **Permission Control**: Manage --dangerously-skip-permissions flag for Claude CLI
- **Flexible Startup Behavior**: Control where Claude starts when no arguments provided

## Quick Install

**Linux / macOS:**

```bash
curl -fsSL https://raw.githubusercontent.com/ourines/codes/main/install.sh | sh
```

**Windows (PowerShell):**

```powershell
irm https://raw.githubusercontent.com/ourines/codes/main/install.ps1 | iex
```

## Installation

### Pre-built Binaries
Expand All @@ -29,16 +43,16 @@ Download the latest release for your platform from the [releases page](https://g
curl -L https://github.com/ourines/codes/releases/latest/download/codes-linux-amd64 -o codes
chmod +x codes

# Install to system path
./codes install
# Install to system path and set up shell completion
./codes init
```

#### Windows

```powershell
# Download the binary for your architecture
# Then run the install command
.\codes.exe install
# Then run the init command
.\codes.exe init
```

### Build from Source
Expand All @@ -55,19 +69,19 @@ cd codes
# Build the binary
make build

# Install to system PATH
./codes install
# Install to system PATH and set up shell completion
./codes init
```

## Quick Start

### 1. Check Your Environment (Optional but Recommended)
### 1. Initialize Your Environment

```bash
codes init
```

This will verify that everything is set up correctly and guide you if something is missing.
This installs the binary to your system PATH, sets up shell completion, and verifies that everything is configured correctly.

### 2. Add Your First Configuration

Expand Down Expand Up @@ -102,30 +116,32 @@ An interactive menu will appear showing all your configurations. Select one to s

### `codes init`

Check your environment and validate your configuration. This command performs comprehensive checks including:
Initialize and configure the codes CLI. This command performs three main tasks:

- Verifies Claude CLI installation
- Detects existing Claude configuration in environment variables
- Offers to import existing configuration if found
- Checks configuration file existence and validity
- Tests API connectivity for the default configuration
- Displays detailed status of all configurations
1. **Installs the binary** to your system PATH (`/usr/local/bin` on Linux/macOS, `~/go/bin` on Windows)
2. **Sets up shell completion** automatically for your current shell
3. **Runs environment health checks**, including:
- Verifies Claude CLI installation
- Detects existing Claude configuration in environment variables
- Offers to import existing configuration if found
- Checks configuration file existence and validity
- Tests API connectivity for the default configuration

```bash
codes init
```

**Example output:**
```
```text
✓ Binary installed to /usr/local/bin/codes
✓ Shell completion configured for zsh
✓ Claude CLI is installed
✓ Found existing configuration in environment variables
✓ Configuration file exists
✓ Found 3 configuration(s)
✓ Default configuration is working
```

This is a great command to run after installation or when troubleshooting issues.

### `codes` (no arguments)

Runs Claude CLI with the currently selected configuration in the last used directory. If Claude CLI is not installed, it will be automatically installed. The tool remembers your last working directory for convenience.
Expand All @@ -141,6 +157,30 @@ codes /path/to/project
codes my-project # if you've added a project alias
```

### `codes completion [shell]`

Generate shell completion scripts. While `codes init` automatically sets up completion, you can also generate scripts manually.

```bash
codes completion [bash|zsh|fish|powershell]
```

**Manual setup (for reference):**

```bash
# Zsh (add to ~/.zshrc)
source <(codes completion zsh)

# Bash (add to ~/.bashrc)
source <(codes completion bash)

# Fish
codes completion fish | source

# PowerShell
codes completion powershell | Out-String | Invoke-Expression
```

### `codes add`

Interactively add a new Claude API configuration.
Expand Down Expand Up @@ -269,17 +309,6 @@ codes skippermissions reset
- Individual configurations can have their own `skipPermissions` setting that takes precedence
- This controls whether Claude bypasses certain security checks for file system access

### `codes install`

Install the codes binary to your system PATH.

```bash
codes install
```

- **Linux/macOS**: Installs to `/usr/local/bin` or `~/bin`
- **Windows**: Installs to `~/go/bin`

### `codes start [path-or-project]`

Start Claude Code in a specific directory or using a project alias. Without arguments, it uses the last working directory.
Expand Down Expand Up @@ -480,7 +509,7 @@ If you get permission errors during installation:

```bash
# Use sudo for system-wide installation
sudo ./codes install
sudo ./codes init

# Or install to user directory
mkdir -p ~/bin
Expand Down
2 changes: 1 addition & 1 deletion cmd/codes/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ var rootCmd = &cobra.Command{

func init() {
rootCmd.AddCommand(commands.InitCmd)
rootCmd.AddCommand(commands.InstallCmd)
rootCmd.AddCommand(commands.AddCmd)
rootCmd.AddCommand(commands.SelectCmd)
rootCmd.AddCommand(commands.TestCmd)
Expand All @@ -28,6 +27,7 @@ func init() {
rootCmd.AddCommand(commands.ConfigCmd)
rootCmd.AddCommand(commands.DefaultBehaviorCmd)
rootCmd.AddCommand(commands.SkipPermissionsCmd)
rootCmd.AddCommand(commands.CompletionCmd)

// 设置默认运行时行为 - 现在使用智能启动
rootCmd.Run = func(cmd *cobra.Command, args []string) {
Expand Down
53 changes: 53 additions & 0 deletions install.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Install script for codes - https://github.com/ourines/codes
# Usage: irm https://raw.githubusercontent.com/ourines/codes/main/install.ps1 | iex
$ErrorActionPreference = "Stop"

$Repo = "ourines/codes"
$Binary = "codes.exe"

# Detect architecture
$Arch = if ([Environment]::Is64BitOperatingSystem) {
if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { "arm64" } else { "amd64" }
} else {
Write-Error "32-bit systems are not supported."
return
}

Write-Host " > Detected platform: windows/$Arch" -ForegroundColor Cyan

$Url = "https://github.com/$Repo/releases/latest/download/codes-windows-$Arch.exe"
$TempFile = Join-Path $env:TEMP "codes-install.exe"

Write-Host " > Downloading codes from $Url..." -ForegroundColor Cyan
try {
Invoke-WebRequest -Uri $Url -OutFile $TempFile -UseBasicParsing
} catch {
Write-Error "Download failed. Check that a release exists for windows/$Arch."
return
}
Write-Host " ✓ Downloaded successfully" -ForegroundColor Green

# Install to user's local bin directory
$InstallDir = Join-Path $env:LOCALAPPDATA "codes"
if (-not (Test-Path $InstallDir)) {
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
}

$InstallPath = Join-Path $InstallDir $Binary
Move-Item -Path $TempFile -Destination $InstallPath -Force
Write-Host " ✓ Installed to $InstallPath" -ForegroundColor Green

# Add to PATH if not already there
$UserPath = [Environment]::GetEnvironmentVariable("Path", "User")
if ($UserPath -notlike "*$InstallDir*") {
[Environment]::SetEnvironmentVariable("Path", "$UserPath;$InstallDir", "User")
$env:Path = "$env:Path;$InstallDir"
Write-Host " ✓ Added $InstallDir to PATH" -ForegroundColor Green
}

# Run init
Write-Host " > Running codes init..." -ForegroundColor Cyan
& $InstallPath init

Write-Host ""
Write-Host " ✓ Installation complete! Run 'codes --help' to get started." -ForegroundColor Green
100 changes: 100 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/bin/sh
# Install script for codes - https://github.com/ourines/codes
# Usage: curl -fsSL https://raw.githubusercontent.com/ourines/codes/main/install.sh | sh
set -e

REPO="ourines/codes"
BINARY="codes"
INSTALL_DIR="/usr/local/bin"

# --- Helpers ---

info() {
printf ' \033[34m>\033[0m %s\n' "$1"
}

ok() {
printf ' \033[32m✓\033[0m %s\n' "$1"
}

err() {
printf ' \033[31m✗\033[0m %s\n' "$1" >&2
}

die() {
err "$1"
exit 1
}

need() {
command -v "$1" >/dev/null 2>&1 || die "'$1' is required but not found"
}

# --- Detect platform ---

detect_os() {
case "$(uname -s)" in
Linux*) echo "linux" ;;
Darwin*) echo "darwin" ;;
*) die "Unsupported OS: $(uname -s)" ;;
esac
}

detect_arch() {
case "$(uname -m)" in
x86_64|amd64) echo "amd64" ;;
aarch64|arm64) echo "arm64" ;;
*) die "Unsupported architecture: $(uname -m)" ;;
esac
}

# --- Main ---

main() {
need curl

OS="$(detect_os)"
ARCH="$(detect_arch)"

info "Detected platform: ${OS}/${ARCH}"

URL="https://github.com/${REPO}/releases/latest/download/${BINARY}-${OS}-${ARCH}"
TMPFILE="$(mktemp)"
trap 'rm -f "$TMPFILE"' EXIT

info "Downloading ${BINARY} from ${URL}..."
if ! curl -fSL --progress-bar -o "$TMPFILE" "$URL"; then
die "Download failed. Check that a release exists for ${OS}/${ARCH}."
fi

chmod +x "$TMPFILE"
ok "Downloaded successfully"

# Try /usr/local/bin first, fall back to ~/bin
if [ -w "$INSTALL_DIR" ]; then
mv "$TMPFILE" "${INSTALL_DIR}/${BINARY}"
ok "Installed to ${INSTALL_DIR}/${BINARY}"
elif command -v sudo >/dev/null 2>&1; then
info "Installing to ${INSTALL_DIR} (requires sudo)..."
sudo mv "$TMPFILE" "${INSTALL_DIR}/${BINARY}"
ok "Installed to ${INSTALL_DIR}/${BINARY}"
else
INSTALL_DIR="${HOME}/bin"
mkdir -p "$INSTALL_DIR"
mv "$TMPFILE" "${INSTALL_DIR}/${BINARY}"
ok "Installed to ${INSTALL_DIR}/${BINARY}"
case ":$PATH:" in
*":${INSTALL_DIR}:"*) ;;
*) printf '\n %s\n\n' "Add ${INSTALL_DIR} to your PATH: export PATH=\"\$HOME/bin:\$PATH\"" ;;
esac
fi

# Run init for shell completion and environment check
info "Running ${BINARY} init..."
"${INSTALL_DIR}/${BINARY}" init

printf '\n'
ok "Installation complete! Run 'codes --help' to get started."
}

main
Loading