@yhong91/cpac 0.1.35 → 0.1.37
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/README.md +20 -27
- package/dist/cpac.js +14 -23
- package/package.json +1 -1
- package/dist/targets/opencode.js +0 -59
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ CPAC 将 Codex 和 Claude Code 接入远端 CLIProxyAPI(CPA):
|
|
|
10
10
|
## 要求
|
|
11
11
|
|
|
12
12
|
- [Node.js](https://nodejs.org/) 20 或更新版本(npm 随 Node 安装)
|
|
13
|
-
- 已安装需要使用的 agent:`codex`、`claude`、`pi`、`kimi` 或 `
|
|
13
|
+
- 已安装需要使用的 agent:`codex`、`claude`、`pi`、`kimi` 或 `grok`
|
|
14
14
|
- 有权访问的 CPA API key
|
|
15
15
|
|
|
16
16
|
## 安装
|
|
@@ -45,11 +45,11 @@ cpac restore codex # 撤掉注入;注入期间的用户改
|
|
|
45
45
|
|
|
46
46
|
# 4b. 临时接管(退出无痕,不写任何配置文件)
|
|
47
47
|
cpac claude # Claude Code 走 CPA
|
|
48
|
-
cpac opencode # opencode 走 CPA(模型选 cpac/<模型名>)
|
|
49
48
|
|
|
50
|
-
# 5. 可选:Agent
|
|
51
|
-
cpac setup codex # Codex 配置向导 → 注入
|
|
52
|
-
cpac setup claude # Claude 模型向导
|
|
49
|
+
# 5. 可选:Agent 配置向导与模型选择(只写配置,不启动)
|
|
50
|
+
cpac setup codex # Codex 配置向导 → 注入
|
|
51
|
+
cpac setup claude # Claude 模型向导
|
|
52
|
+
cpac claude setup # 配置完再启动(agent 下的 setup 才会 launch)
|
|
53
53
|
|
|
54
54
|
# 6. 升级(装上新版本后自动 sync 已接入的 agent)
|
|
55
55
|
cpac upgrade
|
|
@@ -61,7 +61,7 @@ cpac upgrade
|
|
|
61
61
|
|
|
62
62
|
本节面向 AI agent:按顺序执行即可完成安装与配置,**全程无交互**。注意:`cpac codex --config` 和 `cpac claude --config` 的交互向导是 TTY-only,agent 必须走下方直接写配置 JSON 的路径。
|
|
63
63
|
|
|
64
|
-
1. **检查前置**:`node --version` ≥ 20;确认用户需要哪些 agent(`codex`/`claude`/`pi`/`kimi`/`
|
|
64
|
+
1. **检查前置**:`node --version` ≥ 20;确认用户需要哪些 agent(`codex`/`claude`/`pi`/`kimi`/`grok` 在 PATH 上)。向用户索取 CPA API key。
|
|
65
65
|
|
|
66
66
|
2. **安装与密钥**:
|
|
67
67
|
|
|
@@ -90,14 +90,14 @@ cpac status # 验证:各 target 显示 ready/injected
|
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
1. **统一启动与配置**:
|
|
93
|
-
- 启动:`cpac <codex|claude|kimi|grok|pi
|
|
93
|
+
- 启动:`cpac <codex|claude|kimi|grok|pi> [args...]`(所有原生参数如 `-c` 等原样透明传递)
|
|
94
94
|
- `setup` / `--setup`:配置 Codex/Claude,然后启动
|
|
95
95
|
- `clear`:还原原生配置
|
|
96
|
-
-
|
|
96
|
+
- 只写配置、不启动:`cpac setup [claude|codex]`;查看当前:`cpac setup`
|
|
97
97
|
|
|
98
98
|
2. **已安装后升级**:npm 发布新版本后,等 publish 成功再执行 `cpac upgrade`。它会按需 `npm install -g`,再对已接入的 Codex / Pi / Kimi / Grok 做 `sync`。不要拆成 `npm install -g @yhong91/cpac` 再手动 `cpac sync`。只刷新配置、不升 CLI 时才用 `cpac sync`。
|
|
99
99
|
|
|
100
|
-
失败处理:任何一步报错时先跑 `cpac status`;密钥未配置回到步骤 2;注入后异常用 `cpac <agent> clear` 或 `cpac restore <
|
|
100
|
+
失败处理:任何一步报错时先跑 `cpac status`;密钥未配置回到步骤 2;注入后异常用 `cpac <agent> clear` 或 `cpac restore <codex|pi|kimi|grok>` 恢复原配置。
|
|
101
101
|
|
|
102
102
|
## 首次引导
|
|
103
103
|
|
|
@@ -113,7 +113,7 @@ Commands:
|
|
|
113
113
|
cpac <agent> [args...] Launch an agent through CPA
|
|
114
114
|
cpac setup Show current Codex/Claude setup
|
|
115
115
|
cpac status Show agent support status
|
|
116
|
-
cpac restore <
|
|
116
|
+
cpac restore <codex|pi|kimi|grok> | --all Detach injected agents
|
|
117
117
|
cpac --help Show command usage
|
|
118
118
|
```
|
|
119
119
|
|
|
@@ -161,13 +161,13 @@ cpac --help
|
|
|
161
161
|
|
|
162
162
|
### 统一管理(detect / install / sync / restore / uninstall / upgrade)
|
|
163
163
|
|
|
164
|
-
参考 vibetime 的目标式命令,对 `codex`、`pi`、`kimi`
|
|
164
|
+
参考 vibetime 的目标式命令,对 `codex`、`pi`、`kimi`、`grok` 四个持久注入目标统一管理(claude 是临时接管,用 `cpac claude` 启动,不属于 install 目标):
|
|
165
165
|
|
|
166
166
|
```bash
|
|
167
|
-
cpac detect [--json]
|
|
168
|
-
cpac install [codex|pi|kimi|grok...] [--all] [--dry-run] [--force] [--v2_off] [--v2_models] [--max_context]
|
|
169
|
-
cpac sync [codex|pi|kimi|grok...] [--all] [--dry-run] [--v2_off] [--v2_models] [--max_context]
|
|
170
|
-
cpac restore <
|
|
167
|
+
cpac detect [--json]
|
|
168
|
+
cpac install [codex|pi|kimi|grok...] [--all] [--dry-run] [--force] [--v2_off] [--v2_models] [--max_context]
|
|
169
|
+
cpac sync [codex|pi|kimi|grok...] [--all] [--dry-run] [--v2_off] [--v2_models] [--max_context]
|
|
170
|
+
cpac restore <codex|pi|kimi|grok...> | --all [--dry-run]
|
|
171
171
|
cpac uninstall [--dry-run]
|
|
172
172
|
cpac upgrade [--check]
|
|
173
173
|
cpac -v | --version
|
|
@@ -180,7 +180,6 @@ cpac -v | --version
|
|
|
180
180
|
- `--v2_models` 进入 arrow-key 复选框选择最多 5 个 spawn_agent 模型(勾选顺序即推荐顺序),选择结果存入配置文件的 `spawn_models`,注入时把这些模型排到 `codex-models.json` 最前——Codex 客户端只把 catalog 前 5 个可见模型广告为 spawn 覆盖项。
|
|
181
181
|
- `restore` 必须带 agent 名或 `--all`,卸掉指定(或全部)已注入目标。`--all` 时未安装的目标静默跳过。
|
|
182
182
|
- `uninstall` 先用和 `cpac setup codex` 相同的方向键选择器确认(默认 Cancel),再 `restore --all`,最后 `npm uninstall -g @yhong91/cpac`。不要跟 agent 名;卸载的是 cpac 包本身。非终端取消。`--dry-run` 跳过确认。
|
|
183
|
-
- `--home PATH` 临时把 `HOME` 指向给定目录,便于在隔离环境中试验。
|
|
184
183
|
- `upgrade` 是发布后更新本机的一次性入口:查 npm → 需要时 `npm install -g` → 对**已接入**的 Codex / Pi / Kimi 执行 `sync`。已是最新也会 sync。不要先手动 `npm install -g` 再 `cpac sync`。`--check` 只报告版本,不安装也不 sync。没有已安装目标时跳过 sync,不报错。只刷新配置、不升 CLI 时用 `cpac sync`。
|
|
185
184
|
|
|
186
185
|
### Claude Code
|
|
@@ -197,7 +196,8 @@ cpac claude -- -p "检查当前项目"
|
|
|
197
196
|
#### 配置与清除
|
|
198
197
|
|
|
199
198
|
```bash
|
|
200
|
-
cpac setup claude # 交互式依次配置 Sonnet / Haiku / Opus
|
|
199
|
+
cpac setup claude # 交互式依次配置 Sonnet / Haiku / Opus(不启动)
|
|
200
|
+
cpac claude setup # 同上,完成后启动
|
|
201
201
|
cpac claude clear # 重置所有覆盖,恢复自动选择
|
|
202
202
|
```
|
|
203
203
|
|
|
@@ -226,14 +226,15 @@ cpac codex exec "帮我写一个测试"
|
|
|
226
226
|
#### 配置与清除
|
|
227
227
|
|
|
228
228
|
```bash
|
|
229
|
-
cpac setup codex #
|
|
229
|
+
cpac setup codex # 交互式配置后注入(不启动)
|
|
230
|
+
cpac codex setup # 同上,完成后启动 Codex
|
|
230
231
|
cpac codex clear # 还原 Codex 原生配置并关闭代理
|
|
231
232
|
```
|
|
232
233
|
|
|
233
234
|
#### 注入(`cpac install codex`)
|
|
234
235
|
|
|
235
236
|
```bash
|
|
236
|
-
cpac install codex [--v2_off] [--v2_models] [--max_context]
|
|
237
|
+
cpac install codex [--v2_off] [--v2_models] [--max_context]
|
|
237
238
|
cpac restore codex
|
|
238
239
|
```
|
|
239
240
|
|
|
@@ -267,14 +268,6 @@ restore / `<agent> clear` 会删掉该 agent 的备份目录和 state.json 里
|
|
|
267
268
|
|
|
268
269
|
为防止误删或覆盖,`state_dir` 不能是文件系统根目录、用户 home、系统临时目录,也不能包含 Codex 配置文件。
|
|
269
270
|
|
|
270
|
-
### OpenCode(临时接管)
|
|
271
|
-
|
|
272
|
-
```bash
|
|
273
|
-
cpac opencode [--] [opencode args...]
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
通过 `OPENCODE_CONFIG_CONTENT` 内联注入一个 `cpac` OpenAI 兼容 provider(baseURL 直指 CPA,模型列表来自 CPA 目录),不触碰任何 opencode 配置文件,退出即无痕。首次使用时 opencode 会自行安装 `@ai-sdk/openai-compatible` 适配器。模型选择用 `cpac/<模型名>`。
|
|
277
|
-
|
|
278
271
|
### Pi
|
|
279
272
|
|
|
280
273
|
安装 CPA provider 扩展到 Pi:
|
package/dist/cpac.js
CHANGED
|
@@ -8,7 +8,6 @@ import { runClaude, runClaudeConfig } from "./targets/claude.js";
|
|
|
8
8
|
import { multiAgentV2Enabled } from "./targets/codex.js";
|
|
9
9
|
import { isGrokConfigInstalled } from "./targets/grok.js";
|
|
10
10
|
import { isKimiConfigInstalled } from "./targets/kimi.js";
|
|
11
|
-
import { runOpencode } from "./targets/opencode.js";
|
|
12
11
|
import { isPiExtensionInstalled } from "./targets/pi.js";
|
|
13
12
|
import { defaultConfigPath, loadConfig, originalBytes, pickSpawnModels, readState, saveSpawnModels, stateProxy, catalogMaxContextLive, } from "./config.js";
|
|
14
13
|
import { proxyIsHealthy, runProxyChild } from "./proxy.js";
|
|
@@ -21,7 +20,6 @@ export { claudeTierSlots, createClaudeProxy, runClaude, } from "./targets/claude
|
|
|
21
20
|
export { detectClientVersion, detectTargets, runInstall, runRestore, runSync, runTargetLauncher, } from "./agents.js";
|
|
22
21
|
export { installGrokConfig, isGrokConfigInstalled, uninstallGrokConfig, } from "./targets/grok.js";
|
|
23
22
|
export { installKimiConfig, isKimiConfigInstalled, uninstallKimiConfig, } from "./targets/kimi.js";
|
|
24
|
-
export { runOpencode } from "./targets/opencode.js";
|
|
25
23
|
export { installPiExtension, isPiExtensionInstalled, uninstallPiExtension, } from "./targets/pi.js";
|
|
26
24
|
export async function status(config) {
|
|
27
25
|
const apiKey = process.env[config.api_key_env]?.trim();
|
|
@@ -82,9 +80,9 @@ export async function status(config) {
|
|
|
82
80
|
return 0;
|
|
83
81
|
}
|
|
84
82
|
async function guide(config) {
|
|
85
|
-
console.log(`CPA Companion\n\nCPA: ${config.cpa_url}\nCPA_API_KEY: ${process.env[config.api_key_env]?.trim() ? "configured" : "not configured"}\n\nCommands:\n cpac <agent> [args...] Launch an agent (codex, kimi, grok, pi, claude
|
|
83
|
+
console.log(`CPA Companion\n\nCPA: ${config.cpa_url}\nCPA_API_KEY: ${process.env[config.api_key_env]?.trim() ? "configured" : "not configured"}\n\nCommands:\n cpac <agent> [args...] Launch an agent (codex, kimi, grok, pi, claude) through CPA\n cpac setup Show current Codex/Claude setup; cpac setup <codex|claude> to change\n cpac status Show agent support status (Codex, Claude, Pi, Kimi, Grok)\n cpac restore <codex|pi|kimi|grok> | --all Detach injected agents
|
|
86
84
|
cpac detect Show supported targets and install status
|
|
87
|
-
cpac install [
|
|
85
|
+
cpac install [codex|pi|kimi|grok...] Install CPA into detected targets, or named agents
|
|
88
86
|
cpac sync Refresh installed Codex/Pi/Kimi/Grok injections from CPA
|
|
89
87
|
cpac uninstall Detach all agents, then remove the cpac package (confirms first)\n cpac upgrade Update cpac from npm and sync installed agents\n cpac --help Show command usage`);
|
|
90
88
|
if (process.env[config.api_key_env]?.trim())
|
|
@@ -96,33 +94,31 @@ async function guide(config) {
|
|
|
96
94
|
console.log(`\nSaved ${config.api_key_env} to ${profile}. Open a new terminal or run:\n source ${profile}`);
|
|
97
95
|
return 0;
|
|
98
96
|
}
|
|
99
|
-
// opencode's config schema rejects a limit block with context but no output;
|
|
100
|
-
// the catalog has no output field, so a safe budget stands in, clamped to the
|
|
101
97
|
function usage() {
|
|
102
98
|
return [
|
|
103
99
|
"Usage: cpac",
|
|
104
|
-
" cpac <codex|kimi|grok|pi|claude
|
|
100
|
+
" cpac <codex|kimi|grok|pi|claude> [args...]",
|
|
105
101
|
" setup|--setup configure Codex/Claude, then launch",
|
|
106
102
|
" clear restore native config",
|
|
107
|
-
" cpac setup
|
|
103
|
+
" cpac setup Show current Codex/Claude setup",
|
|
108
104
|
" claude [--opus [M]] [--sonnet [M]] [--haiku [M]] [--reset]",
|
|
109
105
|
" codex [--v2_off] [--v2_models] [--max_context]",
|
|
110
|
-
" cpac restore <
|
|
111
|
-
" cpac status
|
|
112
|
-
" cpac detect [--json]
|
|
113
|
-
" cpac install [codex|pi|kimi|grok...] [--all] [--dry-run] [--force] [--v2_off] [--v2_models] [--max_context]
|
|
114
|
-
" cpac sync [codex|pi|kimi|grok...] [--all] [--dry-run] [--v2_off] [--v2_models] [--max_context]
|
|
106
|
+
" cpac restore <codex|pi|kimi|grok...> | --all [--dry-run]",
|
|
107
|
+
" cpac status",
|
|
108
|
+
" cpac detect [--json]",
|
|
109
|
+
" cpac install [codex|pi|kimi|grok...] [--all] [--dry-run] [--force] [--v2_off] [--v2_models] [--max_context]",
|
|
110
|
+
" cpac sync [codex|pi|kimi|grok...] [--all] [--dry-run] [--v2_off] [--v2_models] [--max_context]",
|
|
115
111
|
" cpac uninstall [--dry-run]",
|
|
116
112
|
" cpac upgrade [--check]",
|
|
117
113
|
" cpac -v | --version",
|
|
118
114
|
"",
|
|
119
115
|
"launch an agent with `cpac <agent> [args...]` (remaining args forwarded).",
|
|
120
|
-
"`setup
|
|
116
|
+
"`cpac <agent> setup` configures then launches; `cpac setup [claude|codex]` writes settings only.",
|
|
121
117
|
].join("\n");
|
|
122
118
|
}
|
|
123
119
|
function setupUsage() {
|
|
124
120
|
return [
|
|
125
|
-
"Usage: cpac setup
|
|
121
|
+
"Usage: cpac setup Show current Codex/Claude setup",
|
|
126
122
|
" claude [--opus [M]] [--sonnet [M]] [--haiku [M]] [--reset]",
|
|
127
123
|
" codex [--v2_off] [--v2_models] [--max_context]",
|
|
128
124
|
"",
|
|
@@ -132,7 +128,7 @@ function setupUsage() {
|
|
|
132
128
|
" --haiku high-frequency small tasks (ANTHROPIC_DEFAULT_HAIKU_MODEL)",
|
|
133
129
|
"",
|
|
134
130
|
"A slot without a value opens an arrow-key picker; --reset clears overrides.",
|
|
135
|
-
"No flags on a TTY opens the wizard
|
|
131
|
+
"No flags on a TTY opens the wizard. Does not launch; use `cpac claude setup` / `cpac codex setup` to start.",
|
|
136
132
|
].join("\n");
|
|
137
133
|
}
|
|
138
134
|
function printSetup(config, configPath) {
|
|
@@ -225,7 +221,7 @@ function parseArgs(args) {
|
|
|
225
221
|
}
|
|
226
222
|
return parsed;
|
|
227
223
|
}
|
|
228
|
-
if (["codex", "kimi", "grok", "pi", "claude"
|
|
224
|
+
if (["codex", "kimi", "grok", "pi", "claude"].includes(args[0])) {
|
|
229
225
|
const targetId = args[0];
|
|
230
226
|
let configPath = defaultConfigPath();
|
|
231
227
|
const raw = args.slice(1);
|
|
@@ -419,8 +415,6 @@ function parseArgs(args) {
|
|
|
419
415
|
maxContext,
|
|
420
416
|
reset: false,
|
|
421
417
|
interactive: true,
|
|
422
|
-
launch: true,
|
|
423
|
-
args: [],
|
|
424
418
|
};
|
|
425
419
|
}
|
|
426
420
|
const models = {};
|
|
@@ -462,7 +456,6 @@ function parseArgs(args) {
|
|
|
462
456
|
pick,
|
|
463
457
|
reset,
|
|
464
458
|
interactive,
|
|
465
|
-
launch: interactive && !reset,
|
|
466
459
|
};
|
|
467
460
|
}
|
|
468
461
|
if (args[0] === "claude-models") {
|
|
@@ -574,7 +567,7 @@ export async function main(args = process.argv.slice(2)) {
|
|
|
574
567
|
});
|
|
575
568
|
if (parsed.command === "uninstall") {
|
|
576
569
|
if (parsed.targets.length || parsed.all) {
|
|
577
|
-
throw new CPACError("uninstall removes the cpac package; detach agents with: cpac restore <
|
|
570
|
+
throw new CPACError("uninstall removes the cpac package; detach agents with: cpac restore <codex|pi|kimi|grok> | --all");
|
|
578
571
|
}
|
|
579
572
|
return await runUninstall(config, { dryRun: parsed.dryRun });
|
|
580
573
|
}
|
|
@@ -613,8 +606,6 @@ export async function main(args = process.argv.slice(2)) {
|
|
|
613
606
|
return code;
|
|
614
607
|
return await runTargetLauncher(loadConfig(parsed.configPath, true), "codex", parsed.args ?? [], "codex", { skipSync: true });
|
|
615
608
|
}
|
|
616
|
-
if (parsed.command === "opencode")
|
|
617
|
-
return await runOpencode(config, parsed.args);
|
|
618
609
|
if (parsed.command === "codex") {
|
|
619
610
|
let launcherConfig = config;
|
|
620
611
|
if (parsed.v2Models) {
|
package/package.json
CHANGED
package/dist/targets/opencode.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import { apiBase, catalogModelId, fetchCatalog, } from "../config.js";
|
|
3
|
-
import { CPACError } from "../util.js";
|
|
4
|
-
const OPENCODE_OUTPUT_BUDGET = 32_000;
|
|
5
|
-
// Ephemeral takeover: inline a CPA provider via OPENCODE_CONFIG_CONTENT so no
|
|
6
|
-
// opencode config file is touched; the session ends with zero residue.
|
|
7
|
-
export async function runOpencode(config, args, executable = "opencode") {
|
|
8
|
-
const apiKey = process.env[config.api_key_env]?.trim();
|
|
9
|
-
if (!apiKey)
|
|
10
|
-
throw new CPACError(`environment variable ${config.api_key_env} is not set`);
|
|
11
|
-
const catalog = await fetchCatalog(config.cpa_url, apiKey);
|
|
12
|
-
let document;
|
|
13
|
-
try {
|
|
14
|
-
document = JSON.parse(new TextDecoder().decode(catalog.bytes));
|
|
15
|
-
}
|
|
16
|
-
catch {
|
|
17
|
-
throw new CPACError("invalid CPA catalog");
|
|
18
|
-
}
|
|
19
|
-
const models = {};
|
|
20
|
-
for (const row of document.models) {
|
|
21
|
-
const id = catalogModelId(row);
|
|
22
|
-
if (!id)
|
|
23
|
-
continue;
|
|
24
|
-
const window = typeof row.context_window === "number" && row.context_window > 0
|
|
25
|
-
? Math.floor(row.context_window)
|
|
26
|
-
: 0;
|
|
27
|
-
models[id] =
|
|
28
|
-
window > 0
|
|
29
|
-
? {
|
|
30
|
-
limit: {
|
|
31
|
-
context: window,
|
|
32
|
-
output: Math.min(OPENCODE_OUTPUT_BUDGET, window),
|
|
33
|
-
},
|
|
34
|
-
}
|
|
35
|
-
: {};
|
|
36
|
-
}
|
|
37
|
-
const content = JSON.stringify({
|
|
38
|
-
provider: {
|
|
39
|
-
cpac: {
|
|
40
|
-
npm: "@ai-sdk/openai-compatible",
|
|
41
|
-
options: { baseURL: apiBase(config.cpa_url), apiKey },
|
|
42
|
-
models,
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
const env = {
|
|
47
|
-
...process.env,
|
|
48
|
-
OPENCODE_CONFIG_CONTENT: content,
|
|
49
|
-
};
|
|
50
|
-
return await new Promise((resolve, reject) => {
|
|
51
|
-
const child = spawn(executable, args, { env, stdio: "inherit" });
|
|
52
|
-
child.once("error", (error) => {
|
|
53
|
-
reject(new CPACError(error instanceof Error && "code" in error && error.code === "ENOENT"
|
|
54
|
-
? `${executable} not found`
|
|
55
|
-
: `cannot start ${executable}: ${error.message}`));
|
|
56
|
-
});
|
|
57
|
-
child.once("close", (code) => resolve(code ?? 1));
|
|
58
|
-
});
|
|
59
|
-
}
|