Skip to content
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ tests
.DS_Store
*.log
.env
.env.*
.env.*
dist/
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ jobs:
node-version: 20
cache: npm
- run: npm ci
- run: npm run typecheck
- run: npm run build
- run: npm test -- --runInBand

shellcheck:
Expand Down Expand Up @@ -60,5 +62,27 @@ jobs:
context: .
file: ./Dockerfile
push: false
load: true
tags: opencode2api:ci
cache-from: type=gha
cache-to: type=gha,mode=max
# Minimal smoke: run the compiled proxy directly (bypass opencode
# backend wait) and probe the auth-free shallow /health endpoint.
# `node dist/index.js` hits the entrypoint else-branch
# (exec gosu node "$@") so no backend credentials are needed.
- name: Smoke test built image (/health)
run: |
docker run -d --name opencode2api-smoke -p 10000:10000 opencode2api:ci node dist/index.js
ok=0
for i in $(seq 1 30); do
if curl -sf http://127.0.0.1:10000/health; then
echo
echo "smoke: /health 200"
ok=1
break
fi
sleep 2
done
docker logs opencode2api-smoke || true
docker rm -f opencode2api-smoke || true
test "$ok" = "1"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ yarn-debug.log*
yarn-error.log*
.env
config.json
dist/
9 changes: 8 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,24 @@ git clone https://github.com/samson910022/OpenCode2API.git
cd OpenCode2API
npm install

# Typecheck / build (TS source: index.ts + src/**/*.ts, output: dist/)
npm run typecheck
npm run build

# Run tests
npm test

# Start locally
# Start locally (dev: tsx watch index.ts / prod: node dist/index.js)
npm run dev
npm start
```

## Testing

- Unit tests: `npm run test:unit`
- Integration tests: `npm run test:integration`
- Typecheck: `npm run typecheck`
- Build: `npm run build`
- All tests: `npm test -- --runInBand`

## Code Review Process
Expand Down
22 changes: 20 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
# P5: multi-stage — builder compiles TS -> dist, runtime ships only prod deps + dist.
# Local `dist/` stays in .dockerignore (never enters context); the runtime
# COPY --from=builder bypasses the ignore because it copies from the build
# stage filesystem, not from the build context.
FROM node:lts-slim AS builder

WORKDIR /build

COPY package*.json ./
RUN npm ci

COPY tsconfig.json ./
COPY index.ts ./
COPY src ./src
RUN npm run build

# ---------------- runtime ----------------
FROM node:lts-slim

RUN apt-get update && apt-get install -y --no-install-recommends \
Expand All @@ -23,9 +40,10 @@ RUN chmod +x /usr/local/bin/entrypoint.sh
WORKDIR /home/node/project

COPY package*.json ./
RUN npm install --production
RUN npm ci --omit=dev

COPY . .
COPY --from=builder /build/dist ./dist
RUN chown -R node:node /home/node/project

EXPOSE 10000 10001

Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ git clone https://github.com/samson910022/OpenCode2API.git
cd OpenCode2API
npm install
cp config.json.example config.json
npm run build
npm start
```

Expand Down Expand Up @@ -311,13 +312,27 @@ USE_ISOLATED_HOME=false # 让 OpenCode 复用本地登录态
## 🔨 开发

```bash
# 类型检查(tsc --noEmit)
npm run typecheck

# 构建(tsc -> dist/,入口 dist/index.js)
npm run build

# 本地开发(tsx watch,源码入口 index.ts)
npm run dev

# 生产启动(运行构建产物)
npm start

# 运行测试
npm test -- --runInBand

# Docker 开发
docker compose up -d --build
```

> TypeScript 源码:`index.ts` + `src/**/*.ts`;构建产物:`dist/`(`dist/index.js` 为运行时入口,本地 `dist/` 不进 git/docker context)。

---

## 📄 许可证
Expand Down
17 changes: 13 additions & 4 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ curl -fsSL https://opencode.ai/install | bash
### 启动开发服务器

```bash
# 开发(tsx watch,直接跑 TS 源码 index.ts)
npm run dev

# 生产(先构建再跑产物 dist/index.js)
npm run build
npm start
```

Expand All @@ -58,6 +63,10 @@ cp config.json.example config.json

| 命令 | 说明 |
|:-----|:-----|
| `npm run dev` | 开发模式(tsx watch `index.ts`) |
| `npm run typecheck` | 类型检查(`tsc --noEmit`) |
| `npm run build` | 构建到 `dist/`(入口 `dist/index.js`) |
| `npm start` | 生产启动(`node dist/index.js`) |
| `npm test -- --runInBand` | 运行所有测试 |
| `npm run test:unit` | 运行单元测试 |
| `npm run test:integration` | 运行集成测试 |
Expand Down Expand Up @@ -103,16 +112,16 @@ chore: update build/ci

```
OpenCode2API/
├── src/
│ └── proxy.js # 核心代理逻辑
├── index.ts # 入口(TS 源码)
├── src/**/*.ts # 核心代理逻辑(TS)
├── dist/ # 构建产物(tsc 输出,运行时入口 dist/index.js,不进 git)
├── tests/
│ ├── app.test.js # 单元测试
│ ├── test-integration.sh # 集成测试
│ └── test-streaming-real.sh # 流式测试
├── docs/ # 文档
├── index.js # 入口文件
├── package.json # 项目配置
├── Dockerfile # Docker 镜像
├── Dockerfile # Docker 镜像(多阶段:builder -> runtime)
└── docker-compose.yml # Docker Compose
```

Expand Down
2 changes: 2 additions & 0 deletions docs/docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ docker run -d \

> 后端 `10001` 仅容器内部使用,不要对外发布(compose 默认也只映射代理端口;改端口用 `OPENCODE_PROXY_PORT`,如 `8090`)。

> 注意:镜像构建时**不会**把本地 `config.json` 烘焙进去(多阶段构建只复制 `dist/` 与依赖,避免把本地密钥带进镜像)。容器内配置请用环境变量,或 `-v ./config.json:/home/node/project/config.json:ro` 挂载(代理会按 `dist/` 同层 → 项目根 → 工作目录顺序查找)。

### 多架构

`ghcr.io/samson910022/opencode2api:latest` 同时含 `linux/amd64` 与 `linux/arm64`,ARM 机器可直接 pull,无需本地 build(仅自带 `custom-bin/opencode` 二进制时才需按架构重建)。
Expand Down
3 changes: 2 additions & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
| 3. 安装依赖 | `npm install` |
| 4. 复制配置 | `cp config.json.example config.json` |
| 5. 安装 CLI | `npm install -g opencode-ai` |
| 6. 启动服务 | `npm start` |
| 6. 构建产物 | `npm run build` |
| 7. 启动服务 | `npm start` |

---

Expand Down
2 changes: 1 addition & 1 deletion entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ if [[ "$1" == "opencode" && "$2" == "serve" ]]; then
echo "OpenCode Server is up!"

echo "Starting OpenAI Proxy on port ${PROXY_PORT}..."
exec gosu node node index.js
exec gosu node node dist/index.js
else
exec gosu node "$@"
fi
Loading
Loading