Spaces:
Running
Running
Upload 4 files
Browse files- Dockerfile +50 -0
- config.yaml.example +231 -0
- entrypoint.sh +16 -0
Dockerfile
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM node:22-alpine AS builder
|
| 2 |
+
|
| 3 |
+
WORKDIR /build
|
| 4 |
+
|
| 5 |
+
# Install git
|
| 6 |
+
RUN apk add --no-cache git
|
| 7 |
+
|
| 8 |
+
# Clone latest cursor2api at build time — rebuild Space to get updates
|
| 9 |
+
ARG REPO=https://github.com/lhpqaq/cursor2api
|
| 10 |
+
ARG BRANCH=main
|
| 11 |
+
RUN git clone --depth=1 --branch ${BRANCH} ${REPO} .
|
| 12 |
+
|
| 13 |
+
# Install all deps and build TypeScript
|
| 14 |
+
RUN npm ci
|
| 15 |
+
RUN npm run build
|
| 16 |
+
|
| 17 |
+
# ---- Runtime stage ----
|
| 18 |
+
FROM node:22-alpine AS runner
|
| 19 |
+
|
| 20 |
+
WORKDIR /app
|
| 21 |
+
|
| 22 |
+
ENV NODE_ENV=production
|
| 23 |
+
# Increase heap for tesseract.js / tiktoken / large log files
|
| 24 |
+
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
| 25 |
+
|
| 26 |
+
# node:22-alpine already ships with a 'node' user (uid/gid 1000) — use it directly
|
| 27 |
+
# Install only prod deps
|
| 28 |
+
COPY --from=builder /build/package.json /build/package-lock.json ./
|
| 29 |
+
RUN npm ci --omit=dev && npm cache clean --force
|
| 30 |
+
|
| 31 |
+
# Copy built output and static assets
|
| 32 |
+
COPY --from=builder --chown=node:node /build/dist ./dist
|
| 33 |
+
COPY --from=builder --chown=node:node /build/public ./public
|
| 34 |
+
|
| 35 |
+
# Copy config example from repo
|
| 36 |
+
COPY --from=builder --chown=node:node /build/config.yaml.example ./config.yaml.example
|
| 37 |
+
|
| 38 |
+
# Our custom entrypoint
|
| 39 |
+
COPY --chown=node:node entrypoint.sh ./entrypoint.sh
|
| 40 |
+
RUN chmod +x ./entrypoint.sh
|
| 41 |
+
|
| 42 |
+
# Persistent logs dir
|
| 43 |
+
RUN mkdir -p /app/logs && chown node:node /app/logs
|
| 44 |
+
|
| 45 |
+
USER node
|
| 46 |
+
|
| 47 |
+
# HF Spaces requires port 7860
|
| 48 |
+
EXPOSE 7860
|
| 49 |
+
|
| 50 |
+
ENTRYPOINT ["./entrypoint.sh"]
|
config.yaml.example
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Cursor2API v2 配置文件
|
| 2 |
+
# 复制此文件为 config.yaml 并根据需要修改
|
| 3 |
+
#
|
| 4 |
+
# ⚠️ 环境变量优先级高于此文件:
|
| 5 |
+
# 若通过环境变量(如 docker-compose 的 environment 块)设置了某个参数,
|
| 6 |
+
# 则修改此文件对该参数无效,热重载也不会生效。
|
| 7 |
+
# 需要在 config.yaml 中管理的参数,请勿同时在环境变量中设置。
|
| 8 |
+
|
| 9 |
+
# 服务端口
|
| 10 |
+
# port: 3010 # On HF Spaces this is always overridden to 7860 via PORT env var
|
| 11 |
+
|
| 12 |
+
# 请求超时(秒)
|
| 13 |
+
timeout: 120
|
| 14 |
+
|
| 15 |
+
# ==================== API 鉴权(推荐公网部署时开启) ====================
|
| 16 |
+
# 配置后所有 POST 请求必须携带 Bearer token 才能访问
|
| 17 |
+
# 客户端使用方式:Authorization: Bearer <token> 或 x-api-key: <token>
|
| 18 |
+
# 支持多个 token(数组格式),不配置则全部放行
|
| 19 |
+
# 环境变量: AUTH_TOKEN=token1,token2 (逗号分隔)
|
| 20 |
+
# auth_tokens:
|
| 21 |
+
# - "sk-your-secret-token-1"
|
| 22 |
+
# - "sk-your-secret-token-2"
|
| 23 |
+
|
| 24 |
+
# ==================== 代理设置 ====================
|
| 25 |
+
# 全局代理(可选)
|
| 26 |
+
# ⚠️ Node.js fetch 不读取 HTTP_PROXY / HTTPS_PROXY 环境变量,
|
| 27 |
+
# 必须在此处或通过 PROXY 环境变量显式配置代理。
|
| 28 |
+
# 支持 http 代理,含认证格式: http://用户名:密码@代理地址:端口
|
| 29 |
+
# 💡 国内可直连 Cursor API,通常不需要配置全局代理
|
| 30 |
+
# proxy: "http://127.0.0.1:7890"
|
| 31 |
+
|
| 32 |
+
# Cursor 使用的模型
|
| 33 |
+
cursor_model: "anthropic/claude-sonnet-4.6"
|
| 34 |
+
|
| 35 |
+
# ==================== 自动续写配置 ====================
|
| 36 |
+
# 当模型输出被截断时,自动发起续写请求的最大次数
|
| 37 |
+
# 默认 0(禁用),由客户端(如 Claude Code)自行处理续写,体验更好
|
| 38 |
+
# 设为 1~3 可启用 proxy 内部续写(拼接更完整,但延迟更高)
|
| 39 |
+
# 环境变量: MAX_AUTO_CONTINUE=0
|
| 40 |
+
max_auto_continue: 0
|
| 41 |
+
|
| 42 |
+
# ==================== 历史消息条数硬限制 ====================
|
| 43 |
+
# 输入消息条数上限,超出时删除最早的消息(保留工具 few-shot 示例)
|
| 44 |
+
# 注意:按条数限制无法反映实际 token 体积,建议改用 max_history_tokens(更精准)
|
| 45 |
+
# 如需同时设置,两者独立生效,取更严格的结果
|
| 46 |
+
# 设为 -1 不限制消息条数
|
| 47 |
+
# 环境变量: MAX_HISTORY_MESSAGES=100
|
| 48 |
+
max_history_messages: -1
|
| 49 |
+
|
| 50 |
+
# ==================== 历史消息 Token 数硬限制(推荐) ====================
|
| 51 |
+
# 按 js-tiktoken (cl100k_base) 估算 token 数裁剪历史,比按条数更精准
|
| 52 |
+
# 能有效防止超出 Cursor API 200k 上下文上限,保障模型输出稳定
|
| 53 |
+
#
|
| 54 |
+
# 说明:此值仅计算我们发送的消息内容 token
|
| 55 |
+
# 代码会自动额外补偿 Cursor 后端开销(动态计算):
|
| 56 |
+
# - 基础隐藏系统提示:约 1,300 tokens(固定)
|
| 57 |
+
# - 工具 tokenizer 差异:compact ~20/工具,full ~240/工具,names_only ~5/工具
|
| 58 |
+
# 输出空间不在此预留,由用户自行通过此值控制(建议留 16,000~32,000 余量)
|
| 59 |
+
#
|
| 60 |
+
# 裁剪规则:
|
| 61 |
+
# - 系统提示 + 工具定义的 token 优先扣除(含上述固定开销)
|
| 62 |
+
# - 剩余额度从最新消息往前累加,超出预算的最早消息整条删除
|
| 63 |
+
# - 工具模式的 few-shot 示例(前 2 条)始终保留
|
| 64 |
+
#
|
| 65 |
+
# 参考值:110000~130000,示例推荐 120000
|
| 66 |
+
# 程序内置默认值仍为 150000;此示例采用更保守的 120000,给长回答/长工具参数预留更多输出空间
|
| 67 |
+
# Cursor API 上下文上限约 200k tokens,建议 max_history_tokens + 开销 + 预留输出 ≤ 200000
|
| 68 |
+
#
|
| 69 |
+
# 与 max_history_messages 的关系:
|
| 70 |
+
# 两者独立生效,若同时设置则取更严格的结果
|
| 71 |
+
# 推荐:只设置 max_history_tokens,不设置 max_history_messages
|
| 72 |
+
#
|
| 73 |
+
# 设为 -1 不限制
|
| 74 |
+
# 环境变量: MAX_HISTORY_TOKENS=120000
|
| 75 |
+
max_history_tokens: 120000
|
| 76 |
+
|
| 77 |
+
# ==================== Thinking 开关(最高优先级) ====================
|
| 78 |
+
# 控制是否向 Cursor 发送 thinking 请求,优先级高于客户端传入的 thinking 参数
|
| 79 |
+
# 设为 true: 强制启用 thinking(即使客户端没请求也注入)
|
| 80 |
+
# 设为 false: 强制关闭 thinking(即使客户端请求了 thinking 也不启用)
|
| 81 |
+
# 不配置此项时: 跟随客户端请求(Anthropic API 看 thinking 参数,OpenAI API 看模型名/reasoning_effort)
|
| 82 |
+
# 环境变量: THINKING_ENABLED=true|false
|
| 83 |
+
thinking:
|
| 84 |
+
enabled: false
|
| 85 |
+
|
| 86 |
+
# ==================== 历史消息压缩配置 ====================
|
| 87 |
+
# 对话过长时自动压缩早期消息,释放输出空间,防止 Cursor 上下文溢出
|
| 88 |
+
# 压缩算法会智能识别消息类型,不会破坏工具调用的 JSON 结构
|
| 89 |
+
compression:
|
| 90 |
+
# 是否启用压缩(true/false),关闭后所有消息原样保留
|
| 91 |
+
# 环境变量: COMPRESSION_ENABLED=true|false
|
| 92 |
+
enabled: true
|
| 93 |
+
|
| 94 |
+
# 压缩级别: 1=轻度, 2=中等(推荐), 3=激进
|
| 95 |
+
# 环境变量: COMPRESSION_LEVEL=1|2|3
|
| 96 |
+
# 级别说明:
|
| 97 |
+
# 1(轻度): 保留最近 10 条消息,早期消息保留 4000 字符,适合短对话
|
| 98 |
+
# 2(中等): 保留最近 6 条消息,早期消息保留 2000 字符,推荐日常使用
|
| 99 |
+
# 3(激进): 保留最近 4 条消息,早期消息保留 1000 字符,适合超长对话/大工具集
|
| 100 |
+
level: 2
|
| 101 |
+
|
| 102 |
+
# 以下为高级选项,设置后会覆盖 level 的预设值
|
| 103 |
+
# 保留最近 N 条消息不压缩(数字越大保留越多上下文)
|
| 104 |
+
# keep_recent: 6
|
| 105 |
+
|
| 106 |
+
# 早期消息最大字符数(超过此长度的消息会被智能压缩)
|
| 107 |
+
# early_msg_max_chars: 2000
|
| 108 |
+
|
| 109 |
+
# ==================== 工具处理配置 ====================
|
| 110 |
+
# 控制工具定义如何传递给模型,影响上下文体积和工具调用准确性
|
| 111 |
+
tools:
|
| 112 |
+
# Schema 呈现模式
|
| 113 |
+
# 'compact': [推荐] TypeScript 风格的紧凑签名,体积最小(~15K chars/90工具)
|
| 114 |
+
# 示例: {file_path!: string, encoding?: utf-8|base64}
|
| 115 |
+
# 'full': 程序内置默认值,完整 JSON Schema,工具调用最精确
|
| 116 |
+
# 适合工具少(<20个)或需要最高准确率的场景
|
| 117 |
+
# 'names_only': 只输出工具名和描述,不输出参数Schema
|
| 118 |
+
# 极致省 token,适合模型已经"学过"这些工具的场景(如 Claude Code 内置工具)
|
| 119 |
+
schema_mode: 'compact'
|
| 120 |
+
|
| 121 |
+
# 工具描述截断长度
|
| 122 |
+
# 100: [推荐] 工具多、上下文容易挤满时的折中值
|
| 123 |
+
# 0: 程序内置默认值,不截断,保留完整描述(适合工具少的场景)
|
| 124 |
+
# 200: 保留更多描述信息,适合参数复杂的工具集
|
| 125 |
+
description_max_length: 100
|
| 126 |
+
|
| 127 |
+
# 工具白名单 — 只保留指定名称的工具(不配则保留所有工具)
|
| 128 |
+
# 💡 适合只用核心工具、排除大量不需要的 MCP 工具等场景
|
| 129 |
+
# include_only:
|
| 130 |
+
# - "Read"
|
| 131 |
+
# - "Write"
|
| 132 |
+
# - "Bash"
|
| 133 |
+
# - "Glob"
|
| 134 |
+
# - "Grep"
|
| 135 |
+
# - "Edit"
|
| 136 |
+
|
| 137 |
+
# 工具黑名单 — 排除指定名称的工具
|
| 138 |
+
# 💡 比白名单更灵活,可以只去掉几个不常用的工具
|
| 139 |
+
# exclude:
|
| 140 |
+
# - "some_mcp_tool"
|
| 141 |
+
|
| 142 |
+
# ★ 透传模式(推荐 Roo Code / Cline 等非 Claude Code 客户端开启)
|
| 143 |
+
# true: 跳过 few-shot 注入和工具格式改写,直接将工具定义以原始 JSON 嵌入系统提示词
|
| 144 |
+
# 减少与 Cursor 内建身份的提示词冲突,解决「只有 read_file/read_dir」的错误
|
| 145 |
+
# 工具调用仍使用 ```json action``` 格式,响应解析不受影响
|
| 146 |
+
# false: [默认] 使用标准模式(buildToolInstructions + 多类别 few-shot 注入)
|
| 147 |
+
# Claude Code 推荐此模式,兼容性和工具调用覆盖率更好
|
| 148 |
+
# 环境变量: TOOLS_PASSTHROUGH=true|false
|
| 149 |
+
passthrough: false
|
| 150 |
+
|
| 151 |
+
# ★ 禁用模式(极致省上下文)
|
| 152 |
+
# true: 完全不注入工具定义和 few-shot 示例,节省大量上下文空间
|
| 153 |
+
# 模型凭自身训练记忆处理工具调用(适合已内化工具格式的场景)
|
| 154 |
+
# 响应中的 ```json action``` 块仍会被正常解析
|
| 155 |
+
# false: [默认] 正常注入工具定义
|
| 156 |
+
# 环境变量: TOOLS_DISABLED=true|false
|
| 157 |
+
disabled: false
|
| 158 |
+
|
| 159 |
+
# ==================== 响应内容清洗(可选,默认关闭) ====================
|
| 160 |
+
# 开启后,会将响应中 Cursor 相关的身份引用替换为 Claude
|
| 161 |
+
# 例如 "I am Cursor's support assistant" → "I am Claude, an AI assistant by Anthropic"
|
| 162 |
+
# 同时清洗工具可用性声明、提示注入指控等敏感内容
|
| 163 |
+
# 💡 如果你不需要伪装身份,建议保持关闭以获得最佳性能
|
| 164 |
+
# 💡 开启后,所有响应都会经过正则替换处理,有轻微性能开销
|
| 165 |
+
# sanitize_response: true
|
| 166 |
+
|
| 167 |
+
# ==================== 自定义拒绝检测规则(可选) ====================
|
| 168 |
+
# 追加到内置拒绝检测列表之后(不替换内置规则),匹配到则触发重试逻辑
|
| 169 |
+
# 每条规则作为正则表达式解析(不区分大小写),无效正则会自动退化为字面量匹配
|
| 170 |
+
# 💡 适用场景:特定语言的拒绝措辞、项目特有的拒绝响应、新的 Cursor 拒绝模式
|
| 171 |
+
# 支持热重载:修改后下一次请求即生效
|
| 172 |
+
# refusal_patterns:
|
| 173 |
+
# - "我无法协助"
|
| 174 |
+
# - "this violates our"
|
| 175 |
+
# - "I must decline"
|
| 176 |
+
# - "无法为您提供"
|
| 177 |
+
# - "this request is outside"
|
| 178 |
+
|
| 179 |
+
# 浏览器指纹配置
|
| 180 |
+
fingerprint:
|
| 181 |
+
user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36"
|
| 182 |
+
|
| 183 |
+
# ==================== 视觉处理降级配置(可选) ====================
|
| 184 |
+
# 如果开启,可以拦截您发给大模型的图片进行降级处理(因为目前免费 Cursor 不支持视觉)。
|
| 185 |
+
vision:
|
| 186 |
+
enabled: true
|
| 187 |
+
# mode 选项: 'ocr' 或 'api'
|
| 188 |
+
# 'ocr': [默认模式] 彻底免 Key,零配置,完全依赖本机的 CPU 识图,提取文本、报错日志、代码段后发给大模型。
|
| 189 |
+
# 'api': 需要配置下方的 baseUrl 和 apiKey,把图发给外部视觉模型(如 Gemini、OpenRouter),能"看到"画面内容和色彩。
|
| 190 |
+
mode: 'ocr'
|
| 191 |
+
|
| 192 |
+
# ---------- 以下选项仅在 mode: 'api' 时才生效 ----------
|
| 193 |
+
# base_url: "https://openrouter.ai/api/v1/chat/completions"
|
| 194 |
+
# api_key: "sk-or-v1-..."
|
| 195 |
+
# model: "meta-llama/llama-3.2-11b-vision-instruct:free"
|
| 196 |
+
|
| 197 |
+
# Vision 独立代理(可选)
|
| 198 |
+
# 💡 Cursor API 国内可直连无需代理,但图片分析 API(OpenAI/OpenRouter)可能需要
|
| 199 |
+
# 配置此项后只有图片 API 走代理,不影响主请求的响应速度
|
| 200 |
+
# 如果不配,会回退到上面的全局 proxy(如果有的话)
|
| 201 |
+
# proxy: "http://127.0.0.1:7890"
|
| 202 |
+
|
| 203 |
+
# ==================== 日志持久化配置(可选) ====================
|
| 204 |
+
# 支持两种持久化方式,可单独开启或同时开启(双写)。
|
| 205 |
+
# 支持热重载,修改 config.yaml 后无需重启即可生效。
|
| 206 |
+
#
|
| 207 |
+
# 方式一:JSONL 文件(每天一个文件,适合日志量较小的场景)
|
| 208 |
+
# 环境变量: LOG_FILE_ENABLED=true|false, LOG_DIR=./logs, LOG_PERSIST_MODE=compact|full|summary
|
| 209 |
+
#
|
| 210 |
+
# 方式二:SQLite 数据库(推荐,解决大文件 OOM 问题,支持重启后历史查询和分页)
|
| 211 |
+
# 优势:启动时仅加载 summary,payload 按需查询,彻底避免 OOM
|
| 212 |
+
# 优势:Vue UI 支持重启后翻页查看完整历史,搜索/筛选命中全量数据
|
| 213 |
+
# 环境变量: LOG_DB_ENABLED=true|false, LOG_DB_PATH=./logs/cursor2api.db
|
| 214 |
+
logging:
|
| 215 |
+
# 方式一:JSONL 文件持久化(默认关闭)
|
| 216 |
+
# ⚠️ 单天日志量大时(>100MB)建议改用 SQLite 方式,避免启动 OOM
|
| 217 |
+
file_enabled: false
|
| 218 |
+
# 日志文件存储目录
|
| 219 |
+
dir: "./logs"
|
| 220 |
+
# 日志保留天数(超过天数的日志文件会自动清理)
|
| 221 |
+
max_days: 7
|
| 222 |
+
# 落盘模式:
|
| 223 |
+
# compact = 精简调试信息(保留更多排障细节)
|
| 224 |
+
# full = 完整持久化(文件体积最大,慎用)
|
| 225 |
+
# summary = 仅保留”用户问了什么 / 模型答了什么”与少量元数据(默认)
|
| 226 |
+
persist_mode: summary
|
| 227 |
+
|
| 228 |
+
# 方式二:SQLite 数据库持久化(推荐,默认关闭)
|
| 229 |
+
db_enabled: false
|
| 230 |
+
# SQLite 文件路径(确保 logs 目录已挂载,Docker 下同 dir 目录)
|
| 231 |
+
db_path: "./logs/cursor2api.db"
|
entrypoint.sh
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/sh
|
| 2 |
+
set -e
|
| 3 |
+
|
| 4 |
+
CONFIG_FILE="/app/config.yaml"
|
| 5 |
+
CONFIG_EXAMPLE="/app/config.yaml.example"
|
| 6 |
+
|
| 7 |
+
# Bootstrap config.yaml if missing
|
| 8 |
+
if [ ! -f "$CONFIG_FILE" ]; then
|
| 9 |
+
cp "$CONFIG_EXAMPLE" "$CONFIG_FILE"
|
| 10 |
+
fi
|
| 11 |
+
|
| 12 |
+
# HF Spaces requires port 7860
|
| 13 |
+
export PORT=7860
|
| 14 |
+
|
| 15 |
+
echo "[cursor2api] Starting on port 7860..."
|
| 16 |
+
exec node dist/index.js
|