@xcompiler/cli 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +18 -0
- package/README.CN.md +143 -190
- package/README.md +144 -193
- package/config.example.yaml +138 -0
- package/debug-wiki/README.md +12 -0
- package/debug-wiki/wiki/agent/calibration-fixtures.md +33 -0
- package/debug-wiki/wiki/agent/calibration-network-api.md +36 -0
- package/debug-wiki/wiki/agent/calibration-python-imports.md +33 -0
- package/debug-wiki/wiki/system/debug-issue-flow.md +29 -0
- package/debug-wiki/wiki/system/no-poisoning.md +29 -0
- package/dist/acp/index.d.ts +32 -4
- package/dist/acp/index.js +6064 -1044
- package/dist/acp/index.js.map +1 -1
- package/dist/cli/xcompiler.js +7102 -2051
- package/dist/cli/xcompiler.js.map +1 -1
- package/dist/cli/xcompiler_build.js +3519 -1520
- package/dist/cli/xcompiler_build.js.map +1 -1
- package/dist/cli/xcompiler_run.js +5196 -894
- package/dist/cli/xcompiler_run.js.map +1 -1
- package/dist/plugins/index.d.ts +30 -4
- package/dist/plugins/index.js +401 -85
- package/dist/plugins/index.js.map +1 -1
- package/dist/runtime/runtime.d.ts +79 -17
- package/dist/runtime/runtime.js +7087 -2040
- package/dist/runtime/runtime.js.map +1 -1
- package/docs/XCompiler_design.md +542 -0
- package/docs/acp.md +4 -4
- package/docs/assets/iterative-v-model-pipeline.svg +169 -0
- package/docs/assets/system-architecture.svg +134 -0
- package/docs/assets/xcompiler-icon.png +0 -0
- package/docs/deploy.md +381 -0
- package/docs/openrouter.md +158 -0
- package/docs/versioning.md +12 -0
- package/package.json +9 -1
package/docs/deploy.md
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
# XCompiler 部署指南(deploy)
|
|
2
|
+
|
|
3
|
+
> 适用版本:`@xcompiler/cli ≥ 0.1.0`
|
|
4
|
+
> 两种部署方式:
|
|
5
|
+
>
|
|
6
|
+
> 1. **本地(Local)**:宿主机直接装 Node 24 + Python 3,用 `npm link` 暴露 `xcompiler` 命令。开发与单机生产首选。
|
|
7
|
+
> 2. **Docker**:多阶段构建的 `xcompiler:latest` 镜像 + `docker compose`。适合 CI、共享服务器、网络隔离的生产环境。
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 0. 前置条件(两种方式通用)
|
|
12
|
+
|
|
13
|
+
| 组件 | 版本 | 用途 |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| **LLM 服务** | OpenRouter API key(默认 Free mode)**或** 任一 OpenAI-compatible endpoint;Ollama 可作为本地备选 | XCompiler 的所有 Agent 推理 |
|
|
16
|
+
| **Git** | 任意现代版本 | XCompiler 在 workspace 内做 snapshot/revert(每个 Step 一次提交)|
|
|
17
|
+
| **Python 3.11+** | (仅 `sandbox=subprocess` 必需,docker 模式可省)| 沙盒内运行 pip / pytest |
|
|
18
|
+
|
|
19
|
+
> **网络要求**:沙盒在 `pip install -r requirements.txt` 时需要可达的 PyPI 镜像。建议在 shell 注入:
|
|
20
|
+
> `PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple`(或阿里云、内网 mirror)。
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 1. 本地部署(Local)
|
|
25
|
+
|
|
26
|
+
### 1.1 安装 Node 与依赖
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Linux/macOS
|
|
30
|
+
curl -fsSL https://nodejs.org/dist/v24.18.0/node-v24.18.0-linux-x64.tar.xz | sudo tar -xJ -C /opt
|
|
31
|
+
export PATH=/opt/node-v24.18.0-linux-x64/bin:$PATH
|
|
32
|
+
node -v # v24.x
|
|
33
|
+
|
|
34
|
+
# 克隆并装包
|
|
35
|
+
git clone <repo-url> xcompiler && cd xcompiler
|
|
36
|
+
npm ci
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 1.2 配置
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
cp .env.example .env
|
|
43
|
+
# 编辑 .env:
|
|
44
|
+
# OPENROUTER_API_KEY=<your-key>
|
|
45
|
+
# OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
|
|
46
|
+
# OPENROUTER_MODEL=qwen/qwen3-coder:free
|
|
47
|
+
|
|
48
|
+
cp config.example.yaml config.yaml
|
|
49
|
+
# 关键字段(详见 README.md 与 docs/openrouter.md):
|
|
50
|
+
# llm.providers.<name>.type: openai | ollama
|
|
51
|
+
# llm.roles.{Planner|Architect|Coder|Tester|Debugger}: provider 名数组
|
|
52
|
+
# agent.sandboxes.python.mode / agent.sandboxes.typescript.mode: subprocess | docker
|
|
53
|
+
# agent.max_rounds_per_step / max_debug_rounds_per_step / max_debug_retries
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 1.3 构建并安装为全局命令
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm run build # tsup -> dist/
|
|
60
|
+
npm link # 注册 xcompiler / xcompiler_build / xcompiler_run 到 $PATH
|
|
61
|
+
|
|
62
|
+
xcompiler --help
|
|
63
|
+
xcompiler --version
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
> **不想 `npm link`?** 直接用 `npx`:`npx -p . xcompiler --help`,
|
|
67
|
+
> 或在开发期 `npm run dev -- build -i workspace/intake.md`(tsx 直跑 TS)。
|
|
68
|
+
|
|
69
|
+
### 1.4 烟测
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# 1) 单测(不依赖 LLM/网络)
|
|
73
|
+
npm run typecheck
|
|
74
|
+
npm test # 完整 Vitest 回归(含本机回环网络测试)
|
|
75
|
+
|
|
76
|
+
# 2) OpenRouter endpoint 烟测(需 .env 中 OPENROUTER_API_KEY 可用)
|
|
77
|
+
set -a
|
|
78
|
+
. ./.env
|
|
79
|
+
set +a
|
|
80
|
+
curl https://openrouter.ai/api/v1/models \
|
|
81
|
+
-H "Authorization: Bearer $OPENROUTER_API_KEY"
|
|
82
|
+
|
|
83
|
+
# 3) 端到端编排
|
|
84
|
+
mkdir -p /tmp/hello-demo && cat > /tmp/hello-demo/intake.md <<'EOF'
|
|
85
|
+
开发一个 Python 包 hello,提供 hello.greet(name) -> str;至少 3 个 pytest 用例。
|
|
86
|
+
EOF
|
|
87
|
+
xcompiler build -o /tmp/hello-demo -i /tmp/hello-demo/intake.md --yes
|
|
88
|
+
xcompiler run /tmp/hello-demo/phasePlan.json
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 1.5 升级
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
cd xcompiler
|
|
95
|
+
git pull
|
|
96
|
+
npm ci
|
|
97
|
+
npm run build
|
|
98
|
+
# npm link 一次性建立的符号链接会自动指向新 dist/
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 1.6 卸载
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npm unlink -g @xcompiler/cli
|
|
105
|
+
rm -rf <repo>/node_modules <repo>/dist
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 1.7 单文件可执行程序(无 Node 依赖)
|
|
111
|
+
|
|
112
|
+
> 适合分发到**没有 Node 环境**的目标机器。打出来的可执行程序内嵌了 Node 24 + 全部 JS 依赖,
|
|
113
|
+
> 终端用户只需要把单文件 `xcompiler` / `xcompiler.exe` 解压后直接运行即可。
|
|
114
|
+
>
|
|
115
|
+
> ⚠️ **注意**:单文件可执行程序仍然需要目标机器自带 **Python 3.11+ / git** —— 它们用于沙盒(pip / pytest)和 snapshot/revert。这是 XCompiler 自身的运行期依赖,不在打包范围内。
|
|
116
|
+
|
|
117
|
+
### 1.7.1 本机原生打包与全目标发版
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# 自动识别当前 Linux/macOS 的架构,只打本机可直接运行的目标
|
|
121
|
+
npm run package
|
|
122
|
+
|
|
123
|
+
# 发版模式:linux-x64 / linux-arm64 / macos-arm64 / win-x64 全部打包
|
|
124
|
+
npm run package:all
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
全目标模式会由 `@yao-pkg/pkg` 按需下载各平台的 Node 基础二进制,因此首次执行需要访问其 GitHub Releases;CI 发版固定使用该入口。本机原生模式只需要当前平台的基础二进制。
|
|
128
|
+
|
|
129
|
+
产物布局:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
dist/pkg/
|
|
133
|
+
├── xcompiler-linux-x64/
|
|
134
|
+
│ ├── xcompiler # ELF 64-bit, x86_64
|
|
135
|
+
│ ├── README.md LICENSE NOTICE
|
|
136
|
+
│ ├── config.example.yaml .env.example
|
|
137
|
+
├── xcompiler-linux-x64.tar.gz # 打包发布用
|
|
138
|
+
├── xcompiler-linux-arm64/
|
|
139
|
+
│ ├── xcompiler # ELF 64-bit, aarch64
|
|
140
|
+
│ └── ...(同上)
|
|
141
|
+
├── xcompiler-linux-arm64.tar.gz
|
|
142
|
+
├── xcompiler-macos-arm64/
|
|
143
|
+
│ ├── xcompiler # Mach-O 64-bit, arm64(已 ad-hoc 签名)
|
|
144
|
+
│ └── ...
|
|
145
|
+
├── xcompiler-macos-arm64.tar.gz
|
|
146
|
+
├── xcompiler-win-x64/
|
|
147
|
+
│ ├── xcompiler.exe # PE32+, x86_64 — ⚠️ v0.1.0 未在 Windows 实机验证
|
|
148
|
+
│ └── ...
|
|
149
|
+
└── xcompiler-win-x64.zip # 需要本机有 zip 命令;否则只产生目录
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
> **macOS Apple Silicon 原生目标为 macos-arm64**;`npm run package` 会在 Apple Silicon Mac 上自动选择该目标。
|
|
153
|
+
> 关键点:
|
|
154
|
+
>
|
|
155
|
+
> - `--no-bytecode` 已默认开启 — 解决 V8 bytecode snapshot 在 Node 24 readline / NDJSON HTTP 流场景下的 SIGSEGV。
|
|
156
|
+
> - 强制代码签名 — macOS 本机使用系统 `codesign` 执行并验证 ad-hoc 签名;Linux 交叉打包 macOS 目标时使用 `ldid`。
|
|
157
|
+
> - macos-x64(Intel Mac)会在 Intel Mac 上被自动选择,也可显式执行 `npm run package:macos-x64`。
|
|
158
|
+
|
|
159
|
+
### 1.7.2 单目标打包
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
npm run package:linux-x64
|
|
163
|
+
npm run package:linux-arm64
|
|
164
|
+
npm run package:macos-arm64
|
|
165
|
+
npm run package:macos-x64
|
|
166
|
+
npm run package:win-x64
|
|
167
|
+
|
|
168
|
+
# 或直接调脚本
|
|
169
|
+
./scripts/package.sh linux-x64 win-x64
|
|
170
|
+
./scripts/package.sh macos-arm64 macos-x64
|
|
171
|
+
./scripts/package.sh native
|
|
172
|
+
./scripts/package.sh all
|
|
173
|
+
TARGETS="linux-arm64" ./scripts/package.sh
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### 1.7.3 终端用户的使用流程
|
|
177
|
+
|
|
178
|
+
**Linux**:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
tar -xzf xcompiler-linux-x64.tar.gz
|
|
182
|
+
cd xcompiler-linux-x64
|
|
183
|
+
cp config.example.yaml ~/.xc/config.yaml # 按需编辑
|
|
184
|
+
./xcompiler --help
|
|
185
|
+
./xcompiler build -i intake.md -o ~/myproj --yes
|
|
186
|
+
./xcompiler run ~/myproj/phasePlan.json
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Windows**(PowerShell):
|
|
190
|
+
|
|
191
|
+
> ⚠️ **v0.1.0 状态**:`xcompiler-win-x64.exe` 已能成功打包,但**尚未在 Windows 实机上端到端验证**(沙盒 / git snapshot / pytest 流程)。建议作为预览版试用,遇到问题请提 issue。Linux / macOS Apple Silicon 已通过完整回归。
|
|
192
|
+
|
|
193
|
+
```powershell
|
|
194
|
+
Expand-Archive xcompiler-win-x64.zip
|
|
195
|
+
cd xcompiler-win-x64
|
|
196
|
+
copy config.example.yaml $env:USERPROFILE\.xc\config.yaml
|
|
197
|
+
.\xcompiler.exe --help
|
|
198
|
+
.\xcompiler.exe build -i intake.md -o C:\myproj --yes
|
|
199
|
+
.\xcompiler.exe run C:\myproj\phasePlan.json
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### 1.7.4 实现细节(如何打的包)
|
|
203
|
+
|
|
204
|
+
| 阶段 | 工具 | 输入 → 输出 |
|
|
205
|
+
|---|---|---|
|
|
206
|
+
| 1. 构建 CJS 单包 | [tsup.pkg.config.ts](../tsup.pkg.config.ts) | `src/cli/xcompiler.ts` → `dist/pkg-build/xcompiler.cjs`(约 1.7 MB,已 inline 全部依赖)|
|
|
207
|
+
| 2. 跨平台编译 | `@yao-pkg/pkg` (vercel/pkg 维护活跃 fork) | `xcompiler.cjs` + 内置 Node20 → 各目标平台 native binary(约 55 MB)|
|
|
208
|
+
| 3. 压缩发布 | `tar` / `zip` | `xcompiler-<target>/` → `xcompiler-<target>.tar.gz` / `.zip`(约 21 MB)|
|
|
209
|
+
| 4. 完整性校验 | `sha256sum` / `shasum` | 所有压缩包 → `dist/pkg/SHA256SUMS` |
|
|
210
|
+
|
|
211
|
+
脚本主入口:[scripts/package.sh](../scripts/package.sh)。配置都集中在 `tsup.pkg.config.ts` 与 `package.json -> scripts`。
|
|
212
|
+
|
|
213
|
+
> **为什么不打 `xcompiler_build` / `xcompiler_run` 单独的 exe?**
|
|
214
|
+
> `xcompiler` 是统一入口,`xcompiler build` ≡ `xcompiler_build`,`xcompiler run` ≡ `xcompiler_run`。一个 60 MB 的可执行文件
|
|
215
|
+
> 可以承担全部子命令;如果想要 `xcompiler_build.exe` 这种命名,复制重命名即可,行为不变。
|
|
216
|
+
|
|
217
|
+
> **Windows .zip 需要 zip 命令**:选择 Windows 目标但检测不到 `zip` 时,脚本会终止发版,避免留下不完整的发布产物。Linux / WSL 上可执行 `apt install zip` 安装。
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## 2. Docker 部署
|
|
223
|
+
|
|
224
|
+
### 2.1 镜像结构
|
|
225
|
+
|
|
226
|
+
[Dockerfile](../Dockerfile) 是两阶段:
|
|
227
|
+
|
|
228
|
+
| Stage | 基础镜像 | 用途 |
|
|
229
|
+
|---|---|---|
|
|
230
|
+
| `build` | `node:20-bookworm-slim` | `npm ci` + `npm run build` 生成 `dist/` |
|
|
231
|
+
| `runtime` | `node:20-bookworm-slim` + `python3 / python3-venv / git / docker.io / tini` | 仅装 production deps,运行 `xcompiler` |
|
|
232
|
+
|
|
233
|
+
启动时 `tini` 做 PID 1,运行用户为 `xcompiler (uid=1000)`,工作目录 `/workspace` 以 volume 形式暴露。
|
|
234
|
+
|
|
235
|
+
### 2.2 构建镜像
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
cd xcompiler
|
|
239
|
+
docker build -t xcompiler:latest .
|
|
240
|
+
# 或带版本 tag:docker build -t xcompiler:0.1.3 -t xcompiler:latest .
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### 2.3 配置文件准备
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
cp .env.example .env
|
|
247
|
+
cp config.example.yaml config.yaml
|
|
248
|
+
mkdir -p workspace
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### 2.4 用 docker compose 跑(推荐)
|
|
252
|
+
|
|
253
|
+
[docker-compose.yml](../docker-compose.yml) 已挂好:
|
|
254
|
+
- `./workspace -> /workspace`(编排产出)
|
|
255
|
+
- `./config.yaml -> /home/xcompiler/app/config.yaml:ro`
|
|
256
|
+
- `/var/run/docker.sock -> /var/run/docker.sock`(DooD:让容器内 xcompiler 能起 sibling 沙盒容器)
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
# 看帮助
|
|
260
|
+
docker compose run --rm xcompiler --help
|
|
261
|
+
|
|
262
|
+
# 编译需求 -> phasePlan.json + 当前阶段 plan.P<N>.json(写到指定输出目录)
|
|
263
|
+
docker compose run --rm xcompiler build \
|
|
264
|
+
-i /workspace/intake.md \
|
|
265
|
+
-c /home/xcompiler/app/config.yaml \
|
|
266
|
+
-o /workspace/hello-demo \
|
|
267
|
+
--yes
|
|
268
|
+
|
|
269
|
+
# 执行当前阶段计划
|
|
270
|
+
docker compose run --rm xcompiler run \
|
|
271
|
+
/workspace/<project>/phasePlan.json \
|
|
272
|
+
-c /home/xcompiler/app/config.yaml
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
> **DooD 的 GID 注入**:宿主 `/var/run/docker.sock` 的属主 GID 通常是 `999` 或 `998`。
|
|
276
|
+
> 默认 `group_add: ["999"]`;如果不同,请:
|
|
277
|
+
>
|
|
278
|
+
> ```bash
|
|
279
|
+
> DOCKER_GID=$(stat -c '%g' /var/run/docker.sock) docker compose run --rm xcompiler ...
|
|
280
|
+
> ```
|
|
281
|
+
|
|
282
|
+
### 2.5 直接 `docker run`(不要 compose)
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
docker run --rm -it \
|
|
286
|
+
--env-file .env \
|
|
287
|
+
-v "$PWD/workspace:/workspace" \
|
|
288
|
+
-v "$PWD/config.yaml:/home/xcompiler/app/config.yaml:ro" \
|
|
289
|
+
-v /var/run/docker.sock:/var/run/docker.sock \
|
|
290
|
+
--group-add "$(stat -c '%g' /var/run/docker.sock)" \
|
|
291
|
+
-w /workspace \
|
|
292
|
+
xcompiler:latest \
|
|
293
|
+
build -i /workspace/intake.md -c /home/xcompiler/app/config.yaml --yes
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### 2.6 沙盒模式选择
|
|
297
|
+
|
|
298
|
+
`config.yaml -> agent.sandboxes.<language>.mode`:
|
|
299
|
+
|
|
300
|
+
| 模式 | 适用场景 | 说明 |
|
|
301
|
+
|---|---|---|
|
|
302
|
+
| `subprocess` | **容器部署唯一支持项** / 轻量本地 | 直接在宿主或 XCompiler 镜像内创建语言专属本地沙盒。简单,最快。默认推荐。 |
|
|
303
|
+
| `docker` | **仅限宿主部署使用** | 在宿主 docker daemon 上起 sibling 容器(image 由 `agent.sandboxes.<language>.docker.image` 指定)。 |
|
|
304
|
+
|
|
305
|
+
> ⚠️ **容器内不可使用 `mode: docker`**。XCompiler 启动时会检测运行环境(`/.dockerenv` / `/proc/1/cgroup` / `XC_IN_CONTAINER` env),若检测到在容器内且当前语言 sandbox 使用 Docker,将报错退出并提示改用 `subprocess`。
|
|
306
|
+
>
|
|
307
|
+
> 原因:DooD 路径错位、`docker.sock` GID 冲突、sibling 容器看不到 XCompiler 容器内的 `/workspace` 路径。
|
|
308
|
+
>
|
|
309
|
+
> 如确需绕过(宿主与容器路径完全一致的可控调试场景):`-e XC_IN_CONTAINER=0`。
|
|
310
|
+
|
|
311
|
+
[Dockerfile](../Dockerfile) 已预设 `ENV XC_IN_CONTAINER=1`。
|
|
312
|
+
|
|
313
|
+
### 2.7 内置 Ollama(可选备份)
|
|
314
|
+
|
|
315
|
+
默认配置不需要内置 Ollama。如要在同一 compose 中跑 Ollama 作为 `type: ollama` 备选 provider,
|
|
316
|
+
编辑 [docker-compose.yml](../docker-compose.yml) 取消注释 `ollama` 服务与对应 volume,然后:
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
docker compose up -d ollama
|
|
320
|
+
docker compose exec ollama ollama pull gemma4:31b
|
|
321
|
+
docker compose exec ollama ollama pull qwen3-coder:30b
|
|
322
|
+
# 在 .env 里把 OLLAMA_BASE_URL 改成 http://ollama:11434
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### 2.8 升级
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
cd xcompiler
|
|
329
|
+
git pull
|
|
330
|
+
docker build -t xcompiler:latest .
|
|
331
|
+
# compose run 会自动用新镜像;workspace 与 config.yaml 不会被 rebuild 影响
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### 2.9 清理
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
docker compose down
|
|
338
|
+
docker rmi xcompiler:latest
|
|
339
|
+
# workspace/ 与 .env / config.yaml 是宿主文件,保留或手动删
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## 3. 常见问题
|
|
345
|
+
|
|
346
|
+
| 现象 | 原因 | 处置 |
|
|
347
|
+
|---|---|---|
|
|
348
|
+
| `pip install` 在沙盒里 DNS 失败 | 宿主到 PyPI 不通 | 设 `PIP_INDEX_URL=<可达镜像>` 注入到 XCompiler 进程环境 |
|
|
349
|
+
| docker 模式下沙盒容器找不到工程文件 | 用了 `./workspace` 相对路径 | 改成绝对路径或 `$(pwd)/workspace` |
|
|
350
|
+
| `EACCES: /var/run/docker.sock` | `xcompiler` 用户不在宿主 docker 组 | `DOCKER_GID=$(stat -c '%g' /var/run/docker.sock) docker compose ...` |
|
|
351
|
+
| 长时 LLM 调用后 `audit.jsonl` 没事件 | (已修)旧版异步 appendFile 排队丢失 | 升级到当前版本:审计已改为 `appendFileSync` |
|
|
352
|
+
| `Plan schema 校验失败` | LLM 返回 plan 字段类型异常 | 查看 `<workspace>/docs/.draft/plan.invalid.json` 定位字段,必要时调高 `agent.max_rounds_per_step` 或换更强模型作为 Planner |
|
|
353
|
+
| 测试阶段一直被 DEBUG 重试到 max | 实现层 bug,DEBUG 也修不动 | 看 `<workspace>/.xcompiler/audit.jsonl` 里 `pytest stderr (tail)`;必要时手动改 SUT 后 `xcompiler run --from S<id>` 续跑 |
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## 4. 目录约定
|
|
358
|
+
|
|
359
|
+
部署完成后的工作区典型结构:
|
|
360
|
+
|
|
361
|
+
```
|
|
362
|
+
<workspace>/
|
|
363
|
+
├── intake.md # 需求输入(用户提供)
|
|
364
|
+
├── config.yaml # 本次运行的配置
|
|
365
|
+
├── phasePlan.json # 阶段总览与当前阶段指针
|
|
366
|
+
├── plan.P1.json # 当前阶段的 V 模型执行计划
|
|
367
|
+
├── requirements.txt # 由 pythonRequirements 在 xcompiler run 启动时种入
|
|
368
|
+
├── docs/
|
|
369
|
+
│ ├── requirements.md
|
|
370
|
+
│ ├── architecture.md
|
|
371
|
+
│ ├── tasks.md
|
|
372
|
+
│ ├── refactor.md
|
|
373
|
+
│ ├── delivery.md
|
|
374
|
+
│ ├── process_log.md # AuditLogger 自动生成
|
|
375
|
+
│ ├── history/ # 同名旧文档归档
|
|
376
|
+
│ └── .draft/ # 失败 plan 等中间产物
|
|
377
|
+
├── src/ # CODE 阶段产出
|
|
378
|
+
├── tests/ # UNIT / INTEGRATION / MODULE / FUNCTIONAL 测试产出
|
|
379
|
+
├── .sandbox/venv/ # subprocess 沙盒虚拟环境
|
|
380
|
+
└── .xcompiler/audit.jsonl # 审计事件流(同步落盘)
|
|
381
|
+
```
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# OpenRouter Free Mode Guide
|
|
2
|
+
|
|
3
|
+
XCompiler defaults to OpenRouter Free mode through an OpenAI-compatible `/v1` endpoint.
|
|
4
|
+
The provider must declare `type: openai`; the provider name is only an identifier and is not used to infer the API protocol.
|
|
5
|
+
|
|
6
|
+
Official references:
|
|
7
|
+
|
|
8
|
+
- OpenRouter Quickstart: https://openrouter.ai/docs/quickstart
|
|
9
|
+
- API reference: https://openrouter.ai/docs/api_reference/overview
|
|
10
|
+
- Free model catalog: https://openrouter.ai/models?max_price=0
|
|
11
|
+
- API keys: https://openrouter.ai/settings/keys
|
|
12
|
+
|
|
13
|
+
## 1. Create Local Environment
|
|
14
|
+
|
|
15
|
+
From a source checkout:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cp .env.example .env
|
|
19
|
+
cp config.example.yaml config.yaml
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
From the published npm package:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g @xcompiler/cli
|
|
26
|
+
cp "$(npm root -g)/@xcompiler/cli/.env.example" .env
|
|
27
|
+
cp "$(npm root -g)/@xcompiler/cli/config.example.yaml" config.yaml
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Edit `.env` locally:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
OPENROUTER_API_KEY=<your-openrouter-api-key>
|
|
34
|
+
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
|
|
35
|
+
OPENROUTER_MODEL=openrouter/free
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`.env` is ignored by git. Do not commit real API keys.
|
|
39
|
+
`config.yaml`, `llm_scores.yaml`, and `llm_scores_user.yaml` are local files; keep them outside commits. The package ships `config.example.yaml` and `.env.example` only as templates. `llm_scores.yaml` is maintained by XCompiler; do not edit it directly.
|
|
40
|
+
|
|
41
|
+
## 2. Configure XCompiler
|
|
42
|
+
|
|
43
|
+
`config.example.yaml` already uses OpenRouter Free mode by default:
|
|
44
|
+
|
|
45
|
+
```yaml
|
|
46
|
+
llm:
|
|
47
|
+
default: openrouter_free
|
|
48
|
+
providers:
|
|
49
|
+
openrouter_free:
|
|
50
|
+
type: openai
|
|
51
|
+
api_key: ${OPENROUTER_API_KEY}
|
|
52
|
+
base_url: https://openrouter.ai/api/v1
|
|
53
|
+
model: openrouter/free
|
|
54
|
+
tags: [cluster]
|
|
55
|
+
request_timeout_ms: 900000
|
|
56
|
+
stream_idle_timeout_ms: 300000
|
|
57
|
+
roles:
|
|
58
|
+
Planner: [openrouter_free]
|
|
59
|
+
Architect: [openrouter_free]
|
|
60
|
+
Coder: [openrouter_free]
|
|
61
|
+
Tester: [openrouter_free]
|
|
62
|
+
Debugger: [openrouter_free]
|
|
63
|
+
cluster_score_min: 0.2
|
|
64
|
+
cluster_score_max: 0.5
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`type: openai` means XCompiler will use the OpenAI-compatible chat completions client. This is also the correct type for local `/v1` endpoints such as vLLM or mlx-server.
|
|
68
|
+
`tags: [cluster]` marks the provider as an aggregated route. XCompiler scores those providers in a lower default band (`0.2..0.5`) so they behave as backups rather than replacing dedicated role models too early.
|
|
69
|
+
OpenRouter requires `OPENROUTER_API_KEY`. Local OpenAI-compatible endpoints may leave `api_key` empty when they run without authentication.
|
|
70
|
+
|
|
71
|
+
If an OpenAI-compatible request fails, XCompiler reports the provider, model, base URL, request mode, HTTP status/body when available, and a concrete hint such as setting `OPENROUTER_API_KEY`, changing `json_response_format`, checking quota/rate limits, or switching provider.
|
|
72
|
+
|
|
73
|
+
## 3. Choose A Free Model
|
|
74
|
+
|
|
75
|
+
OpenRouter free models normally use model ids ending with `:free`.
|
|
76
|
+
Browse https://openrouter.ai/models?max_price=0, copy the model slug, and set:
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
providers:
|
|
80
|
+
openrouter_coder:
|
|
81
|
+
type: openai
|
|
82
|
+
api_key: ${OPENROUTER_API_KEY}
|
|
83
|
+
base_url: https://openrouter.ai/api/v1
|
|
84
|
+
model: qwen/qwen3-coder:free
|
|
85
|
+
openrouter_free:
|
|
86
|
+
type: openai
|
|
87
|
+
api_key: ${OPENROUTER_API_KEY}
|
|
88
|
+
base_url: https://openrouter.ai/api/v1
|
|
89
|
+
model: openrouter/free
|
|
90
|
+
tags: [cluster]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
If one free model returns quota, availability, or capability errors, pick another free model slug and rerun the task.
|
|
94
|
+
|
|
95
|
+
## 4. Engineering Recommendation
|
|
96
|
+
|
|
97
|
+
For real development runs, avoid relying on a single aggregated route as the only model. Use a role-specific primary model, then append `openrouter_free` as the last fallback for every role:
|
|
98
|
+
|
|
99
|
+
```yaml
|
|
100
|
+
roles:
|
|
101
|
+
Planner: [openrouter_planner, openrouter_free]
|
|
102
|
+
Architect: [openrouter_architect, openrouter_free]
|
|
103
|
+
Coder: [openrouter_coder, openrouter_free]
|
|
104
|
+
Tester: [openrouter_tester, openrouter_free]
|
|
105
|
+
Debugger: [openrouter_debugger, openrouter_free]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Keep the default cluster score band (`cluster_score_min: 0.2`, `cluster_score_max: 0.5`) when `openrouter/free` is a safety net. Raise `cluster_score_max` toward `1.0` only when you intentionally want the aggregated route to compete with dedicated models.
|
|
109
|
+
|
|
110
|
+
For manual local priority overrides, create `llm_scores_user.yaml` beside `config.yaml`:
|
|
111
|
+
|
|
112
|
+
```yaml
|
|
113
|
+
openrouter_free: 0.3
|
|
114
|
+
local_openai: 0
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
User overrides take precedence over the dynamic `llm_scores.yaml` snapshot. Use `0` to disable a provider; use `0.1..1` to pin its effective priority. This file is local runtime policy and should not be committed.
|
|
118
|
+
|
|
119
|
+
## 5. Optional Local Backups
|
|
120
|
+
|
|
121
|
+
Local OpenAI-compatible endpoints:
|
|
122
|
+
|
|
123
|
+
```yaml
|
|
124
|
+
local_openai:
|
|
125
|
+
type: openai
|
|
126
|
+
api_key: ${LOCAL_OPENAI_API_KEY}
|
|
127
|
+
base_url: ${LOCAL_OPENAI_BASE_URL}
|
|
128
|
+
model: ${LOCAL_OPENAI_MODEL}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
For no-auth local servers, set `LOCAL_OPENAI_API_KEY=` or leave the provider `api_key` empty.
|
|
132
|
+
|
|
133
|
+
Ollama native endpoints:
|
|
134
|
+
|
|
135
|
+
```yaml
|
|
136
|
+
ollama_code:
|
|
137
|
+
type: ollama
|
|
138
|
+
base_url: ${OLLAMA_BASE_URL}
|
|
139
|
+
model: ${OLLAMA_CODE_MODEL}
|
|
140
|
+
think: false
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Add backups to `roles` or `fallbacks` only after the provider block is enabled.
|
|
144
|
+
|
|
145
|
+
## 6. Validate
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
npm run typecheck
|
|
149
|
+
npm test
|
|
150
|
+
xcompiler doctor
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
For a direct endpoint check:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
curl https://openrouter.ai/api/v1/models \
|
|
157
|
+
-H "Authorization: Bearer $OPENROUTER_API_KEY"
|
|
158
|
+
```
|
package/docs/versioning.md
CHANGED
|
@@ -24,10 +24,22 @@ npm run version:sync
|
|
|
24
24
|
|
|
25
25
|
# 设置下一个核心版本并同步全部位置
|
|
26
26
|
npm run version:set -- 0.1.4
|
|
27
|
+
|
|
28
|
+
# 准备一次本地发版(不 push)
|
|
29
|
+
npm run release:local -- v0.1.4
|
|
27
30
|
```
|
|
28
31
|
|
|
29
32
|
核心版本遵循 SemVer。发布 tag 必须是 `v<package version>`,例如 `v0.1.3`;Release workflow 会在测试和打包前强制校验,版本不一致时停止发布。二进制分发包内包含 `VERSION` 文件,CLI 的 `--version` 也读取同一个生成常量。
|
|
30
33
|
|
|
34
|
+
`release:local` 会要求工作区干净,然后同步 `package.json`、`package-lock.json` 与 `src/version.ts`,执行本地发版门禁(`version:check`、`npm audit --omit=dev`、`typecheck`、`lint`、`test`、`build`、`npm pack --dry-run`),提交 `chore: release <tag>`,并创建本地 annotated tag。它不会 push;完成后手工执行:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git push origin <branch>
|
|
38
|
+
git push origin <tag>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
如果上一次本地 tag 创建错了但还没有推送远端,可使用 `npm run release:local -- v0.1.4 --replace-local-tag` 删除并重建本地 tag;该选项不会删除远端 tag。离线环境可加 `--skip-audit` 跳过本地 `npm audit`,但 GitHub Release workflow 仍会执行审计。
|
|
42
|
+
|
|
31
43
|
Plugin API 版本独立于核心版本,只在插件公共接口出现不兼容修改时递增整数主版本。插件自身使用 SemVer,并在 manifest 中强制声明 `apiVersion` 和 `minXCompilerVersion`;详细规则见 [plugin_api.md](plugin_api.md)。
|
|
32
44
|
|
|
33
45
|
审计内容默认使用 `redacted` 模式遮蔽 API key、token、密码等凭据。需要最小化留存时设置 `XC_AUDIT_CONTENT_MODE=metadata`(只保留长度和 SHA-256);只有在受控环境确实需要完整回放时才使用 `full`。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xcompiler/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "XCompiler — AI Software Factory: V-model driven, multi-LLM orchestrated software development agent.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -40,7 +40,14 @@
|
|
|
40
40
|
"dist/plugins",
|
|
41
41
|
"dist/runtime",
|
|
42
42
|
"dist/acp",
|
|
43
|
+
"config.example.yaml",
|
|
44
|
+
".env.example",
|
|
45
|
+
"debug-wiki",
|
|
46
|
+
"docs/assets",
|
|
43
47
|
"docs/acp.md",
|
|
48
|
+
"docs/XCompiler_design.md",
|
|
49
|
+
"docs/deploy.md",
|
|
50
|
+
"docs/openrouter.md",
|
|
44
51
|
"docs/plugin_api.md",
|
|
45
52
|
"docs/self_bootstrap.md",
|
|
46
53
|
"docs/versioning.md",
|
|
@@ -52,6 +59,7 @@
|
|
|
52
59
|
"version:check": "node scripts/version.mjs check",
|
|
53
60
|
"version:sync": "node scripts/version.mjs sync",
|
|
54
61
|
"version:set": "node scripts/version.mjs set",
|
|
62
|
+
"release:local": "bash scripts/release-local.sh",
|
|
55
63
|
"prepack": "npm run version:check",
|
|
56
64
|
"prebuild": "npm run version:check",
|
|
57
65
|
"build": "tsup",
|