u1s1-cli 1.2.5 → 1.2.6

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.
@@ -89,4 +89,10 @@ export declare function ensureWorkflowPromptTemplate(): void;
89
89
  export declare function scrubForeignProviderEnv(): void;
90
90
  /** 把各端点密钥放进环境(TUI 直接 process.env;web 传给子进程)。 */
91
91
  export declare function endpointKeyEnv(): Record<string, string>;
92
- export declare function ensureProviderModels(cfg: CliConfig): void;
92
+ export interface ProviderModelsFileOptions {
93
+ /** Destination for the composed provider config. Defaults to the shared agent models file. */
94
+ outputPath?: string;
95
+ /** Existing config to preserve. Defaults to outputPath. */
96
+ sourcePath?: string;
97
+ }
98
+ export declare function ensureProviderModels(cfg: CliConfig, options?: ProviderModelsFileOptions): void;
@@ -206,10 +206,10 @@ export function writeWebToolsExtension(cfg, features) {
206
206
  mkdirSync(dir, { recursive: true });
207
207
  const toolsUrl = new URL("./tools.js", import.meta.url).href;
208
208
  const searchLine = features.webSearch
209
- ? ` pi.registerTool(tools.createSearchTool({ baseUrl: ${JSON.stringify(cfg.baseUrl)}, apiKey: process.env.U1S1_API_KEY }));\n`
209
+ ? ` pi.registerTool(tools.createSearchTool({ baseUrl, apiKey: process.env.U1S1_API_KEY }));\n`
210
210
  : "";
211
211
  const imageLine = features.imageGen
212
- ? ` pi.registerTool(tools.createImageTool({ baseUrl: ${JSON.stringify(cfg.baseUrl)}, apiKey: process.env.U1S1_API_KEY }));\n`
212
+ ? ` pi.registerTool(tools.createImageTool({ baseUrl, apiKey: process.env.U1S1_API_KEY }));\n`
213
213
  : "";
214
214
  // spawn_subagent / run_workflow 只给主会话注册;子 agent 环境里跳过,杜绝孙 agent 递归 spawn
215
215
  const subagentBlock = ` if (process.env.U1S1_IN_SUBAGENT !== "1") {\n` +
@@ -227,9 +227,10 @@ export function writeWebToolsExtension(cfg, features) {
227
227
  writeFileSync(join(dir, "u1s1-tools.js"), `// 由 u1s1 每次启动自动生成,请勿手改\n` +
228
228
  `export default async function (pi) {\n` +
229
229
  ` if (process.env.U1S1_TOOLS_VIA_EXTENSION !== "1") return;\n` +
230
+ ` const baseUrl = process.env.U1S1_SIGNING_PROXY_URL || ${JSON.stringify(cfg.baseUrl)};\n` +
230
231
  ` const tools = await import(${JSON.stringify(toolsUrl)});\n` +
231
232
  searchLine +
232
- ` pi.registerTool(tools.createFetchTool({ baseUrl: ${JSON.stringify(cfg.baseUrl)}, apiKey: process.env.U1S1_API_KEY, renderFallback: ${features.webFetchRender} }));\n` +
233
+ ` pi.registerTool(tools.createFetchTool({ baseUrl, apiKey: process.env.U1S1_API_KEY, renderFallback: ${features.webFetchRender} }));\n` +
233
234
  imageLine +
234
235
  subagentBlock +
235
236
  `}\n`);
@@ -528,13 +529,14 @@ export function endpointKeyEnv() {
528
529
  }
529
530
  return env;
530
531
  }
531
- export function ensureProviderModels(cfg) {
532
- mkdirSync(agentDir, { recursive: true });
533
- const p = join(agentDir, "models.json");
532
+ export function ensureProviderModels(cfg, options = {}) {
533
+ const outputPath = options.outputPath ?? join(agentDir, "models.json");
534
+ const sourcePath = options.sourcePath ?? outputPath;
535
+ mkdirSync(dirname(outputPath), { recursive: true });
534
536
  let root = {};
535
- if (existsSync(p)) {
537
+ if (existsSync(sourcePath)) {
536
538
  try {
537
- root = JSON.parse(readFileSync(p, "utf8"));
539
+ root = JSON.parse(readFileSync(sourcePath, "utf8"));
538
540
  }
539
541
  catch {
540
542
  root = {};
@@ -563,5 +565,5 @@ export function ensureProviderModels(cfg) {
563
565
  providers[ep.id] = endpointProviderEntry(ep);
564
566
  }
565
567
  root["providers"] = providers;
566
- writeFileSync(p, JSON.stringify(root, null, 2) + "\n");
568
+ writeFileSync(outputPath, JSON.stringify(root, null, 2) + "\n", { mode: 0o600 });
567
569
  }
package/dist/embed.d.ts CHANGED
@@ -6,6 +6,6 @@
6
6
  export { agentDir, loadConfig, saveConfig, u1s1Dir, VERSION, type CliConfig, } from "./config.js";
7
7
  export { fetchMe, fetchModels } from "./api.js";
8
8
  export { apiOrigin, pollDeviceLogin, startDeviceLogin, type DeviceStart } from "./login.js";
9
- export { prepareWebEnv } from "./web.js";
9
+ export { prepareWebEnv, refreshWebModels } from "./web.js";
10
10
  export { applyWebUiBranding } from "./webui-brand.js";
11
11
  export { DASHBOARD_URL } from "./brand.js";
package/dist/embed.js CHANGED
@@ -6,6 +6,6 @@
6
6
  export { agentDir, loadConfig, saveConfig, u1s1Dir, VERSION, } from "./config.js";
7
7
  export { fetchMe, fetchModels } from "./api.js";
8
8
  export { apiOrigin, pollDeviceLogin, startDeviceLogin } from "./login.js";
9
- export { prepareWebEnv } from "./web.js";
9
+ export { prepareWebEnv, refreshWebModels } from "./web.js";
10
10
  export { applyWebUiBranding } from "./webui-brand.js";
11
11
  export { DASHBOARD_URL } from "./brand.js";
package/dist/index.js CHANGED
@@ -212,6 +212,7 @@ async function runAgent(cfg, args) {
212
212
  // must be set before pi reads them (getAgentDir() reads at call time, env at import is fine too)
213
213
  process.env["PI_CODING_AGENT_DIR"] = agentDir;
214
214
  process.env["U1S1_API_KEY"] = officialCfg.apiKey;
215
+ process.env["U1S1_SIGNING_PROXY_URL"] = officialCfg.baseUrl;
215
216
  process.env["U1S1_TOOLS_VIA_EXTENSION"] = "1";
216
217
  // 自定义端点的密钥走环境变量引用(models.json 里只有 $VAR,不落明文)
217
218
  Object.assign(process.env, endpointKeyEnv());
package/dist/web.d.ts CHANGED
@@ -1,4 +1,10 @@
1
1
  import { type CliConfig } from "./config.js";
2
+ /**
3
+ * Refresh the web/Desktop process-local model snapshot while preserving user
4
+ * providers from the shared agent config. The u1s1 provider always remains
5
+ * pinned to this process's signing proxy.
6
+ */
7
+ export declare function refreshWebModels(): string | undefined;
2
8
  /**
3
9
  * Desktop App 启动 agent server 前的公共准备:品牌 prompt、模型列表、
4
10
  * auth.json 凭据、联网工具扩展、默认模型,并返回子进程需要的环境变量。
package/dist/web.js CHANGED
@@ -1,4 +1,5 @@
1
- import { mkdirSync } from "node:fs";
1
+ import { mkdirSync, mkdtempSync, rmSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
2
3
  import { join } from "node:path";
3
4
  import { cleanupBrandThemes, endpointKeyEnv, ensureAuthCredential, ensureBrandPrompt, ensureWorkflowPromptTemplate, ensureDefaultSettings, ensureProviderModels, scrubForeignProviderEnv, writeAttributionExtension, writeWebToolsExtension, } from "./agent-setup.js";
4
5
  import { agentDir, apiModelToDef, MODELS, resolvePreferredModel, setModelsFromApi, u1s1Dir, writeAgentDefaultModel, } from "./config.js";
@@ -6,6 +7,33 @@ import { ensureSearchTools } from "./search-tools.js";
6
7
  import { ensureUsableShell } from "./shell-doctor.js";
7
8
  import { fetchModels, loadCustomEndpoints } from "./api.js";
8
9
  import { ensureSigningProxy } from "./device-auth.js";
10
+ let webModelsDir;
11
+ let webOfficialCfg;
12
+ function processModelsPath() {
13
+ if (!webModelsDir) {
14
+ webModelsDir = mkdtempSync(join(tmpdir(), "u1s1-web-"));
15
+ process.once("exit", () => {
16
+ if (webModelsDir)
17
+ rmSync(webModelsDir, { recursive: true, force: true });
18
+ });
19
+ }
20
+ return join(webModelsDir, "models.json");
21
+ }
22
+ /**
23
+ * Refresh the web/Desktop process-local model snapshot while preserving user
24
+ * providers from the shared agent config. The u1s1 provider always remains
25
+ * pinned to this process's signing proxy.
26
+ */
27
+ export function refreshWebModels() {
28
+ if (!webOfficialCfg)
29
+ return undefined;
30
+ const outputPath = processModelsPath();
31
+ ensureProviderModels(webOfficialCfg, {
32
+ outputPath,
33
+ sourcePath: join(agentDir, "models.json"),
34
+ });
35
+ return outputPath;
36
+ }
9
37
  /**
10
38
  * Desktop App 启动 agent server 前的公共准备:品牌 prompt、模型列表、
11
39
  * auth.json 凭据、联网工具扩展、默认模型,并返回子进程需要的环境变量。
@@ -41,10 +69,11 @@ export async function prepareWebEnv(cfg) {
41
69
  ensureDefaultSettings(MODELS);
42
70
  const signing = await ensureSigningProxy(cfg, "desktop");
43
71
  const officialCfg = { ...cfg, baseUrl: signing.baseUrl, apiKey: signing.localKey };
72
+ webOfficialCfg = officialCfg;
73
+ const modelsPath = refreshWebModels();
44
74
  ensureBrandPrompt(await shellReady);
45
75
  // /workflow 提示词模板与 TUI 同源,Desktop App 也要有
46
76
  ensureWorkflowPromptTemplate();
47
- ensureProviderModels(officialCfg);
48
77
  // pi-web-ui 靠 auth.json 判断「已配置」,否则网页会弹 pi 安装引导
49
78
  ensureAuthCredential();
50
79
  // 联网工具经 agentDir/extensions 投影,和 TUI 共用一份注册
@@ -67,6 +96,8 @@ export async function prepareWebEnv(cfg) {
67
96
  return {
68
97
  PI_CODING_AGENT_DIR: agentDir,
69
98
  U1S1_API_KEY: officialCfg.apiKey,
99
+ U1S1_MODELS_PATH: modelsPath,
100
+ U1S1_SIGNING_PROXY_URL: officialCfg.baseUrl,
70
101
  U1S1_TOOLS_VIA_EXTENSION: "1",
71
102
  PI_WEB_DATA_DIR: dataDir,
72
103
  // 自定义端点的密钥经环境变量传给 App 子进程(models.json 里只有 $VAR 引用)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "u1s1-cli",
3
- "version": "1.2.5",
3
+ "version": "1.2.6",
4
4
  "description": "u1s1 — 有一说一,最省心的 AI 编程搭子。终端里用中文说需求,AI 帮你读文件、改代码、跑命令。",
5
5
  "type": "module",
6
6
  "bin": {