171 lines
8.3 KiB
Makefile
171 lines
8.3 KiB
Makefile
# ──────────────────────────────────────────────
|
||
# cursor-api-proxy — 設定與建置
|
||
# 編輯下方變數,然後執行 make env 產生 .env 檔
|
||
# ──────────────────────────────────────────────
|
||
|
||
# ── 伺服器設定 ─────────────────────────────────
|
||
HOST ?= 127.0.0.1
|
||
PORT ?= 8766
|
||
API_KEY ?=
|
||
TIMEOUT_MS ?= 3600000
|
||
MULTI_PORT ?= false
|
||
VERBOSE ?= false
|
||
|
||
# ── Agent / 模型設定 ──────────────────────────
|
||
AGENT_BIN ?= agent
|
||
AGENT_NODE ?=
|
||
AGENT_SCRIPT ?=
|
||
DEFAULT_MODEL ?= auto
|
||
STRICT_MODEL ?= true
|
||
MAX_MODE ?= false
|
||
FORCE ?= false
|
||
APPROVE_MCPS ?= false
|
||
|
||
# ── 工作區與帳號 ──────────────────────────────
|
||
WORKSPACE ?=
|
||
CHAT_ONLY_WORKSPACE ?= true
|
||
CONFIG_DIRS ?=
|
||
|
||
# ── TLS / HTTPS ───────────────────────────────
|
||
TLS_CERT ?=
|
||
TLS_KEY ?=
|
||
|
||
# ── 記錄 ──────────────────────────────────────
|
||
SESSIONS_LOG ?=
|
||
|
||
# ──────────────────────────────────────────────
|
||
|
||
ENV_FILE ?= .env
|
||
|
||
OPENCODE_CONFIG ?= $(HOME)/.config/opencode/opencode.json
|
||
|
||
.PHONY: env run build clean help opencode opencode-models pm2 pm2-stop pm2-logs claude-code pm2-claude-code
|
||
|
||
## 產生 .env 檔(預設輸出至 .env,可用 ENV_FILE=xxx 覆寫)
|
||
env:
|
||
@printf '# 由 make env 自動產生,請勿手動編輯\n' > $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_HOST=%s\n' "$(HOST)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_PORT=%s\n' "$(PORT)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_API_KEY=%s\n' "$(API_KEY)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_TIMEOUT_MS=%s\n' "$(TIMEOUT_MS)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_MULTI_PORT=%s\n' "$(MULTI_PORT)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_VERBOSE=%s\n' "$(VERBOSE)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_AGENT_BIN=%s\n' "$(AGENT_BIN)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_AGENT_NODE=%s\n' "$(AGENT_NODE)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_AGENT_SCRIPT=%s\n' "$(AGENT_SCRIPT)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_DEFAULT_MODEL=%s\n' "$(DEFAULT_MODEL)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_STRICT_MODEL=%s\n' "$(STRICT_MODEL)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_MAX_MODE=%s\n' "$(MAX_MODE)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_FORCE=%s\n' "$(FORCE)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_APPROVE_MCPS=%s\n' "$(APPROVE_MCPS)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_WORKSPACE=%s\n' "$(WORKSPACE)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_CHAT_ONLY_WORKSPACE=%s\n' "$(CHAT_ONLY_WORKSPACE)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_CONFIG_DIRS=%s\n' "$(CONFIG_DIRS)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_TLS_CERT=%s\n' "$(TLS_CERT)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_TLS_KEY=%s\n' "$(TLS_KEY)" >> $(ENV_FILE)
|
||
@printf 'CURSOR_BRIDGE_SESSIONS_LOG=%s\n' "$(SESSIONS_LOG)" >> $(ENV_FILE)
|
||
@echo "已產生 $(ENV_FILE)"
|
||
|
||
## 編譯二進位檔
|
||
build:
|
||
go build -o cursor-api-proxy .
|
||
|
||
## 載入 .env 後直接執行(需先執行 make env 或已有 .env)
|
||
run: build
|
||
@if [ -f $(ENV_FILE) ]; then \
|
||
set -a && . ./$(ENV_FILE) && set +a && ./cursor-api-proxy; \
|
||
else \
|
||
echo "找不到 $(ENV_FILE),請先執行 make env"; exit 1; \
|
||
fi
|
||
|
||
## 清除產出物
|
||
clean:
|
||
rm -f cursor-api-proxy $(ENV_FILE)
|
||
|
||
## 設定 OpenCode 使用此代理(更新 opencode.json 的 cursor provider)
|
||
opencode: build
|
||
@if [ ! -f "$(OPENCODE_CONFIG)" ]; then \
|
||
echo "找不到 $(OPENCODE_CONFIG),建立新設定檔"; \
|
||
mkdir -p $$(dirname "$(OPENCODE_CONFIG)"); \
|
||
printf '{\n "provider": {\n "cursor": {\n "npm": "@ai-sdk/openai-compatible",\n "name": "Cursor Agent",\n "options": {\n "baseURL": "http://$(HOST):$(PORT)/v1",\n "apiKey": "unused"\n },\n "models": { "auto": { "name": "Cursor Auto" } }\n }\n }\n}\n' > "$(OPENCODE_CONFIG)"; \
|
||
echo "已建立 $(OPENCODE_CONFIG)"; \
|
||
elif [ -n "$(API_KEY)" ]; then \
|
||
jq '.provider.cursor.options.baseURL = "http://$(HOST):$(PORT)/v1" | .provider.cursor.options.apiKey = "$(API_KEY)"' "$(OPENCODE_CONFIG)" > "$(OPENCODE_CONFIG).tmp" && mv "$(OPENCODE_CONFIG).tmp" "$(OPENCODE_CONFIG)"; \
|
||
echo "已更新 $(OPENCODE_CONFIG)(baseURL → http://$(HOST):$(PORT)/v1,apiKey 已設定)"; \
|
||
else \
|
||
jq '.provider.cursor.options.baseURL = "http://$(HOST):$(PORT)/v1"' "$(OPENCODE_CONFIG)" > "$(OPENCODE_CONFIG).tmp" && mv "$(OPENCODE_CONFIG).tmp" "$(OPENCODE_CONFIG)"; \
|
||
echo "已更新 $(OPENCODE_CONFIG)(baseURL → http://$(HOST):$(PORT)/v1)"; \
|
||
fi
|
||
|
||
## 啟動代理並用 curl 同步模型列表到 opencode.json
|
||
opencode-models: opencode
|
||
@echo "啟動代理以取得模型列表..."
|
||
@set -a && . ./$(ENV_FILE) 2>/dev/null; set +a; \
|
||
./cursor-api-proxy & PID=$$!; \
|
||
sleep 2; \
|
||
MODELS=$$(curl -s http://$(HOST):$(PORT)/v1/models | jq '[.data[].id]'); \
|
||
kill $$PID 2>/dev/null; wait $$PID 2>/dev/null; \
|
||
if [ -n "$$MODELS" ] && [ "$$MODELS" != "null" ]; then \
|
||
jq --argjson ids "$$MODELS" 'reduce $ids[] as $id (.; .provider.cursor.models[$id] = { name: $id })' "$(OPENCODE_CONFIG)" > "$(OPENCODE_CONFIG).tmp" && mv "$(OPENCODE_CONFIG).tmp" "$(OPENCODE_CONFIG)"; \
|
||
echo "已同步模型列表到 $(OPENCODE_CONFIG)"; \
|
||
else \
|
||
echo "無法取得模型列表,請確認代理已啟動"; \
|
||
fi
|
||
|
||
## 編譯並用 pm2 啟動
|
||
pm2: build
|
||
@if [ -f "$(ENV_FILE)" ]; then \
|
||
env $$(cat $(ENV_FILE) | grep -v '^#' | xargs) CURSOR_BRIDGE_HOST=$(HOST) CURSOR_BRIDGE_PORT=$(PORT) pm2 start ./cursor-api-proxy --name cursor-api-proxy --update-env; \
|
||
else \
|
||
CURSOR_BRIDGE_HOST=$(HOST) CURSOR_BRIDGE_PORT=$(PORT) pm2 start ./cursor-api-proxy --name cursor-api-proxy; \
|
||
fi
|
||
@pm2 save
|
||
@echo "pm2 已啟動 cursor-api-proxy(http://$(HOST):$(PORT))"
|
||
|
||
## 用 pm2 啟動 OpenCode 代理(設定 + 啟動一步完成)
|
||
pm2-opencode: opencode pm2
|
||
@echo "OpenCode 設定已更新並用 pm2 啟動代理"
|
||
|
||
## 編譯並用 pm2 啟動 + 設定 Claude Code 環境變數
|
||
pm2-claude-code: pm2
|
||
@echo ""
|
||
@echo "Claude Code 設定:將以下指令加入你的 shell 啟動檔(~/.bashrc 或 ~/.zshrc):"
|
||
@echo ""
|
||
@echo " export ANTHROPIC_BASE_URL=http://$(HOST):$(PORT)"
|
||
@echo " export ANTHROPIC_API_KEY=$(if $(API_KEY),$(API_KEY),dummy-key)"
|
||
@echo ""
|
||
@echo "或在當前 shell 執行:"
|
||
@echo ""
|
||
@echo " export ANTHROPIC_BASE_URL=http://$(HOST):$(PORT)"
|
||
@echo " export ANTHROPIC_API_KEY=$(if $(API_KEY),$(API_KEY),dummy-key)"
|
||
@echo " claude"
|
||
@echo ""
|
||
|
||
## 停止 pm2 中的代理
|
||
pm2-stop:
|
||
pm2 stop cursor-api-proxy 2>/dev/null || echo "cursor-api-proxy 未在執行"
|
||
|
||
## 查看 pm2 日誌
|
||
pm2-logs:
|
||
pm2 logs cursor-api-proxy
|
||
|
||
## 顯示說明
|
||
help:
|
||
@echo "可用目標:"
|
||
@echo " make env 產生 .env(先在 Makefile 頂端填好變數)"
|
||
@echo " make build 編譯 cursor-api-proxy 二進位檔"
|
||
@echo " make run 編譯並載入 .env 執行"
|
||
@echo " make pm2 編譯並用 pm2 啟動代理"
|
||
@echo " make pm2-stop 停止 pm2 中的代理"
|
||
@echo " make pm2-logs 查看 pm2 日誌"
|
||
@echo " make pm2-claude-code 啟動代理 + 輸出 Claude Code 設定指令"
|
||
@echo " make opencode 編譯並設定 OpenCode(更新 opencode.json)"
|
||
@echo " make pm2-opencode 設定 OpenCode + 啟動代理"
|
||
@echo " make opencode-models 編譯、設定 OpenCode 並同步模型列表"
|
||
@echo " make clean 刪除二進位檔與 .env"
|
||
@echo ""
|
||
@echo "覆寫範例:"
|
||
@echo " make env PORT=9000 API_KEY=mysecret TIMEOUT_MS=60000"
|
||
@echo " make pm2-claude-code PORT=8765 API_KEY=mykey"
|
||
@echo " make pm2-opencode PORT=8765"
|