From acd71dcb1a7a49f3810c752b9ed5b2c338bbd4be Mon Sep 17 00:00:00 2001 From: huangzhenpc Date: Tue, 3 Mar 2026 10:20:10 +0800 Subject: [PATCH 1/4] =?UTF-8?q?chore:=20=E6=B7=BB=E5=8A=A0=20sync-upstream?= =?UTF-8?q?=20skill=20=E8=87=AA=E5=8A=A8=E5=8C=96=E4=B8=8A=E6=B8=B8?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 定义拉取上游、合并、重新应用自定义配置(品牌、链接、docker-compose、更新模块禁用)的标准化流程, 使用 /sync-upstream 即可触发。 Co-Authored-By: Claude Opus 4.6 --- skills/sync-upstream/SKILL.md | 206 ++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 skills/sync-upstream/SKILL.md diff --git a/skills/sync-upstream/SKILL.md b/skills/sync-upstream/SKILL.md new file mode 100644 index 00000000..7d6bd452 --- /dev/null +++ b/skills/sync-upstream/SKILL.md @@ -0,0 +1,206 @@ +--- +name: sync-upstream +description: 从上游 Wei-Shaw/sub2api 拉取最新代码并合并,自动保留所有 StarFireAPI 自定义配置(品牌、链接、docker-compose、更新模块禁用)。 +license: MIT +metadata: + author: huangzhenpc + version: "1.0" +--- + +# 同步上游(sync-upstream) + +## 触发条件 + +当以下任一条件满足时激活本技能: + +- 用户要求"拉取上游"、"同步上游"、"合并上游"、"sync upstream"。 +- 用户使用 `/sync-upstream` 命令。 + +## 目标 + +从上游仓库 `https://github.com/Wei-Shaw/sub2api.git` 拉取最新代码,合并到本地 `main` 分支,并确保所有 StarFireAPI 自定义配置不被覆盖。 + +## 自定义配置清单(必须保留) + +以下是本项目相对于上游的所有自定义改动,合并后必须逐项检查并保留: + +### 1. 品牌替换:`Sub2API` → `StarFireAPI` + +所有面向用户的前端代码中,`Sub2API` 必须替换为 `StarFireAPI`。涉及的文件类型: + +- `frontend/index.html` — 页面标题 +- `frontend/src/stores/app.ts` — siteName 默认值 +- `frontend/src/i18n/locales/en.ts` — 英文翻译中所有 `Sub2API` +- `frontend/src/i18n/locales/zh.ts` — 中文翻译中所有 `Sub2API` +- `frontend/src/views/**/*.vue` — HomeView、RegisterView、EmailVerifyView 等 +- `frontend/src/components/layout/AuthLayout.vue` — siteName 默认值 +- `frontend/src/router/title.ts` — 页面标题 fallback +- `frontend/src/router/index.ts` — siteName fallback +- `frontend/src/views/admin/SettingsView.vue` — site_name 默认值 +- `frontend/src/router/__tests__/title.spec.ts` — 测试期望值 + +**扫描方法**:合并后执行 `grep -rn "Sub2API" frontend/src/ --include="*.ts" --include="*.vue" --include="*.html"`,对所有影响运行时的结果替换为 `StarFireAPI`(代码注释可保留)。 + +### 2. 链接替换:GitHub → 官网 + +| 原始值 | 替换为 | +|--------|--------| +| `https://github.com/Wei-Shaw/sub2api` | `https://anthropic.edu.pl` | +| GitHub 图标 SVG(长 path) | 房子图标 `` | +| `viewOnGithub: 'View on GitHub'` | `viewOnGithub: 'Official Site'` | +| `viewOnGithub: '在 GitHub 上查看'` | `viewOnGithub: '访问官网'` | + +涉及文件: +- `frontend/src/components/layout/AppHeader.vue` +- `frontend/src/views/HomeView.vue` +- `frontend/src/i18n/locales/en.ts` +- `frontend/src/i18n/locales/zh.ts` + +**扫描方法**:合并后执行 `grep -rn "github.com/Wei-Shaw/sub2api" frontend/src/`,检查是否有新的前端 GitHub 链接被引入。 + +### 3. docker-compose 自定义(`deploy/docker-compose.yml`) + +| 配置项 | 上游默认值 | 我们的值 | +|--------|-----------|---------| +| compose project name | 无 | `name: xinghuoapi` | +| 镜像 | `weishaw/sub2api:latest` | `starfireapi:latest` | +| 端口映射 | `8080:8080` | `6580:8080` | +| Redis Host | `redis`(内置容器) | `${REDIS_HOST:-172.18.0.2}`(外部 Redis) | +| Redis Password | `${REDIS_PASSWORD:-}` | `${REDIS_PASSWORD:-redis_JCHeKT}` | +| Redis 容器 | 正常启用 | `profiles: [disabled]`(禁用) | +| sub2api depends_on | postgres + redis | 仅 postgres | + +**重要**:合并 docker-compose.yml 时要特别小心,新增的环境变量(如数据库连接池参数、OAuth secrets 等)应该接受,但上述自定义项必须保留。 + +### 4. 更新模块禁用 + +#### 后端 `backend/internal/handler/admin/system_handler.go` + +`CheckUpdates` 方法始终返回无更新: + +```go +func (h *SystemHandler) CheckUpdates(c *gin.Context) { + info, _ := h.updateSvc.CheckUpdate(c.Request.Context(), false) + response.Success(c, gin.H{ + "current_version": info.CurrentVersion, + "latest_version": info.CurrentVersion, + "has_update": false, + "build_type": "source", + }) +} +``` + +#### 前端 `frontend/src/stores/app.ts` + +`checkUpdates` action 中强制返回无更新: + +```typescript +latestVersion.value = data.current_version // 不用 data.latest_version +hasUpdate.value = false +buildType.value = 'source' +releaseInfo.value = null +``` + +#### 前端 `frontend/src/components/common/VersionBadge.vue` + +- `isReleaseBuild` 始终为 `false` +- 移除 `buildType` 和 `releaseInfo` computed 变量(避免 TS 未使用变量报错) +- 移除所有 GitHub release 链接、changelog 跳转链接 +- 移除 `viewRelease` / `viewChangelog` 相关的 `` 标签 + +## 工作流程 + +### 第 1 步:准备 + +```bash +# 1. 确保工作区干净 +git status + +# 2. 添加上游 remote(如果不存在) +git remote get-url upstream 2>/dev/null || git remote add upstream https://github.com/Wei-Shaw/sub2api.git + +# 3. 拉取上游最新代码 +git fetch upstream +``` + +### 第 2 步:分析差异 + +```bash +# 1. 查看上游领先的提交数 +git log --oneline HEAD..upstream/main | wc -l + +# 2. 查看变更统计 +git diff --stat HEAD...upstream/main | tail -5 + +# 3. 查看我们领先上游的自定义提交 +git log --oneline --no-merges upstream/main..HEAD +``` + +向用户报告差异概况,确认后继续。 + +### 第 3 步:执行合并 + +```bash +git merge upstream/main --no-edit +``` + +### 第 4 步:处理冲突(如有) + +- 如果有冲突文件,逐一解决 +- 优先采用上游的架构/代码重构,但保留自定义配置清单中的值 +- 解决后 `git add` 冲突文件 + +### 第 5 步:重新应用自定义配置 + +合并完成后(无论是否有冲突),必须全面扫描并修复: + +1. **品牌扫描**: + ```bash + grep -rn "Sub2API" frontend/src/ --include="*.ts" --include="*.vue" --include="*.html" + ``` + 将所有影响运行时的 `Sub2API` 替换为 `StarFireAPI`(代码注释除外)。 + +2. **链接扫描**: + ```bash + grep -rn "github.com/Wei-Shaw/sub2api" frontend/src/ + ``` + 将前端代码中的 GitHub 链接替换为 `anthropic.edu.pl`。 + +3. **docker-compose 检查**: + 确认 `deploy/docker-compose.yml` 中的自定义项未被覆盖。 + +4. **更新模块检查**: + 确认 `system_handler.go`、`app.ts`、`VersionBadge.vue` 中的更新禁用逻辑仍然生效。 + +### 第 6 步:提交 + +```bash +git add -A +git commit -m "同步上游至最新版本并重新应用自定义配置 + +上游新增功能: +- [列出主要新功能] + +自定义配置保留: +- 品牌化:Sub2API → StarFireAPI +- 链接:GitHub → anthropic.edu.pl 官网 +- docker-compose:starfireapi镜像、端口6580、外部Redis、项目名xinghuoapi +- 更新模块禁用 + +Co-Authored-By: Claude Opus 4.6 " +``` + +### 第 7 步:确认推送 + +询问用户是否推送到 origin: + +```bash +git push origin main +``` + +## 注意事项 + +- 合并前必须确保工作区干净(无未提交的改动) +- 如果上游有大量重构导致自定义文件结构变化,需要根据新结构重新应用自定义 +- `deploy/` 和 `backend/` 目录下的文档/配置模板中的 GitHub 链接和 Sub2API 字样可以保留(不影响运行时) +- 只替换 `frontend/src/` 下影响运行时行为的代码 From 4bc7fa0e3f4f416dc6f587b197fab936f4515418 Mon Sep 17 00:00:00 2001 From: huangzhenpc Date: Tue, 3 Mar 2026 10:23:20 +0800 Subject: [PATCH 2/4] =?UTF-8?q?chore:=20=E6=B7=BB=E5=8A=A0=20CLAUDE.md=20?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E6=8C=87=E5=8D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 包含 fork 自定义配置清单、构建测试命令、架构概览、编码规范和 skills 索引。 Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..730d38d9 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,85 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Fork Identity + +This is a **customized fork** of [Wei-Shaw/sub2api](https://github.com/Wei-Shaw/sub2api.git), branded as **StarFireAPI**. Upstream remote: `https://github.com/Wei-Shaw/sub2api.git`. + +### Customizations to preserve on every upstream sync + +| Category | Details | +|----------|---------| +| **Brand** | All user-facing `Sub2API` → `StarFireAPI` in `frontend/src/` (stores, i18n, views, components, router) | +| **Links** | GitHub links → `https://anthropic.edu.pl` in AppHeader, HomeView, i18n | +| **docker-compose** | Image: `starfireapi:latest`, port `6580:8080`, external Redis at `172.18.0.2:6379`, project name `xinghuoapi`, built-in Redis disabled | +| **Update module** | Disabled in `system_handler.go` (always returns no update), `app.ts` (forces `hasUpdate=false`), `VersionBadge.vue` (`isReleaseBuild=false`, removed GitHub release links) | + +Full details: `skills/sync-upstream/SKILL.md` + +## Build & Test Commands + +```bash +# Full build (backend + frontend) +make build + +# Backend only +cd backend && make build # Binary → bin/server +cd backend && make test # go test ./... + golangci-lint +cd backend && make test-unit # Unit tests only +cd backend && go test ./internal/service/... -run TestXxx # Single test + +# Frontend only +cd frontend && pnpm install --frozen-lockfile +cd frontend && pnpm dev # Dev server +cd frontend && pnpm build # Type-check + production build +cd frontend && pnpm test:run # Vitest +cd frontend && pnpm lint:check # ESLint (no fix) + +# Code generation (Ent ORM + Wire DI) +cd backend && make generate +``` + +## Architecture + +**AI API Gateway**: receives requests with user API keys → authenticates → selects upstream account (sticky session / load-aware) → forwards to upstream AI service → records usage for billing. + +### Backend (`backend/internal/`) + +- **Entry**: `cmd/server/main.go` — supports setup mode, auto-setup (Docker), normal server +- **DI**: Google Wire (`cmd/server/wire.go`) +- **Layers**: handler → service → repository (enforced by `depguard` — service must not import repository) +- **Key services**: `GatewayService` (request forwarding, account selection, failover), `OpenAIGatewayService`, `GeminiMessagesCompatService`, `AntigravityGatewayService` +- **ORM**: Ent (`ent/schema/` for definitions, `ent/` for generated code) +- **Middleware stack**: Recovery → Logger → CORS → SecurityHeaders → RequestBodyLimit → ClientRequestID → APIKeyAuth +- **Run modes**: `standard` (full SaaS with billing) / `simple` (skip billing checks) + +### Frontend (`frontend/src/`) + +- **Framework**: Vue 3 + Pinia + Vue Router + TailwindCSS +- **State**: `stores/app.ts` (global), `stores/auth.ts` (JWT auth) +- **i18n**: `i18n/locales/en.ts`, `zh.ts` — all user-facing strings +- **Embedded**: production build goes to `backend/internal/web/dist/` and is embedded into the Go binary + +### Gateway Routes + +``` +/v1/messages — Claude API compatible +/v1/responses — OpenAI API compatible +/v1beta/models/* — Gemini native API +/antigravity/v1/* — Antigravity platform +``` + +## Coding Conventions + +- **Go**: `gofmt`, `golangci-lint` (see `backend/.golangci.yml`), max 3 levels of `if` nesting +- **Frontend**: Vue SFC + TypeScript, 2-space indent, ESLint, components `PascalCase.vue`, composables `useXxx.ts` +- **Commits**: Conventional Commits (`feat(scope):`, `fix(scope):`, `chore(scope):`) +- **JSON hot-path**: prefer `gjson` over `encoding/json` for read-only/partial extraction +- **Layering**: handler/service must NOT import repository/gorm/redis directly + +## Skills (in `skills/`) + +- **sync-upstream** — Pulls and merges upstream sub2api, re-applies all StarFireAPI customizations. Trigger: "拉取上游", "同步上游", "sync upstream" +- **bug-fix-expert** — Multi-agent bug fix workflow with worktree isolation and cross-validation +- **code-review-expert** — Parallel 5-dimension code review with worktree isolation From 7b01adabe36fedd80cd475f68dd679169233b5dc Mon Sep 17 00:00:00 2001 From: huangzhenpc Date: Tue, 3 Mar 2026 10:46:12 +0800 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=20system=5Fhandle?= =?UTF-8?q?r.go=20=E6=9C=AA=E4=BD=BF=E7=94=A8=E7=9A=84=20net/http=20?= =?UTF-8?q?=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 合并上游后 CheckUpdates 方法不再使用 http 包,删除多余导入修复编译错误。 Co-Authored-By: Claude Opus 4.6 --- backend/internal/handler/admin/system_handler.go | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/internal/handler/admin/system_handler.go b/backend/internal/handler/admin/system_handler.go index a061cd31..98ac6784 100644 --- a/backend/internal/handler/admin/system_handler.go +++ b/backend/internal/handler/admin/system_handler.go @@ -2,7 +2,6 @@ package admin import ( "context" - "net/http" "strconv" "strings" "time" From cd95e143186d327ef4edcf38eaf0f46099790517 Mon Sep 17 00:00:00 2001 From: huangzhenpc Date: Tue, 3 Mar 2026 11:01:43 +0800 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20PGDATA=20=E8=B7=AF=E5=BE=84=E6=94=B9?= =?UTF-8?q?=E5=9B=9E=20PG18=20=E9=BB=98=E8=AE=A4=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=E7=8E=B0=E6=9C=89=E6=95=B0=E6=8D=AE=E5=8D=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现有数据存储在 /var/lib/postgresql/18/docker,上游新增的 PGDATA=/var/lib/postgresql/data 导致 initdb 找不到数据报错。 Co-Authored-By: Claude Opus 4.6 --- deploy/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index b1d0a012..e6925502 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -167,7 +167,7 @@ services: # postgres:18-alpine 默认 PGDATA=/var/lib/postgresql/18/docker(位于镜像声明的匿名卷 /var/lib/postgresql 内)。 # 若不显式设置 PGDATA,则即使挂载了 postgres_data 到 /var/lib/postgresql/data,数据也不会落盘到该命名卷, # docker compose down/up 后会触发 initdb 重新初始化,导致用户/密码等数据丢失。 - - PGDATA=/var/lib/postgresql/data + - PGDATA=/var/lib/postgresql/18/docker - POSTGRES_USER=${POSTGRES_USER:-sub2api} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required} - POSTGRES_DB=${POSTGRES_DB:-sub2api}