u1s1-cli 1.14.6 → 1.15.1
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 +7 -0
- package/dist/agent-setup.js +14 -0
- package/dist/agents/agent-config.d.ts +83 -0
- package/dist/agents/agent-config.js +154 -0
- package/dist/agents/claude.d.ts +113 -0
- package/dist/agents/claude.js +411 -0
- package/dist/agents/codex.d.ts +111 -0
- package/dist/agents/codex.js +392 -0
- package/dist/agents/launch.d.ts +109 -0
- package/dist/agents/launch.js +444 -0
- package/dist/agents/pi.d.ts +9 -0
- package/dist/agents/pi.js +562 -0
- package/dist/agents/prefs.d.ts +35 -0
- package/dist/agents/prefs.js +96 -0
- package/dist/agents/runtime.d.ts +354 -0
- package/dist/agents/runtime.js +884 -0
- package/dist/agents/status.d.ts +20 -0
- package/dist/agents/status.js +241 -0
- package/dist/config-command.d.ts +18 -0
- package/dist/config-command.js +335 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.js +35 -1
- package/dist/device-auth.d.ts +37 -1
- package/dist/device-auth.js +43 -8
- package/dist/embed.d.ts +13 -0
- package/dist/embed.js +15 -0
- package/dist/index.js +22 -556
- package/dist/launcher.d.ts +48 -0
- package/dist/launcher.js +235 -0
- package/dist/mcp-server.d.ts +105 -0
- package/dist/mcp-server.js +449 -0
- package/dist/pi-ui-text.d.ts +57 -0
- package/dist/pi-ui-text.js +148 -0
- package/dist/usage.js +2 -2
- package/package.json +1 -1
- package/scripts/p0-claude-code/README.md +39 -0
- package/scripts/p0-claude-code/launch-claude.ts +94 -0
- package/scripts/p0-claude-code/replay.ts +74 -0
- package/scripts/p0-claude-code/seed-local.mjs +145 -0
- package/scripts/p0-claude-code/tap.mjs +105 -0
- package/scripts/patch-pi.js +76 -55
- package/scripts/pi-patch-report.mjs +224 -0
- package/scripts/pi-upgrade.mjs +829 -0
- package/scripts/render-regression.mjs +67 -5
package/dist/config.js
CHANGED
|
@@ -259,8 +259,11 @@ export function findModel(query) {
|
|
|
259
259
|
}
|
|
260
260
|
return undefined;
|
|
261
261
|
}
|
|
262
|
+
export function isDefaultAgent(value) {
|
|
263
|
+
return value === "pi" || value === "claude" || value === "codex";
|
|
264
|
+
}
|
|
262
265
|
export const u1s1Dir = join(homedir(), ".u1s1");
|
|
263
|
-
const configFile = join(u1s1Dir, "config.json");
|
|
266
|
+
export const configFile = join(u1s1Dir, "config.json");
|
|
264
267
|
/** pi keeps auth/models/settings/sessions under this dir — isolated from any real pi install. */
|
|
265
268
|
export const agentDir = join(u1s1Dir, "agent");
|
|
266
269
|
export const agentSettingsFile = join(agentDir, "settings.json");
|
|
@@ -368,6 +371,7 @@ export function configFromFile(file, env = process.env, currentCnApiBase = SITES
|
|
|
368
371
|
model: file.model,
|
|
369
372
|
modelProvider: typeof file.modelProvider === "string" ? file.modelProvider : undefined,
|
|
370
373
|
email: typeof file.email === "string" && file.email ? file.email : undefined,
|
|
374
|
+
...(isDefaultAgent(file.defaultAgent) ? { defaultAgent: file.defaultAgent } : {}),
|
|
371
375
|
};
|
|
372
376
|
}
|
|
373
377
|
/**
|
|
@@ -442,6 +446,36 @@ export function saveConfig(cfg) {
|
|
|
442
446
|
resetLang();
|
|
443
447
|
}
|
|
444
448
|
/** Persist the user's preferred model to both stores. */
|
|
449
|
+
/**
|
|
450
|
+
* 只改 config.json 里的 defaultAgent 一个键,其余原样保留(还没登录、文件不存在时也能写)。
|
|
451
|
+
* 不经 saveConfig:那会把默认 baseUrl 等生效值一并写死进文件。
|
|
452
|
+
*/
|
|
453
|
+
export function saveDefaultAgent(agent) {
|
|
454
|
+
updateRawConfigFile((file) => {
|
|
455
|
+
if (agent === undefined)
|
|
456
|
+
delete file["defaultAgent"];
|
|
457
|
+
else
|
|
458
|
+
file["defaultAgent"] = agent;
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* 只改 config.json 里 mutate 碰到的键,其余原样保留(不经 saveConfig,理由同 saveDefaultAgent)。
|
|
463
|
+
* 文件在但读不出来时不覆盖(里面可能有登录凭据),抛错让用户先修好。
|
|
464
|
+
*/
|
|
465
|
+
export function updateRawConfigFile(mutate) {
|
|
466
|
+
const raw = readJsonFile(configFile);
|
|
467
|
+
if (existsSync(configFile) && (!raw || typeof raw !== "object" || Array.isArray(raw))) {
|
|
468
|
+
throw new Error(tr(`${configFile} 格式不正确,没有改动它。`, `${configFile} is malformed; it was left unchanged.`));
|
|
469
|
+
}
|
|
470
|
+
const file = { ...raw };
|
|
471
|
+
mutate(file);
|
|
472
|
+
writePrivateFile(configFile, JSON.stringify(file, null, 2) + "\n");
|
|
473
|
+
}
|
|
474
|
+
/** config.json 的原始内容(不叠加环境变量);不存在或解析失败为 undefined。 */
|
|
475
|
+
export function readRawConfigFile() {
|
|
476
|
+
const raw = readJsonFile(configFile);
|
|
477
|
+
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : undefined;
|
|
478
|
+
}
|
|
445
479
|
export function persistPreferredModel(cfg, provider, modelId) {
|
|
446
480
|
const next = { ...cfg, model: modelId, modelProvider: provider };
|
|
447
481
|
saveConfig(next);
|
package/dist/device-auth.d.ts
CHANGED
|
@@ -50,8 +50,44 @@ interface SigningProxy {
|
|
|
50
50
|
localKey: string;
|
|
51
51
|
token: string;
|
|
52
52
|
client: ClientSurface;
|
|
53
|
+
agent?: LaunchedAgent;
|
|
53
54
|
attestation: AttestationHolder;
|
|
54
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Which client the launcher started behind this proxy. Sent as `x-u1s1-agent` /
|
|
58
|
+
* `x-u1s1-agent-version` so the Gateway knows which request shape to check
|
|
59
|
+
* (workers/gateway/src/launcher-agents.ts). The headers carry no authority of
|
|
60
|
+
* their own: the Gateway still requires the DPoP proof and a valid attestation.
|
|
61
|
+
*/
|
|
62
|
+
export interface LaunchedAgent {
|
|
63
|
+
name: "pi" | "claude-code" | "codex";
|
|
64
|
+
/** The client's own version (e.g. Claude Code `2.1.322`), not the CLI's. */
|
|
65
|
+
version?: string;
|
|
66
|
+
}
|
|
67
|
+
export declare const AGENT_HEADER = "x-u1s1-agent";
|
|
68
|
+
export declare const AGENT_VERSION_HEADER = "x-u1s1-agent-version";
|
|
69
|
+
/**
|
|
70
|
+
* With a declared agent the proxy owns both headers: whatever the child sent is
|
|
71
|
+
* replaced (or dropped when no version is declared). Without one the request
|
|
72
|
+
* passes through exactly as before this option existed.
|
|
73
|
+
*/
|
|
74
|
+
export declare function applyAgentHeaders(headers: Headers, agent: LaunchedAgent | undefined): void;
|
|
75
|
+
/**
|
|
76
|
+
* Errors the proxy produces itself (wrong local token, path outside /v1, body too large) are final:
|
|
77
|
+
* retrying cannot fix them. Codex retries 401/403/413 like transient failures (five times) and then
|
|
78
|
+
* shows the raw JSON, so for a declared `codex` child they become 400 with `error.code:
|
|
79
|
+
* "invalid_prompt"`, which Codex reports once and displays as `error.message`. Other clients keep
|
|
80
|
+
* the original status codes.
|
|
81
|
+
*/
|
|
82
|
+
export declare function localFinalError(agent: LaunchedAgent | undefined, status: number, message: string): {
|
|
83
|
+
status: number;
|
|
84
|
+
body: {
|
|
85
|
+
error: {
|
|
86
|
+
message: string;
|
|
87
|
+
code?: string;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
};
|
|
55
91
|
/** Attach a fresh (self-healing) attestation header to an outbound proxy request. */
|
|
56
92
|
export declare function attachAttestationHeader(holder: AttestationHolder, headers: Headers): Promise<void>;
|
|
57
93
|
export type ClientSurface = "terminal" | "web" | "desktop";
|
|
@@ -62,4 +98,4 @@ export declare function onGatewayFetchFailure(listener: ((failure: GatewayFetchF
|
|
|
62
98
|
* pi accepts static provider headers only. Keep it behind a loopback proxy that
|
|
63
99
|
* replaces the local bearer credential with a fresh DPoP proof per request.
|
|
64
100
|
*/
|
|
65
|
-
export declare function ensureSigningProxy(cfg: CliConfig, fallbackClient?: ClientSurface, attestationSource?: ClientAttestationSource): Promise<SigningProxy>;
|
|
101
|
+
export declare function ensureSigningProxy(cfg: CliConfig, fallbackClient?: ClientSurface, attestationSource?: ClientAttestationSource, agent?: LaunchedAgent): Promise<SigningProxy>;
|
package/dist/device-auth.js
CHANGED
|
@@ -130,6 +130,37 @@ export async function readSigningProxyRequestBody(request, maxBytes = SIGNING_PR
|
|
|
130
130
|
}
|
|
131
131
|
return chunks.length ? Buffer.concat(chunks, total) : undefined;
|
|
132
132
|
}
|
|
133
|
+
export const AGENT_HEADER = "x-u1s1-agent";
|
|
134
|
+
export const AGENT_VERSION_HEADER = "x-u1s1-agent-version";
|
|
135
|
+
function sameAgent(a, b) {
|
|
136
|
+
return a?.name === b?.name && a?.version === b?.version;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* With a declared agent the proxy owns both headers: whatever the child sent is
|
|
140
|
+
* replaced (or dropped when no version is declared). Without one the request
|
|
141
|
+
* passes through exactly as before this option existed.
|
|
142
|
+
*/
|
|
143
|
+
export function applyAgentHeaders(headers, agent) {
|
|
144
|
+
if (!agent)
|
|
145
|
+
return;
|
|
146
|
+
headers.set(AGENT_HEADER, agent.name);
|
|
147
|
+
if (agent.version)
|
|
148
|
+
headers.set(AGENT_VERSION_HEADER, agent.version);
|
|
149
|
+
else
|
|
150
|
+
headers.delete(AGENT_VERSION_HEADER);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Errors the proxy produces itself (wrong local token, path outside /v1, body too large) are final:
|
|
154
|
+
* retrying cannot fix them. Codex retries 401/403/413 like transient failures (five times) and then
|
|
155
|
+
* shows the raw JSON, so for a declared `codex` child they become 400 with `error.code:
|
|
156
|
+
* "invalid_prompt"`, which Codex reports once and displays as `error.message`. Other clients keep
|
|
157
|
+
* the original status codes.
|
|
158
|
+
*/
|
|
159
|
+
export function localFinalError(agent, status, message) {
|
|
160
|
+
if (agent?.name === "codex")
|
|
161
|
+
return { status: 400, body: { error: { message, code: "invalid_prompt" } } };
|
|
162
|
+
return { status, body: { error: { message } } };
|
|
163
|
+
}
|
|
133
164
|
// Refresh once we are within a day of the server-side 7-day expiry; back off for
|
|
134
165
|
// a while after a failed refresh so a flaky Gateway is not hammered per request.
|
|
135
166
|
const ATTESTATION_REFRESH_MARGIN_MS = 24 * 60 * 60 * 1000;
|
|
@@ -222,12 +253,12 @@ export function onGatewayFetchFailure(listener) {
|
|
|
222
253
|
* pi accepts static provider headers only. Keep it behind a loopback proxy that
|
|
223
254
|
* replaces the local bearer credential with a fresh DPoP proof per request.
|
|
224
255
|
*/
|
|
225
|
-
export async function ensureSigningProxy(cfg, fallbackClient = "terminal", attestationSource) {
|
|
256
|
+
export async function ensureSigningProxy(cfg, fallbackClient = "terminal", attestationSource, agent) {
|
|
226
257
|
if (!hasDeviceCredential(cfg))
|
|
227
258
|
throw new Error(tr("当前安装需要重新登录,以创建设备凭证", "Please sign in again to create a device credential for this install."));
|
|
228
259
|
const client = clientSurface(fallbackClient);
|
|
229
260
|
const current = signingProxy;
|
|
230
|
-
if (current && current.token === cfg.deviceToken && current.client === client) {
|
|
261
|
+
if (current && current.token === cfg.deviceToken && current.client === client && sameAgent(current.agent, agent)) {
|
|
231
262
|
updateAttestationHolder(current.attestation, attestationSource);
|
|
232
263
|
return current;
|
|
233
264
|
}
|
|
@@ -235,19 +266,22 @@ export async function ensureSigningProxy(cfg, fallbackClient = "terminal", attes
|
|
|
235
266
|
updateAttestationHolder(attestation, attestationSource);
|
|
236
267
|
const localKey = `local-${randomBytes(32).toString("hex")}`;
|
|
237
268
|
const upstreamOrigin = new URL(cfg.baseUrl).origin;
|
|
269
|
+
const localError = (res, status, message) => {
|
|
270
|
+
const final = localFinalError(agent, status, message);
|
|
271
|
+
res.writeHead(final.status, { "content-type": "application/json" });
|
|
272
|
+
res.end(JSON.stringify(final.body));
|
|
273
|
+
};
|
|
238
274
|
const server = createServer(async (req, res) => {
|
|
239
275
|
try {
|
|
240
276
|
if (req.headers.authorization !== `Bearer ${localKey}` || !req.url) {
|
|
241
|
-
res
|
|
242
|
-
res.end(JSON.stringify({ error: { message: "local signing proxy authentication failed" } }));
|
|
277
|
+
localError(res, 401, "local signing proxy authentication failed");
|
|
243
278
|
return;
|
|
244
279
|
}
|
|
245
280
|
// Only proxy the gateway namespace. Absolute-form request targets must not
|
|
246
281
|
// be allowed to override the configured upstream origin and steal a proof.
|
|
247
282
|
const localUrl = new URL(req.url, "http://127.0.0.1");
|
|
248
283
|
if (!localUrl.pathname.startsWith("/v1/")) {
|
|
249
|
-
res
|
|
250
|
-
res.end(JSON.stringify({ error: { message: "signing proxy only serves /v1/*" } }));
|
|
284
|
+
localError(res, 403, "signing proxy only serves /v1/*");
|
|
251
285
|
return;
|
|
252
286
|
}
|
|
253
287
|
const upstreamAbort = new AbortController();
|
|
@@ -266,6 +300,7 @@ export async function ensureSigningProxy(cfg, fallbackClient = "terminal", attes
|
|
|
266
300
|
outboundHeaders.set("x-u1s1-client", client);
|
|
267
301
|
outboundHeaders.set("x-u1s1-version", VERSION);
|
|
268
302
|
outboundHeaders.set("x-u1s1-platform", `${process.platform}-${process.arch}`);
|
|
303
|
+
applyAgentHeaders(outboundHeaders, agent);
|
|
269
304
|
await attachAttestationHeader(attestation, outboundHeaders);
|
|
270
305
|
// 中国站主域建连失败时 authorizedFetch 会换到大陆加速入口,和启动时的请求共用选路状态
|
|
271
306
|
const upstream = await authorizedFetch(cfg, new URL(pathAndQuery, upstreamOrigin).toString(), {
|
|
@@ -288,8 +323,7 @@ export async function ensureSigningProxy(cfg, fallbackClient = "terminal", attes
|
|
|
288
323
|
catch (error) {
|
|
289
324
|
if (error instanceof SigningProxyRequestTooLargeError && !res.destroyed) {
|
|
290
325
|
req.resume();
|
|
291
|
-
res
|
|
292
|
-
res.end(JSON.stringify({ error: { message: "local signing proxy request body is too large" } }));
|
|
326
|
+
localError(res, 413, "local signing proxy request body is too large");
|
|
293
327
|
return;
|
|
294
328
|
}
|
|
295
329
|
if (res.destroyed)
|
|
@@ -322,6 +356,7 @@ export async function ensureSigningProxy(cfg, fallbackClient = "terminal", attes
|
|
|
322
356
|
localKey,
|
|
323
357
|
token: cfg.deviceToken,
|
|
324
358
|
client,
|
|
359
|
+
...(agent ? { agent: { ...agent } } : {}),
|
|
325
360
|
attestation,
|
|
326
361
|
};
|
|
327
362
|
return signingProxy;
|
package/dist/embed.d.ts
CHANGED
|
@@ -11,3 +11,16 @@ export { applyWebUiBranding } from "./webui-brand.js";
|
|
|
11
11
|
export { DASHBOARD_URL } from "./brand.js";
|
|
12
12
|
export { SITES, siteForBaseUrl, siteLinks, type Site, type SiteId, type SiteLinks } from "./site.js";
|
|
13
13
|
export { hasNudge, markNudge, readNudges, type NudgeKey } from "./nudges.js";
|
|
14
|
+
export { ensureAgentRuntime, RuntimeInstallError, RuntimePlanError, type DownloadInfo, type EnsureRuntimeOptions, type EnsuredRuntime, type InstallHooks, type RuntimeBrake, type SkippedRuntime, } from "./agents/runtime.js";
|
|
15
|
+
export { agentLaunchEnv, claudeLaunchArgs, claudePaths, type ClaudeLaunchInput } from "./agents/claude.js";
|
|
16
|
+
export { codexLaunchArgs, codexLaunchEnv, codexPaths, writeCodexConfig, type CodexLaunchInput, type CodexPaths, } from "./agents/codex.js";
|
|
17
|
+
export { loadAgentConfig, loadPublicAgentRuntime, type AgentConfig, type AgentConfigResult, type PublicAgentRuntimeResult, } from "./agents/agent-config.js";
|
|
18
|
+
export { bestInstallTarget, checkBrake, compareVersions, dailyUpdateCheck, downloadSize, fetchLatestVersion, fetchPackageMeta, findNpm, findOnPath, installedVersions, isManagedAgent, MANAGED_AGENTS, managedBinPath, NO_BRAKE, normalizeVersion, npmRegistryFor, planRuntime, platformPackageRef, probeVersion, readRuntimeState, runtimeSpec, type BrakeVerdict, type FoundRuntime, type ManagedAgent, type NpmCommand, type PackageMeta, type RuntimePlan, type RuntimeState, } from "./agents/runtime.js";
|
|
19
|
+
export { AGENT_PROFILES, agentsRoot, CLAUDE_TERMS_URL, CODEX_LICENSE_URL, notOpenText, overMaxTestedText, runtimeErrorText, type LaunchPaths, } from "./agents/launch.js";
|
|
20
|
+
export { launchPaths } from "./agents/status.js";
|
|
21
|
+
export { parseAgentConfig, readConfigCache, type AgentModel, type GatewayAgentName } from "./agents/agent-config.js";
|
|
22
|
+
export { chooseAgentModel, isModelId, readAgentPrefs, saveAgentPrefs, type AgentPrefs } from "./agents/prefs.js";
|
|
23
|
+
export { CONFIG_KEYS, isConfigKey, readConfigValue, writeConfigValue, type ConfigKey, type ConfigValue, } from "./config-command.js";
|
|
24
|
+
export { isDefaultAgent, readRawConfigFile, saveDefaultAgent, type DefaultAgent } from "./config.js";
|
|
25
|
+
export { isExistingUser } from "./launcher.js";
|
|
26
|
+
export { gatewayFetch } from "./gateway-route.js";
|
package/dist/embed.js
CHANGED
|
@@ -11,3 +11,18 @@ export { applyWebUiBranding } from "./webui-brand.js";
|
|
|
11
11
|
export { DASHBOARD_URL } from "./brand.js";
|
|
12
12
|
export { SITES, siteForBaseUrl, siteLinks } from "./site.js";
|
|
13
13
|
export { hasNudge, markNudge, readNudges } from "./nudges.js";
|
|
14
|
+
// 启动器:桌面端复用同一套运行时下载/更新/刹车与子进程注入逻辑
|
|
15
|
+
export { ensureAgentRuntime, RuntimeInstallError, RuntimePlanError, } from "./agents/runtime.js";
|
|
16
|
+
export { agentLaunchEnv, claudeLaunchArgs, claudePaths } from "./agents/claude.js";
|
|
17
|
+
export { codexLaunchArgs, codexLaunchEnv, codexPaths, writeCodexConfig, } from "./agents/codex.js";
|
|
18
|
+
export { loadAgentConfig, loadPublicAgentRuntime, } from "./agents/agent-config.js";
|
|
19
|
+
// 启动器(桌面端服务层):状态、刹车、偏好与 `u1s1 config` 读写都走 CLI 的同一份实现
|
|
20
|
+
export { bestInstallTarget, checkBrake, compareVersions, dailyUpdateCheck, downloadSize, fetchLatestVersion, fetchPackageMeta, findNpm, findOnPath, installedVersions, isManagedAgent, MANAGED_AGENTS, managedBinPath, NO_BRAKE, normalizeVersion, npmRegistryFor, planRuntime, platformPackageRef, probeVersion, readRuntimeState, runtimeSpec, } from "./agents/runtime.js";
|
|
21
|
+
export { AGENT_PROFILES, agentsRoot, CLAUDE_TERMS_URL, CODEX_LICENSE_URL, notOpenText, overMaxTestedText, runtimeErrorText, } from "./agents/launch.js";
|
|
22
|
+
export { launchPaths } from "./agents/status.js";
|
|
23
|
+
export { parseAgentConfig, readConfigCache } from "./agents/agent-config.js";
|
|
24
|
+
export { chooseAgentModel, isModelId, readAgentPrefs, saveAgentPrefs } from "./agents/prefs.js";
|
|
25
|
+
export { CONFIG_KEYS, isConfigKey, readConfigValue, writeConfigValue, } from "./config-command.js";
|
|
26
|
+
export { isDefaultAgent, readRawConfigFile, saveDefaultAgent } from "./config.js";
|
|
27
|
+
export { isExistingUser } from "./launcher.js";
|
|
28
|
+
export { gatewayFetch } from "./gateway-route.js";
|