u1s1-cli 0.13.0 → 0.13.2
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/dist/agent-setup.d.ts +1 -0
- package/dist/agent-setup.js +50 -0
- package/dist/index.js +3 -1
- package/dist/update.js +57 -9
- package/dist/web.js +3 -1
- package/package.json +4 -4
package/dist/agent-setup.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ export declare function toProviderModels(models: ModelDef[]): {
|
|
|
46
46
|
* 这是 pi 自带 llama provider 的同款兜底,本地服务会忽略 Authorization 头。
|
|
47
47
|
*/
|
|
48
48
|
export declare function endpointProviderEntry(ep: CustomEndpoint): Record<string, unknown>;
|
|
49
|
+
export declare function scrubForeignProviderEnv(): void;
|
|
49
50
|
/** 把各端点密钥放进环境(TUI 直接 process.env;web 传给子进程)。 */
|
|
50
51
|
export declare function endpointKeyEnv(): Record<string, string>;
|
|
51
52
|
export declare function ensureProviderModels(cfg: CliConfig): void;
|
package/dist/agent-setup.js
CHANGED
|
@@ -160,6 +160,56 @@ export function endpointProviderEntry(ep) {
|
|
|
160
160
|
models: toProviderModels(ep.models),
|
|
161
161
|
};
|
|
162
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* pi 会把环境里的厂商密钥(ANTHROPIC_API_KEY 等)当作「已配置的 provider」,
|
|
165
|
+
* /model 里冒出一大串没在用的模型(u1s1 又拦了 /login,配了也没法管理)。
|
|
166
|
+
* u1s1 的口径是:官方模型 + 自定义端点,所以启动 pi 前把这批**纯 LLM 厂商**
|
|
167
|
+
* 密钥从 pi 进程环境里剔掉。名单来自 pi-ai env-api-keys.ts;刻意保留
|
|
168
|
+
* AWS_WEB_IDENTITY_TOKEN_FILE / HF_TOKEN / GOOGLE_CLOUD_API_KEY /
|
|
169
|
+
* CLOUDFLARE_API_KEY 这类通用凭据 —— agent 终端里的其他工具还要用。
|
|
170
|
+
* 注意 agent 的 Bash 子进程也继承不到被剔的变量;项目 .env 文件不受影响。
|
|
171
|
+
*/
|
|
172
|
+
const FOREIGN_PROVIDER_ENV_KEYS = [
|
|
173
|
+
"AI_GATEWAY_API_KEY",
|
|
174
|
+
"ANTHROPIC_API_KEY",
|
|
175
|
+
"ANTHROPIC_AUTH_TOKEN",
|
|
176
|
+
"ANTHROPIC_OAUTH_TOKEN",
|
|
177
|
+
"ANT_LING_API_KEY",
|
|
178
|
+
"AWS_BEARER_TOKEN_BEDROCK",
|
|
179
|
+
"AZURE_OPENAI_API_KEY",
|
|
180
|
+
"BASETEN_API_KEY",
|
|
181
|
+
"CEREBRAS_API_KEY",
|
|
182
|
+
"COPILOT_GITHUB_TOKEN",
|
|
183
|
+
"DEEPSEEK_API_KEY",
|
|
184
|
+
"FIREWORKS_API_KEY",
|
|
185
|
+
"GEMINI_API_KEY",
|
|
186
|
+
"GROQ_API_KEY",
|
|
187
|
+
"KIMI_API_KEY",
|
|
188
|
+
"MINIMAX_API_KEY",
|
|
189
|
+
"MINIMAX_CN_API_KEY",
|
|
190
|
+
"MISTRAL_API_KEY",
|
|
191
|
+
"MOONSHOT_API_KEY",
|
|
192
|
+
"NVIDIA_API_KEY",
|
|
193
|
+
"OPENAI_API_KEY",
|
|
194
|
+
"OPENCODE_API_KEY",
|
|
195
|
+
"OPENROUTER_API_KEY",
|
|
196
|
+
"QWEN_TOKEN_PLAN_API_KEY",
|
|
197
|
+
"QWEN_TOKEN_PLAN_CN_API_KEY",
|
|
198
|
+
"RADIUS_API_KEY",
|
|
199
|
+
"TOGETHER_API_KEY",
|
|
200
|
+
"XAI_API_KEY",
|
|
201
|
+
"XIAOMI_API_KEY",
|
|
202
|
+
"XIAOMI_TOKEN_PLAN_AMS_API_KEY",
|
|
203
|
+
"XIAOMI_TOKEN_PLAN_CN_API_KEY",
|
|
204
|
+
"XIAOMI_TOKEN_PLAN_SGP_API_KEY",
|
|
205
|
+
"ZAI_API_KEY",
|
|
206
|
+
"ZAI_CODING_CN_API_KEY",
|
|
207
|
+
];
|
|
208
|
+
export function scrubForeignProviderEnv() {
|
|
209
|
+
for (const key of FOREIGN_PROVIDER_ENV_KEYS) {
|
|
210
|
+
delete process.env[key];
|
|
211
|
+
}
|
|
212
|
+
}
|
|
163
213
|
/** 把各端点密钥放进环境(TUI 直接 process.env;web 传给子进程)。 */
|
|
164
214
|
export function endpointKeyEnv() {
|
|
165
215
|
const env = {};
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawnSync } from "node:child_process";
|
|
3
3
|
import { writeFileSync } from "node:fs";
|
|
4
|
-
import { cleanupBrandThemes, endpointKeyEnv, endpointProviderEntry, ensureBrandPrompt, ensureDefaultSettings, ensureProviderModels, toProviderModels, writeWebToolsExtension, } from "./agent-setup.js";
|
|
4
|
+
import { cleanupBrandThemes, endpointKeyEnv, endpointProviderEntry, ensureBrandPrompt, ensureDefaultSettings, ensureProviderModels, scrubForeignProviderEnv, toProviderModels, writeWebToolsExtension, } from "./agent-setup.js";
|
|
5
5
|
import { printConsoleBanner } from "./brand.js";
|
|
6
6
|
import { agentDir, apiModelToDef, CUSTOM_ENDPOINTS, isPortableInstall, loadConfig, MODELS, persistPreferredModel, PROVIDER_ID, readSettings, refValid, resolvePreferredModel, setModelsFromApi, VERSION, } from "./config.js";
|
|
7
7
|
import { ensureSearchTools } from "./search-tools.js";
|
|
@@ -145,6 +145,8 @@ async function runAgent(cfg, args) {
|
|
|
145
145
|
process.env["U1S1_TOOLS_VIA_EXTENSION"] = "1";
|
|
146
146
|
// 自定义端点的密钥走环境变量引用(models.json 里只有 $VAR,不落明文)
|
|
147
147
|
Object.assign(process.env, endpointKeyEnv());
|
|
148
|
+
// 剔掉环境里的其他厂商密钥,/model 只展示 u1s1 官方模型 + 自定义端点
|
|
149
|
+
scrubForeignProviderEnv();
|
|
148
150
|
// hide pi's own "Run pi update" banner; users should run `u1s1 update` instead
|
|
149
151
|
process.env["PI_SKIP_VERSION_CHECK"] = "1";
|
|
150
152
|
await searchToolsReady;
|
package/dist/update.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { execSync } from "node:child_process";
|
|
1
|
+
import { execSync, spawn } from "node:child_process";
|
|
2
|
+
import { mkdtempSync, writeFileSync } from "node:fs";
|
|
2
3
|
import { createRequire } from "node:module";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
3
6
|
import { isPortableInstall } from "./config.js";
|
|
4
7
|
const require = createRequire(import.meta.url);
|
|
5
8
|
const pkg = require("../package.json");
|
|
@@ -49,6 +52,57 @@ export function compareVersions(a, b) {
|
|
|
49
52
|
}
|
|
50
53
|
return 0;
|
|
51
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* 便携版原地升级:下载官网安装脚本并替用户执行,整包替换安装目录。
|
|
57
|
+
*
|
|
58
|
+
* - Linux/macOS:同进程跑 bash 安装脚本。替换正在运行的文件在 unix 上安全
|
|
59
|
+
* (旧 inode 继续存活到进程退出)。
|
|
60
|
+
* - Windows:正在运行的 node.exe 锁着自己,同进程装不了 —— 弹一个新的
|
|
61
|
+
* PowerShell 窗口跑 install.ps1(脚本会先结束安装目录里残留的 node 进程,
|
|
62
|
+
* 包括本进程,属预期),本进程立刻退出把文件锁让出来。
|
|
63
|
+
*/
|
|
64
|
+
async function portableSelfUpdate(latest) {
|
|
65
|
+
if (process.platform === "win32") {
|
|
66
|
+
console.log(`正在打开更新窗口(升级到 v${latest})…`);
|
|
67
|
+
console.log("更新在新窗口里进行,本窗口会退出;装完后重新打开终端运行 u1s1 即可。");
|
|
68
|
+
// 不走 `cmd /c start`:start 只把**带引号**的首参当窗口标题,而 node 对
|
|
69
|
+
// 无空格参数不加引号,标题会被当成命令执行(0.13.1 翻车现场)。node 在
|
|
70
|
+
// Windows 上 detached + stdio ignore 的子进程自带新控制台,直接 spawn
|
|
71
|
+
// powershell 即可,参数按 Win32 规则原样传递,没有二次解析。
|
|
72
|
+
const tmp = join(mkdtempSync(join(tmpdir(), "u1s1-update-")), "update.ps1");
|
|
73
|
+
writeFileSync(tmp, "irm https://u1s1.io/releases/install.ps1 | iex\n");
|
|
74
|
+
const child = spawn("powershell.exe", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-NoExit", "-File", tmp], { detached: true, stdio: "ignore" });
|
|
75
|
+
child.unref();
|
|
76
|
+
// 立刻退出释放 node.exe 的文件锁,让安装器能替换安装目录
|
|
77
|
+
process.exit(0);
|
|
78
|
+
}
|
|
79
|
+
console.log(`正在下载安装脚本并升级到 v${latest}…`);
|
|
80
|
+
let script;
|
|
81
|
+
try {
|
|
82
|
+
const res = await fetch("https://u1s1.io/releases/install.sh", {
|
|
83
|
+
signal: AbortSignal.timeout(30_000),
|
|
84
|
+
});
|
|
85
|
+
if (!res.ok)
|
|
86
|
+
throw new Error(`HTTP ${res.status}`);
|
|
87
|
+
script = await res.text();
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
console.error("安装脚本下载失败。请手动运行:");
|
|
91
|
+
console.error(" curl -fsSL https://u1s1.io/releases/install.sh | bash");
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
const tmp = join(mkdtempSync(join(tmpdir(), "u1s1-update-")), "install.sh");
|
|
95
|
+
writeFileSync(tmp, script, { mode: 0o755 });
|
|
96
|
+
try {
|
|
97
|
+
execSync(`bash ${JSON.stringify(tmp)}`, { stdio: "inherit" });
|
|
98
|
+
console.log(`\n✅ 已升级到 v${latest},重新运行 u1s1 生效。`);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
console.error("\n自动升级失败。请手动运行:");
|
|
102
|
+
console.error(" curl -fsSL https://u1s1.io/releases/install.sh | bash");
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
52
106
|
export async function update() {
|
|
53
107
|
console.log("正在检查更新…");
|
|
54
108
|
const latest = await getLatestVersion();
|
|
@@ -62,15 +116,9 @@ export async function update() {
|
|
|
62
116
|
}
|
|
63
117
|
console.log(`发现新版本 v${latest} (当前 v${VERSION})`);
|
|
64
118
|
// 便携版:npm 装到全局目录,但 PATH 先命中便携目录,怎么更都还是旧版。
|
|
65
|
-
//
|
|
119
|
+
// 正确方式是重跑官网安装脚本整包替换 —— 这里直接替用户跑,不再让人手抄命令。
|
|
66
120
|
if (isPortableInstall()) {
|
|
67
|
-
|
|
68
|
-
console.log("");
|
|
69
|
-
console.log("你装的是便携版(自带 Node),npm 更新不了它。升级分两步:");
|
|
70
|
-
console.log(" 1. 关闭所有 u1s1 窗口");
|
|
71
|
-
console.log(isWin
|
|
72
|
-
? " 2. 打开 PowerShell 运行: irm https://u1s1.io/releases/install.ps1 | iex"
|
|
73
|
-
: " 2. 在终端运行: curl -fsSL https://u1s1.io/releases/install.sh | bash");
|
|
121
|
+
await portableSelfUpdate(latest);
|
|
74
122
|
return;
|
|
75
123
|
}
|
|
76
124
|
const pm = detectPackageManager();
|
package/dist/web.js
CHANGED
|
@@ -2,7 +2,7 @@ import { spawn, spawnSync } from "node:child_process";
|
|
|
2
2
|
import { mkdirSync } from "node:fs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
5
|
-
import { cleanupBrandThemes, endpointKeyEnv, ensureAuthCredential, ensureBrandPrompt, ensureDefaultSettings, ensureProviderModels, writeWebToolsExtension, } from "./agent-setup.js";
|
|
5
|
+
import { cleanupBrandThemes, endpointKeyEnv, ensureAuthCredential, ensureBrandPrompt, ensureDefaultSettings, ensureProviderModels, scrubForeignProviderEnv, writeWebToolsExtension, } from "./agent-setup.js";
|
|
6
6
|
import { agentDir, apiModelToDef, resolvePreferredModel, setModelsFromApi, u1s1Dir, writeAgentDefaultModel, } from "./config.js";
|
|
7
7
|
import { ensureSearchTools } from "./search-tools.js";
|
|
8
8
|
import { applyWebUiBranding, applyWebUiFrontend } from "./webui-brand.js";
|
|
@@ -49,6 +49,8 @@ export async function prepareWebEnv(cfg) {
|
|
|
49
49
|
writeAgentDefaultModel(pref.provider, pref.id);
|
|
50
50
|
const dataDir = join(u1s1Dir, "web");
|
|
51
51
|
mkdirSync(dataDir, { recursive: true });
|
|
52
|
+
// web 子进程按 {...process.env, ...返回值} 起,这里剔掉即对子进程生效
|
|
53
|
+
scrubForeignProviderEnv();
|
|
52
54
|
await searchToolsReady;
|
|
53
55
|
return {
|
|
54
56
|
PI_CODING_AGENT_DIR: agentDir,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "u1s1-cli",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.2",
|
|
4
4
|
"description": "u1s1 — 有一说一,最省心的 AI 编程搭子。终端里用中文说需求,AI 帮你读文件、改代码、跑命令。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"pi-web-ui": "0.26.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@types/node": "^22.
|
|
51
|
-
"tsx": "^4.
|
|
52
|
-
"typescript": "^5.9.
|
|
50
|
+
"@types/node": "^22.20.1",
|
|
51
|
+
"tsx": "^4.23.12",
|
|
52
|
+
"typescript": "^5.9.3"
|
|
53
53
|
}
|
|
54
54
|
}
|