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
48 changes: 48 additions & 0 deletions .github/workflows/style.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# 代码风格检查: rustfmt + clippy
# 仅在修改核心源码/构建配置时运行

name: Code Style

on:
push:
paths:
- 'src/**'
- 'Cargo.toml'
- 'Cargo.lock'
- 'rustfmt.toml'
- 'clippy.toml'
pull_request:
paths:
- 'src/**'
- 'Cargo.toml'
- 'Cargo.lock'
- 'rustfmt.toml'
- 'clippy.toml'

env:
RUSTFLAGS: "-D warnings"
CARGO_TERM_COLOR: always

jobs:
rustfmt:
name: rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: cargo fmt --all -- --check
run: cargo fmt --all -- --check

clippy:
name: clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
- name: cargo clippy --all-targets -- -D warnings
run: cargo clippy --all-targets --all-features -- -D warnings
31 changes: 27 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,17 +1,40 @@
# Python
# ======================================================================
# CCL-dev .gitignore
# 用户数据目录不上传: config/ 与 logs/ 为本地生成,不进版本库
# ======================================================================

# Rust
target/
*.rs.bk

# Config & Logs (user data, not tracked) — 仅根目录, 不影响 src/config/
/config/
/logs/

# Tauri (GUI 构建产物)
src-tauri/target/
src-tauri/gen/
*.dmg
*.msi
*.AppImage

# Node (GUI 前端)
node_modules/
src-tauri/frontend/dist/
src-tauri/frontend/node_modules/

# Python (遗留参考,若清理则删除以下)
__pycache__/
*.py[cod]
*.egg-info/
dist/
build/

# Virtual env
venv/
.venv/

# IDE
.vscode/
.idea/
.vscode/
*.swp
*.swo

Expand Down
144 changes: 64 additions & 80 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,105 +6,89 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

- **GitHub 操作**:使用 `gh` CLI,不用浏览器手动操作
- **提交信息**:不要包含 `Co-Authored-By` 尾注
- **个人排除项**:不要编辑 `.gitignore`,用户通过 `.git/info/exclude` 自行管理
- **代码修改**:始终先 `EnterWorktree` 隔离工作,提交后推送并创建 draft PR
- **代码修改**:始终先 `EnterWorktree` 隔离工作
- **提交策略**:仅在最终提交时合并 PR 到主目录并清理 worktree(非每次提交)
- **隐私**:提交前必须检查无本地私人文件进仓库(API keys、settings.json、config/、logs/ 等)

## 项目概述

Claude Code Custom Launcher — Claude Code 的 Python 通用启动器,支持多后端切换、环境变量管理、插件更新和配置 GUI。不是一个 pip 包,通过 `python -m claude_custom` 直接运行。要求 Python 3.10+
Claude Code 的 Rust 配置驱动启动器(`cc-launcher`)。零硬编码,所有行为由 `config/config.toml` 控制。便携式部署:程序 + `config/` + `logs/` 同目录

**三个入口点:**
- `claude-custom.cmd` → 普通用户 CLI 入口(设置 PYTHONPATH 后调用 `python -m claude_custom`)
- `python -m claude_custom` → 开发者直接调用
- `claude-config.pyw` → GUI 独立入口(双击启动,无控制台窗口
**三个 UI 形态:**
- **CLI**(clap 子命令)→ 默认入口,无子命令时启动 CC
- **TUI**(ratatui 4 Tab)→ `cc-launcher tui`
- **GUI**(Tauri 2 + React)→ `cc-launcher gui`(独立 `src-tauri/` crate,可选构建

## 常用命令

```bash
# 首次安装依赖
pip install -r requirements.txt
# 构建 + 测试 + 风格 + lint
cargo build
cargo test
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings

# 启动 Claude Code(默认)
cargo run --

# 管理命令
cargo run -- update
cargo run -- repair
cargo run -- rollback
cargo run -- check
cargo run -- tui

# GUI(独立构建)
cd src-tauri && cargo build
```

```bash
# 直接启动
python -m claude_custom

# 预览模式(查看配置但不启动)
python -m claude_custom -n

# 运行诊断检查
python -m claude_custom --check

# 启动 GUI
python -m claude_custom --gui # CLI 触发
python claude-config.pyw # 双击启动(无控制台窗口)

# 本地导入测试
python -c "import sys; sys.path.insert(0, '.'); from claude_custom import config"
```

本项目无测试套件、无 linter 配置、无构建步骤。验证方式:直接运行 `python -m claude_custom --help` 和 `python -m claude_custom --check`。

## 核心架构

### 启动流程(无参启动路径)

```
__main__.py:main()
→ 参数分类(自定义 FLAGS vs 透传 CC 参数)
→ 无管理参数时 → launch_cc()
→ config.get_claude_exe() # 查找 CC 可执行文件
→ env_manager.apply() # 应用 user_config.yaml 中的环境变量
→ auth_manager.setup_daemon_bypass() # 注入 ANTHROPIC_AUTH_TOKEN + CLAUDE_CODE_SIMPLE
→ _prelaunch_interactive_check() # 交互式更新/修复确认(-s 跳过)
→ ApiKeyInjector 上下文注入 API Key
→ subprocess.run(claude.exe) # 透传 stdio
```

### 模块职责

| 模块 | 职责 |
|------|------|
| `__main__.py` | CLI 入口,参数路由。`--` 分隔自定义参数和 CC 透传参数 |
| `config.py` | 路径推导(基于 `__file__` + 环境变量覆盖 + `user_config.yaml`)+ YAML 配置读写 |
| `launcher.py` | subprocess 启动 CC、启动前交互式检查、二进制健康检查 |
| `auth_manager.py` | Daemon OAuth 绕过:设置 `ANTHROPIC_AUTH_TOKEN`+`CLAUDE_CODE_SIMPLE` |
| `env_manager.py` | 环境变量分层管理(快照/回滚),支持 `user_config.yaml` 中 `env:` 块 |
| `settings_manager.py` | `settings.json` 安全读写(原子写入 + 备份);`ApiKeyInjector` 上下文管理器(进入注入 API Key,退出清理) |
| `credential_manager.py` | 多源 API Key 查找:命令行 `-k` → 环境变量 → keyring → `.api_key` 文件 |
| `updater.py` | CC 二进制升级/修复、插件/Skills 更新,支持镜像源回退 |
| `diagnostics.py` | `--check`/`--doctor`/`--reset`/`--env`/`--logs`/`--config` 等管理操作 |
| `network.py` | HTTP GET(带重试 + 指数退避 + 镜像回退) |
| `gui/` | PySide6 配置 GUI(7 个标签页),`claude-config.pyw` 独立入口 |

### 路径推导

所有路径基于 `__file__` 相对推导,按优先级可被覆盖:
- `CLAUDECODE_ROOT` → `ROOT_DIR`
- `CLAUDECODE_MAIN_DIR` → `MAIN_DIR`(CC npm 包所在目录)
- `CLAUDECODE_CONFIG_DIR` → `CONFIG_DIR`
- `CLAUDECODE_EXE_PATH` → CC 可执行文件路径(最高优先级)
- `user_config.yaml` 中 `custom_exe_path` → 次优先级

## 关键设计模式
| `cli.rs` | clap 子命令定义(help 中英双语) |
| `config/` | TOML schema + 加载/校验 + 自动生成模板 + Profile |
| `launch/` | preflight 检查 + 环境注入 + spawn + 崩溃检测 |
| `env/` | 环境变量优先级链 + 快照回滚 + 模板替换 |
| `auth/` | 多源 API Key + daemon 绕过 + settings.json 注入-清理(自愈) |
| `update/` | 多源更新(自更新/GitHub/镜像)+ 分段下载 + SHA-256 |
| `repair/` | 崩溃检测 + 指数退避 + 熔断器 |
| `rollback/` | 版本清单 + 原子替换 |
| `logging/` | tracing 日志(文件+控制台)+ 按天轮转 |
| `i18n/` | 中英双语翻译 + 系统 locale 检测 |
| `tui.rs` | ratatui 4 Tab 仪表盘 |
| `src-tauri/` | Tauri 2 GUI(独立 crate,React 前端) |

### 配置系统

- `config/config.toml`:首次运行自动生成全注释模板(不提供默认配置,用代码内置默认)
- 优先级:CLI 参数 > 配置文件 > 系统环境 > 内置默认
- 校验:加载时检查类型/范围,无效则报具体错误

### 数据流

### 参数透传
`__main__.py:main()` 将参数分为三类:自定义 FLAGS(管理操作)、自定义 VALUED(`-m`/`-d`/`-k` 等)、其余全部透传给 CC。不识别 = 透传,无需在启动器中重复定义 CC 原生参数。
```
main() → 加载配置 + I18N + 日志
→ 无子命令: launch(preflight → env → auth 注入 → spawn → 崩溃检测/修复)
→ 有子命令: update/repair/rollback/check/reset/env/logs/config-path/completions/tui/gui
```

### API Key 安全
`ApiKeyInjector` 上下文管理器在 subprocess 启动前将 API Key 注入 `settings.json`,进程退出后在 `__exit__` 中自动清除。支持 keyring 系统凭据管理器。
## 关键设计模式

### 错误处理
- `launcher.py:launch_cc()` 在 `get_claude_exe()` 调用外捕获 `FileNotFoundError`,输出格式化错误信息(问题描述 + 修复步骤 + 默认路径),返回退出码 1
- `__main__.py:main()` 有顶层 `try/except` 兜底(`FileNotFoundError`/`KeyboardInterrupt`/`Exception`)
- `_run_management()` 使用 `except (RuntimeError, FileNotFoundError, TimeoutError)` 模式
- `network.py` 使用返回 `None` 而非抛异常处理网络失败
- **零硬编码**:所有路径/URL/超时/模型名从配置读取,内置默认在 `config/schema.rs`
- **多源更新**:`update.strategy` 控制 auto/native/github/mirror 顺序;通道按环境检测排序
- **API Key 安全**:`ApiKeyInjector` 启动注入 settings.json、退出清理,带脏数据自愈 + 信号处理器
- **错误处理**:库级 `thiserror`,应用级 `anyhow`,绝不静默崩溃
- **自愈**:崩溃检测(宽限期)+ 熔断器防无限重装

### 镜像回退
`network.py` 和 `updater.py` 支持 `--mirror` 参数切换到国内 npm 镜像源。网络操作失败时自动尝试回退到官方源。
## CI

## 配置
GitHub Actions(`.github/workflows/`,全 YAML,独立 job 文件):
- `style.yml`:rustfmt + clippy(`-D warnings`)
- `build-test.yml`:3 OS 编译 + 测试 + 构建产物验证(--help/--version/--dry-run)
- `config-validation.yml`:配置 schema 测试
- `i18n-check.yml`:语言文件 key 一致性

- **Python**: 3.10+
- `user_config.yaml`:用户可编辑,`backend`/`mirror`/`skip_check`/`custom_exe_path`/`env`/`launch_presets`
- 环境变量优先级:命令行参数 > `user_config.yaml` `env:` > 系统环境变量 > 代码内置默认值
触发:仅核心文件变更(src/**, Cargo.toml, Cargo.lock, i18n/**)。
Loading
Loading