@yhong91/cpac 0.2.5 → 0.2.7
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 +2 -2
- package/dist/cpac.js +28 -2
- package/dist/models.js +8 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -166,7 +166,7 @@ cpac --help
|
|
|
166
166
|
|
|
167
167
|
```bash
|
|
168
168
|
cpac detect [--json]
|
|
169
|
-
cpac models [--json]
|
|
169
|
+
cpac models [--json] [--diff]
|
|
170
170
|
cpac install [codex|pi|kimi|grok|zed|hermes|codebuddy...] [--all] [--dry-run] [--force] [--v2_off] [--v2_models] [--max_context]
|
|
171
171
|
cpac sync [codex|pi|kimi|grok|zed|hermes|codebuddy...] [--all] [--dry-run] [--v2_off] [--v2_models] [--max_context]
|
|
172
172
|
cpac restore <codex|pi|kimi|grok|zed|hermes|codebuddy...> | --all [--dry-run]
|
|
@@ -175,7 +175,7 @@ cpac upgrade [--check]
|
|
|
175
175
|
cpac -v | --version
|
|
176
176
|
```
|
|
177
177
|
|
|
178
|
-
- `models` 从远端 CPA 拉取 rich catalog,默认一行一个 slug;`--json` 输出 `cpa_url` 和模型字段(`slug` / `display_name` / `context_window`)。用来核对 catalog 里有没有某个模型(例如 `*-fast
|
|
178
|
+
- `models` 从远端 CPA 拉取 rich catalog,默认一行一个 slug;`--json` 输出 `cpa_url` 和模型字段(`slug` / `display_name` / `context_window`)。用来核对 catalog 里有没有某个模型(例如 `*-fast`),不写本地配置。`--diff` 拿已保存的 `state_dir/models.json` 和当前 catalog 比 slug:`+` 是新增,`-` 是去掉;没有差别打印 `unchanged`。还没有保存列表时报错,先跑 `cpac sync`。
|
|
179
179
|
- `detect` 列出每个目标是否被检测到、是否已接入 CPAC;`--json` 输出机器可读结果。
|
|
180
180
|
- `install` 默认作用于检测到的目标;后面直接写 agent 名(`cpac install codex pi`),`--all` 全部。`codex` 写入 catalog 并拉起 loopback 代理;`pi`/`kimi`/`grok`/`zed`/`hermes`/`codebuddy` 写入各自配置。`--dry-run` 只打印将要做的事,`--force` 允许重装已安装目标。
|
|
181
181
|
- `sync` 把 CPA 模型列表和更新时间写到 `state_dir/models.json`(默认 `~/.cpac/models.json`)。这个时间戳就是模型版本:列表没变则时间戳不变,目标上次同步到的版本相同就跳过,不同才重写。不带参数只看已安装目标;`--all` 还会装上检测到但还没接入的目标。`install` 仍总是重写。`spawn_models`、`v2_off`、`max_context` 和代理端口不改这个版本,要马上生效用 `cpac install`。`--max_context` 仍只对 `cpac install codex` 有效。
|
package/dist/cpac.js
CHANGED
|
@@ -13,6 +13,7 @@ import { isZedConfigInstalled } from "./targets/zed.js";
|
|
|
13
13
|
import { isHermesConfigInstalled } from "./targets/hermes.js";
|
|
14
14
|
import { isCodebuddyConfigInstalled } from "./targets/codebuddy.js";
|
|
15
15
|
import { defaultConfigPath, loadConfig, originalBytes, pickSpawnModels, readState, saveSpawnModels, stateProxy, catalogMaxContextLive, catalogModelId, catalogModelRows, catalogSlugs, fetchCatalog, } from "./config.js";
|
|
16
|
+
import { canonicalModels, diffModelSlugs, readModelIndex } from "./models.js";
|
|
16
17
|
import { runPing } from "./ping.js";
|
|
17
18
|
import { proxyIsHealthy, runProxyChild } from "./proxy.js";
|
|
18
19
|
import { CPACError, expandUserPath, promptSecret, saveApiKeyExport, shellProfile, } from "./util.js";
|
|
@@ -93,11 +94,30 @@ export async function status(config) {
|
|
|
93
94
|
return 2;
|
|
94
95
|
return 0;
|
|
95
96
|
}
|
|
96
|
-
async function listModels(config, json) {
|
|
97
|
+
async function listModels(config, json, diff = false) {
|
|
97
98
|
const apiKey = process.env[config.api_key_env]?.trim();
|
|
98
99
|
if (!apiKey)
|
|
99
100
|
throw new CPACError(`environment variable ${config.api_key_env} is not set`);
|
|
100
101
|
const catalog = await fetchCatalog(config.cpa_url, apiKey);
|
|
102
|
+
if (diff) {
|
|
103
|
+
const index = readModelIndex(config.state_dir);
|
|
104
|
+
if (!index)
|
|
105
|
+
throw new CPACError("no saved model list; run cpac sync");
|
|
106
|
+
const { added, removed } = diffModelSlugs(index.models.map((model) => model.slug), canonicalModels(catalog.bytes).map((model) => model.slug));
|
|
107
|
+
if (json) {
|
|
108
|
+
console.log(JSON.stringify({ added, removed }, null, 2));
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
if (added.length === 0 && removed.length === 0) {
|
|
112
|
+
console.log("unchanged");
|
|
113
|
+
return 0;
|
|
114
|
+
}
|
|
115
|
+
for (const slug of added)
|
|
116
|
+
console.log(`+ ${slug}`);
|
|
117
|
+
for (const slug of removed)
|
|
118
|
+
console.log(`- ${slug}`);
|
|
119
|
+
return 0;
|
|
120
|
+
}
|
|
101
121
|
if (!json) {
|
|
102
122
|
for (const slug of catalogSlugs(catalog.bytes))
|
|
103
123
|
console.log(slug);
|
|
@@ -183,6 +203,7 @@ function usage() {
|
|
|
183
203
|
"",
|
|
184
204
|
"Command options:",
|
|
185
205
|
opt("--json", "JSON output", "[models, detect]"),
|
|
206
|
+
opt("--diff", "models added or removed since the saved list", "[models]"),
|
|
186
207
|
opt("--all", "every detected or installed agent", "[install, sync, restore]"),
|
|
187
208
|
opt("--dry-run", "print actions without writing", "[install, sync, restore, uninstall]"),
|
|
188
209
|
opt("--force", "allow reinstall of already-injected agents", "[install]"),
|
|
@@ -288,6 +309,11 @@ function parseArgs(args) {
|
|
|
288
309
|
}
|
|
289
310
|
if (arg === "--json")
|
|
290
311
|
parsed.json = true;
|
|
312
|
+
else if (arg === "--diff") {
|
|
313
|
+
if (parsed.command !== "models")
|
|
314
|
+
throw new CPACError("--diff is only valid with models");
|
|
315
|
+
parsed.diff = true;
|
|
316
|
+
}
|
|
291
317
|
else if (arg === "--all")
|
|
292
318
|
parsed.all = true;
|
|
293
319
|
else if (arg === "--dry-run")
|
|
@@ -654,7 +680,7 @@ export async function main(args = process.argv.slice(2)) {
|
|
|
654
680
|
if (parsed.command === "guide")
|
|
655
681
|
return await guide(config);
|
|
656
682
|
if (parsed.command === "models")
|
|
657
|
-
return await listModels(config, parsed.json);
|
|
683
|
+
return await listModels(config, parsed.json, parsed.diff === true);
|
|
658
684
|
if (parsed.command === "detect")
|
|
659
685
|
return await runDetect(config, parsed.json);
|
|
660
686
|
if (parsed.command === "install") {
|
package/dist/models.js
CHANGED
|
@@ -33,6 +33,14 @@ function stableValue(value) {
|
|
|
33
33
|
stable[key] = stableValue(value[key]);
|
|
34
34
|
return stable;
|
|
35
35
|
}
|
|
36
|
+
export function diffModelSlugs(saved, live) {
|
|
37
|
+
const savedSet = new Set(saved);
|
|
38
|
+
const liveSet = new Set(live);
|
|
39
|
+
return {
|
|
40
|
+
added: live.filter((slug) => !savedSet.has(slug)),
|
|
41
|
+
removed: saved.filter((slug) => !liveSet.has(slug)),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
36
44
|
export function canonicalModels(bytes) {
|
|
37
45
|
let document;
|
|
38
46
|
try {
|