u1s1-cli 1.7.0 → 1.8.0
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 +35 -2
- package/dist/api.d.ts +5 -0
- package/dist/api.js +5 -0
- package/dist/brand.js +1 -1
- package/dist/error-humanize.js +21 -1
- package/dist/index.js +47 -4
- package/dist/login.js +2 -0
- package/dist/mcp/client.d.ts +53 -0
- package/dist/mcp/client.js +452 -0
- package/dist/mcp/command.d.ts +25 -0
- package/dist/mcp/command.js +349 -0
- package/dist/mcp/config.d.ts +59 -0
- package/dist/mcp/config.js +0 -0
- package/dist/mcp/extension.d.ts +14 -0
- package/dist/mcp/extension.js +128 -0
- package/dist/mcp/tools.d.ts +22 -0
- package/dist/mcp/tools.js +96 -0
- package/dist/nudges.d.ts +1 -1
- package/dist/nudges.js +1 -1
- package/dist/update.js +1 -0
- package/dist/usage.d.ts +6 -2
- package/dist/usage.js +12 -5
- package/dist/web.js +3 -1
- package/package.json +1 -1
- package/scripts/patch-pi.js +151 -0
package/dist/nudges.js
CHANGED
|
@@ -37,4 +37,4 @@ export function shouldShowDeployHint(file = nudgesFile) {
|
|
|
37
37
|
const state = readNudges(file);
|
|
38
38
|
return state.deploy_hint_shown === undefined && state.deploy_done === undefined;
|
|
39
39
|
}
|
|
40
|
-
export const DEPLOY_HINT_TEXT = "
|
|
40
|
+
export const DEPLOY_HINT_TEXT = "做好了想给朋友看?输入 /exit 回到终端,运行 u1s1 deploy 一键上线";
|
package/dist/update.js
CHANGED
package/dist/usage.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { type MeResponse } from "./api.js";
|
|
2
2
|
export declare const TOPUP_URL = "https://u1s1.io/dashboard#usage-topup-card";
|
|
3
|
-
/**
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* 报告尾巴的两条行动入口:邀请(永久加量)与充值(撞线用户的直接出口,运营清单 A2)。
|
|
5
|
+
* 支付通道关闭时充值是死路(仪表盘会报「支付通道未开放」),改说即将上线并指向
|
|
6
|
+
* 仪表盘的加量包/打卡入口;老网关没有 pay_enabled 字段,按开放处理。
|
|
7
|
+
*/
|
|
8
|
+
export declare function usageCtaLines(me?: Pick<MeResponse, "pay_enabled">): string[];
|
|
5
9
|
/** 额度报告正文(不含首尾空行),终端 `u1s1 usage` 和会话内 /usage 共用。 */
|
|
6
10
|
export declare function usageReportLines(me: MeResponse): string[];
|
|
7
11
|
/** 会话内 /usage 用:拉取额度并打包成 entry data,错误转成中文提示而不是抛出。 */
|
package/dist/usage.js
CHANGED
|
@@ -94,7 +94,7 @@ function packageUsageLines(me, tokensPerUsd) {
|
|
|
94
94
|
lines.push(" 其他模型(如 DeepSeek V4 Pro)不走免费包,可用余额或全模型包 → https://u1s1.io/dashboard");
|
|
95
95
|
lines.push(" Token 数按默认模型单价折算,为约数;用更贵的模型时消耗更快。");
|
|
96
96
|
lines.push("");
|
|
97
|
-
lines.push(...usageCtaLines());
|
|
97
|
+
lines.push(...usageCtaLines(me));
|
|
98
98
|
return lines;
|
|
99
99
|
}
|
|
100
100
|
function legacyUsageLines(me, tokensPerUsd) {
|
|
@@ -118,15 +118,22 @@ function legacyUsageLines(me, tokensPerUsd) {
|
|
|
118
118
|
lines.push(` 本月成本 $${me.mtd_usd.toFixed(2)}`);
|
|
119
119
|
}
|
|
120
120
|
lines.push("");
|
|
121
|
-
lines.push(...usageCtaLines());
|
|
121
|
+
lines.push(...usageCtaLines(me));
|
|
122
122
|
return lines;
|
|
123
123
|
}
|
|
124
124
|
export const TOPUP_URL = "https://u1s1.io/dashboard#usage-topup-card";
|
|
125
|
-
/**
|
|
126
|
-
|
|
125
|
+
/**
|
|
126
|
+
* 报告尾巴的两条行动入口:邀请(永久加量)与充值(撞线用户的直接出口,运营清单 A2)。
|
|
127
|
+
* 支付通道关闭时充值是死路(仪表盘会报「支付通道未开放」),改说即将上线并指向
|
|
128
|
+
* 仪表盘的加量包/打卡入口;老网关没有 pay_enabled 字段,按开放处理。
|
|
129
|
+
*/
|
|
130
|
+
export function usageCtaLines(me) {
|
|
131
|
+
const payClosed = me?.pay_enabled === false;
|
|
127
132
|
return [
|
|
128
133
|
" 免费额度每天自动恢复;邀请朋友双方各得永久加量 → https://u1s1.io/dashboard",
|
|
129
|
-
|
|
134
|
+
payClosed
|
|
135
|
+
? " 充值通道即将开放;额度不够先到仪表盘领加量包、每日打卡 → https://u1s1.io/dashboard"
|
|
136
|
+
: ` 额度不够用?充值 → ${TOPUP_URL}`,
|
|
130
137
|
];
|
|
131
138
|
}
|
|
132
139
|
/** 额度报告正文(不含首尾空行),终端 `u1s1 usage` 和会话内 /usage 共用。 */
|
package/dist/web.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mkdirSync, mkdtempSync, rmSync } from "node:fs";
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import { cleanupBrandThemes, endpointKeyEnv, ensureAuthCredential, ensureBrandPrompt, ensureWorkflowPromptTemplate, ensureDefaultSettings, ensureProviderModels, scrubForeignProviderEnv, writeAttributionExtension, writeWebToolsExtension, } from "./agent-setup.js";
|
|
4
|
+
import { cleanupBrandThemes, endpointKeyEnv, ensureAuthCredential, ensureBrandPrompt, ensureWorkflowPromptTemplate, ensureDefaultSettings, ensureProviderModels, scrubForeignProviderEnv, writeAttributionExtension, writeMcpExtension, writeWebToolsExtension, } from "./agent-setup.js";
|
|
5
5
|
import { agentDir, apiModelToDef, MODELS, resolvePreferredModel, setModelsFromApi, u1s1Dir, writeAgentDefaultModel, } from "./config.js";
|
|
6
6
|
import { ensureSearchTools } from "./search-tools.js";
|
|
7
7
|
import { ensureUsableShell } from "./shell-doctor.js";
|
|
@@ -98,6 +98,8 @@ export async function prepareWebEnv(cfg) {
|
|
|
98
98
|
});
|
|
99
99
|
// OpenRouter 应用归因:直连流量计入 u1s1 的公开排行(与 TUI 同源)
|
|
100
100
|
writeAttributionExtension();
|
|
101
|
+
// 自定义 MCP 服务的工具(与 TUI 同源)
|
|
102
|
+
writeMcpExtension();
|
|
101
103
|
// Desktop App 新会话从 settings.json 的 defaultModel 取模型(TUI 是每次传 --model),
|
|
102
104
|
// 确保它有值;resolvePreferredModel 优先尊重已有的 in-session 选择,不会回退覆盖。
|
|
103
105
|
const pref = resolvePreferredModel(cfg);
|
package/package.json
CHANGED
package/scripts/patch-pi.js
CHANGED
|
@@ -271,6 +271,156 @@ function patchCompactUi() {
|
|
|
271
271
|
}
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
+
// ---- TUI 零散英文汉化(与 pnpm coding-agent patch 同步,patch-pi.test.ts 校验双轨一致) ----
|
|
275
|
+
// 新手最常撞见的几句:Esc 中断后的 "Operation aborted"、每条报错前缀 "Error:"、
|
|
276
|
+
// 每轮都在转的 "Working..."、选择器脚注的 "navigate/select/cancel"、/model 列表只显示 id
|
|
277
|
+
// 看不到免费/价格提示、/settings 整页英文。行为不变,只换文案;选择器改为渲染 name(带提示)。
|
|
278
|
+
const ASSISTANT_TEXT_REPLACEMENTS = [
|
|
279
|
+
['theme.fg("error", "Response was truncated before completion.")', 'theme.fg("error", "回复超出单次长度上限被截断了,输入「继续」可以接着写。")'],
|
|
280
|
+
[': "Operation aborted";', ': "已中断";'],
|
|
281
|
+
['const errorMsg = message.errorMessage || "Unknown error";', 'const errorMsg = message.errorMessage || "未知错误(反复出现可运行 u1s1 feedback 反馈)";'],
|
|
282
|
+
['theme.fg("error", `Error: ${errorMsg}`)', 'theme.fg("error", `出错:${errorMsg}`)'],
|
|
283
|
+
];
|
|
284
|
+
const WORKING_TEXT_REPLACEMENTS = [
|
|
285
|
+
['defaultWorkingMessage = "Working...";', 'defaultWorkingMessage = "思考中…";'],
|
|
286
|
+
['defaultHiddenThinkingLabel = "Thinking...";', 'defaultHiddenThinkingLabel = "思考中…";'],
|
|
287
|
+
];
|
|
288
|
+
// 脚注提示(↑↓ navigate · enter select · esc cancel …)在十几个组件里各写各的,
|
|
289
|
+
// 在 keyHint/rawKeyHint 出口处统一查表翻译,新组件加进来也能覆盖到。
|
|
290
|
+
const KEY_HINT_REPLACEMENTS = [
|
|
291
|
+
[
|
|
292
|
+
'export function keyHint(keybinding, description) {',
|
|
293
|
+
'const U1S1_HINTS = { cancel: "取消", "to cancel": "取消", "to cancel,": "取消,", navigate: "上下选择", submit: "提交", "to submit": "提交", save: "保存", select: "选择", confirm: "确认", scope: "切换范围", "to expand": "展开", "to collapse": "收起", "to run bash": "直接跑命令", "to run bash (no context)": "跑命令(不进上下文)", toggle: "切换", "cycle inherit/+/-": "循环 继承/+/-", "for commands": "输入命令", commands: "命令", bash: "命令", close: "关闭", "to close": "关闭", "to attach": "拖入文件即附加", "skip setup": "跳过设置", "switch mode": "切换模式", newline: "换行", "to delete to end": "删到行尾", sort: "排序", named: "只看已命名", rename: "重命名", delete: "删除", "to exit": "退出", "to cycle models": "切换模型", "external editor": "外部编辑器", "clear/exit": "清空/退出" };\nconst u1s1Hint = (d) => U1S1_HINTS[d] ?? d;\nexport function keyHint(keybinding, description) {',
|
|
294
|
+
],
|
|
295
|
+
{ from: 'theme.fg("muted", ` ${description}`)', to: 'theme.fg("muted", ` ${u1s1Hint(description)}`)', expected: 2 },
|
|
296
|
+
];
|
|
297
|
+
const MODEL_SELECTOR_REPLACEMENTS = [
|
|
298
|
+
// 两处 modelText(有/无两空格缩进)同一规则覆盖;测试的空白折叠匹配不认双空格
|
|
299
|
+
{ from: '${item.id}`;', to: '${item.model.name || item.id}`;', expected: 2 },
|
|
300
|
+
['Model Name: ${selected.model.name}`)', '模型 ID: ${selected.model.id}`)'],
|
|
301
|
+
['No matching models")', '没有匹配的模型")'],
|
|
302
|
+
['theme.fg("muted", " · default")', 'theme.fg("muted", " · 默认")'],
|
|
303
|
+
['const allText = this.scope === "all" ? theme.fg("accent", "all") : theme.fg("muted", "all");', 'const allText = this.scope === "all" ? theme.fg("accent", "全部") : theme.fg("muted", "全部");'],
|
|
304
|
+
['const scopedText = this.scope === "scoped" ? theme.fg("accent", "scoped") : theme.fg("muted", "scoped");', 'const scopedText = this.scope === "scoped" ? theme.fg("accent", "已配置") : theme.fg("muted", "已配置");'],
|
|
305
|
+
['theme.fg("muted", "Scope: ")', 'theme.fg("muted", "范围: ")'],
|
|
306
|
+
['theme.fg("muted", " (all/scoped)")', 'theme.fg("muted", " (全部/已配置)")'],
|
|
307
|
+
['refreshStatusMessage = "Refreshing model catalogs…";', 'refreshStatusMessage = "正在刷新模型列表…";'],
|
|
308
|
+
['"Model catalogs refreshed."', '"模型列表已刷新。"'],
|
|
309
|
+
['const hintText = "Only showing models from configured providers. Use /login to add providers.";', 'const hintText = "只显示已配置渠道的模型。";'],
|
|
310
|
+
];
|
|
311
|
+
const SETTINGS_REPLACEMENTS = [
|
|
312
|
+
['off: "No reasoning",', 'off: "不推理",'],
|
|
313
|
+
['minimal: "Very brief reasoning (~1k tokens)",', 'minimal: "极简推理(约 1k token)",'],
|
|
314
|
+
['low: "Light reasoning (~2k tokens)",', 'low: "轻度推理(约 2k token)",'],
|
|
315
|
+
['medium: "Moderate reasoning (~8k tokens)",', 'medium: "中等推理(约 8k token)",'],
|
|
316
|
+
['high: "Deep reasoning (~16k tokens)",', 'high: "深度推理(约 16k token)",'],
|
|
317
|
+
['xhigh: "Extra-high reasoning (~32k tokens)",', 'xhigh: "超深推理(约 32k token)",'],
|
|
318
|
+
['max: "Maximum reasoning",', 'max: "最大推理",'],
|
|
319
|
+
['ask: "Ask",', 'ask: "每次询问",'],
|
|
320
|
+
['always: "Always trust",', 'always: "始终信任",'],
|
|
321
|
+
['never: "Never trust",', 'never: "从不信任",'],
|
|
322
|
+
['new SelectSubmenu("Theme", "Select a theme, or choose Automatic to follow terminal appearance."', 'new SelectSubmenu("主题", "选择一个主题,或选「自动」跟随终端明暗。"'],
|
|
323
|
+
['label: "Automatic",', 'label: "自动",'],
|
|
324
|
+
['description: "Use separate themes for light and dark terminal appearance",', 'description: "终端明暗各用一套主题",'],
|
|
325
|
+
['theme.fg("accent", "Automatic Theme")', 'theme.fg("accent", "自动主题")'],
|
|
326
|
+
['theme.fg("muted", "Choose themes for terminal light and dark appearance.")', 'theme.fg("muted", "分别为终端的浅色/深色外观选主题。")'],
|
|
327
|
+
['theme.fg("muted", "Light/dark detection requires terminal support.")', 'theme.fg("muted", "明暗检测需要终端支持。")'],
|
|
328
|
+
['label: "Light theme",', 'label: "浅色主题",'],
|
|
329
|
+
['description: "Theme to use in automatic mode when the terminal is light",', 'description: "自动模式下终端为浅色时使用的主题",'],
|
|
330
|
+
['label: "Dark theme",', 'label: "深色主题",'],
|
|
331
|
+
['description: "Theme to use in automatic mode when the terminal is dark",', 'description: "自动模式下终端为深色时使用的主题",'],
|
|
332
|
+
['label: "Apply",', 'label: "应用",'],
|
|
333
|
+
['description: "Save and go back",', 'description: "保存并返回",'],
|
|
334
|
+
['label: "Change mode",', 'label: "切换模式",'],
|
|
335
|
+
['description: "Switch to one theme for light and dark",', 'description: "明暗共用一个主题",'],
|
|
336
|
+
['label: "Auto-compact",', 'label: "自动压缩上下文",'],
|
|
337
|
+
['description: "Automatically compact context when it gets too large",', 'description: "上下文过长时自动压缩",'],
|
|
338
|
+
['label: "Steering mode",', 'label: "插话模式",'],
|
|
339
|
+
['description: "Enter while streaming queues steering messages. \'one-at-a-time\': deliver one, wait for response. \'all\': deliver all at once.",', 'description: "回复进行中按 Enter 发送插话。one-at-a-time:发一条等回复;all:一次全发。",'],
|
|
340
|
+
['label: "Follow-up mode",', 'label: "追问模式",'],
|
|
341
|
+
['description: `${followUpKey} queues follow-up messages until agent stops. \'one-at-a-time\': deliver one, wait for response. \'all\': deliver all at once.`,', 'description: `${followUpKey} 把追问排队到本轮结束再发。one-at-a-time:发一条等回复;all:一次全发。`,'],
|
|
342
|
+
['label: "Transport",', 'label: "传输方式",'],
|
|
343
|
+
['description: "Preferred transport for providers that support multiple transports",', 'description: "支持多种传输方式的渠道优先用哪种",'],
|
|
344
|
+
['label: "HTTP idle timeout",', 'label: "HTTP 空闲超时",'],
|
|
345
|
+
['description: "Maximum idle gap while waiting for HTTP headers or body chunks. Disable for local models that pause longer than five minutes.",', 'description: "等待响应头或数据块的最长空闲间隔;本地模型停顿超过五分钟可关闭。",'],
|
|
346
|
+
['label: "Hide thinking",', 'label: "隐藏思考过程",'],
|
|
347
|
+
['description: "Hide thinking blocks in assistant responses",', 'description: "不显示回复里的思考块",'],
|
|
348
|
+
['label: "Mermaid diagrams",', 'label: "Mermaid 图表",'],
|
|
349
|
+
['description: "Render Mermaid code blocks as Unicode diagrams",', 'description: "把 Mermaid 代码块渲染成字符图",'],
|
|
350
|
+
['label: "Cache miss notices",', 'label: "缓存未命中提示",'],
|
|
351
|
+
['description: "Show transcript notices for significant prompt-cache misses and compaction costs",', 'description: "提示明显的提示词缓存未命中与压缩开销",'],
|
|
352
|
+
['label: "Collapse changelog",', 'label: "折叠更新日志",'],
|
|
353
|
+
['description: "Show condensed changelog after updates",', 'description: "更新后只显示精简的更新日志",'],
|
|
354
|
+
['label: "Quiet startup",', 'label: "安静启动",'],
|
|
355
|
+
['description: "Disable verbose printing at startup",', 'description: "启动时不打印冗长信息",'],
|
|
356
|
+
['label: "Install telemetry",', 'label: "安装统计",'],
|
|
357
|
+
['description: "Send an anonymous version/update ping after changelog-detected updates",', 'description: "更新后匿名上报一次版本信息",'],
|
|
358
|
+
['label: "Default project trust",', 'label: "默认项目信任",'],
|
|
359
|
+
['description: "Fallback behavior when no extension or saved trust decision decides project trust",', 'description: "没有扩展或已保存决定时,项目信任的兜底行为",'],
|
|
360
|
+
['label: "Double-escape action",', 'label: "双击 Esc 动作",'],
|
|
361
|
+
['description: "Action when pressing Escape twice with empty editor",', 'description: "输入框为空时连按两次 Esc 的动作",'],
|
|
362
|
+
['label: "Tree filter mode",', 'label: "会话树筛选",'],
|
|
363
|
+
['description: "Default filter when opening /tree",', 'description: "打开 /tree 时的默认筛选",'],
|
|
364
|
+
['label: "Warnings",', 'label: "警告提示",'],
|
|
365
|
+
['description: "Enable or disable individual warnings",', 'description: "逐项开关各类警告",'],
|
|
366
|
+
['label: "Default thinking level per model",', 'label: "各模型默认推理强度",'],
|
|
367
|
+
['description: `Override the default thinking level for specific models. ${cycleThinkingKey} cycles in-session.`,', 'description: `按模型覆盖默认推理强度;会话内用 ${cycleThinkingKey} 切换。`,'],
|
|
368
|
+
['description: "Select a model to configure",', 'description: "选择要设置的模型",'],
|
|
369
|
+
['label: "No models available",', 'label: "没有可用模型",'],
|
|
370
|
+
['description: "Log in to a provider or configure an API key first",', 'description: "请先登录",'],
|
|
371
|
+
['description: "Select default thinking level for this model",', 'description: "选择这个模型的默认推理强度",'],
|
|
372
|
+
['label: "(clear override)",', 'label: "(清除覆盖)",'],
|
|
373
|
+
['description: `Revert to global default (${config.thinkingLevel})`,', 'description: `恢复为全局默认(${config.thinkingLevel})`,'],
|
|
374
|
+
['label: "TUI mode",', 'label: "界面模式",'],
|
|
375
|
+
['description: "Interface layout; fullscreen mode is experimental",', 'description: "界面布局;全屏模式为实验功能",'],
|
|
376
|
+
['label: "Fullscreen exit output",', 'label: "退出全屏时的输出",'],
|
|
377
|
+
['description: "Print the transcript or only a session resume hint when exiting fullscreen mode",', 'description: "退出全屏时打印完整对话,还是只留一条恢复会话提示",'],
|
|
378
|
+
['label: "Fullscreen scrollbar",', 'label: "全屏滚动条",'],
|
|
379
|
+
['description: "Scrollbar behavior in fullscreen mode; has no effect in regular mode",', 'description: "全屏模式下的滚动条行为;普通模式无效",'],
|
|
380
|
+
['label: "Fullscreen copy on select",', 'label: "全屏选中即复制",'],
|
|
381
|
+
['description: "Automatically copy selected text in fullscreen mode; disable to copy selections with Ctrl+X",', 'description: "全屏模式下选中文字自动复制;关闭后用 Ctrl+X 复制",'],
|
|
382
|
+
['label: "Theme",', 'label: "主题",'],
|
|
383
|
+
['description: "Color theme for the interface",', 'description: "界面配色主题",'],
|
|
384
|
+
];
|
|
385
|
+
|
|
386
|
+
const TUI_TEXT_TARGETS = [
|
|
387
|
+
[["modes", "interactive", "components", "assistant-message.js"], ASSISTANT_TEXT_REPLACEMENTS, "回复状态文案"],
|
|
388
|
+
[["modes", "interactive", "interactive-mode.js"], WORKING_TEXT_REPLACEMENTS, "工作中提示"],
|
|
389
|
+
[["modes", "interactive", "components", "keybinding-hints.js"], KEY_HINT_REPLACEMENTS, "按键脚注"],
|
|
390
|
+
[["modes", "interactive", "components", "model-selector.js"], MODEL_SELECTOR_REPLACEMENTS, "模型选择器"],
|
|
391
|
+
[["modes", "interactive", "components", "settings-selector.js"], SETTINGS_REPLACEMENTS, "设置菜单"],
|
|
392
|
+
];
|
|
393
|
+
|
|
394
|
+
function patchTuiText() {
|
|
395
|
+
for (const piDir of findPackageDirs("@earendil-works/pi-coding-agent")) {
|
|
396
|
+
for (const [parts, rules, label] of TUI_TEXT_TARGETS) {
|
|
397
|
+
const target = join(piDir, "dist", ...parts);
|
|
398
|
+
try {
|
|
399
|
+
let text = readFileSync(target, "utf8");
|
|
400
|
+
let applied = 0;
|
|
401
|
+
for (const rule of rules) {
|
|
402
|
+
const { from, to, expected } = Array.isArray(rule) ? { from: rule[0], to: rule[1], expected: 1 } : rule;
|
|
403
|
+
if (text.includes(to)) {
|
|
404
|
+
applied++;
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
if (text.split(from).length !== expected + 1) continue;
|
|
408
|
+
text = text.split(from).join(to);
|
|
409
|
+
applied++;
|
|
410
|
+
}
|
|
411
|
+
if (applied < rules.length) {
|
|
412
|
+
console.log(
|
|
413
|
+
`[u1s1] 提示: pi 版本可能已更新,${label}汉化补丁只应用了 ${applied}/${rules.length} 处(不影响使用)`,
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
writeFileSync(target, text);
|
|
417
|
+
} catch {
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
274
424
|
function patchMainScreenAutowrap() {
|
|
275
425
|
const tuiDirs = findTuiDirs();
|
|
276
426
|
if (tuiDirs.length === 0) {
|
|
@@ -329,6 +479,7 @@ try {
|
|
|
329
479
|
patchSlashCommands();
|
|
330
480
|
patchExtensionError();
|
|
331
481
|
patchHotkeys();
|
|
482
|
+
patchTuiText();
|
|
332
483
|
patchMainScreenAutowrap();
|
|
333
484
|
} catch (err) {
|
|
334
485
|
console.log(`[u1s1] 提示: pi 运行时补丁未生效(${err?.message ?? err}),不影响安装`);
|