{"id":50484759,"url":"https://github.com/seakee/cpa-manager-plus","last_synced_at":"2026-06-01T21:01:50.299Z","repository":{"id":358838167,"uuid":"1241362619","full_name":"seakee/CPA-Manager-Plus","owner":"seakee","description":"Management panel for CLI Proxy API with a Docker-ready Manager Server, SQLite usage analytics, request monitoring, model pricing, quota views, and Codex inspection.","archived":false,"fork":false,"pushed_at":"2026-05-26T10:14:04.000Z","size":9040,"stargazers_count":86,"open_issues_count":8,"forks_count":6,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-26T12:11:27.058Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seakee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-17T09:41:43.000Z","updated_at":"2026-05-26T12:05:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/seakee/CPA-Manager-Plus","commit_stats":null,"previous_names":["seakee/cpa-manager-plus"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/seakee/CPA-Manager-Plus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seakee%2FCPA-Manager-Plus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seakee%2FCPA-Manager-Plus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seakee%2FCPA-Manager-Plus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seakee%2FCPA-Manager-Plus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seakee","download_url":"https://codeload.github.com/seakee/CPA-Manager-Plus/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seakee%2FCPA-Manager-Plus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33793044,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-01T21:01:48.743Z","updated_at":"2026-06-01T21:01:50.290Z","avatar_url":"https://github.com/seakee.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CPA Manager Plus\n\n[中文文档](README_CN.md)\n\nA single-file Web UI for **CLI Proxy API (CPA)** plus a **Manager Server** for persistent usage analytics and panel hosting.\n\nSince v6.10.0, CPA no longer includes built-in usage statistics. This project now supports usage analytics through a long-running Manager Server that consumes the CPA usage queue, persists request events to SQLite, and exposes panel-compatible usage APIs.\n\nCPA Manager Plus is the recommended successor to CPA-Manager. It combines the CPA management panel with a Docker-ready Manager Server, admin-key protected full-panel mode, encrypted CPA Management Key storage, server-backed analytics, model pricing, API key aliases, dashboard cards, and Codex account inspection.\n\n- **CPA Main project**: https://github.com/router-for-me/CLIProxyAPI\n- **Recommended CPA version**: \u003e= v7.1.18\n- **Minimum CPA version for HTTP usage queue**: \u003e= v6.10.8\n\n## Panel Preview\n\n![Home dashboard showing traffic overview, collector status, usage metrics, health alerts, and version information](img/home.jpg)\n![Monitoring center showing usage analytics, realtime request events, account overview, API key breakdowns, and model cost statistics](img/monitoring.jpg)\n![Codex account inspection showing probe progress, account status, cleanup recommendations, and execution logs](img/codex-inspection.png)\n\n## What This Provides\n\n- A single-file React management panel for CPA Management API (`/v0/management`)\n- A Dockerized Manager Server for SQLite-backed usage persistence and built-in panel hosting\n- Native `amd64` and `arm64` packages for Windows, macOS, and Linux with the panel embedded\n- Two deployment modes:\n  - **Full Docker mode**: open the built-in panel from Manager Server; first startup logs an admin key, first setup uses that admin key to save the CPA connection, and later logins use the admin key to manage the whole panel\n  - **CPA panel mode**: keep using CPA's `/management.html` as a pure CPA panel; it does not configure or call a separate Manager Server\n- Full Docker mode adds runtime monitoring, account/model/channel breakdowns, model pricing, estimated token cost, imports/exports, API key aliases, server Codex inspection, and Manager Server system utilities\n- Both modes keep normal CPA management and local Codex account inspection available\n\n## Choose a Deployment Mode\n\n| Mode | Entry URL | What the user configures | Best for |\n|---|---|---|---|\n| Full Docker mode | `http://\u003chost\u003e:18317/management.html` | First startup log provides the admin key; first setup: admin key + CPA URL + CPA Management Key; later login: admin key | New deployments, one entry point, least browser/CORS complexity |\n| CPA panel mode | `http://\u003ccpa-host\u003e:8317/management.html` | Log in to CPA with the CPA Management Key | Existing CPA automatic panel loading without Manager Server analytics |\n| Frontend only | Vite dev server or `apps/web/dist/index.html` | CPA URL | Development |\n\nFull Docker mode does not bundle CPA itself. CPA still runs as the upstream service; the Docker image provides the Manager Server plus an embedded copy of this management panel.\n\n### Feature Boundary by Mode\n\n| Capability | Full Docker mode | CPA panel mode |\n|---|---:|---:|\n| CPA config, provider/account/key management, auth files, logs, quota views, and CPA Management API features | Yes | Yes |\n| Local Codex account inspection in the browser | Yes | Yes |\n| Manager Server setup, admin-key login, encrypted CPA Management Key storage | Yes | No |\n| Request monitoring, dashboard usage statistics, model prices, API key aliases, usage import/export | Yes | No |\n| Server Codex inspection, scheduled runs, persisted inspection history | Yes | No |\n| Manager Server `/status`, `/usage-service/config`, `/v0/management/usage`, model-price, alias, and import/export APIs | Admin key only | Not used |\n\nOne Manager Server binds to exactly one CPA during setup. The regular configuration page can change collector settings and update the CPA Management Key for that bound CPA, but it cannot switch to another CPA URL. To bind a different CPA, intentionally reset or migrate the Manager Server data/configuration.\n\n## CPA Prerequisites\n\nRequest statistics require the CPA usage queue:\n\n- CPA Management must be enabled because the usage queue uses the same availability and CPA Management Key as `/v0/management`.\n- Request monitoring requires CPA usage publishing: set `usage-statistics-enabled: true`, or submit `{ \"value\": true }` to `PUT /usage-statistics-enabled`. CPA Manager Plus enables this automatically when request monitoring is enabled during setup or configuration save.\n- Disabling CPAM request monitoring only stops the Manager Server collector. It does not automatically disable CPA usage publishing or clear the CPA usage queue. If CPA usage publishing remains enabled, re-enabling request monitoring within the queue retention window may collect events retained while the collector was stopped.\n- CPA `v7.1.18+` is recommended for current panel capabilities and the full Redis usage metadata set used by newer monitoring views: request-side `reasoning_effort`, `tokens.cache_read_tokens`, `tokens.cache_creation_tokens`, `fail.status_code`, and `fail.body`. CPA `v6.10.8+` already exposes the HTTP usage queue endpoint `/v0/management/usage-queue`, which can pass through regular HTTP reverse proxies. Older compatible CPA versions omit these optional fields; CPA Manager Plus still imports and collects those events, with missing string fields shown as empty/unknown and missing numeric fields treated as `0`.\n- `reasoning_effort` is the request-side reasoning configuration. It is not actual reasoning token usage; actual reasoning consumption is still reported by `tokens.reasoning_tokens`.\n- Manager Server `auto` mode tries RESP Pub/Sub (`subscribe`) first, then the HTTP usage queue, then RESP pop mode for older CPA versions. RESP transports listen on the CPA API port, usually `8317`, and cannot pass through a regular HTTP reverse proxy.\n- CPA keeps queue items in memory for `redis-usage-queue-retention-seconds`, default `60` seconds and maximum `3600` seconds. Keep Manager Server running continuously.\n- Manager Server `pollIntervalMs` must be less than or equal to the CPA queue retention window converted to milliseconds. Saves are rejected when the collector would poll too slowly and risk expired queue items.\n- Exactly one Manager Server should consume the same CPA usage queue.\n\n## Architecture\n\n### Full Docker Mode\n\n```text\nBrowser\n  -\u003e Manager Server :18317\n      -\u003e built-in management.html\n      -\u003e /v0/management/usage and /v0/management/model-prices from SQLite\n      -\u003e other /v0/management/* proxied to CPA\n      -\u003e HTTP/RESP/PubSub consumer -\u003e CPA API port\n      -\u003e SQLite /data/usage.sqlite\n```\n\nOn first startup, if `CPA_MANAGER_ADMIN_KEY` / `CPA_MANAGER_ADMIN_KEY_FILE` is not provided, Manager Server generates a `cmp_admin_...` admin key and prints it to the startup log only once. The login page calls `GET /usage-service/info` and detects that it is hosted by Manager Server. If the response is not configured yet, it shows the setup wizard: you first enter the admin key, then the CPA URL, CPA Management Key, and choose whether to enable request monitoring. When monitoring is enabled, you also set the collector polling interval; Manager Server validates the CPA Management API, enables CPA usage publishing, checks that the poll interval does not exceed the CPA queue retention window, stores CPA Manager Plus configuration in SQLite, starts the collector with the configured mode (`auto` by default: RESP Pub/Sub, then HTTP queue, then RESP pop fallback), and serves the panel from the same origin. When monitoring is disabled, the CPA connection is still saved for Management API proxying, but CPA usage publishing and the collector stay off.\n\nAfter Manager Server is configured, a new browser opening the same URL uses the normal login form. Full Docker mode uses the admin key as the login credential; the CPA Management Key is stored server-side and is only used by Manager Server when it talks to CPA upstream.\n\n### CPA Panel Mode\n\n```text\nBrowser\n  -\u003e CPA /management.html\n      -\u003e normal CPA Management API calls stay on CPA\n      -\u003e local Codex inspection runs in the browser\n```\n\nUse this when CPA still auto-downloads and serves the panel. This mode is served by CPA and is fully isolated from Manager Server. It does not show the full Docker setup wizard, does not ask for the Manager Server admin key, does not save a Manager Server URL, and does not expose features backed by Manager Server SQLite or CPA usage statistics. The monitoring center, dashboard usage statistics, model pricing, API key aliases, usage import/export, collector status, and server Codex inspection are hidden or unavailable. Local Codex account inspection remains available because it runs in the browser against the CPA-accessible auth files.\n\n### Manager Server Backend\n\nThe Go backend lives under the `github.com/seakee/cpa-manager-plus/apps/manager-server` module. It still exposes the compatible `/usage-service/*` management endpoints. Its request path follows a layered shape:\n\n```text\nmodel -\u003e repository -\u003e service -\u003e controller -\u003e router\n```\n\n- `internal/model` defines persisted and API-facing data structures.\n- `internal/repository` owns SQLite access and schema migration while keeping the existing tables compatible.\n- `internal/service` contains setup, manager config, usage, model price, API key alias, proxy, panel, and collector lifecycle rules.\n- `internal/http/controller`, `internal/http/middleware`, and `internal/http/router` keep HTTP decoding, CORS/auth/recovery, Gin routing, and response writing at the edge.\n- `internal/httpapi` remains a compatibility wrapper for the current `cmd/cpa-manager-plus` entrypoint.\n- `internal/worker` coordinates collector startup/restart/stop without changing the existing HTTP, RESP Pub/Sub, RESP pop, and auto queue consumers.\n\n## Quick Start: Full Docker Mode\n\n### Container Images\n\nPublic multi-arch images are published to both registries:\n\n- Docker Hub: `seakee/cpa-manager-plus`\n- GitHub Container Registry: `ghcr.io/seakee/cpa-manager-plus`\n\n```bash\ndocker run -d \\\n  --name cpa-manager-plus \\\n  --restart unless-stopped \\\n  -p 18317:18317 \\\n  -v cpa-manager-plus-data:/data \\\n  seakee/cpa-manager-plus:latest\n```\n\nOpen:\n\n```text\nhttp://\u003chost\u003e:18317/management.html\n```\n\nOn first setup, enter:\n\n- Admin key: `CPA Manager Plus admin key generated: cmp_admin_...` from the first startup log\n- CPA URL:\n  - Docker Desktop host CPA: `http://host.docker.internal:8317` (default suggestion unless the panel was built with `VITE_DEFAULT_CPA_BASE_URL`)\n  - Same compose network: `http://cli-proxy-api:8317`\n  - Remote CPA: `https://your-cpa.example.com`\n- CPA Management Key\n\nYou can read the generated admin key with `docker logs cpa-manager-plus`. After setup, the same entry URL uses the saved CPA connection from Manager Server SQLite. New browsers only need the admin key on the login page.\n\nThe published image supports `linux/amd64` and `linux/arm64`. Docker examples use Docker Hub by default. To pull from GitHub Container Registry instead, replace `seakee/cpa-manager-plus:latest` with `ghcr.io/seakee/cpa-manager-plus:latest`.\n\n### Native Packages\n\nGitHub Releases also provide native packages with the panel embedded:\n\n- `cpa-manager-plus_\u003cversion\u003e_linux_amd64.tar.gz`\n- `cpa-manager-plus_\u003cversion\u003e_linux_arm64.tar.gz`\n- `cpa-manager-plus_\u003cversion\u003e_darwin_amd64.tar.gz`\n- `cpa-manager-plus_\u003cversion\u003e_darwin_arm64.tar.gz`\n- `cpa-manager-plus_\u003cversion\u003e_windows_amd64.zip`\n- `cpa-manager-plus_\u003cversion\u003e_windows_arm64.zip`\n\nmacOS/Linux:\n\n```bash\ntar -xzf cpa-manager-plus_vX.Y.Z_linux_amd64.tar.gz\ncd cpa-manager-plus_vX.Y.Z_linux_amd64\n./cpa-manager-plus\n```\n\nThe tar archives preserve execute permissions, so no extra `chmod +x` is normally required after extraction. If macOS blocks the unsigned binary, run `xattr -dr com.apple.quarantine .` in the extracted directory and start it again.\n\nWindows PowerShell:\n\n```powershell\nExpand-Archive .\\cpa-manager-plus_vX.Y.Z_windows_amd64.zip -DestinationPath .\ncd .\\cpa-manager-plus_vX.Y.Z_windows_amd64\n.\\cpa-manager-plus.exe\n```\n\nYou can double-click `cpa-manager-plus.exe` on Windows, but PowerShell is recommended because it keeps logs and startup errors visible.\n\nThen open:\n\n```text\nhttp://\u003chost\u003e:18317/management.html\n```\n\nNative packages do not include CPA itself. Run CPA separately, then enter the admin key, CPA URL, and CPA Management Key during first setup. After setup, the login page only needs the admin key. Set `USAGE_DATA_DIR` or `USAGE_DB_PATH` only when you want to override the default data location.\n\nOn first start, if `USAGE_DATA_DIR` and `USAGE_DB_PATH` are not set, the native package creates `config.json` next to the binary and writes SQLite data to `data/usage.sqlite` in the same directory. The extracted package directory therefore contains both the program and its user data.\n\n### Docker Compose\n\n```yaml\nservices:\n  cpa-manager-plus:\n    image: seakee/cpa-manager-plus:latest\n    restart: unless-stopped\n    ports:\n      - \"18317:18317\"\n    volumes:\n      - cpa-manager-plus-data:/data\n\nvolumes:\n  cpa-manager-plus-data:\n```\n\nStart:\n\n```bash\ndocker compose up -d\n```\n\nTo use GitHub Container Registry, replace the compose image with `ghcr.io/seakee/cpa-manager-plus:latest`.\n\n### Linux Host CPA\n\nIf CPA runs directly on a Linux host and Manager Server runs in Docker, add a host gateway:\n\n```bash\ndocker run -d \\\n  --name cpa-manager-plus \\\n  --restart unless-stopped \\\n  --add-host=host.docker.internal:host-gateway \\\n  -p 18317:18317 \\\n  -v cpa-manager-plus-data:/data \\\n  seakee/cpa-manager-plus:latest\n```\n\nThen enter `http://host.docker.internal:8317` as the CPA URL during first setup.\n\n## Quick Start: CPA Panel Mode\n\n1. Start CPA as usual and open:\n\n   ```text\n   http://\u003ccpa-host\u003e:8317/management.html\n   ```\n\n   Log in to CPA with the CPA Management Key. This entry is served by CPA and does not use the full Docker setup wizard.\n\n2. To make CPA use this project as its default panel, open:\n\n   ```text\n   Configuration -\u003e Remote Access and Control Panel\n   ```\n\n   Set **Panel Repository** (`remote-management.panel-repo`) to:\n\n   ```text\n   https://github.com/seakee/CPA-Manager-Plus\n   ```\n\n   Keep **Disable Control Panel** off. If **Disable Panel Auto Updates** is on, CPA only downloads the panel when the cached `static/management.html` is missing.\n\n3. Save the CPA configuration and reload:\n\n   ```text\n   http://\u003ccpa-host\u003e:8317/management.html\n   ```\n\n4. Use the CPA panel normally.\n\nThis mode is intentionally limited to CPA-backed functionality. It does not configure Manager Server, does not send the current CPA URL or CPA Management Key to Manager Server, and does not read Manager Server SQLite data. Use Full Docker mode when you need request monitoring, historical usage statistics, model pricing, API key aliases, usage import/export, or server Codex inspection.\n\n## Build Locally\n\n```bash\ndocker compose -f docker-compose.manager.yml up --build\n```\n\nThis builds the React panel and embeds it into the Go Manager Server binary.\n\n## Manager Server Configuration\n\nThe CPA URL and CPA Management Key are bound during first setup, or from environment variables for unattended startup. After that, **Configuration -\u003e CPA Manager Plus Configuration** manages request monitoring enablement, collection mode, polling interval, and CPA Management Key rotation for the already bound CPA; it does not change the CPA URL. CPA Manager Plus configuration is persisted in SQLite.\n\nThe variables below are Manager Server runtime settings. Frontend build-time settings are separate: `VITE_DEFAULT_CPA_BASE_URL` sets the default CPA URL shown by the Manager Server-hosted first setup wizard. When it is not set, the Docker-hosted panel suggests `http://host.docker.internal:8317`.\n\n| Variable | Default | Description |\n|---|---:|---|\n| `CPA_MANAGER_CONFIG` | empty | Optional config file path. When empty, native packages use `config.json` next to the binary |\n| `HTTP_ADDR` | `0.0.0.0:18317` | Manager Server HTTP listen address |\n| `USAGE_DB_PATH` | Docker: `/data/usage.sqlite`; native: `./data/usage.sqlite` | SQLite database path |\n| `USAGE_DATA_DIR` | Docker: `/data`; native: `./data` | Base data directory when `USAGE_DB_PATH` is not overridden |\n| `CPA_MANAGER_ADMIN_KEY` | empty | Optional admin key; when empty, first startup generates and logs one |\n| `CPA_MANAGER_ADMIN_KEY_FILE` | `/run/secrets/cpa_admin_key` | Optional admin key file |\n| `CPA_MANAGER_DATA_KEY` | empty | Optional data encryption key; when empty, read or generate it through `CPA_MANAGER_DATA_KEY_PATH` |\n| `CPA_MANAGER_DATA_KEY_FILE` | `/run/secrets/cpa_data_key` | Optional data encryption key file |\n| `CPA_MANAGER_DATA_KEY_PATH` | Docker: `/data/data.key`; native: `./data/data.key` | Auto-generated data encryption key file path |\n| `CPA_UPSTREAM_URL` | empty | Optional CPA base URL for unattended startup |\n| `CPA_MANAGEMENT_KEY` | empty | Optional CPA Management Key for unattended startup |\n| `CPA_MANAGEMENT_KEY_FILE` | `/run/secrets/cpa_management_key` | Optional file containing the CPA Management Key |\n| `USAGE_COLLECTOR_MODE` | `auto` | Collection mode: `auto` tries RESP Pub/Sub, then HTTP usage queue, then RESP pop fallback; `subscribe` forces RESP Pub/Sub; `http` forces HTTP; `resp` forces RESP pop |\n| `USAGE_RESP_QUEUE` | `usage` | RESP key argument; CPA currently ignores it, leave the default unless upstream changes |\n| `USAGE_RESP_POP_SIDE` | `right` | `right` uses `RPOP`; `left` uses `LPOP` |\n| `USAGE_BATCH_SIZE` | `100` | Maximum queue records per pop |\n| `USAGE_POLL_INTERVAL_MS` | `500` | Idle polling interval |\n| `USAGE_QUERY_LIMIT` | `50000` | Maximum recent events returned through compatible `/usage` |\n| `USAGE_CORS_ORIGINS` | `*` | Allowed browser origins for CPA panel mode |\n| `USAGE_RESP_TLS_SKIP_VERIFY` | `false` | Skip TLS verification for RESP connection |\n| `PANEL_PATH` | empty | Serve a custom `management.html` instead of the embedded one |\n\nStartup configuration precedence is: environment variables \u003e `config.json` \u003e program defaults. Relative paths in the config file are resolved from the config file directory. The generated default config is:\n\n```json\n{\n  \"httpAddr\": \"0.0.0.0:18317\",\n  \"dataDir\": \"./data\"\n}\n```\n\nIf `CPA_MANAGER_ADMIN_KEY` is set, the service initializes the admin credential from that value and does not log a generated admin key. If `CPA_UPSTREAM_URL` and `CPA_MANAGEMENT_KEY` are set, collection starts automatically on boot and the connection is shown as environment-managed in the panel. Otherwise, use the full Docker setup flow; the result is saved to SQLite `settings.manager_config_v1`. The legacy `settings.setup` value is still written for compatibility and rollback.\n\n### CPA vs CPA Manager Plus Configuration Boundary\n\n- **CPA configuration**: `usage-statistics-enabled`, `redis-usage-queue-retention-seconds`, proxy, logging, routing, auth files, and related fields still belong to CPA and are managed by `/config` / `/config.yaml`.\n- **CPA Manager Plus configuration**: the setup-bound CPA URL, encrypted CPA Management Key, request monitoring enablement, Manager Server collection mode, `pollIntervalMs`, `batchSize`, and `queryLimit` are persisted in Manager Server SQLite in Full Docker mode. The key can be rotated for the same CPA; changing the CPA URL requires resetting setup.\n- The configuration panel shows CPA and CPA Manager Plus settings separately. Saving CPAM settings does not write to CPA `config.yaml`; enabling request monitoring calls CPA Management API to enable usage publishing, while disabling request monitoring only stops the CPAM collector.\n\n### Migration Guide\n\nWhen upgrading from the old CPA-Manager project, read [Migration from CPA-Manager](docs/migration-from-cpa-manager.md) first. The core rules are:\n\n1. Stop the old backend service before backup, then back up the old `/data` directory or Docker volume, including at least `usage.sqlite`, `usage.sqlite-wal`, and `usage.sqlite-shm`.\n2. Start CPA Manager Plus with the same old `/data` volume, or copy the old data into the new `/data`. The old project often used `cpa-manager-data`; the Plus examples use `cpa-manager-plus-data`. Do not accidentally start with an empty new volume.\n3. On first Plus startup, the service adds `settings.admin_credential_v1`, `settings.bootstrap_state_v1`, and `/data/data.key`. From this point forward, backups must include both SQLite files and `data.key`.\n4. Full Docker mode now logs in with the Manager Server admin key, not the CPA Management Key. Prefer setting `CPA_MANAGER_ADMIN_KEY` or `CPA_MANAGER_ADMIN_KEY_FILE` during migration; otherwise save the generated `cmp_admin_...` value from the first startup log.\n5. If an older version already saved CPA URL and CPA Management Key through `/setup`, the service migrates from `settings.setup` to `settings.manager_config_v1` and rewrites the old plaintext CPA Management Key as encrypted storage during startup migration.\n6. If you use `CPA_UPSTREAM_URL` / `CPA_MANAGEMENT_KEY`, the connection remains environment-managed. To switch to panel persistence, remove those environment variables, restart, and save from the panel.\n7. Older external-Manager CPA panel integrations are no longer supported. Open the Manager Server-hosted panel to view historical usage data, model prices, aliases, imports/exports, and server inspection history. CPA panel mode remains a pure CPA panel.\n\n## Data and Security Notes\n\n- SQLite data is stored under `/data`; mount it to persistent storage.\n- The admin key is not stored in plaintext. SQLite `settings.admin_credential_v1` stores only the salt and HMAC-SHA256 digest. An automatically generated admin key is printed to the first startup log once; use `CPA_MANAGER_ADMIN_KEY_FILE` with Docker Secret or an external secret manager for managed deployments.\n- CPA Management Key is encrypted with the data key before it is stored in SQLite `settings`, so collection and CPA Management API proxying can resume after restart.\n- The data key is provided by `CPA_MANAGER_DATA_KEY` / `CPA_MANAGER_DATA_KEY_FILE`, or generated at `CPA_MANAGER_DATA_KEY_PATH`; Docker defaults to `/data/data.key` with `0600` permissions.\n- Data key security assessment: AES-GCM prevents a leaked SQLite file alone from directly exposing the CPA Management Key. If an attacker gets both `/data/usage.sqlite` and `/data/data.key`, the CPA Management Key can still be decrypted. If the data key is lost, encrypted CPA Management Key values cannot be recovered and the CPA connection must be initialized or saved again.\n- New versions prefer SQLite `settings.manager_config_v1`; legacy `settings.setup` is kept as compatibility data.\n- Protect the `/data` volume. It contains usage metadata, admin credential digest, the data key file, and the encrypted CPA Management Key.\n- Manager Server redacts key-like fields before storing raw JSON payload snapshots, but request metadata may still expose requested/resolved models, endpoints, account labels, project snapshots, and token usage.\n- RESP pop queue consumption is destructive. RESP Pub/Sub is streaming. Do not run multiple Manager Server consumers against the same CPA instance.\n- If Manager Server is down longer than CPA's queue retention window, that period's usage cannot be recovered without CPA-side persistence.\n- If only the CPAM collector is stopped while CPA usage publishing remains enabled, restarting the collector within the retention window may consume queue items produced while collection was disabled.\n\n## Runtime Endpoints\n\n| Endpoint | Purpose |\n|---|---|\n| `GET /health` | Basic health check |\n| `GET /status` | Collector, SQLite, event count, and error status |\n| `GET /usage-service/info` | Allows the frontend to detect full Docker mode and read `configured` for setup vs login flow |\n| `GET /usage-service/config` | Reads persistent CPA Manager Plus configuration and CPA usage publishing status |\n| `PUT /usage-service/config` | Saves CPA Manager Plus configuration and restarts the collector when needed |\n| `POST /setup` | Protected by the admin key; saves CPA URL + CPA Management Key and starts collection |\n| `GET /v0/management/usage` | Compatible usage payload for the panel |\n| `GET /v0/management/usage/export` | Export usage events as JSONL |\n| `POST /v0/management/usage/import` | Import JSONL usage events or legacy JSON snapshots |\n| `GET /v0/management/model-prices` | Read SQLite-backed model pricing |\n| `PUT /v0/management/model-prices` | Replace saved model pricing |\n| `POST /v0/management/model-prices/sync` | Sync model prices from LiteLLM, OpenRouter, and other pricing metadata sources, including source metadata |\n| `GET /models`, `GET /v1/models` | Proxy model-list requests to CPA after setup |\n| `/v0/management/*` | Proxied to CPA except usage endpoints |\n\nAfter full Docker setup, `/status`, usage, model-pricing, and `/v0/management/*` proxy endpoints require the admin key as a Bearer token. CPA Management Key is not accepted for Manager Server-only endpoints; it is stored server-side and used only by Manager Server when it talks to the bound CPA upstream.\n\nUsage import accepts two file families: JSONL/NDJSON event files exported by Manager Server, and legacy JSON snapshots produced by older CPA `/usage/export`. Legacy JSON can be converted only when `usage.apis.*.models.*.details[]` request details are present. Files that contain only aggregate totals are rejected because request-level monitoring data cannot be reconstructed. Legacy import is a migration/recovery path, not a perfect continuation of newly collected Manager Server data: old files may miss metadata such as `api_key_hash`, channel, request ID, method/path, latency, cache tokens, or failure reason, so account matching, API Key level analysis, and detail accuracy may be lower. Importing legacy files affects totals, trend charts, and account/key breakdowns; use a test or backup database first when accuracy matters.\n\nFailure bodies from CPA usage events are treated as sensitive diagnostics. Manager Server keeps the raw `fail_body` only in the local SQLite database for internal troubleshooting, while normal APIs, compatible usage payloads, and JSONL exports expose only `fail_summary`, which is redacted and truncated. JSONL exports intentionally omit `raw_json` and raw `fail_body`; imports remain compatible with older exports and snapshots.\n\n## Feature Overview\n\n- **Dashboard**: connection state, backend version, quick health summary\n- **Configuration**: visual/source editing for CPA configuration and separate CPA Manager Plus configuration\n- **AI Providers**: Gemini, Codex, Claude, Vertex, OpenAI-compatible providers, and Ampcode\n- **Auth Files**: upload, download, delete, status, OAuth exclusions, model aliases\n- **Quota**: quota views for supported providers\n- **Request Monitoring**: persisted usage KPIs, model/channel/account/API-key breakdowns, requested vs resolved model tracking, project snapshots, model pricing, estimated token cost, failure analysis, realtime tables with a readable source label and one prioritized supplemental detail\n- **Codex Account Inspection**: batch probing and cleanup suggestions for Codex auth pools\n- **Logs**: incremental file log reading and filtering\n- **System Info**: model list, version checks, and local state tools\n\n## Development\n\nFrontend:\n\n```bash\nnpm install\nnpm run dev\nnpm run type-check\nnpm run lint\nnpm run build\n```\n\nManager Server:\n\n```bash\ncd apps/manager-server\ngo test ./...\ngo test -race ./...\ngo vet ./...\ngo run ./cmd/cpa-manager-plus\n```\n\n## Build and Release\n\n- Vite builds a single-file `apps/web/dist/index.html`.\n- Tagging `vX.Y.Z` or a prerelease tag such as `vX.Y.Z-beta` triggers `.github/workflows/release.yml`.\n- The release workflow uploads `apps/web/dist/management.html`, native packages, and `checksums.txt` to GitHub Releases.\n- Native packages are published for `linux`, `darwin`, and `windows` on both `amd64` and `arm64`, with the management panel embedded.\n- The same workflow builds `Dockerfile.manager-server` and pushes public images to Docker Hub and GitHub Container Registry.\n- The Docker image is published for `linux/amd64` and `linux/arm64`.\n- The GitHub Container Registry image is `ghcr.io/seakee/cpa-manager-plus`; it uses the workflow `GITHUB_TOKEN` with `packages: write`.\n- The workflow syncs `README.md` to the Docker Hub overview when Docker Hub publishing is enabled.\n- Optional GitHub secrets for Docker Hub publishing:\n  - `DOCKERHUB_USERNAME`\n  - `DOCKERHUB_TOKEN`\n\n## Troubleshooting\n\n- **Cannot connect in full Docker mode**: verify the CPA URL from inside the Manager Server container. For host CPA on Linux, use `--add-host=host.docker.internal:host-gateway`.\n- **Full Docker mode opens the login form instead of setup**: Manager Server is already configured. Enter the admin key; the CPA URL comes from the server-side configuration.\n- **Wrong default CPA URL in first setup**: rebuild the panel with `VITE_DEFAULT_CPA_BASE_URL=\u003cyour-cpa-url\u003e` or enter the correct CPA URL manually.\n- **Monitoring is empty**: enable CPA usage publishing, verify Manager Server `/status`, and confirm only one consumer is running.\n- **`unsupported RESP prefix 'H'`**: upgrade CPA to `v6.10.8+` or keep `USAGE_COLLECTOR_MODE=http` for reverse-proxied HTTP queue access. RESP Pub/Sub/RESP pop modes require the CPA URL to be a container/host direct address for port `8317`, not a regular HTTP reverse-proxy domain.\n- **CPA panel still shows the old panel**: verify that CPA **Panel Repository** is `https://github.com/seakee/CPA-Manager-Plus`. If the new panel still does not load, clear CPA's cached panel file and reload or restart CPA:\n  ```bash\n  rm static/management.html\n  ```\n- **401 from Manager Server**: Manager Server endpoints use the admin key. CPA Management Key only logs in to CPA and is not accepted for Manager Server-only APIs.\n- **Docker panel shows stale data**: check `/status` for `lastConsumedAt`, `lastInsertedAt`, and `lastError`.\n- **CPA panel mode is missing monitoring/pricing/imports**: this is expected. These are Full Docker / Manager Server-hosted panel features.\n- **Data disappears after container rebuild**: mount `/data` to a Docker volume or host directory.\n- **Old data is missing after migrating from CPA-Manager**: verify that the Plus container is mounting the old `/data` volume, not a newly created empty `cpa-manager-plus-data` volume.\n- **Admin key is lost**: setting `CPA_MANAGER_ADMIN_KEY` does not overwrite an existing `settings.admin_credential_v1`. Follow the offline recovery steps in the migration guide after backing up `/data`.\n- **Detailed FAQ**: see [FAQ and Troubleshooting](https://github.com/seakee/CPA-Manager-Plus/wiki/CPA-Manager-Plus-FAQ-and-Troubleshooting) or the [Chinese FAQ](https://github.com/seakee/CPA-Manager-Plus/wiki/CPA%E2%80%90Manager-%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E4%B8%8E%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88).\n\n## References\n\n- CLIProxyAPI: https://github.com/router-for-me/CLIProxyAPI\n- Redis usage queue documentation: https://help.router-for.me/management/redis-usage-queue.html\n- Migration from CPA-Manager: [docs/migration-from-cpa-manager.md](docs/migration-from-cpa-manager.md)\n- Release checklist: [docs/release-checklist.md](docs/release-checklist.md)\n\n## Acknowledgements\n\n- Thanks to the upstream projects [CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI) and [Cli-Proxy-API-Management-Center](https://github.com/router-for-me/Cli-Proxy-API-Management-Center) for the foundation and inspiration.\n- Thanks to the [Linux.do](https://linux.do/) community for project promotion and feedback.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseakee%2Fcpa-manager-plus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseakee%2Fcpa-manager-plus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseakee%2Fcpa-manager-plus/lists"}