Skip to content
Closed
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 11 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
# NOTE: Environment variables are only required when using remote storage options.
# For local file-based storage (default), no environment variables need to be set.

# ------------------------------------------------------------------------------
# Docker Runtime Configuration (overrides config.yaml)
# ------------------------------------------------------------------------------
# CLIPROXY_HOST= # Server host (default: "" for all interfaces)
# CLIPROXY_PORT=8317 # Server port (default: 8317)
# CLIPROXY_SECRET_KEY= # Management API secret key
# CLIPROXY_ALLOW_REMOTE=false # Allow remote management access (true/false)
# CLIPROXY_DEBUG=false # Enable debug logging (true/false)
# CLIPROXY_ROUTING_STRATEGY=round-robin # Routing strategy (round-robin/fill-first)
# CLIPROXY_API_KEYS=key1,key2,key3 # Comma-separated list of API keys

# ------------------------------------------------------------------------------
# Management Web UI
# ------------------------------------------------------------------------------
Expand Down
33 changes: 15 additions & 18 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,41 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
about: Report a bug in cliproxyapi++
title: '[BUG] '
labels: 'bug'
assignees: ''

---

**Is it a request payload issue?**
[ ] Yes, this is a request payload issue. I am using a client/cURL to send a request payload, but I received an unexpected error.
[ ] No, it's another issue.
[ ] Yes, this is a request payload issue. I am using a client/cURL to send a request payload, but I received an unexpected error.
[ ] No, it's another issue.

**If it's a request payload issue, you MUST know**
Our team doesn't have any GODs or ORACLEs or MIND READERs. Please make sure to attach the request log or curl payload.
To help us diagnose the problem, please provide as much detail as possible, including request logs or `curl` payloads.

**Describe the bug**
A clear and concise description of what the bug is.

**CLI Type**
What type of CLI account do you use? (gemini-cli, gemini, codex, claude code or openai-compatibility)

**Model Name**
What model are you using? (example: gemini-2.5-pro, claude-sonnet-4-20250514, gpt-5, etc.)
**cliproxyapi++ Configuration**
What provider and model are you using? (e.g. Kiro, Claude, Gemini)

**LLM Client**
What LLM Client are you using? (example: roo-code, cline, claude code, etc.)
What LLM Client are you using? (e.g. Roo Code, Claude Code, Cursor, etc.)

**Environment Information**
- **cliproxyapi++ Version**: (e.g., v6.0.0-++.1)
- **Deployment Method**: (e.g., Docker, Binary)
- **OS**: (e.g. macOS, Ubuntu 22.04)

**Request Information**
The best way is to paste the cURL command of the HTTP request here.
Alternatively, you can set `request-log: true` in the `config.yaml` file and then upload the detailed log file.
Please provide the `curl` command or the logs from `config.yaml` with `request-log: true`.

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**OS Type**
- OS: [e.g. macOS]
- Version [e.g. 15.6.0]

**Additional context**
Add any other context about the problem here.
42 changes: 42 additions & 0 deletions .github/policies/approved-external-endpoints.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Approved external endpoint hosts.
# Matching is exact host or subdomain of an entry.

accounts.google.com
aiplatform.googleapis.com
ampcode.com
api.anthropic.com
api.api.githubcopilot.com
api.deepseek.com
api.fireworks.ai
api.github.com
api.groq.com
api.kilo.ai
api.kimi.com
api.minimax.chat
api.minimax.io
api.mistral.ai
api.novita.ai
api.openai.com
api.roocode.com
api.siliconflow.cn
api.together.xyz
apis.iflow.cn
auth.openai.com
chat.qwen.ai
chatgpt.com
claude.ai
cloudcode-pa.googleapis.com
cloudresourcemanager.googleapis.com
generativelanguage.googleapis.com
github.com
golang.org
iflow.cn
integrate.api.nvidia.com
oauth2.googleapis.com
openrouter.ai
platform.iflow.cn
platform.openai.com
portal.qwen.ai
raw.githubusercontent.com
serviceusage.googleapis.com
www.googleapis.com
13 changes: 13 additions & 0 deletions .github/release-required-checks.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# workflow_file|job_name
pr-test-build.yml|go-ci
pr-test-build.yml|quality-ci
pr-test-build.yml|quality-staged-check
pr-test-build.yml|fmt-check
pr-test-build.yml|golangci-lint
pr-test-build.yml|route-lifecycle
pr-test-build.yml|test-smoke
pr-test-build.yml|pre-release-config-compat-smoke
pr-test-build.yml|distributed-critical-paths
pr-test-build.yml|changelog-scope-classifier
pr-test-build.yml|docs-build
pr-test-build.yml|ci-summary
16 changes: 16 additions & 0 deletions .github/required-checks.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# workflow_file|job_name
pr-test-build.yml|go-ci
pr-test-build.yml|quality-ci
pr-test-build.yml|quality-staged-check
pr-test-build.yml|fmt-check
pr-test-build.yml|golangci-lint
pr-test-build.yml|route-lifecycle
pr-test-build.yml|provider-smoke-matrix
pr-test-build.yml|provider-smoke-matrix-cheapest
pr-test-build.yml|test-smoke
pr-test-build.yml|pre-release-config-compat-smoke
pr-test-build.yml|distributed-critical-paths
pr-test-build.yml|changelog-scope-classifier
pr-test-build.yml|docs-build
pr-test-build.yml|ci-summary
pr-path-guard.yml|ensure-no-translator-changes
67 changes: 67 additions & 0 deletions .github/scripts/check-approved-external-endpoints.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env bash
set -euo pipefail

policy_file=".github/policies/approved-external-endpoints.txt"
if [[ ! -f "${policy_file}" ]]; then
echo "Missing policy file: ${policy_file}"
exit 1
fi

mapfile -t approved_hosts < <(grep -Ev '^\s*#|^\s*$' "${policy_file}" | tr '[:upper:]' '[:lower:]')
if [[ "${#approved_hosts[@]}" -eq 0 ]]; then
echo "No approved hosts in policy file"
exit 1
fi

matches_policy() {
local host="$1"
local approved
for approved in "${approved_hosts[@]}"; do
if [[ "${host}" == "${approved}" || "${host}" == *."${approved}" ]]; then
return 0
fi
done
return 1
}

mapfile -t discovered_hosts < <(
rg -No --hidden \
--glob '!docs/**' \
--glob '!**/*_test.go' \
--glob '!**/node_modules/**' \
--glob '!**/*.png' \
--glob '!**/*.jpg' \
--glob '!**/*.jpeg' \
--glob '!**/*.gif' \
--glob '!**/*.svg' \
--glob '!**/*.webp' \
'https?://[^"\047 )\]]+' \
cmd pkg sdk scripts .github/workflows config.example.yaml README.md README_CN.md 2>/dev/null \
| awk -F'://' '{print $2}' \
| cut -d/ -f1 \
| cut -d: -f1 \
| tr '[:upper:]' '[:lower:]' \
| sort -u
)

unknown=()
for host in "${discovered_hosts[@]}"; do
[[ -z "${host}" ]] && continue
[[ "${host}" == *"%"* ]] && continue
[[ "${host}" == *"{"* ]] && continue
[[ "${host}" == "localhost" || "${host}" == "127.0.0.1" || "${host}" == "0.0.0.0" ]] && continue
[[ "${host}" == "example.com" || "${host}" == "www.example.com" ]] && continue
[[ "${host}" == "proxy.com" || "${host}" == "proxy.local" ]] && continue
[[ "${host}" == "api.example.com" ]] && continue
if ! matches_policy "${host}"; then
unknown+=("${host}")
fi
done

if [[ "${#unknown[@]}" -ne 0 ]]; then
echo "Found external hosts not in ${policy_file}:"
printf ' - %s\n' "${unknown[@]}"
exit 1
fi

echo "external endpoint policy check passed"
19 changes: 19 additions & 0 deletions .github/scripts/check-distributed-critical-paths.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -euo pipefail

echo "[distributed-critical-paths] validating filesystem-sensitive paths"
go test -count=1 -run '^(TestMultiSourceSecret_FileHandling|TestMultiSourceSecret_CacheBehavior|TestMultiSourceSecret_Concurrency|TestAmpModule_OnConfigUpdated_CacheInvalidation)$' ./pkg/llmproxy/api/modules/amp

echo "[distributed-critical-paths] validating ops endpoint route registration"
go test -count=1 -run '^TestRegisterManagementRoutes$' ./pkg/llmproxy/api/modules/amp

echo "[distributed-critical-paths] validating compute/cache-sensitive paths"
go test -count=1 -run '^(TestEnsureCacheControl|TestCacheControlOrder|TestCountOpenAIChatTokens|TestCountClaudeChatTokens)$' ./pkg/llmproxy/runtime/executor

echo "[distributed-critical-paths] validating queue telemetry to provider metrics path"
go test -count=1 -run '^TestBuildProviderMetricsFromSnapshot_FailoverAndQueueTelemetry$' ./pkg/llmproxy/usage

echo "[distributed-critical-paths] validating signature cache primitives"
go test -count=1 -run '^(TestCacheSignature_BasicStorageAndRetrieval|TestCacheSignature_ExpirationLogic)$' ./pkg/llmproxy/cache

echo "[distributed-critical-paths] all targeted checks passed"
53 changes: 53 additions & 0 deletions .github/scripts/check-docs-secret-samples.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env bash
set -euo pipefail

patterns=(
'sk-[A-Za-z0-9]{20,}'
'ghp_[A-Za-z0-9]{20,}'
'AKIA[0-9A-Z]{16}'
'AIza[0-9A-Za-z_-]{20,}'
'-----BEGIN (RSA|OPENSSH|EC|DSA|PRIVATE) KEY-----'
)

allowed_context='\$\{|\{\{.*\}\}|<[^>]+>|\[REDACTED|your[_-]?|example|dummy|sample|placeholder'

tmp_hits="$(mktemp)"
trap 'rm -f "${tmp_hits}"' EXIT

for pattern in "${patterns[@]}"; do
rg -n --pcre2 --hidden \
--glob '!docs/node_modules/**' \
--glob '!**/*.min.*' \
--glob '!**/*.svg' \
--glob '!**/*.png' \
--glob '!**/*.jpg' \
--glob '!**/*.jpeg' \
--glob '!**/*.gif' \
--glob '!**/*.webp' \
--glob '!**/*.pdf' \
--glob '!**/*.lock' \
--glob '!**/*.snap' \
-e "${pattern}" docs README.md README_CN.md examples >> "${tmp_hits}" || true
done

if [[ ! -s "${tmp_hits}" ]]; then
echo "docs secret sample check passed"
exit 0
fi

violations=0
while IFS= read -r hit; do
line_content="${hit#*:*:}"
if printf '%s' "${line_content}" | rg -qi "${allowed_context}"; then
continue
fi
echo "Potential secret detected: ${hit}"
violations=1
done < "${tmp_hits}"

if [[ "${violations}" -ne 0 ]]; then
echo "Secret sample check failed. Replace with placeholders or redact."
exit 1
fi

echo "docs secret sample check passed"
49 changes: 49 additions & 0 deletions .github/scripts/check-open-items-fragmented-parity.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env bash
set -euo pipefail

report="${REPORT_PATH:-docs/reports/fragemented/OPEN_ITEMS_VALIDATION_2026-02-22.md}"
if [[ ! -f "$report" ]]; then
echo "[FAIL] Missing report: $report"
exit 1
fi

section="$(awk '
BEGIN { in_issue=0 }
/^- Issue #258/ { in_issue=1 }
in_issue {
if ($0 ~ /^- (Issue|PR) #[0-9]+/ && $0 !~ /^- Issue #258/) {
exit
}
print
}
' "$report")"

if [[ -z "$section" ]]; then
echo "[FAIL] $report missing Issue #258 section."
exit 1
fi

status_line="$(echo "$section" | awk 'BEGIN{IGNORECASE=1} /- (Status|State):/{print; exit}')"
if [[ -z "$status_line" ]]; then
echo "[FAIL] $report missing explicit status line for #258 (expected '- Status:' or '- State:')."
exit 1
fi

status_lower="$(echo "$status_line" | tr '[:upper:]' '[:lower:]')"

if echo "$status_lower" | rg -q "\b(partial|partially|not implemented|todo|to-do|pending|wip|in progress|open|blocked|backlog)\b"; then
echo "[FAIL] $report has non-implemented status for #258: $status_line"
exit 1
fi

if ! echo "$status_lower" | rg -q "\b(implemented|resolved|complete|completed|closed|done|fixed|landed|shipped)\b"; then
echo "[FAIL] $report has unrecognized completion status for #258: $status_line"
exit 1
fi

if ! rg -n "pkg/llmproxy/translator/codex/openai/chat-completions/codex_openai_request.go" "$report" >/dev/null 2>&1; then
echo "[FAIL] $report missing codex variant fallback evidence path."
exit 1
fi

echo "[OK] fragmented open-items report parity checks passed"
31 changes: 31 additions & 0 deletions .github/scripts/check-workflow-token-permissions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -euo pipefail

violations=0
allowed_write_keys='security-events|id-token|pages'

for workflow in .github/workflows/*.yml .github/workflows/*.yaml; do
[[ -f "${workflow}" ]] || continue

if rg -n '^permissions:\s*write-all\s*$' "${workflow}" >/dev/null; then
echo "${workflow}: uses permissions: write-all"
violations=1
fi

if rg -n '^on:' "${workflow}" >/dev/null && rg -n 'pull_request:' "${workflow}" >/dev/null; then
while IFS= read -r line; do
key="$(printf '%s' "${line}" | sed -E 's/^[0-9]+:\s*([a-zA-Z-]+):\s*write\s*$/\1/')"
if [[ "${key}" != "${line}" ]] && ! printf '%s' "${key}" | grep -Eq "^(${allowed_write_keys})$"; then
echo "${workflow}: pull_request workflow grants '${key}: write'"
violations=1
fi
done < <(rg -n '^\s*[a-zA-Z-]+:\s*write\s*$' "${workflow}")
fi
done

if [[ "${violations}" -ne 0 ]]; then
echo "workflow token permission check failed"
exit 1
fi

echo "workflow token permission check passed"
Loading
Loading