CPAMC 是从 Cli-Proxy-API-Management-Center(下称 Center)的历史分支分叉出来的项目,在 Center 基础上新增了用量监控(Usage Service)、服务商管理(Service Providers)、细化 AI Provider 编辑页等特性。
核心诉求:以「做加法」的方式将 CPAMC 的独有功能迁移到 Center,尽量不改动 Center 现有代码,避免 Center 的分支合并冲突和混乱开发。
| 类别 | 路径 | 说明 |
|---|---|---|
| Go 后端 | backend/ |
完整的独立 Go HTTP 服务(SQLite + Collector + API) |
| Docker | .devcontainer/docker-compose.usage.yml, .devcontainer/Dockerfile.usage-service, .devcontainer/.dockerignore |
Usage Service 部署配置 |
| 脚本 | bin/release, start-usage.sh, start-usage.bat |
发布与启动脚本 |
| 功能模块 | frontend/src/features/serviceProviders/ |
服务商管理完整页面 |
| Provider 组件 | frontend/src/components/providers/{AmpcodeSection,ClaudeSection,CodexSection,GeminiSection,OpenAISection,VertexSection,ProviderList,ProviderNav}/ |
各 Provider 独立编辑组件 |
| Provider 导出 | frontend/src/components/providers/index.ts, types.ts |
Provider 模块入口与类型 |
| UI 组件 | frontend/src/components/ui/{DropdownMenu,HeaderInputList,ModelInputList,modelInputListUtils}.* |
新增 UI 组件 |
| 页面 | frontend/src/pages/AiProviders*, MonitoringCenterPage, CodexInspectionPage |
各 Provider 编辑页、监控页 |
| Store | frontend/src/stores/use{ClaudeEdit,OpenAIEdit,UsageService}Store.ts |
新增状态管理 |
| 类型 | frontend/src/types/sourceInfo.ts |
来源信息类型 |
| 工具 | frontend/src/utils/{apiKeyHash,sourceResolver,usage}.*, frontend/src/utils/quota/{codexQuota,providers}/ |
API Key 哈希、来源解析、用量计算 |
| 测试 | ../../frontend/src/test/, frontend/src/utils/*.test.ts, frontend/src/utils/quota/*.test.ts |
测试文件 |
| CI | .github/workflows/{issue-check,pr-check}.yml |
GitHub Actions |
| 图片 | img/ |
项目图片资源 |
| 类别 | 文件 | 分歧程度 | 说明 |
|---|---|---|---|
| 路由 | frontend/src/router/MainRoutes.tsx |
重大 | CPA 拆分为各 Provider 独立路由;Center 用 ProvidersWorkbenchPage |
| 布局 | frontend/src/components/layout/MainLayout.tsx |
中等 | 导航项差异 |
| 样式 | frontend/src/styles/{components,layout,mixins,themes,variables}.scss |
中等 | 新增样式变量/组件 |
| 配置组件 | frontend/src/components/config/* |
中等 | 差异化配置编辑器 |
| Provider 组件 | frontend/src/components/providers/{ProviderStatusBar,hooks/useProviderRecentRequests,utils}.ts |
中等 | 逻辑扩展 |
| Quota | frontend/src/components/quota/*, frontend/src/utils/quota/* |
中等 | 新增 codex/xAI quota 支持 |
| 类型 | frontend/src/types/{authFile,config,provider,visualConfig}.ts |
中等 | 字段扩展 |
| 工具 | frontend/src/utils/{clipboard,connection,constants,format,helpers,validation}.ts |
轻微 | 小幅功能扩展 |
| Store | frontend/src/stores/index.ts, useQuotaStore.ts |
轻微 | 新增 store 注册 |
| i18n | frontend/src/i18n/locales/*.json |
轻微 | 新增翻译 key |
| 其他 | package.json, vite.config.ts, tsconfig.* |
轻微 | 新增依赖/配置 |
思路:将 CPAMC 独有代码组织为 Center 的一个独立 feature module,通过注册机制接入,不修改 Center 现有文件。
Center 项目结构(迁移后)
├── src/
│ ├── features/
│ │ ├── providers/ ← Center 原有
│ │ ├── serviceProviders/ ← CPA 新增(直接复制)
│ │ └── monitoring/ ← CPA 新增(从 pages/ 重组)
│ ├── modules/
│ │ └── cpa-extension/ ← CPA 扩展模块入口
│ │ ├── index.ts ← 注册路由、导航、store
│ │ ├── routes.tsx ← 扩展路由定义
│ │ └── nav.ts ← 扩展导航项
│ ├── components/
│ │ ├── providers/ ← Center 原有(不改动)
│ │ └── cpa/ ← CPA 新增 Provider 组件
│ │ ├── AmpcodeSection/
│ │ ├── ClaudeSection/
│ │ └── ...
│ └── ...
├── backend/ ← CPA 新增(直接复制)
└── ...
关键设计:
MainRoutes.tsx 不改动,新增一个 ModuleRegistry 在应用启动时动态注入扩展路由:
// src/modules/registry.ts
type RouteModule = { routes: RouteObject[] };
const modules: RouteModule[] = [];
export const registerModule = (m: RouteModule) => modules.push(m);
export const getModuleRoutes = () => modules.flatMap(m => m.routes);
MainLayout.tsx 不改动,通过注册函数注入导航项:
// src/modules/registry.ts
type NavItem = { path: string; label: string; icon: ReactNode };
const navItems: NavItem[] = [];
export const registerNav = (items: NavItem[]) => navItems.push(...items);
export const getNavItems = () => navItems;
// src/modules/cpa-extension/index.ts
import { registerModule, registerNav } from '../registry';
import { cpaRoutes } from './routes';
import { cpaNavItems } from './nav';
export function initCpaExtension() {
registerModule({ routes: cpaRoutes });
registerNav(cpaNavItems);
}
main.tsx 或 App.tsx 中加一行:
import { initCpaExtension } from '@/modules/cpa-extension';
initCpaExtension();
优点:
main.tsx 一行 + 注册机制基础设施)modules/cpa/ 下缺点:
对 Center 分叉修改的处理策略:
| 修改类型 | 处理方式 |
|---|---|
类型扩展 (types/*.ts) |
新建 frontend/src/modules/cpa/types/ 扩展类型,通过 interface 继承或交叉类型组合 |
| Store 扩展 | 新建 frontend/src/modules/cpa/stores/ 独立 store,不修改 Center 的 stores/index.ts |
| 工具函数扩展 | 新建 frontend/src/modules/cpa/utils/ 包装扩展,import Center 原函数后再组合 |
| 样式扩展 | 新建 frontend/src/modules/cpa/styles/ 覆盖样式,利用 CSS 优先级 |
| i18n 新增 key | 新建 frontend/src/modules/cpa/i18n/ 独立 namespace,通过 i18next 的 addResourceBundle 动态注入 |
| Provider 组件差异 | CPA 的新 Provider 组件放 frontend/src/components/cpa/,不修改 Center 的 providers/ |
思路:将 CPAMC 的独有代码独立为子模块,Center 通过 git submodule 引入。
优点:
缺点:
结论:不适合前端项目,不推荐。
思路:将 CPAMC 独有功能打包为 @cpa/extension npm 包,Center 安装后使用。
优点:
缺点:
结论:适合开源/跨团队场景,当前场景不推荐。
思路:直接将 CPAMC 新增文件复制到 Center,对分叉修改的文件手动合并。
优点:
缺点:
结论:不符合需求约束,仅作为最后手段。
frontend/src/modules/registry.ts — 模块注册中心(路由、导航、store)frontend/src/modules/types.ts — 模块接口定义frontend/src/main.tsx — 加载模块注册 + 初始化MainRoutes.tsx — 读取注册的路由(仅改这一处:用 getModuleRoutes() 替代硬编码)MainLayout.tsx — 读取注册的导航(仅改这一处:用 getNavItems() 替代硬编码)backend/ → 直接复制.devcontainer/docker-compose.usage.yml, .devcontainer/Dockerfile.usage-service → 直接复制frontend/src/features/serviceProviders/ → 直接复制frontend/src/components/ui/{DropdownMenu,HeaderInputList,ModelInputList}* → 直接复制frontend/src/utils/{apiKeyHash,sourceResolver,usage}* → 直接复制frontend/src/utils/quota/{codexQuota,providers}* → 直接复制../../frontend/src/test/ → 直接复制frontend/src/components/providers/{AmpcodeSection,...,VertexSection} → 复制到 frontend/src/components/cpa/frontend/src/components/providers/{ProviderList,ProviderNav,index,types}* → 复制到 frontend/src/components/cpa/frontend/src/modules/cpa-extension/routes.tsx,将 CPA 的各 Provider 路由和监控路由定义在此registerModule() 注册frontend/src/modules/cpa-extension/nav.ts,将 CPA 的导航项定义在此registerNav() 注册types/*.ts 不改动frontend/src/modules/cpa/types/,通过交叉类型组合useUsageServiceStore、useClaudeEditDraftStore、useOpenAIEditDraftStore 放 frontend/src/modules/cpa/stores/stores/index.tsfrontend/src/modules/cpa/i18n/ 各语言文件i18next.addResourceBundle() 在模块初始化时注入frontend/src/modules/cpa/styles/tsc --noEmit 无错误| 文件 | 改动 | 行数估计 |
|---|---|---|
frontend/src/main.tsx |
增加 initCpaExtension() 一行调用 |
+2 |
frontend/src/modules/registry.ts |
新增文件 | +50 |
frontend/src/modules/types.ts |
新增文件 | +20 |
frontend/src/router/MainRoutes.tsx |
用 getModuleRoutes() 替代硬编码 |
+3/-1 |
frontend/src/components/layout/MainLayout.tsx |
用 getNavItems() 替代硬编码 |
+3/-1 |
| 合计改动 Center 现有文件 | 2 个文件 | 约 5 行 |
| 风险 | 等级 | 应对 |
|---|---|---|
| 注册机制不够灵活 | 低 | 先满足当前需求,后续按需扩展 |
| CPA Provider 组件引用了 Center 内部类型 | 中 | 通过 re-export 或扩展类型桥接 |
| 样式冲突 | 低 | CSS Modules 本身隔离,CPA 扩展用独立前缀 |
| Center 上游升级破坏注册接口 | 低 | 注册接口极简(仅 route + nav),破坏概率极低 |
| 构建体积增大 | 低 | CPA 新增代码约 3700+ 行,对 SPA 影响可忽略 |
| 阶段 | 工时 |
|---|---|
| 基础设施(注册机制) | 2h |
| 纯增量代码迁移 | 3h |
| 分叉修改适配 | 4h |
| 验证与清理 | 2h |
| 合计 | 约 11h |
方案 A 追求的是:
这里的“会改动的文件”分三类:
../Cli-Proxy-API-Management-Center/src/router/MainRoutes.tsx是否必须改:是
改动目的:把 CPA 扩展页面挂进主路由
当前现状:路由表 mainRoutes 是硬编码数组,没有扩展点
预计改动内容:
cpaRoutes 或 getModuleRoutes()mainRoutes 改为:
改动量:小(约 3~8 行)
风险等级:低
原因:
建议写法:
MainRoutes.tsxconst routes = [...mainRoutes, ...cpaRoutes];
../Cli-Proxy-API-Management-Center/src/components/layout/MainLayout.tsx是否必须改:是
改动目的:把 CPA 扩展菜单挂进侧边栏/导航
当前现状:导航项和图标映射是硬编码的
预计改动内容:
cpaNavItems 或 getNavItems()改动量:小到中(约 5~15 行)
风险等级:低到中
原因:
建议写法:
MainLayout.tsx 知道 CPA 菜单细节const navItems = [...coreNavItems, ...cpaNavItems];
labelKey/icon/path../Cli-Proxy-API-Management-Center/src/main.tsx是否必须改:通常建议改,但理论上可绕开
改动目的:初始化 CPA 扩展(i18n 注入、模块注册、一次性 setup)
预计改动内容:
initCpaExtension();
改动量:极小(1~3 行)
风险等级:低
原因:
为什么建议改:
MainRoutes.tsx / MainLayout.tsx 分别做隐式初始化如果不改 main.tsx:
MainRoutes.tsx 或 MainLayout.tsx 中直接 import 扩展数据../Cli-Proxy-API-Management-Center/src/i18n/index.ts是否必须改:否
推荐策略:尽量不改
原因:
i18next.addResourceBundle() 动态注入什么时候才需要改:
改动量:如果改,也很小
风险等级:低
结论:能不改就不改
../Cli-Proxy-API-Management-Center/package.json是否必须改:大概率需要
但性质不同:这是依赖接入,不属于业务侵入
预计改动内容:
vitest、react-test-renderer、@types/node 等风险等级:低
原因:
建议:
以下文件虽然 CPAMC 与 Center 存在差异,但在方案 A 下,原则上都应该通过“扩展层新增文件”来绕开,而不是直接修改 Center 原文件。
../Cli-Proxy-API-Management-Center/src/types/provider.ts../Cli-Proxy-API-Management-Center/src/types/config.ts../Cli-Proxy-API-Management-Center/src/types/authFile.ts../Cli-Proxy-API-Management-Center/src/types/visualConfig.ts原因:
ExtendedProviderExtendedAppConfigUsageConfig风险:低
结论:不建议改原文件
../Cli-Proxy-API-Management-Center/src/stores/index.ts原因:
useUsageServiceStore、useOpenAIEditDraftStore、useClaudeEditDraftStore风险:低
结论:不建议改原文件
../Cli-Proxy-API-Management-Center/src/i18n/locales/en.json../Cli-Proxy-API-Management-Center/src/i18n/locales/zh-CN.json../Cli-Proxy-API-Management-Center/src/i18n/locales/zh-TW.json../Cli-Proxy-API-Management-Center/src/i18n/locales/ru.json原因:
风险:中(如果直接改)
结论:尽量不要改
frontend/src/components/config/*frontend/src/components/quota/*frontend/src/components/providers/*(Center 原有部分)frontend/src/features/providers/*frontend/src/pages/*(Center 原有页面)原因:
推荐做法:
风险:高(如果直接改)
结论:原则上不动
../Cli-Proxy-API-Management-Center/src/router/MainRoutes.tsx../Cli-Proxy-API-Management-Center/src/components/layout/MainLayout.tsx../Cli-Proxy-API-Management-Center/src/main.tsx../Cli-Proxy-API-Management-Center/package.json(仅在缺依赖时)../Cli-Proxy-API-Management-Center/src/types/*../Cli-Proxy-API-Management-Center/src/stores/index.ts../Cli-Proxy-API-Management-Center/src/i18n/locales/*.json../Cli-Proxy-API-Management-Center/src/components/config/*../Cli-Proxy-API-Management-Center/src/components/providers/*(Center 原生部分)../Cli-Proxy-API-Management-Center/src/components/quota/*../Cli-Proxy-API-Management-Center/src/features/providers/*../Cli-Proxy-API-Management-Center/src/pages/*(已有页面)只改 2 个原文件:
MainRoutes.tsxMainLayout.tsx特点:
cpaRoutes / cpaNavItems改 3 个原文件:
main.tsxMainRoutes.tsxMainLayout.tsx特点:
改 4~6 个原文件/核心文件:
main.tsxMainRoutes.tsxMainLayout.tsxfrontend/src/modules/registry.ts、frontend/src/modules/types.ts特点:
如果当前目标是:
那么最合适的是:
frontend/src/main.tsxfrontend/src/router/MainRoutes.tsxfrontend/src/components/layout/MainLayout.tsxpackage.json(仅当确实缺依赖时)也就是说,Center 真正需要改的业务壳层文件,大概率只有 3 个。
这已经是“能挂进去、能维护、还能控制冲突”的一个比较优的平衡点。
以下按三个层次分类:不需要移植、需要隔离(放 frontend/src/external/)、可直接使用社区原文件。
这些文件是 CPAMC 对社区样式的覆盖/重写,移植回去会破坏社区的界面风格和布局,应当放弃。
| 文件 | 差异内容 | 不移植原因 |
|---|---|---|
frontend/src/styles/variables.scss |
色彩体系从暖灰改为 Element Plus 蓝色风格 | 会覆盖社区配色方案 |
frontend/src/styles/themes.scss |
全部 CSS 变量值不同(暖灰 vs 冷蓝) | 会覆盖社区主题 |
frontend/src/styles/components.scss |
142 行差异,组件样式覆盖 | 会覆盖社区组件样式 |
frontend/src/styles/layout.scss |
409 行差异,布局/间距/宽度覆盖 | 会覆盖社区布局 |
frontend/src/styles/mixins.scss |
新增 4 个响应式断点 mixin | 仅 CPA 自用布局需要 |
frontend/src/components/ui/icons.tsx |
图标替换(Plus/Pencil/AlertTriangle → Chevron 系列),stroke 属性不同 | 社区图标体系不同,按需在 external 中单独定义 |
../README.md / ../README_CN.md |
项目描述差异 | 各自维护,不需要移植 |
doc.local/summary.md |
各自技术文档 | 各自维护 |
AGENTS.md |
各自开发约束 | 各自维护 |
frontend/src/external/)这些是 CPAMC 新增或大幅改动的功能代码,必须移植但不能放入社区原目录,需隔离到 frontend/src/external/ 下。
frontend/src/external/)| 原路径 | 目标路径 | 说明 |
|---|---|---|
backend/ |
backend/ |
Go 后端服务,独立进程,直接放项目根目录 |
.devcontainer/docker-compose.usage.yml |
.devcontainer/docker-compose.usage.yml |
Docker 部署配置 |
.devcontainer/Dockerfile.usage-service |
.devcontainer/Dockerfile.usage-service |
Docker 镜像 |
.devcontainer/.dockerignore |
.devcontainer/.dockerignore |
Docker 忽略规则 |
bin/ |
bin/ |
发布/启动脚本 |
../../frontend/src/test/ |
../../frontend/src/test/ |
测试文件 |
img/ |
img/ |
项目图片 |
前端 frontend/src/ 下的纯新增:
| 原路径 | 目标路径 | 说明 |
|---|---|---|
frontend/src/features/monitoring/ |
frontend/src/external/features/monitoring/ |
监控模块(账号额度/健康状态/使用量) |
frontend/src/features/requestMonitor/ |
frontend/src/external/features/requestMonitor/ |
请求监控页面 |
frontend/src/features/serviceProviders/hooks/ |
frontend/src/external/features/serviceProviders/hooks/ |
服务商 hooks |
frontend/src/features/serviceProviders/ui/ |
frontend/src/external/features/serviceProviders/ui/ |
服务商 UI 组件 |
frontend/src/features/serviceProviders/utils/ |
frontend/src/external/features/serviceProviders/utils/ |
服务商工具函数 |
frontend/src/features/serviceProviders/styles/ |
frontend/src/external/features/serviceProviders/styles/ |
服务商样式 |
frontend/src/features/serviceProviders/types.ts |
frontend/src/external/features/serviceProviders/types.ts |
服务商类型 |
frontend/src/features/serviceProviders/index.tsx |
frontend/src/external/features/serviceProviders/index.tsx |
服务商入口 |
frontend/src/components/providers/AmpcodeSection/ |
frontend/src/external/components/providers/AmpcodeSection/ |
Ampcode 编辑组件 |
frontend/src/components/providers/ClaudeSection/ |
frontend/src/external/components/providers/ClaudeSection/ |
Claude 编辑组件 |
frontend/src/components/providers/CodexSection/ |
frontend/src/external/components/providers/CodexSection/ |
Codex 编辑组件 |
frontend/src/components/providers/GeminiSection/ |
frontend/src/external/components/providers/GeminiSection/ |
Gemini 编辑组件 |
frontend/src/components/providers/OpenAISection/ |
frontend/src/external/components/providers/OpenAISection/ |
OpenAI 编辑组件 |
frontend/src/components/providers/VertexSection/ |
frontend/src/external/components/providers/VertexSection/ |
Vertex 编辑组件 |
frontend/src/components/providers/ProviderList.tsx |
frontend/src/external/components/providers/ProviderList.tsx |
Provider 列表 |
frontend/src/components/providers/ProviderNav/ |
frontend/src/external/components/providers/ProviderNav/ |
Provider 导航 |
frontend/src/components/providers/index.ts |
frontend/src/external/components/providers/index.ts |
Provider 导出入口 |
frontend/src/components/providers/types.ts |
frontend/src/external/components/providers/types.ts |
Provider 扩展类型 |
frontend/src/components/ui/DropdownMenu.* |
frontend/src/external/components/ui/DropdownMenu.* |
下拉菜单组件 |
frontend/src/components/ui/HeaderInputList.tsx |
frontend/src/external/components/ui/HeaderInputList.tsx |
Header 输入列表 |
frontend/src/components/ui/ModelInputList.tsx |
frontend/src/external/components/ui/ModelInputList.tsx |
Model 输入列表 |
frontend/src/components/ui/modelInputListUtils.ts |
frontend/src/external/components/ui/modelInputListUtils.ts |
Model 输入工具 |
frontend/src/pages/AiProvidersPage.tsx |
frontend/src/external/pages/AiProvidersPage.tsx |
AI Provider 列表页 |
frontend/src/pages/AiProvidersPage.module.scss |
frontend/src/external/pages/AiProvidersPage.module.scss |
列表页样式 |
frontend/src/pages/AiProviders*EditPage.tsx (8个) |
frontend/src/external/pages/AiProviders*EditPage.tsx |
各 Provider 编辑页 |
frontend/src/pages/AiProvidersEditLayout.module.scss |
frontend/src/external/pages/AiProvidersEditLayout.module.scss |
编辑页布局样式 |
frontend/src/pages/MonitoringCenterPage.* |
frontend/src/external/pages/MonitoringCenterPage.* |
监控中心页 |
frontend/src/pages/CodexInspectionPage.* |
frontend/src/external/pages/CodexInspectionPage.* |
Codex 巡检页 |
frontend/src/pages/Login/ |
frontend/src/external/pages/Login/ |
登录页模块 |
frontend/src/pages/loginMode.ts |
frontend/src/external/pages/loginMode.ts |
登录模式 |
frontend/src/stores/useUsageServiceStore.ts |
frontend/src/external/stores/useUsageServiceStore.ts |
Usage 服务状态 |
frontend/src/stores/useClaudeEditDraftStore.ts |
frontend/src/external/stores/useClaudeEditDraftStore.ts |
Claude 编辑草稿 |
frontend/src/stores/useOpenAIEditDraftStore.ts |
frontend/src/external/stores/useOpenAIEditDraftStore.ts |
OpenAI 编辑草稿 |
frontend/src/types/sourceInfo.ts |
frontend/src/external/types/sourceInfo.ts |
来源信息类型 |
frontend/src/utils/apiKeyHash.ts |
frontend/src/external/utils/apiKeyHash.ts |
API Key 哈希 |
frontend/src/utils/sourceResolver.ts |
frontend/src/external/utils/sourceResolver.ts |
来源解析 |
frontend/src/utils/usage.ts |
frontend/src/external/utils/usage.ts |
使用量计算 |
frontend/src/utils/quota/codexQuota.ts |
frontend/src/external/utils/quota/codexQuota.ts |
Codex 额度 |
frontend/src/utils/quota/providers/ |
frontend/src/external/utils/quota/providers/ |
额度 Provider |
frontend/src/hooks/useApi.ts |
frontend/src/external/hooks/useApi.ts |
API 请求 hook |
frontend/src/hooks/useDebounce.ts |
frontend/src/external/hooks/useDebounce.ts |
防抖 hook |
frontend/src/hooks/usePagination.ts |
frontend/src/external/hooks/usePagination.ts |
分页 hook |
frontend/src/hooks/useRequestMonitoringAvailability.ts |
frontend/src/external/hooks/useRequestMonitoringAvailability.ts |
监控可用性 hook |
frontend/src/services/api/usageService.ts |
frontend/src/external/backend/api/usageService.ts |
Usage API 层 |
frontend/src/services/api/codexQuota.ts |
frontend/src/external/backend/api/codexQuota.ts |
Codex 额度 API |
frontend/src/features/authFiles/sessionAuthConverter.ts |
frontend/src/external/features/authFiles/sessionAuthConverter.ts |
Session 认证转换 |
测试文件:
| 原路径 | 目标路径 |
|---|---|
frontend/src/utils/apiKeyHash.test.ts |
frontend/src/external/utils/apiKeyHash.test.ts |
frontend/src/utils/connection.test.ts |
frontend/src/external/utils/connection.test.ts |
frontend/src/utils/usage.test.ts |
frontend/src/external/utils/usage.test.ts |
frontend/src/utils/quota/codexQuota.test.ts |
frontend/src/external/utils/quota/codexQuota.test.ts |
frontend/src/services/api/usageService.test.ts |
frontend/src/external/backend/api/usageService.test.ts |
frontend/src/services/api/codexQuota.test.ts |
frontend/src/external/backend/api/codexQuota.test.ts |
frontend/src/services/api/providers.test.ts |
frontend/src/external/backend/api/providers.test.ts |
frontend/src/services/api/authFiles.test.ts |
frontend/src/external/backend/api/authFiles.test.ts |
frontend/src/features/authFiles/sessionAuthConverter.test.ts |
frontend/src/external/features/authFiles/sessionAuthConverter.test.ts |
frontend/src/features/authFiles/hooks/useAuthFilesData.test.ts |
frontend/src/external/features/authFiles/hooks/useAuthFilesData.test.ts |
frontend/src/pages/MonitoringCenterPage.test.tsx |
frontend/src/external/pages/MonitoringCenterPage.test.tsx |
frontend/src/pages/AuthFilesPage.*.test.tsx |
frontend/src/external/pages/AuthFilesPage.*.test.tsx |
frontend/src/pages/ConfigPage.test.ts |
frontend/src/external/pages/ConfigPage.test.ts |
frontend/src/pages/LoginPage.test.ts |
frontend/src/external/pages/LoginPage.test.ts |
frontend/src/features/monitoring/*.test.ts |
frontend/src/external/features/monitoring/*.test.ts |
这些文件在社区项目中已存在,CPAMC 对其做了功能扩展或修改。不能直接覆盖社区文件,需要把 CPA 的差异部分拆到 frontend/src/external/ 中。
| 文件 | 差异内容 | 隔离策略 |
|---|---|---|
frontend/src/components/providers/ProviderStatusBar.tsx |
扩展了状态展示逻辑 | 将 CPA 扩展版本放 frontend/src/external/components/providers/ProviderStatusBar.tsx,external 页面引用扩展版 |
frontend/src/components/providers/hooks/useProviderRecentRequests.ts |
扩展了请求监控 | 将 CPA 扩展版本放 frontend/src/external/components/providers/hooks/ |
frontend/src/components/providers/utils.ts |
扩展了工具函数 | 将 CPA 扩展版本放 frontend/src/external/components/providers/utils.ts |
frontend/src/components/quota/quotaConfigs.ts |
新增 codex/xAI quota 配置 | 将扩展配置放 frontend/src/external/components/quota/quotaConfigs.ts,动态合并 |
frontend/src/components/quota/QuotaSection.tsx |
集成 codex quota | 将扩展版放 frontend/src/external/components/quota/QuotaSection.tsx |
frontend/src/components/quota/index.ts |
新增 re-export | 在 frontend/src/external/components/quota/index.ts 自行导出 |
frontend/src/utils/quota/constants.ts |
新增 codex 常量 | 将扩展常量放 frontend/src/external/utils/quota/constants.ts |
frontend/src/utils/quota/index.ts |
新增 codex 导出 | 在 frontend/src/external/utils/quota/index.ts 自行导出 |
frontend/src/utils/quota/parsers.ts |
新增 codex 解析 | 将扩展版放 frontend/src/external/utils/quota/parsers.ts |
frontend/src/utils/quota/resolvers.ts |
新增 codex 解析 | 将扩展版放 frontend/src/external/utils/quota/resolvers.ts |
frontend/src/utils/quota/validators.ts |
新增 codex 验证 | 将扩展版放 frontend/src/external/utils/quota/validators.ts |
frontend/src/utils/connection.ts |
新增 resolveDefaultCPAConnectionBase 等 |
将新增函数放 frontend/src/external/utils/connection.ts,import 社区原函数后扩展 |
frontend/src/utils/constants.ts |
新增 OAuth/分页/日志等常量 | 将新增常量放 frontend/src/external/utils/constants.ts |
frontend/src/utils/format.ts |
新增 maskSensitiveText、formatDateTime 等 |
将新增函数放 frontend/src/external/utils/format.ts |
frontend/src/utils/helpers.ts |
新增 normalizeArrayResponse、debounce、throttle |
将新增函数放 frontend/src/external/utils/helpers.ts |
frontend/src/utils/validation.ts |
新增 isValidUrl、isValidApiBase、isValidApiKey 等 |
将新增函数放 frontend/src/external/utils/validation.ts |
frontend/src/utils/clipboard.ts |
CPA 删除了 readFromClipboard |
不需要移植,社区原版保持不变 |
frontend/src/types/provider.ts |
新增 headers?: Record<string, string> |
在 frontend/src/external/types/provider.ts 中定义 ExtendedProvider 交叉类型 |
frontend/src/types/config.ts |
新增 clean、usageStatisticsEnabled 等 |
在 frontend/src/external/types/config.ts 中定义 ExtendedAppConfig 交叉类型 |
frontend/src/types/authFile.ts |
字段扩展 | 在 frontend/src/external/types/authFile.ts 中定义扩展类型 |
frontend/src/types/visualConfig.ts |
字段扩展 | 在 frontend/src/external/types/visualConfig.ts 中定义扩展类型 |
frontend/src/stores/index.ts |
新增 3 个 store re-export | 不需要改,external 内部自行 import |
frontend/src/stores/useQuotaStore.ts |
扩展了 quota 逻辑 | 将扩展版放 frontend/src/external/stores/useQuotaStore.ts |
frontend/src/services/api/version.ts |
新增 checkManagerLatest |
将扩展版放 frontend/src/external/backend/api/version.ts |
frontend/src/i18n/locales/*.json |
新增大量翻译 key(1272 行差异) | 将新增 key 放 frontend/src/external/i18n/ 独立 JSON,运行时动态注入 |
这些文件的差异主要是样式/布局,必须用 CSS Modules 局部作用域隔离,确保不影响社区界面。
| 文件 | 差异内容 | 隔离策略 |
|---|---|---|
frontend/src/components/config/ConfigSection.tsx + .module.scss |
社区新增 indexLabel prop,CPA 去掉了 |
不移植,使用社区原版 |
frontend/src/components/config/VisualConfigEditor.tsx + .module.scss + Blocks.tsx |
样式和布局差异 | 不移植样式差异,功能差异如需要则在 external 中另建 |
frontend/src/components/common/PageTransition.tsx |
动画差异 | 不移植,使用社区原版 |
frontend/src/components/modelAlias/ModelMappingDiagram.tsx |
渲染差异 | 不移植,使用社区原版 |
frontend/src/components/ui/Modal.tsx |
样式差异 | 不移植,使用社区原版 |
frontend/src/components/ui/Select.tsx + .module.scss |
样式差异 | 不移植,使用社区原版 |
frontend/src/components/ui/SelectionCheckbox.tsx + .module.scss |
样式差异 | 不移植,使用社区原版 |
frontend/src/components/ui/ToggleSwitch.module.scss |
样式差异 | 不移植,使用社区原版 |
frontend/src/features/authFiles/components/*.tsx |
样式/布局差异 | 不移植样式差异,功能差异如需要则在 external 中另建 |
以下类型的文件不存在合并冲突风险,可以直接使用社区版本:
| 类型 | 说明 |
|---|---|
frontend/src/assets/ 下的 SVG/图片 |
静态资源,直接引用社区路径 |
frontend/src/components/ui/Collapsible/ |
社区独有的 UI 组件,CPA 不需要 |
frontend/src/utils/routeParams.ts |
社区独有的路由工具,CPA 不需要 |
frontend/src/components/ui/scrollLock.ts |
社区独有,CPA 不需要 |
.github/workflows/release.yml |
各自维护 |
.gitignore |
各自维护 |
| 分类 | 数量 | 处理方式 |
|---|---|---|
| 不需要移植 | ~13 个文件 | 放弃(样式覆盖/各自维护) |
纯新增,直接搬入 frontend/src/external/ |
~70+ 个文件/目录 | 搬入对应 external 子目录 |
| 社区已有但需拆分隔离 | ~25 个文件 | 差异部分拆到 external,复用社区原文件 |
| 需要样式隔离 | ~9 个文件 | 不移植样式差异,用社区原版 |
| 可直接使用社区原文件 | 若干 | 直接引用,不拷贝 |
仅列出 CPAMC 比 Center 多出来或版本不同的依赖。迁移到 Center 时只补真正缺失的,不做无谓升级。
Center 与 CPAMC 的运行时依赖完全一致(名称相同,版本号差异可忽略),无需追加。
| 包名 | Center 有? | CPA 版本 | 是否需补 | 说明 |
|---|---|---|---|---|
vitest |
❌ | ^4.1.5 |
是 | external 模块和测试依赖 vitest 运行 |
react-test-renderer |
❌ | ^19.2.1 |
是 | 测试所需,renderer 组件测试 |
@types/react-test-renderer |
❌ | ^19.1.0 |
是 | TypeScript 类型定义 |
@types/node |
❌ | ^25.7.0 |
视需求 | 如果 external 中无 Node 特定代码则不需要 |
prettier |
✅ | ^3.7.4 |
否 | Center 已有,版本可对齐 |
操作建议:
package.json 中只追加 vitest、react-test-renderer、@types/react-test-renderer| 文件 | 处理 |
|---|---|
package-lock.json |
不迁移(Center 使用 bun,保留 bun.lock) |
bun.lock |
不迁移(各自锁定) |
下面列出 CPAMC 所有新增页面路由、对应目标路径、以及导航归属。
frontend/src/external/pages/)| CPA 当前路由 | external 目标页面 | 说明 |
|---|---|---|
/ai-providers |
frontend/src/external/pages/AiProvidersPage.tsx |
AI Provider 总览列表(替换 Center 的 /ai-providers 单页) |
/ai-providers/gemini/new |
frontend/src/external/pages/AiProvidersGeminiEditPage.tsx |
新建 Gemini |
/ai-providers/gemini/:index |
frontend/src/external/pages/AiProvidersGeminiEditPage.tsx |
编辑 Gemini |
/ai-providers/codex/new |
frontend/src/external/pages/AiProvidersCodexEditPage.tsx |
新建 Codex |
/ai-providers/codex/:index |
frontend/src/external/pages/AiProvidersCodexEditPage.tsx |
编辑 Codex |
/ai-providers/claude/new |
frontend/src/external/pages/AiProvidersClaudeEditLayout.tsx |
新建 Claude 布局 |
/ai-providers/claude/new (子) |
frontend/src/external/pages/AiProvidersClaudeEditPage.tsx |
Claude 编辑(含模型) |
/ai-providers/claude/:index |
frontend/src/external/pages/AiProvidersClaudeEditLayout.tsx |
编辑 Claude 布局 |
/ai-providers/claude/:index (子) |
frontend/src/external/pages/AiProvidersClaudeEditPage.tsx |
Claude 编辑 |
/ai-providers/claude/:index/models |
frontend/src/external/pages/AiProvidersClaudeModelsPage.tsx |
Claude 模型管理 |
/ai-providers/vertex/new |
frontend/src/external/pages/AiProvidersVertexEditPage.tsx |
新建 Vertex |
/ai-providers/vertex/:index |
frontend/src/external/pages/AiProvidersVertexEditPage.tsx |
编辑 Vertex |
/ai-providers/openai/new |
frontend/src/external/pages/AiProvidersOpenAIEditLayout.tsx |
新建 OpenAI 布局 |
/ai-providers/openai/:index |
frontend/src/external/pages/AiProvidersOpenAIEditLayout.tsx |
编辑 OpenAI 布局 |
/ai-providers/openai/:index/models |
frontend/src/external/pages/AiProvidersOpenAIModelsPage.tsx |
OpenAI 模型管理 |
/ai-providers/ampcode |
frontend/src/external/pages/AiProvidersAmpcodeEditPage.tsx |
Ampcode 编辑 |
/monitoring |
frontend/src/external/pages/MonitoringCenterPage.tsx |
监控中心 |
/monitoring/codex-inspection |
frontend/src/external/pages/CodexInspectionPage.tsx |
Codex 巡检 |
/realtime/request |
frontend/src/external/features/requestMonitor/RequestMonitorPage.tsx |
实时请求监控 |
MainLayout.tsx)| 路径 | 导航标签 key | 图标 | 分组 | 触发条件 |
|---|---|---|---|---|
/ai-providers |
nav.ai_providers |
sidebarIcons.aiProviders |
gateway | 替换 Center 原有 AI Providers 页 |
/realtime/request |
nav.realtime_monitor |
sidebarIcons.monitoring |
gateway | 始终显示 |
/monitoring |
nav.monitoring_center |
sidebarIcons.monitoring |
observe | 仅在 requestMonitoring 可用时显示 |
/monitoring/codex-inspection |
— | — | — | 不单独显示导航,入口在监控中心页面内 |
| Center 当前 | CPA 版本 | 冲突 | 处理 |
|---|---|---|---|
/ai-providers → ProvidersWorkbenchPage |
/ai-providers → AiProvidersPage(新增子路由) |
是 | external 页面接管该路由路径 |
无 /monitoring 路由 |
新增 /monitoring 和子路由 |
否 | 纯新增,追加到路由表 |
无 /realtime/request 路由 |
新增 /realtime/request |
否 | 纯新增 |
/service-providers → ServiceProvidersPage |
同 Center 路径,但 CPA 额外有 hooks/utils | 轻微 | 保留 Center 入口,external 补充增量 |
frontend/src/i18n/locales/*.json(CPA 版本)中仅提取 Center 版本不存在的 keyfrontend/src/external/i18n/locales/i18next.addResourceBundle()frontend/src/i18n/locales/*.jsonfrontend/src/i18n/index.ts| Center 文件 | CPA 新增字段 | 扩展方式 | 存放位置 |
|---|---|---|---|
frontend/src/types/provider.ts |
headers?: Record<string, string> |
交叉类型 ExtendedProvider |
frontend/src/external/types/provider.ts |
frontend/src/types/config.ts |
clean?, usageStatisticsEnabled? 等 |
交叉类型 ExtendedAppConfig |
frontend/src/external/types/config.ts |
frontend/src/types/authFile.ts |
字段扩展 | 交叉类型 | frontend/src/external/types/authFile.ts |
frontend/src/types/visualConfig.ts |
字段扩展 | 交叉类型 | frontend/src/external/types/visualConfig.ts |
frontend/src/types/sourceInfo.ts |
纯新增 | 直接定义 | frontend/src/external/types/sourceInfo.ts |
| 文件 | 差异存在? | 说明 |
|---|---|---|
vite.config.ts |
无差异 | 完全一致 |
eslint.config.js |
无差异 | 完全一致 |
tsconfig.json |
仅多 types: ["vite/client"] |
如 external 编译报类型错误,可申请追加 |
tsconfig.node.json |
仅多 declaration 输出 | 如 external 不需要声明文件输出,不修改 |
| 文件 | 改动范围 |
|---|---|
frontend/src/main.tsx |
追加 external 初始化调用,<= 3 行 |
frontend/src/router/MainRoutes.tsx |
追加 external 路由,不对 Center 已有路由做结构性改动 |
frontend/src/components/layout/MainLayout.tsx |
追加 external 导航项,不改变现有导航分组结构 |
package.json |
仅追加 external 所需依赖,不升级已有依赖 |
| # | 验收项 | 通过标准 |
|---|---|---|
| 1 | external 隔离 | 所有 CPA 增量代码在 frontend/src/external/ 和 backend/ 目录下 |
| 2 | Center 主题不变 | 页面打开后色彩、字体、间距、圆角等与 Center 原版一致 |
| 3 | Center 样式不变 | 社区原有页面渲染效果与迁移前无差异 |
| 4 | 壳层改动最小 | git diff 仅包含 4 个壳层文件 + external 新增 |
| 5 | 新增路由可访问 | /monitoring、/ai-providers/gemini/new 等新路由在浏览器可正常访问 |
| 6 | 新增导航可见 | 导航栏出现 monitoring_center、realtime_monitor 等新菜单项 |
| 7 | i18n 正常 | 切换语言后 external 页面文案同步切换 |
| 8 | 编译通过 | bun run build 成功 |
| 9 | 类型检查通过 | tsc --noEmit 无错误 |
| 10 | 测试通过 | bun test 或 vitest run 通过 |
| 11 | 无社区无关改动 | git diff 中不存在对 Center 现有组件的无意修改 |
| 12 | Center 原有路由正常 | /、/config、/auth-files、/oauth 等核心路由可访问 |
main 创建 feat/cpa-integration 分支frontend/src/external/ 和 backend/ — 增量功能代码(大面积)| 版本 | 日期 | 变更 |
|---|---|---|
| 0.1 | 2026-06-15 | 初稿:背景 + 四种方案分析 |
| 0.2 | 2026-06-15 | 补充方案 A 文件改动评估 |
| 0.3 | 2026-06-16 | 补充增量隔离清单、依赖差异、路由映射、i18n策略、类型扩展、验收标准 |
本节补充
frontend/src/features/authFiles/相关的功能差异,这些在原文档中被低估了。
| 文件 | 说明 |
|---|---|
frontend/src/features/authFiles/sessionAuthConverter.ts + .test.ts |
Session Auth 转换器,将外部 auth json 转换为 CPA 格式 |
frontend/src/features/authFiles/components/AuthJsonPasteModal.tsx + .module.scss + .test.tsx |
Auth JSON 粘贴弹窗 |
frontend/src/features/authFiles/hooks/useAuthFilesData.test.ts |
测试文件 |
| CPA 改动 | 差异内容 | 隔离建议 |
|---|---|---|
constants.ts |
新增 isHealthyAuthFile() 辅助函数 |
将该函数提取到 external |
uiState.ts |
排序模式从 3 种扩展到 8 种;新增 AUTH_FILES_VIEW_MODES(diagram/list);新增 viewMode、healthyOnly 状态 |
将扩展的状态放 external |
useAuthFilesData.ts |
新增 loadFiles({ throwOnError }) 参数;新增 savePastedAuthJson() 方法;新增 healthyOnly 筛选;新增 authJsonPasteSaving 状态 |
将 hook 扩展版放入 external,不改社区原 hook |
useAuthFilesPrefixProxyEditor.ts |
细微调整(1 行差异) | 可忽略,沿用社区版 |
AuthFileCard.tsx |
新增 projectIdValue 字段展示;新增健康状态卡片样式;按钮展 logic 调整 |
展示层差异,不改社区组件,external 如需要则另建卡片组件 |
AuthFileQuotaSection.tsx |
字段/样式调整 | 同上 |
AuthFilesPrefixProxyEditorModal.tsx |
细微调整 | 可忽略 |
frontend/src/features/authFiles/ 下的任何已有文件src/external/features/authFiles/
├── sessionAuthConverter.ts # 复制
├── sessionAuthConverter.test.ts # 复制
├── components/
│ ├── AuthJsonPasteModal.tsx # 复制
│ ├── AuthJsonPasteModal.module.scss
│ └── AuthJsonPasteModal.test.tsx
├── hooks/
│ └── useAuthFilesDataExternal.ts # 重写,依赖社区的 useAuthFilesData 但扩展功能
├── uiState.ts # 复制 CPA 版或按需重写
└── constants.ts # 只复制 isHealthyAuthFile 等 CPA 特有函数
frontend/src/features/serviceProviders/ServiceProvidersPage.tsx 已被大幅改造./ui/*、./utils/*、./types 等相对路径而不是 @/features/providers/* 的绝对路径| 做法 | 说明 |
|---|---|
| 方案 A:直接替换 | 将 CPA 整个 ServiceProvidersPage.tsx 复制到 external,MainRoutes 仍然指向它 |
| 方案 B:保留社区页 | 只用 CPA 的 hooks/ui/utils,页面层仍然用社区原版(当前文档倾向这个) |
更推荐方案 A,因为:
frontend/src/hooks/index.ts| 差异 | 说明 |
|---|---|
新增 useApi、useDebounce、usePagination 导出 |
必须迁移到 external |
frontend/src/hooks/useVisualConfig.ts| 差异 | 说明 |
|---|---|
新增 usageStatisticsEnabled 校验 |
属于 usage 配置链,配置链路改动需慎重 |
新增 redisUsageQueueRetentionSeconds 校验 |
同上 |
校验函数实现差异(从 getNonNegativeIntegerError 改为 getRedisUsageQueueRetentionError) |
函数实现层面差异 |
useVisualConfig.ts以下差异在原文档中被归为“样式/布局”,但实际属于行为/交互层差异。首轮迁移时不处理,保持用社区版本。
| 文件 | 差异性质 | 首轮策略 |
|---|---|---|
frontend/src/components/common/PageTransition.tsx |
146 行 diff,动画行为差异 | 不迁移,继续用社区版 |
frontend/src/features/authFiles/components/AuthFileCard.tsx |
展示逻辑和行为调整 | 不迁移,external 如需要则另建 |
frontend/src/features/serviceProviders/ServiceProvidersPage.tsx |
页面本体改造 | 迁移到 external |
frontend/src/utils/quota/providers/ |
Codex 额度相关逻辑 | 迁移(已有) |
frontend/src/services/api/version.ts 的 checkManagerLatest |
GitHub API 调用,非核心功能 | 标记为“可选迁移” |
frontend/src/components/ui/icons.tsxfrontend/src/external/components/ui/icons.tsx 中定义 external 专用图标frontend/src/services/api/version.ts 中的 checkManagerLatest 访问 GitHub APItsc --noEmit 报错时再追加| 原文档表述 | 修正后 |
|---|---|
frontend/src/features/authFiles/ 只提 sessionAuthConverter.ts |
补充完整的 authFiles 增量清单(15.1–15.3) |
frontend/src/features/serviceProviders/ 只搬子目录 |
明确页面本体也要迁移(方案 A) |
frontend/src/hooks/index.ts 无差异 |
补充新增导出项(17.1) |
frontend/src/hooks/useVisualConfig.ts 无差异 |
补充配置校验差异(17.2) |
frontend/src/components/common/PageTransition.tsx 归为样式差异 |
改为“行为/交互差异,首轮不迁移” |
@types/node “视需求” |
明确“默认不加,报错再加” |
| 缺少图标策略 | 补充 19.1 节 |
| 版本 | 日期 | 变更 |
|---|---|---|
| 0.1 | 2026-06-15 | 初稿:背景 + 四种方案分析 |
| 0.2 | 2026-06-15 | 补充方案 A 文件改动评估 |
| 0.3 | 2026-06-16 | 补充增量隔离清单、依赖差异、路由映射、i18n策略、类型扩展、验收标准 |
| 0.4 | 2026-06-16 | 补充 authFiles 增量、serviceProviders 页面差异、hooks 差异、勘误对照表 |