docs: update README with repo URL, add setup guide and .gitignore

- Update README installation to use uv tool install with self-hosted repo URL
- Add docs/SETUP.md for AI agent consumption
- Add .gitignore for __pycache__, build artifacts, venv, IDE files
- Remove obsolete superpowers planning docs

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-28 18:15:50 +08:00
parent f54d142fde
commit 8af421206b
5 changed files with 44 additions and 1241 deletions

17
.gitignore vendored Normal file
View File

@@ -0,0 +1,17 @@
__pycache__/
*.py[cod]
*$py.class
# Distribution
dist/
*.egg-info/
*.whl
# Virtual environments
.venv/
venv/
# IDE
.idea/
.vscode/
*.swp

View File

@@ -2,6 +2,8 @@
HTTP proxy for Gitea LFS -- rewrites Host header to bypass ICP domain blocking. HTTP proxy for Gitea LFS -- rewrites Host header to bypass ICP domain blocking.
**Repository:** `ssh://git@git.zz.com:2222/Developer/jianda-proxy.git`
## Background ## Background
Internal Gitea is exposed via a reverse tunnel on a Tencent Cloud server. The client resolves the domain via `hosts` file to the cloud IP. SSH clone works fine, but LFS file downloads go over HTTP. Tencent Cloud detects the unregistered domain from the Host header and blocks the request with a 302 redirect. Internal Gitea is exposed via a reverse tunnel on a Tencent Cloud server. The client resolves the domain via `hosts` file to the cloud IP. SSH clone works fine, but LFS file downloads go over HTTP. Tencent Cloud detects the unregistered domain from the Host header and blocks the request with a 302 redirect.
@@ -11,11 +13,7 @@ This proxy rewrites the Host header on all requests to the upstream IP address,
## Installation ## Installation
```bash ```bash
# Install as a global CLI tool (recommended) uv tool install git+ssh://git@git.zz.com:2222/Developer/jianda-proxy.git
uv tool install .
# Or with pip
pip install .
``` ```
## CLI Commands ## CLI Commands
@@ -92,7 +90,7 @@ git config --global http.http://git.zz.com:3000/.proxy http://127.0.0.1:13000
3. Clone as usual: 3. Clone as usual:
```bash ```bash
git clone ssh://git@git.zz.com:2222/your-repo.git git clone ssh://git@git.zz.com:2222/Developer/jianda-proxy.git
``` ```
LFS downloads will be routed through the proxy transparently. LFS downloads will be routed through the proxy transparently.

23
docs/SETUP.md Normal file
View File

@@ -0,0 +1,23 @@
# jianda-proxy Setup Guide
## Install
```bash
uv tool install git+ssh://git@git.zz.com:2222/Developer/jianda-proxy.git
```
## Git Config
After installation, run once to route LFS requests through the proxy:
```bash
git config --global http.http://git.zz.com:3000/.proxy http://127.0.0.1:13000
```
## Start Proxy
```bash
jianda-proxy start
```
After that, `git clone` / `git pull` / `git push` over SSH will automatically use the proxy for LFS downloads. No extra steps needed.

File diff suppressed because it is too large Load Diff

View File

@@ -1,148 +0,0 @@
# jianda-proxy CLI 工具打包设计
**日期**2026-05-28
**状态**:已批准
## 背景
jianda-proxy 是一个 HTTP 代理工具,用于解决腾讯云 ICP 拦截导致 Git LFS 下载失败的问题。目前是一个单文件 Python 脚本(`lfs-proxy.py`),配置硬编码,直接 `python3` 运行。
目标:将其打包为标准的 Python CLI 工具,支持 `uvx` 运行、`uv tool install` 安装、后台运行、CLI 管理生命周期且跨平台Windows + Mac
## 决策
- **工具名称**`jianda-proxy`
- **配置格式**INI标准库 `configparser`,零外部依赖)
- **后台运行**纯标准库Unix 用 `os.fork()`Windows 用 `subprocess` detached
- **配置管理**CLI `config` 子命令
## 项目结构
```
jianda-proxy/
├── pyproject.toml
├── src/
│ └── jianda_proxy/
│ ├── __init__.py
│ ├── cli.py # CLI 入口argparse 子命令
│ ├── proxy.py # 代理逻辑
│ ├── config.py # INI 配置管理
│ └── daemon.py # 跨平台后台运行管理
├── docs/
│ └── superpowers/specs/
└── README.md
```
### pyproject.toml
- 零外部依赖
- Python >= 3.8
- 入口点:`jianda-proxy = "jianda_proxy.cli:main"`
- 构建后端:`hatchling`
## 打包与分发
- `uv tool install .`:本地安装
- `uvx jianda-proxy`:临时运行(需发布到 PyPI 后)
- `python -m jianda_proxy`:作为模块运行
## 配置管理
### 配置文件位置
- Mac/Linux`~/.config/jianda-proxy/config.ini`
- Windows`%APPDATA%\jianda-proxy\config.ini`
通过 `os.path.expanduser``os.environ` 手动拼路径,不引入 `platformdirs`
### 配置格式
```ini
[proxy]
remote_domain = git.zz.com
upstream_host = 62.234.191.215
upstream_port = 3000
listen_port = 13000
listen_host = 127.0.0.1
```
### config 子命令
| 命令 | 说明 |
|------|------|
| `config set <key> <value>` | 设置配置项 |
| `config get <key>` | 查看单个配置项 |
| `config list` | 列出所有配置 |
| `config path` | 显示配置文件路径 |
首次使用 `start` 时,如果配置文件不存在,用默认值自动创建。
## CLI 命令
```
jianda-proxy start [--port PORT] [--foreground]
jianda-proxy stop
jianda-proxy status
jianda-proxy config set <key> <value>
jianda-proxy config get <key>
jianda-proxy config list
jianda-proxy config path
```
`start --foreground`:前台运行,日志直接输出到终端,方便调试。
## 后台运行与生命周期
### start
1. 检查端口是否可用
2. 检查是否已有进程运行PID 文件存在且进程存活)
3. 如果已有进程:提示错误并退出
4. 如果 PID 文件存在但进程已死:清理后继续
5. Unix`os.fork()` 后父进程退出
6. Windows`subprocess.Popen` with `CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS`
7. 写 PID 文件
8. 日志写到 `~/.config/jianda-proxy/proxy.log`RotatingFileHandler5MB3 个备份)
### stop
1. 读取 PID 文件
2. 检查进程是否存在
3. 发送 SIGTERMUnix/ taskkillWindows
4. 等待最多 3 秒
5. 如果还活着SIGKILL / 强制终止
6. 删除 PID 文件
### status
1. 读取 PID 文件
2. 检查进程是否存在
3. 显示运行状态、PID、端口、运行时间
### PID 文件
位置:和配置文件同目录 `~/.config/jianda-proxy/daemon.pid`
## 跨平台细节
| 操作 | Unix | Windows |
|------|------|---------|
| 后台启动 | `os.fork()` | `subprocess.Popen` + detached flags |
| 进程检查 | `os.kill(pid, 0)` | `ctypes` 调用 `kernel32.OpenProcess` + `GetExitCodeProcess` |
| 优雅停止 | `SIGTERM` | `taskkill /PID` |
| 强制停止 | `SIGKILL` | `taskkill /F /PID` |
| 配置目录 | `~/.config/` | `%APPDATA%` |
## 错误处理
- 端口被占用:提示具体端口和可能原因
- 配置无效IP 格式错误等):启动前验证
- 权限不足:提示需要的权限
- 后台进程异常退出:`status` 检测到后提示查看日志
## 模块职责
- **cli.py**argparse 定义、子命令分发、入口函数
- **config.py**:读写配置文件、默认值管理、配置路径计算
- **proxy.py**HTTP 代理服务器逻辑(从现有 `lfs-proxy.py` 提取)
- **daemon.py**PID 文件管理、跨平台进程检查、进程终止