@eddyskywalker/dsh-chatgpt-subscription 0.59.0 → 0.61.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/CHANGELOG.md +42 -0
- package/README.md +1 -1
- package/lib/client.js +1578 -232
- package/lib/client.js.map +1 -1
- package/lib/codemode.js +795 -178
- package/lib/entry-plan-mode-CLRKkgYG.js +1787 -0
- package/lib/{entry-progress-updates-CxQewio9.js → entry-progress-updates-DZ0ZRus4.js} +14 -1
- package/lib/index.js +1079 -754
- package/lib/llm-compat-u9mor0uu.js +110 -0
- package/lib/plan-mode.js +2 -779
- package/lib/progress-updates.js +1 -1
- package/lib/types/client/codemode/CodeRunToolView.d.ts +68 -0
- package/lib/types/client/codemode/CodeRunToolView.d.ts.map +1 -0
- package/lib/types/client/codemode/highlight.d.ts +25 -0
- package/lib/types/client/codemode/highlight.d.ts.map +1 -0
- package/lib/types/client/codemode/styles.d.ts +11 -0
- package/lib/types/client/codemode/styles.d.ts.map +1 -0
- package/lib/types/client/codemode/tool-name.d.ts +10 -0
- package/lib/types/client/codemode/tool-name.d.ts.map +1 -0
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/locales-ru/hub.d.ts.map +1 -1
- package/lib/types/client/locales.d.ts +23 -1
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/compat.d.ts +1 -1
- package/lib/types/entry-codemode.d.ts.map +1 -1
- package/lib/types/entry-plan-mode.d.ts +136 -0
- package/lib/types/entry-plan-mode.d.ts.map +1 -1
- package/lib/types/host/agent-preset.d.ts.map +1 -1
- package/lib/types/host/claude/adapter.d.ts +16 -0
- package/lib/types/host/claude/adapter.d.ts.map +1 -1
- package/lib/types/host/claude/client.d.ts +7 -1
- package/lib/types/host/claude/client.d.ts.map +1 -1
- package/lib/types/host/claude/mapper.d.ts +9 -0
- package/lib/types/host/claude/mapper.d.ts.map +1 -1
- package/lib/types/host/claude/types.d.ts +10 -0
- package/lib/types/host/claude/types.d.ts.map +1 -1
- package/lib/types/host/cline-pass/mapper.d.ts.map +1 -1
- package/lib/types/host/codemode/discovery.d.ts.map +1 -1
- package/lib/types/host/codemode/executor.d.ts.map +1 -1
- package/lib/types/host/codemode/rules.d.ts +16 -6
- package/lib/types/host/codemode/rules.d.ts.map +1 -1
- package/lib/types/host/codemode/transport.d.ts +120 -41
- package/lib/types/host/codemode/transport.d.ts.map +1 -1
- package/lib/types/host/command-code/mapper.d.ts.map +1 -1
- package/lib/types/host/command-code/model-catalog.d.ts +14 -14
- package/lib/types/host/command-code/model-catalog.d.ts.map +1 -1
- package/lib/types/host/command-code/routes.d.ts.map +1 -1
- package/lib/types/host/common/orphan-tool-calls.d.ts +48 -0
- package/lib/types/host/common/orphan-tool-calls.d.ts.map +1 -0
- package/lib/types/host/dispatch-execution-guard.d.ts +32 -2
- package/lib/types/host/dispatch-execution-guard.d.ts.map +1 -1
- package/lib/types/host/glm-coding-plan/mapper-anthropic.d.ts.map +1 -1
- package/lib/types/host/glm-coding-plan/mapper-openai.d.ts.map +1 -1
- package/lib/types/host/kimi-code/mapper.d.ts.map +1 -1
- package/lib/types/host/minimax-code/mapper.d.ts.map +1 -1
- package/lib/types/host/model-catalog.d.ts +21 -0
- package/lib/types/host/model-catalog.d.ts.map +1 -1
- package/lib/types/host/opendesign/mapper.d.ts.map +1 -1
- package/lib/types/host/plan-mode-cache-guard.d.ts.map +1 -1
- package/lib/types/host/preset-sync.d.ts +19 -4
- package/lib/types/host/preset-sync.d.ts.map +1 -1
- package/lib/types/host/progress-updates/nudge.d.ts +13 -1
- package/lib/types/host/progress-updates/nudge.d.ts.map +1 -1
- package/lib/types/host/qoder/mapper.d.ts.map +1 -1
- package/lib/types/host/responses-client.d.ts.map +1 -1
- package/lib/types/host/responses-mapper.d.ts +12 -0
- package/lib/types/host/responses-mapper.d.ts.map +1 -1
- package/lib/types/host/settled-job-guard.d.ts +77 -0
- package/lib/types/host/settled-job-guard.d.ts.map +1 -0
- package/lib/types/host/step-code/mapper.d.ts.map +1 -1
- package/lib/types/host/workbuddy/mapper.d.ts.map +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/presets/dispatch/README.md +8 -13
- package/presets/dispatch/agent.cordis.yml +11 -16
package/lib/client.js
CHANGED
|
@@ -2978,10 +2978,10 @@ window.__ModuleLoader__.load({
|
|
|
2978
2978
|
"aria-label": label,
|
|
2979
2979
|
"data-copied": copied ? "true" : "false",
|
|
2980
2980
|
onClick,
|
|
2981
|
-
children: copied ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckIcon, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopyIcon, {})
|
|
2981
|
+
children: copied ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckIcon$1, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopyIcon$1, {})
|
|
2982
2982
|
});
|
|
2983
2983
|
}
|
|
2984
|
-
function CopyIcon() {
|
|
2984
|
+
function CopyIcon$1() {
|
|
2985
2985
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
2986
2986
|
viewBox: "0 0 16 16",
|
|
2987
2987
|
width: "14",
|
|
@@ -3005,7 +3005,7 @@ window.__ModuleLoader__.load({
|
|
|
3005
3005
|
})]
|
|
3006
3006
|
});
|
|
3007
3007
|
}
|
|
3008
|
-
function CheckIcon() {
|
|
3008
|
+
function CheckIcon$1() {
|
|
3009
3009
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
3010
3010
|
viewBox: "0 0 16 16",
|
|
3011
3011
|
width: "14",
|
|
@@ -7093,7 +7093,7 @@ window.__ModuleLoader__.load({
|
|
|
7093
7093
|
* rather than inferred from the JSX.
|
|
7094
7094
|
*/
|
|
7095
7095
|
/** The card's own dictionary; stable identity keeps effect dependencies intact. */
|
|
7096
|
-
const fallbackTranslate$
|
|
7096
|
+
const fallbackTranslate$6 = (key) => zh$11[key];
|
|
7097
7097
|
/**
|
|
7098
7098
|
* The shared pool card's labels, resolved through this card's dictionary.
|
|
7099
7099
|
*
|
|
@@ -7188,7 +7188,7 @@ window.__ModuleLoader__.load({
|
|
|
7188
7188
|
/** Device-code poll cadence. The host owns the real expiry. */
|
|
7189
7189
|
const LOGIN_POLL_INTERVAL_MS$3 = 2e3;
|
|
7190
7190
|
function useMinimaxCodeSection({ onModelChange }) {
|
|
7191
|
-
const t = fallbackTranslate$
|
|
7191
|
+
const t = fallbackTranslate$6;
|
|
7192
7192
|
const [status, setStatus] = (0, react.useState)(null);
|
|
7193
7193
|
const [loading, setLoading] = (0, react.useState)(true);
|
|
7194
7194
|
const [busy, setBusy] = (0, react.useState)(null);
|
|
@@ -8646,7 +8646,7 @@ window.__ModuleLoader__.load({
|
|
|
8646
8646
|
const { status, loading, busy, error, flow, copied, connectionNotice, contextDrafts, savingModel, pool, resetCards, resetNotice, selectedResetCardId } = state;
|
|
8647
8647
|
const { authenticated, account, quota, models, contextModels, overrideCount, poolLabels, resetCardList, resetCardFlows } = derived;
|
|
8648
8648
|
const { login, cancelLogin, copyCode, logout, poolAction, setStrategy, toggleModel, setAllModels, setCheckinEnabled, runCheckinNow, updateEffort, saveContextWindow, resetContextWindow, resetAllContextWindows, refreshQuota, refreshResetCards, selectResetCard, useResetCard, testConnection, updateContextDraft } = actions;
|
|
8649
|
-
const t = fallbackTranslate$
|
|
8649
|
+
const t = fallbackTranslate$6;
|
|
8650
8650
|
const videoDefaultsRef = react.default.useRef(null);
|
|
8651
8651
|
if (videoDefaultsRef.current === null) videoDefaultsRef.current = readVideoDefaults();
|
|
8652
8652
|
const saveVideoDefaults = react.default.useCallback((next) => {
|
|
@@ -9424,7 +9424,7 @@ window.__ModuleLoader__.load({
|
|
|
9424
9424
|
/** 登录状态机的轮询节奏。真实超时与间隔由 host 拥有,卡片只是跟随。 */
|
|
9425
9425
|
const LOGIN_POLL_INTERVAL_MS$2 = 2e3;
|
|
9426
9426
|
/** 本卡片的字典;身份稳定,依赖它的 effect 才不会每次渲染重建。 */
|
|
9427
|
-
const fallbackTranslate$
|
|
9427
|
+
const fallbackTranslate$5 = (key) => zh$10[key];
|
|
9428
9428
|
/**
|
|
9429
9429
|
* 共享账号池卡片需要的标签集,按本卡片的字典逐键查出来。
|
|
9430
9430
|
*
|
|
@@ -9488,7 +9488,7 @@ window.__ModuleLoader__.load({
|
|
|
9488
9488
|
});
|
|
9489
9489
|
}
|
|
9490
9490
|
function useGlmCodingPlanSection({ onModelChange } = {}) {
|
|
9491
|
-
const t = fallbackTranslate$
|
|
9491
|
+
const t = fallbackTranslate$5;
|
|
9492
9492
|
const [status, setStatus] = (0, react.useState)(null);
|
|
9493
9493
|
const [loading, setLoading] = (0, react.useState)(true);
|
|
9494
9494
|
const [busy, setBusy] = (0, react.useState)(null);
|
|
@@ -12577,7 +12577,7 @@ window.__ModuleLoader__.load({
|
|
|
12577
12577
|
/** 登录状态机的轮询节奏。真实超时与间隔由 host 拥有,卡片只是跟随。 */
|
|
12578
12578
|
const LOGIN_POLL_INTERVAL_MS$1 = 2e3;
|
|
12579
12579
|
/** 本卡片的字典;身份稳定,依赖它的 effect 才不会每次渲染重建。 */
|
|
12580
|
-
const fallbackTranslate$
|
|
12580
|
+
const fallbackTranslate$4 = (key) => zh$7[key];
|
|
12581
12581
|
/**
|
|
12582
12582
|
* 共享账号池卡片需要的标签集,按本卡片的字典逐键查出来。
|
|
12583
12583
|
*
|
|
@@ -12706,7 +12706,7 @@ window.__ModuleLoader__.load({
|
|
|
12706
12706
|
/** 写侧的线路常量;卡片用它渲染说明,而不是渲染一条永远为 0 的进度条。 */
|
|
12707
12707
|
const CACHE_WRITE_NOTE = STEP_CODE_CACHE_WRITE_NOTE;
|
|
12708
12708
|
function useStepCodeSection({ onModelChange } = {}) {
|
|
12709
|
-
const t = fallbackTranslate$
|
|
12709
|
+
const t = fallbackTranslate$4;
|
|
12710
12710
|
const [status, setStatus] = (0, react.useState)(null);
|
|
12711
12711
|
const [loading, setLoading] = (0, react.useState)(true);
|
|
12712
12712
|
const [busy, setBusy] = (0, react.useState)(null);
|
|
@@ -16379,7 +16379,7 @@ window.__ModuleLoader__.load({
|
|
|
16379
16379
|
/** 登录状态机的轮询节奏。真实超时与间隔由 host 拥有,卡片只是跟随。 */
|
|
16380
16380
|
const LOGIN_POLL_INTERVAL_MS = 2e3;
|
|
16381
16381
|
/** 本卡片的字典;身份稳定,依赖它的 effect 才不会每次渲染重建。 */
|
|
16382
|
-
const fallbackTranslate$
|
|
16382
|
+
const fallbackTranslate$3 = (key) => zh$5[key];
|
|
16383
16383
|
/**
|
|
16384
16384
|
* 共享账号池卡片需要的标签集,按本卡片的字典逐键查出来。
|
|
16385
16385
|
*
|
|
@@ -16478,7 +16478,7 @@ window.__ModuleLoader__.load({
|
|
|
16478
16478
|
return stats.cacheReadTokens / denominator;
|
|
16479
16479
|
}
|
|
16480
16480
|
function useQoderSection({ onModelChange } = {}) {
|
|
16481
|
-
const t = fallbackTranslate$
|
|
16481
|
+
const t = fallbackTranslate$3;
|
|
16482
16482
|
const [status, setStatus] = (0, react.useState)(null);
|
|
16483
16483
|
const [loading, setLoading] = (0, react.useState)(true);
|
|
16484
16484
|
const [busy, setBusy] = (0, react.useState)(null);
|
|
@@ -21023,217 +21023,229 @@ window.__ModuleLoader__.load({
|
|
|
21023
21023
|
//#endregion
|
|
21024
21024
|
//#region src/client/locales.ts
|
|
21025
21025
|
const NS = "dsh-chatgpt-subscription";
|
|
21026
|
+
const zh$2 = {
|
|
21027
|
+
...accountPoolZh,
|
|
21028
|
+
title: "ChatGPT",
|
|
21029
|
+
hubTitle: "订阅服务",
|
|
21030
|
+
intro: "使用 ChatGPT 账号登录,在 DSH 中使用订阅可用的模型。",
|
|
21031
|
+
account: "账号",
|
|
21032
|
+
signedOut: "尚未登录",
|
|
21033
|
+
signedIn: "已登录",
|
|
21034
|
+
plan: "套餐",
|
|
21035
|
+
accountId: "账号 ID",
|
|
21036
|
+
expires: "令牌到期",
|
|
21037
|
+
signIn: "使用 ChatGPT 登录",
|
|
21038
|
+
signInAgain: "重新登录",
|
|
21039
|
+
cancel: "取消登录",
|
|
21040
|
+
signOut: "注销",
|
|
21041
|
+
refreshToken: "刷新凭据",
|
|
21042
|
+
pending: "请在浏览器中完成登录。",
|
|
21043
|
+
popupBlocked: "浏览器拦截了登录窗口,请使用下面的链接继续。",
|
|
21044
|
+
continueLogin: "打开 ChatGPT 登录页",
|
|
21045
|
+
loading: "正在读取状态…",
|
|
21046
|
+
connection: "连接",
|
|
21047
|
+
testConnection: "测试连接",
|
|
21048
|
+
testing: "测试中…",
|
|
21049
|
+
latency: "最近延迟",
|
|
21050
|
+
selectAll: "全选",
|
|
21051
|
+
unselectAll: "全不选",
|
|
21052
|
+
models: "可用模型",
|
|
21053
|
+
modelsHint: "勾选后模型才会显示在对话页的模型选择列表中;全部取消勾选或关闭上方开关可在列表中隐藏该供应商。",
|
|
21054
|
+
proxySettings: "网络代理",
|
|
21055
|
+
proxyMode: "代理模式",
|
|
21056
|
+
proxyModeHint: "本插件的全部供应线路共用这一份代理设置,登录、令牌续期、模型目录与配额读取同样经过它;支持自动读取系统代理,修改后对后续请求生效。",
|
|
21057
|
+
proxyModeAuto: "系统代理(自动检测)",
|
|
21058
|
+
proxyModeCustom: "自定义代理",
|
|
21059
|
+
proxyModeDirect: "直连(禁用代理)",
|
|
21060
|
+
customProxyUrl: "自定义代理地址",
|
|
21061
|
+
customProxyUrlHint: "支持 HTTP/HTTPS/SOCKS5 代理地址,例如 http://127.0.0.1:7890",
|
|
21062
|
+
customProxyUrlPlaceholder: "例如: http://127.0.0.1:7890",
|
|
21063
|
+
saveProxyUrl: "保存代理地址",
|
|
21064
|
+
proxyDetected: "检测到系统代理",
|
|
21065
|
+
proxyDetectedEffective: "(已自动生效)",
|
|
21066
|
+
proxyNoneDetected: "未检测到系统代理,将使用直连",
|
|
21067
|
+
proxyDirectHint: "本插件的全部请求将直接连接,不经过任何代理服务器。",
|
|
21068
|
+
poolStorageTitle: "账号存储位置",
|
|
21069
|
+
poolStorageKeyring: "桌面密钥环",
|
|
21070
|
+
poolStorageCredentials: "DSH 凭据库",
|
|
21071
|
+
poolStorageKeyringHint: "仅限桌面安装:使用操作系统密钥环(DPAPI / 钥匙串 / Secret Service)。在服务器或无桌面的 Linux 主机上密钥环通常不可用,登录会失败——请改选 DSH 凭据库。",
|
|
21072
|
+
poolStorageCredentialsHint: "DSH 的标准密钥存储($DSH_HOME/.credentials.yaml)。POSIX 上强制 0600、创建者独占;Windows 上只有 profile ACL,没有权限位可强制。服务器以及任何没有桌面密钥环的主机都用它。静态不加密,靠宿主权限保护。",
|
|
21073
|
+
poolStorageEffective: "当前实际使用:{storage}",
|
|
21074
|
+
poolStorageBackendKeyring: "桌面密钥环(Secret Service),静态加密",
|
|
21075
|
+
poolStorageBackendDpapi: "Windows DPAPI,静态加密",
|
|
21076
|
+
poolStorageBackendKeychain: "macOS 钥匙串,静态加密",
|
|
21077
|
+
poolStorageBackendCredentials: "DSH 凭据库(.credentials.yaml),由文件权限保护",
|
|
21078
|
+
poolStorageSwitchWarning: "已保存在另一个存储里的账号会留在原处,切回去之前不会显示。不会做迁移。",
|
|
21079
|
+
poolStorageUnavailableKeyring: "这台主机上没有可用的桌面密钥环,因此号池无法读写。请把「账号存储位置」改成 DSH 凭据库。",
|
|
21080
|
+
poolStorageUnavailableCredentials: "这个 harness 没有凭据库(ctx.credentials),因此号池无法读写。请把「账号存储位置」改成桌面密钥环。",
|
|
21081
|
+
poolStorageUnavailableStore: "号池存储这次没有应答,所以这里没有列出账号——账号并没有被删除,存储恢复后重新打开本页即可。",
|
|
21082
|
+
enhancements: "增强功能",
|
|
21083
|
+
fastMode: "快速模式(1.5x 速度)",
|
|
21084
|
+
fastModeHint: "提升 Token 生成速度至约 1.5 倍;将以约 2x–2.5x 速度消耗 Codex 订阅额度。",
|
|
21085
|
+
outputVerbosity: "输出详细程度",
|
|
21086
|
+
outputVerbosityHint: "控制 Codex 最终回答的详细程度;不影响思考深度。默认值与官方 Codex 客户端一致(低)。",
|
|
21087
|
+
verbosityLow: "低(保持回答简洁)",
|
|
21088
|
+
verbosityMedium: "中(兼顾细节与简洁)",
|
|
21089
|
+
verbosityHigh: "高(在回答中包含更多细节)",
|
|
21090
|
+
reasoningSummary: "推理摘要",
|
|
21091
|
+
reasoningSummaryHint: "选择 ChatGPT 总结其推理的方式;不影响思考深度。默认值与官方 Codex 客户端一致(不生成摘要,可省额度)。",
|
|
21092
|
+
summaryAuto: "自动(让模型选择摘要详细程度)",
|
|
21093
|
+
summaryConcise: "简洁(显示简要推理摘要)",
|
|
21094
|
+
summaryDetailed: "详细(显示更详细的推理摘要)",
|
|
21095
|
+
summaryNone: "无(不显示推理摘要)",
|
|
21096
|
+
searchProvider: "搜索来源",
|
|
21097
|
+
searchProviderHint: "选择 DSH 联网搜索使用默认来源,或改用当前 ChatGPT 订阅的 Codex 来源(自动走代理隧道)。抓取模式为 auto 时,抓取来源跟随此选择。",
|
|
21098
|
+
searchProviderDsh: "DSH 默认",
|
|
21099
|
+
searchProviderCodex: "ChatGPT(代理隧道)",
|
|
21100
|
+
fetchStatus: "抓取来源(只读)",
|
|
21101
|
+
fetchStatusHint: "以下内容由 Host 上报,只读展示。",
|
|
21102
|
+
fetchConfiguredProvider: "配置的抓取 Provider",
|
|
21103
|
+
fetchProviderDshDefault: "DSH 默认(Host 未固定抓取 provider)",
|
|
21104
|
+
switcherState: "抓取选择器状态",
|
|
21105
|
+
switcherStateIdle: "空闲(尚未应用选择)",
|
|
21106
|
+
switcherStateApplying: "应用中(正在切换 Host 的 web provider)",
|
|
21107
|
+
switcherStateApplied: "已应用",
|
|
21108
|
+
switcherStateMissing: "未找到可切换的 web 服务",
|
|
21109
|
+
switcherStateFailed: "切换失败,请检查 Host 日志",
|
|
21110
|
+
fetchMode: "抓取模式",
|
|
21111
|
+
fetchModeAuto: "auto(有可用代理或选了 ChatGPT 搜索时用插件抓取)",
|
|
21112
|
+
fetchModePlugin: "plugin(始终用本插件抓取)",
|
|
21113
|
+
fetchModeDsh: "dsh(保留 DSH 原有抓取来源)",
|
|
21114
|
+
fetchMaxBodyChars: "插件正文上限",
|
|
21115
|
+
fetchMaxResponseBytes: "插件响应体上限",
|
|
21116
|
+
characters: "字符",
|
|
21117
|
+
bytes: "字节",
|
|
21118
|
+
fetchLimitsInactive: "仅在实际使用插件抓取时生效;走 DSH 原有抓取来源时不适用这两个上限。",
|
|
21119
|
+
fetchConfigSource: "模式与上限在插件 Config 中修改(不是本页面偏好),修改后重载插件或重启 DSH 生效。",
|
|
21120
|
+
providerDefault: "使用 Provider 默认值",
|
|
21121
|
+
contextWindows: "模型上下文窗口",
|
|
21122
|
+
contextWindowsHint: "只列出已勾选「可用模型」的条目。默认取模型目录值(GPT-6 系列 384K,最高 872K;其余最高 1M),该值用于 DSH 的压缩与溢出判断,可输入 872K、512K 等容量;改过的模型可单独或一键恢复默认。",
|
|
21123
|
+
contextWindow: "上下文窗口",
|
|
21124
|
+
contextWindowInvalid: "上下文窗口必须是正整数,且不能超过模型上限(GPT-6 系列为 872K,其余为 1M);可使用 K 或 M 后缀。",
|
|
21125
|
+
contextWindowReset: "恢复默认",
|
|
21126
|
+
contextWindowResetAll: "全部恢复默认",
|
|
21127
|
+
contextWindowResetAllConfirm: "确定把已改过的模型上下文窗口全部恢复为默认值吗?",
|
|
21128
|
+
contextWindowsNoneEnabled: "还没有勾选任何模型。在上方「可用模型」里勾选后,这里会出现该模型的上下文窗口设置。",
|
|
21129
|
+
saveContextWindow: "保存上下文窗口",
|
|
21130
|
+
save: "保存",
|
|
21131
|
+
tokens: "tokens",
|
|
21132
|
+
quickQuota: "在输入框旁显示快捷用量",
|
|
21133
|
+
quickQuotaHint: "仅在当前会话选中 codex-chatgpt 模型时显示。",
|
|
21134
|
+
quota: "用量与限额",
|
|
21135
|
+
quotaIntro: "数据来自 ChatGPT Codex 用量服务。页面可见时最多每 60 秒刷新一次。",
|
|
21136
|
+
refreshQuota: "刷新用量",
|
|
21137
|
+
refreshing: "刷新中…",
|
|
21138
|
+
noQuota: "当前套餐未返回可显示的限额窗口。",
|
|
21139
|
+
quotaSignedOut: "登录后可查看订阅限额。",
|
|
21140
|
+
stale: "显示的是上次成功获取的数据。",
|
|
21141
|
+
updated: "更新时间",
|
|
21142
|
+
primary: "主要窗口",
|
|
21143
|
+
secondary: "次要窗口",
|
|
21144
|
+
limitWindow: "额度",
|
|
21145
|
+
used: "已使用",
|
|
21146
|
+
remaining: "剩余",
|
|
21147
|
+
available: "可用",
|
|
21148
|
+
unavailable: "不可用",
|
|
21149
|
+
unlimited: "无限",
|
|
21150
|
+
credits: "Credits",
|
|
21151
|
+
monthlySpend: "月度消费控制",
|
|
21152
|
+
resetCredits: "重置次数",
|
|
21153
|
+
resetCreditExpires: "到期时间",
|
|
21154
|
+
useResetCredit: "使用重置卡",
|
|
21155
|
+
usingResetCredit: "使用中…",
|
|
21156
|
+
useResetCreditConfirm: "使用后会立即消耗 1 次重置机会,并重置符合条件的 Codex 额度窗口。确定继续吗?",
|
|
21157
|
+
resetCreditUsed: "重置卡已使用,用量数据已刷新。",
|
|
21158
|
+
spendControlReached: "已触发月度消费控制,新的订阅调用可能被限制。",
|
|
21159
|
+
limit: "上限",
|
|
21160
|
+
exhausted: "额度已用尽",
|
|
21161
|
+
resets: "重置",
|
|
21162
|
+
quickQuotaLabel: "Codex 剩余",
|
|
21163
|
+
quickQuotaLoading: "用量…",
|
|
21164
|
+
imageToolRunning: "正在生成图片",
|
|
21165
|
+
imageToolDone: "已生成图片",
|
|
21166
|
+
imageToolFailed: "图片生成失败",
|
|
21167
|
+
image: "图片",
|
|
21168
|
+
openImage: "打开图片",
|
|
21169
|
+
openNamedImage: "打开 {name}",
|
|
21170
|
+
imageLoading: "加载图片…",
|
|
21171
|
+
imageLoadFailed: "图片加载失败,点击重试",
|
|
21172
|
+
imagePreviewClose: "关闭",
|
|
21173
|
+
imagePreviewOpenOriginal: "打开原图",
|
|
21174
|
+
retry: "重试",
|
|
21175
|
+
unknown: "未知",
|
|
21176
|
+
hubBack: "订阅服务",
|
|
21177
|
+
hubOverviewHint: "选择供应商以管理账号、模型与配额;右侧开关控制该供应商是否出现在模型列表中。",
|
|
21178
|
+
hubAccountCount: "{count} 个账号",
|
|
21179
|
+
hubNoAccounts: "暂无账号,点击进入添加",
|
|
21180
|
+
hubStateEnabled: "已启用",
|
|
21181
|
+
hubStateDisabled: "已停用",
|
|
21182
|
+
hubModelsEnabled: "{count} 个模型可用",
|
|
21183
|
+
hubModelsEnabledOfTotal: "{count}/{total} 个模型可用",
|
|
21184
|
+
hubStatusFailed: "状态读取失败",
|
|
21185
|
+
hubSwitchOn: "启用 {name}",
|
|
21186
|
+
hubSwitchOff: "停用 {name}",
|
|
21187
|
+
hubCardLabel: "{name},{annotation}",
|
|
21188
|
+
hubUpdateCheck: "检测更新",
|
|
21189
|
+
hubUpdateChecking: "检测中…",
|
|
21190
|
+
hubUpdateApply: "更新到 v{version}",
|
|
21191
|
+
hubUpdateApplying: "更新中…",
|
|
21192
|
+
hubUpdateUpToDate: "已是最新版本 {version}",
|
|
21193
|
+
hubUpdateLatestWithUnknownCurrent: "最新版本 {version},当前版本未知",
|
|
21194
|
+
hubUpdateAvailable: "有新版本 {version},当前 {current}",
|
|
21195
|
+
hubUpdateInstalled: "已安装 v{version},重启宿主后生效",
|
|
21196
|
+
hubUpdateInstalledReplaced: "已移除旧版并安装 v{version},重启宿主后生效",
|
|
21197
|
+
hubUpdateInstalledLive: "已安装 v{version},当前已生效,无需重启",
|
|
21198
|
+
hubUpdateInstalledReplacedLive: "已移除旧版并安装 v{version},当前已生效,无需重启",
|
|
21199
|
+
hubUpdateFailedRestored: "更新失败,已恢复 v{version}",
|
|
21200
|
+
hubUpdateFailedRollbackFailed: "更新失败,且旧版本也没能重新装回来——插件可能已不可用",
|
|
21201
|
+
hubUpdateFailedRollbackSkipped: "更新失败,且无法自动恢复原版本——插件可能已被移除",
|
|
21202
|
+
hubUpdateDevelopmentInstall: "有新版本 {version};当前是本地链接安装,无法自动更新",
|
|
21203
|
+
hubUpdatePluginManagerMissing: "有新版本 {version};宿主未提供 pluginManager,无法自动更新",
|
|
21204
|
+
hubUpdateManualOnly: "有新版本 {version};当前安装方式无法自动更新",
|
|
21205
|
+
hubUpdateCheckFailed: "检测失败:无法连接 npm 源,请检查网络或代理",
|
|
21206
|
+
hubUpdateCommandLabel: "手动更新命令",
|
|
21207
|
+
localCodexLoginImport: "导入本机登录",
|
|
21208
|
+
localCodexLoginImporting: "导入中…",
|
|
21209
|
+
deviceCodeLogin: "设备代码登录",
|
|
21210
|
+
deviceCodeLoginStarting: "获取代码…",
|
|
21211
|
+
deviceCodeLoginDetail: "用设备代码添加账号",
|
|
21212
|
+
deviceCodeHint: "在任意设备上打开下面的链接并输入这个代码,本页会自动完成登录:这条路不需要浏览器回调到本机端口。",
|
|
21213
|
+
deviceCodeLabel: "设备代码",
|
|
21214
|
+
deviceCodeOpen: "打开确认页面",
|
|
21215
|
+
deviceCodeCopy: "复制到剪贴板",
|
|
21216
|
+
deviceCodeWaiting: "等待确认… 剩余 {time}",
|
|
21217
|
+
stopImporting: "停止导入全部本机登录",
|
|
21218
|
+
stopImportingLabel: "停止导入全部本机登录(当前 {count} 个)",
|
|
21219
|
+
stopImportingBusy: "停止导入中…",
|
|
21220
|
+
stopImportingHint: "停止导入只会让本插件忘记本机 CLI 登录的副本;Codex CLI 自己的登录文件不会被删除或修改。账号池不允许逐条删除借来的凭据,所以这里一次会停止全部导入。",
|
|
21221
|
+
"cardName.chatgpt": "ChatGPT",
|
|
21222
|
+
"cardName.antigravity": "Antigravity",
|
|
21223
|
+
"cardName.command-code": "Command Code",
|
|
21224
|
+
"cardName.kimi-code": "Kimi Code",
|
|
21225
|
+
"cardName.minimax-code": "MiniMax Code",
|
|
21226
|
+
"cardName.glm-coding-plan": "GLM(ZCode 账号)",
|
|
21227
|
+
"cardName.claude": "Claude",
|
|
21228
|
+
"cardName.ollama": "Ollama",
|
|
21229
|
+
"cardName.step-code": "Step Code(Step Plan 订阅)",
|
|
21230
|
+
"cardName.cline-pass": "Cline Pass",
|
|
21231
|
+
"cardName.qoder": "Qoder(订阅)",
|
|
21232
|
+
"cardName.opendesign": "OpenDesign",
|
|
21233
|
+
"cardName.workbuddy": "WorkBuddy",
|
|
21234
|
+
modelChecklistCount: "已启用 {count}/{total}",
|
|
21235
|
+
codeRunTitle: "代码",
|
|
21236
|
+
codeRunOutput: "输出",
|
|
21237
|
+
codeRunCopy: "复制",
|
|
21238
|
+
codeRunCopied: "已复制",
|
|
21239
|
+
codeRunWrap: "自动换行",
|
|
21240
|
+
codeRunUnwrap: "取消自动换行",
|
|
21241
|
+
codeRunInspect: "查看轨迹",
|
|
21242
|
+
codeRunPreparing: "准备中",
|
|
21243
|
+
codeRunRunning: "运行中",
|
|
21244
|
+
codeRunFailed: "失败",
|
|
21245
|
+
codeRunStopped: "已停止"
|
|
21246
|
+
};
|
|
21026
21247
|
const dictionaries$2 = {
|
|
21027
|
-
zh:
|
|
21028
|
-
...accountPoolZh,
|
|
21029
|
-
title: "ChatGPT",
|
|
21030
|
-
hubTitle: "订阅服务",
|
|
21031
|
-
intro: "使用 ChatGPT 账号登录,在 DSH 中使用订阅可用的模型。",
|
|
21032
|
-
account: "账号",
|
|
21033
|
-
signedOut: "尚未登录",
|
|
21034
|
-
signedIn: "已登录",
|
|
21035
|
-
plan: "套餐",
|
|
21036
|
-
accountId: "账号 ID",
|
|
21037
|
-
expires: "令牌到期",
|
|
21038
|
-
signIn: "使用 ChatGPT 登录",
|
|
21039
|
-
signInAgain: "重新登录",
|
|
21040
|
-
cancel: "取消登录",
|
|
21041
|
-
signOut: "注销",
|
|
21042
|
-
refreshToken: "刷新凭据",
|
|
21043
|
-
pending: "请在浏览器中完成登录。",
|
|
21044
|
-
popupBlocked: "浏览器拦截了登录窗口,请使用下面的链接继续。",
|
|
21045
|
-
continueLogin: "打开 ChatGPT 登录页",
|
|
21046
|
-
loading: "正在读取状态…",
|
|
21047
|
-
connection: "连接",
|
|
21048
|
-
testConnection: "测试连接",
|
|
21049
|
-
testing: "测试中…",
|
|
21050
|
-
latency: "最近延迟",
|
|
21051
|
-
selectAll: "全选",
|
|
21052
|
-
unselectAll: "全不选",
|
|
21053
|
-
models: "可用模型",
|
|
21054
|
-
modelsHint: "勾选后模型才会显示在对话页的模型选择列表中;全部取消勾选或关闭上方开关可在列表中隐藏该供应商。",
|
|
21055
|
-
proxySettings: "网络代理",
|
|
21056
|
-
proxyMode: "代理模式",
|
|
21057
|
-
proxyModeHint: "本插件的全部供应线路共用这一份代理设置,登录、令牌续期、模型目录与配额读取同样经过它;支持自动读取系统代理,修改后对后续请求生效。",
|
|
21058
|
-
proxyModeAuto: "系统代理(自动检测)",
|
|
21059
|
-
proxyModeCustom: "自定义代理",
|
|
21060
|
-
proxyModeDirect: "直连(禁用代理)",
|
|
21061
|
-
customProxyUrl: "自定义代理地址",
|
|
21062
|
-
customProxyUrlHint: "支持 HTTP/HTTPS/SOCKS5 代理地址,例如 http://127.0.0.1:7890",
|
|
21063
|
-
customProxyUrlPlaceholder: "例如: http://127.0.0.1:7890",
|
|
21064
|
-
saveProxyUrl: "保存代理地址",
|
|
21065
|
-
proxyDetected: "检测到系统代理",
|
|
21066
|
-
proxyDetectedEffective: "(已自动生效)",
|
|
21067
|
-
proxyNoneDetected: "未检测到系统代理,将使用直连",
|
|
21068
|
-
proxyDirectHint: "本插件的全部请求将直接连接,不经过任何代理服务器。",
|
|
21069
|
-
poolStorageTitle: "账号存储位置",
|
|
21070
|
-
poolStorageKeyring: "桌面密钥环",
|
|
21071
|
-
poolStorageCredentials: "DSH 凭据库",
|
|
21072
|
-
poolStorageKeyringHint: "仅限桌面安装:使用操作系统密钥环(DPAPI / 钥匙串 / Secret Service)。在服务器或无桌面的 Linux 主机上密钥环通常不可用,登录会失败——请改选 DSH 凭据库。",
|
|
21073
|
-
poolStorageCredentialsHint: "DSH 的标准密钥存储($DSH_HOME/.credentials.yaml)。POSIX 上强制 0600、创建者独占;Windows 上只有 profile ACL,没有权限位可强制。服务器以及任何没有桌面密钥环的主机都用它。静态不加密,靠宿主权限保护。",
|
|
21074
|
-
poolStorageEffective: "当前实际使用:{storage}",
|
|
21075
|
-
poolStorageBackendKeyring: "桌面密钥环(Secret Service),静态加密",
|
|
21076
|
-
poolStorageBackendDpapi: "Windows DPAPI,静态加密",
|
|
21077
|
-
poolStorageBackendKeychain: "macOS 钥匙串,静态加密",
|
|
21078
|
-
poolStorageBackendCredentials: "DSH 凭据库(.credentials.yaml),由文件权限保护",
|
|
21079
|
-
poolStorageSwitchWarning: "已保存在另一个存储里的账号会留在原处,切回去之前不会显示。不会做迁移。",
|
|
21080
|
-
poolStorageUnavailableKeyring: "这台主机上没有可用的桌面密钥环,因此号池无法读写。请把「账号存储位置」改成 DSH 凭据库。",
|
|
21081
|
-
poolStorageUnavailableCredentials: "这个 harness 没有凭据库(ctx.credentials),因此号池无法读写。请把「账号存储位置」改成桌面密钥环。",
|
|
21082
|
-
poolStorageUnavailableStore: "号池存储这次没有应答,所以这里没有列出账号——账号并没有被删除,存储恢复后重新打开本页即可。",
|
|
21083
|
-
enhancements: "增强功能",
|
|
21084
|
-
fastMode: "快速模式(1.5x 速度)",
|
|
21085
|
-
fastModeHint: "提升 Token 生成速度至约 1.5 倍;将以约 2x–2.5x 速度消耗 Codex 订阅额度。",
|
|
21086
|
-
outputVerbosity: "输出详细程度",
|
|
21087
|
-
outputVerbosityHint: "控制 Codex 最终回答的详细程度;不影响思考深度。默认值与官方 Codex 客户端一致(低)。",
|
|
21088
|
-
verbosityLow: "低(保持回答简洁)",
|
|
21089
|
-
verbosityMedium: "中(兼顾细节与简洁)",
|
|
21090
|
-
verbosityHigh: "高(在回答中包含更多细节)",
|
|
21091
|
-
reasoningSummary: "推理摘要",
|
|
21092
|
-
reasoningSummaryHint: "选择 ChatGPT 总结其推理的方式;不影响思考深度。默认值与官方 Codex 客户端一致(不生成摘要,可省额度)。",
|
|
21093
|
-
summaryAuto: "自动(让模型选择摘要详细程度)",
|
|
21094
|
-
summaryConcise: "简洁(显示简要推理摘要)",
|
|
21095
|
-
summaryDetailed: "详细(显示更详细的推理摘要)",
|
|
21096
|
-
summaryNone: "无(不显示推理摘要)",
|
|
21097
|
-
searchProvider: "搜索来源",
|
|
21098
|
-
searchProviderHint: "选择 DSH 联网搜索使用默认来源,或改用当前 ChatGPT 订阅的 Codex 来源(自动走代理隧道)。抓取模式为 auto 时,抓取来源跟随此选择。",
|
|
21099
|
-
searchProviderDsh: "DSH 默认",
|
|
21100
|
-
searchProviderCodex: "ChatGPT(代理隧道)",
|
|
21101
|
-
fetchStatus: "抓取来源(只读)",
|
|
21102
|
-
fetchStatusHint: "以下内容由 Host 上报,只读展示。",
|
|
21103
|
-
fetchConfiguredProvider: "配置的抓取 Provider",
|
|
21104
|
-
fetchProviderDshDefault: "DSH 默认(Host 未固定抓取 provider)",
|
|
21105
|
-
switcherState: "抓取选择器状态",
|
|
21106
|
-
switcherStateIdle: "空闲(尚未应用选择)",
|
|
21107
|
-
switcherStateApplying: "应用中(正在切换 Host 的 web provider)",
|
|
21108
|
-
switcherStateApplied: "已应用",
|
|
21109
|
-
switcherStateMissing: "未找到可切换的 web 服务",
|
|
21110
|
-
switcherStateFailed: "切换失败,请检查 Host 日志",
|
|
21111
|
-
fetchMode: "抓取模式",
|
|
21112
|
-
fetchModeAuto: "auto(有可用代理或选了 ChatGPT 搜索时用插件抓取)",
|
|
21113
|
-
fetchModePlugin: "plugin(始终用本插件抓取)",
|
|
21114
|
-
fetchModeDsh: "dsh(保留 DSH 原有抓取来源)",
|
|
21115
|
-
fetchMaxBodyChars: "插件正文上限",
|
|
21116
|
-
fetchMaxResponseBytes: "插件响应体上限",
|
|
21117
|
-
characters: "字符",
|
|
21118
|
-
bytes: "字节",
|
|
21119
|
-
fetchLimitsInactive: "仅在实际使用插件抓取时生效;走 DSH 原有抓取来源时不适用这两个上限。",
|
|
21120
|
-
fetchConfigSource: "模式与上限在插件 Config 中修改(不是本页面偏好),修改后重载插件或重启 DSH 生效。",
|
|
21121
|
-
providerDefault: "使用 Provider 默认值",
|
|
21122
|
-
contextWindows: "模型上下文窗口",
|
|
21123
|
-
contextWindowsHint: "只列出已勾选「可用模型」的条目。默认取模型目录值(GPT-6 系列 384K,最高 872K;其余最高 1M),该值用于 DSH 的压缩与溢出判断,可输入 872K、512K 等容量;改过的模型可单独或一键恢复默认。",
|
|
21124
|
-
contextWindow: "上下文窗口",
|
|
21125
|
-
contextWindowInvalid: "上下文窗口必须是正整数,且不能超过模型上限(GPT-6 系列为 872K,其余为 1M);可使用 K 或 M 后缀。",
|
|
21126
|
-
contextWindowReset: "恢复默认",
|
|
21127
|
-
contextWindowResetAll: "全部恢复默认",
|
|
21128
|
-
contextWindowResetAllConfirm: "确定把已改过的模型上下文窗口全部恢复为默认值吗?",
|
|
21129
|
-
contextWindowsNoneEnabled: "还没有勾选任何模型。在上方「可用模型」里勾选后,这里会出现该模型的上下文窗口设置。",
|
|
21130
|
-
saveContextWindow: "保存上下文窗口",
|
|
21131
|
-
save: "保存",
|
|
21132
|
-
tokens: "tokens",
|
|
21133
|
-
quickQuota: "在输入框旁显示快捷用量",
|
|
21134
|
-
quickQuotaHint: "仅在当前会话选中 codex-chatgpt 模型时显示。",
|
|
21135
|
-
quota: "用量与限额",
|
|
21136
|
-
quotaIntro: "数据来自 ChatGPT Codex 用量服务。页面可见时最多每 60 秒刷新一次。",
|
|
21137
|
-
refreshQuota: "刷新用量",
|
|
21138
|
-
refreshing: "刷新中…",
|
|
21139
|
-
noQuota: "当前套餐未返回可显示的限额窗口。",
|
|
21140
|
-
quotaSignedOut: "登录后可查看订阅限额。",
|
|
21141
|
-
stale: "显示的是上次成功获取的数据。",
|
|
21142
|
-
updated: "更新时间",
|
|
21143
|
-
primary: "主要窗口",
|
|
21144
|
-
secondary: "次要窗口",
|
|
21145
|
-
limitWindow: "额度",
|
|
21146
|
-
used: "已使用",
|
|
21147
|
-
remaining: "剩余",
|
|
21148
|
-
available: "可用",
|
|
21149
|
-
unavailable: "不可用",
|
|
21150
|
-
unlimited: "无限",
|
|
21151
|
-
credits: "Credits",
|
|
21152
|
-
monthlySpend: "月度消费控制",
|
|
21153
|
-
resetCredits: "重置次数",
|
|
21154
|
-
resetCreditExpires: "到期时间",
|
|
21155
|
-
useResetCredit: "使用重置卡",
|
|
21156
|
-
usingResetCredit: "使用中…",
|
|
21157
|
-
useResetCreditConfirm: "使用后会立即消耗 1 次重置机会,并重置符合条件的 Codex 额度窗口。确定继续吗?",
|
|
21158
|
-
resetCreditUsed: "重置卡已使用,用量数据已刷新。",
|
|
21159
|
-
spendControlReached: "已触发月度消费控制,新的订阅调用可能被限制。",
|
|
21160
|
-
limit: "上限",
|
|
21161
|
-
exhausted: "额度已用尽",
|
|
21162
|
-
resets: "重置",
|
|
21163
|
-
quickQuotaLabel: "Codex 剩余",
|
|
21164
|
-
quickQuotaLoading: "用量…",
|
|
21165
|
-
imageToolRunning: "正在生成图片",
|
|
21166
|
-
imageToolDone: "已生成图片",
|
|
21167
|
-
imageToolFailed: "图片生成失败",
|
|
21168
|
-
image: "图片",
|
|
21169
|
-
openImage: "打开图片",
|
|
21170
|
-
openNamedImage: "打开 {name}",
|
|
21171
|
-
imageLoading: "加载图片…",
|
|
21172
|
-
imageLoadFailed: "图片加载失败,点击重试",
|
|
21173
|
-
imagePreviewClose: "关闭",
|
|
21174
|
-
imagePreviewOpenOriginal: "打开原图",
|
|
21175
|
-
retry: "重试",
|
|
21176
|
-
unknown: "未知",
|
|
21177
|
-
hubBack: "订阅服务",
|
|
21178
|
-
hubOverviewHint: "选择供应商以管理账号、模型与配额;右侧开关控制该供应商是否出现在模型列表中。",
|
|
21179
|
-
hubAccountCount: "{count} 个账号",
|
|
21180
|
-
hubNoAccounts: "暂无账号,点击进入添加",
|
|
21181
|
-
hubStateEnabled: "已启用",
|
|
21182
|
-
hubStateDisabled: "已停用",
|
|
21183
|
-
hubModelsEnabled: "{count} 个模型可用",
|
|
21184
|
-
hubModelsEnabledOfTotal: "{count}/{total} 个模型可用",
|
|
21185
|
-
hubStatusFailed: "状态读取失败",
|
|
21186
|
-
hubSwitchOn: "启用 {name}",
|
|
21187
|
-
hubSwitchOff: "停用 {name}",
|
|
21188
|
-
hubCardLabel: "{name},{annotation}",
|
|
21189
|
-
hubUpdateCheck: "检测更新",
|
|
21190
|
-
hubUpdateChecking: "检测中…",
|
|
21191
|
-
hubUpdateApply: "更新到 v{version}",
|
|
21192
|
-
hubUpdateApplying: "更新中…",
|
|
21193
|
-
hubUpdateUpToDate: "已是最新版本 {version}",
|
|
21194
|
-
hubUpdateLatestWithUnknownCurrent: "最新版本 {version},当前版本未知",
|
|
21195
|
-
hubUpdateAvailable: "有新版本 {version},当前 {current}",
|
|
21196
|
-
hubUpdateInstalled: "已安装 v{version},重启宿主后生效",
|
|
21197
|
-
hubUpdateInstalledReplaced: "已移除旧版并安装 v{version},重启宿主后生效",
|
|
21198
|
-
hubUpdateInstalledLive: "已安装 v{version},当前已生效,无需重启",
|
|
21199
|
-
hubUpdateInstalledReplacedLive: "已移除旧版并安装 v{version},当前已生效,无需重启",
|
|
21200
|
-
hubUpdateFailedRestored: "更新失败,已恢复 v{version}",
|
|
21201
|
-
hubUpdateFailedRollbackFailed: "更新失败,且旧版本也没能重新装回来——插件可能已不可用",
|
|
21202
|
-
hubUpdateFailedRollbackSkipped: "更新失败,且无法自动恢复原版本——插件可能已被移除",
|
|
21203
|
-
hubUpdateDevelopmentInstall: "有新版本 {version};当前是本地链接安装,无法自动更新",
|
|
21204
|
-
hubUpdatePluginManagerMissing: "有新版本 {version};宿主未提供 pluginManager,无法自动更新",
|
|
21205
|
-
hubUpdateManualOnly: "有新版本 {version};当前安装方式无法自动更新",
|
|
21206
|
-
hubUpdateCheckFailed: "检测失败:无法连接 npm 源,请检查网络或代理",
|
|
21207
|
-
hubUpdateCommandLabel: "手动更新命令",
|
|
21208
|
-
localCodexLoginImport: "导入本机登录",
|
|
21209
|
-
localCodexLoginImporting: "导入中…",
|
|
21210
|
-
deviceCodeLogin: "设备代码登录",
|
|
21211
|
-
deviceCodeLoginStarting: "获取代码…",
|
|
21212
|
-
deviceCodeLoginDetail: "用设备代码添加账号",
|
|
21213
|
-
deviceCodeHint: "在任意设备上打开下面的链接并输入这个代码,本页会自动完成登录:这条路不需要浏览器回调到本机端口。",
|
|
21214
|
-
deviceCodeLabel: "设备代码",
|
|
21215
|
-
deviceCodeOpen: "打开确认页面",
|
|
21216
|
-
deviceCodeCopy: "复制到剪贴板",
|
|
21217
|
-
deviceCodeWaiting: "等待确认… 剩余 {time}",
|
|
21218
|
-
stopImporting: "停止导入全部本机登录",
|
|
21219
|
-
stopImportingLabel: "停止导入全部本机登录(当前 {count} 个)",
|
|
21220
|
-
stopImportingBusy: "停止导入中…",
|
|
21221
|
-
stopImportingHint: "停止导入只会让本插件忘记本机 CLI 登录的副本;Codex CLI 自己的登录文件不会被删除或修改。账号池不允许逐条删除借来的凭据,所以这里一次会停止全部导入。",
|
|
21222
|
-
"cardName.chatgpt": "ChatGPT",
|
|
21223
|
-
"cardName.antigravity": "Antigravity",
|
|
21224
|
-
"cardName.command-code": "Command Code",
|
|
21225
|
-
"cardName.kimi-code": "Kimi Code",
|
|
21226
|
-
"cardName.minimax-code": "MiniMax Code",
|
|
21227
|
-
"cardName.glm-coding-plan": "GLM(ZCode 账号)",
|
|
21228
|
-
"cardName.claude": "Claude",
|
|
21229
|
-
"cardName.ollama": "Ollama",
|
|
21230
|
-
"cardName.step-code": "Step Code(Step Plan 订阅)",
|
|
21231
|
-
"cardName.cline-pass": "Cline Pass",
|
|
21232
|
-
"cardName.qoder": "Qoder(订阅)",
|
|
21233
|
-
"cardName.opendesign": "OpenDesign",
|
|
21234
|
-
"cardName.workbuddy": "WorkBuddy",
|
|
21235
|
-
modelChecklistCount: "已启用 {count}/{total}"
|
|
21236
|
-
},
|
|
21248
|
+
zh: zh$2,
|
|
21237
21249
|
en: {
|
|
21238
21250
|
...accountPoolEn,
|
|
21239
21251
|
title: "ChatGPT",
|
|
@@ -21442,7 +21454,18 @@ window.__ModuleLoader__.load({
|
|
|
21442
21454
|
"cardName.qoder": "Qoder Subscription",
|
|
21443
21455
|
"cardName.opendesign": "OpenDesign",
|
|
21444
21456
|
"cardName.workbuddy": "WorkBuddy",
|
|
21445
|
-
modelChecklistCount: "{count}/{total} enabled"
|
|
21457
|
+
modelChecklistCount: "{count}/{total} enabled",
|
|
21458
|
+
codeRunTitle: "Code",
|
|
21459
|
+
codeRunOutput: "Output",
|
|
21460
|
+
codeRunCopy: "Copy",
|
|
21461
|
+
codeRunCopied: "Copied",
|
|
21462
|
+
codeRunWrap: "Wrap lines",
|
|
21463
|
+
codeRunUnwrap: "Do not wrap lines",
|
|
21464
|
+
codeRunInspect: "Inspect",
|
|
21465
|
+
codeRunPreparing: "Preparing",
|
|
21466
|
+
codeRunRunning: "Running",
|
|
21467
|
+
codeRunFailed: "Failed",
|
|
21468
|
+
codeRunStopped: "Stopped"
|
|
21446
21469
|
}
|
|
21447
21470
|
};
|
|
21448
21471
|
//#endregion
|
|
@@ -22443,7 +22466,18 @@ window.__ModuleLoader__.load({
|
|
|
22443
22466
|
"cardName.qoder": "Qoder (подписка)",
|
|
22444
22467
|
"cardName.opendesign": "OpenDesign",
|
|
22445
22468
|
"cardName.workbuddy": "WorkBuddy",
|
|
22446
|
-
modelChecklistCount: "Включено {count}/{total}"
|
|
22469
|
+
modelChecklistCount: "Включено {count}/{total}",
|
|
22470
|
+
codeRunTitle: "Код",
|
|
22471
|
+
codeRunOutput: "Вывод",
|
|
22472
|
+
codeRunCopy: "Копировать",
|
|
22473
|
+
codeRunCopied: "Скопировано",
|
|
22474
|
+
codeRunWrap: "Переносить строки",
|
|
22475
|
+
codeRunUnwrap: "Не переносить строки",
|
|
22476
|
+
codeRunInspect: "Инспектор",
|
|
22477
|
+
codeRunPreparing: "Подготовка",
|
|
22478
|
+
codeRunRunning: "Выполняется",
|
|
22479
|
+
codeRunFailed: "Ошибка",
|
|
22480
|
+
codeRunStopped: "Остановлено"
|
|
22447
22481
|
};
|
|
22448
22482
|
//#endregion
|
|
22449
22483
|
//#region src/client/locales-ru/kimi-code.ts
|
|
@@ -27515,7 +27549,7 @@ window.__ModuleLoader__.load({
|
|
|
27515
27549
|
}
|
|
27516
27550
|
}
|
|
27517
27551
|
/** 兜底翻译:只在没有 locale 服务时用到(测试、以及菜单渲染早于字典注册)。 */
|
|
27518
|
-
function fallbackTranslate$
|
|
27552
|
+
function fallbackTranslate$2(key, params) {
|
|
27519
27553
|
const template = zh$11[key] ?? key;
|
|
27520
27554
|
if (params === void 0) return template;
|
|
27521
27555
|
return template.replace(/\{(\w+)\}/g, (_match, name) => String(params[name] ?? ""));
|
|
@@ -27531,7 +27565,7 @@ window.__ModuleLoader__.load({
|
|
|
27531
27565
|
* @returns 一份可直接交给 `commandUi.register` 的贡献。
|
|
27532
27566
|
*/
|
|
27533
27567
|
function createVideoCommand(ctx, options) {
|
|
27534
|
-
const t = options.translate ?? fallbackTranslate$
|
|
27568
|
+
const t = options.translate ?? fallbackTranslate$2;
|
|
27535
27569
|
const defaultsOf = options.defaults ?? (() => normalizeVideoDefaults({}));
|
|
27536
27570
|
return {
|
|
27537
27571
|
name: VIDEO_COMMAND_NAME,
|
|
@@ -27691,7 +27725,7 @@ window.__ModuleLoader__.load({
|
|
|
27691
27725
|
defaults: request?.defaults ?? normalizeVideoDefaults({}),
|
|
27692
27726
|
seedPrompt: request?.seedPrompt ?? "",
|
|
27693
27727
|
listWorkspace,
|
|
27694
|
-
t: fallbackTranslate$
|
|
27728
|
+
t: fallbackTranslate$2
|
|
27695
27729
|
});
|
|
27696
27730
|
};
|
|
27697
27731
|
}
|
|
@@ -27736,7 +27770,7 @@ window.__ModuleLoader__.load({
|
|
|
27736
27770
|
return commandUi.register(createVideoCommand(ctx, {
|
|
27737
27771
|
openForm: openVideoForm,
|
|
27738
27772
|
defaults: () => readVideoDefaults(),
|
|
27739
|
-
translate: fallbackTranslate$
|
|
27773
|
+
translate: fallbackTranslate$2
|
|
27740
27774
|
}));
|
|
27741
27775
|
} catch {
|
|
27742
27776
|
return () => {};
|
|
@@ -54726,7 +54760,7 @@ window.__ModuleLoader__.load({
|
|
|
54726
54760
|
* @param params - `{name}` 模板参数。
|
|
54727
54761
|
* @returns 该键的文案;缺键时回退为键本身。
|
|
54728
54762
|
*/
|
|
54729
|
-
function fallbackTranslate(key, params) {
|
|
54763
|
+
function fallbackTranslate$1(key, params) {
|
|
54730
54764
|
return interpolate(zh$1[key] ?? key, params);
|
|
54731
54765
|
}
|
|
54732
54766
|
/**
|
|
@@ -55026,7 +55060,7 @@ window.__ModuleLoader__.load({
|
|
|
55026
55060
|
* @returns 面板标题文本。
|
|
55027
55061
|
*/
|
|
55028
55062
|
function ProgressUpdatesTabTitle({ t }) {
|
|
55029
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: t === void 0 ? fallbackTranslate("progressTitle") : t("progressTitle") });
|
|
55063
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: t === void 0 ? fallbackTranslate$1("progressTitle") : t("progressTitle") });
|
|
55030
55064
|
}
|
|
55031
55065
|
//#endregion
|
|
55032
55066
|
//#region src/client/progress-updates/progress-row.tsx
|
|
@@ -55186,7 +55220,7 @@ window.__ModuleLoader__.load({
|
|
|
55186
55220
|
* @returns 一行进展;标题行常显,正文按交互展开。
|
|
55187
55221
|
*/
|
|
55188
55222
|
function ProgressRow({ block, t }) {
|
|
55189
|
-
const translate = (key) => t === void 0 ? fallbackTranslate(key) : t(key);
|
|
55223
|
+
const translate = (key) => t === void 0 ? fallbackTranslate$1(key) : t(key);
|
|
55190
55224
|
const state = isSettled(block) ? block.isError === true ? "error" : "done" : "running";
|
|
55191
55225
|
const { title, message } = progressOfBlock(block);
|
|
55192
55226
|
const heading = title ?? message.split("\n").find((line) => line.trim() !== "") ?? translate("rowPending");
|
|
@@ -55513,7 +55547,7 @@ window.__ModuleLoader__.load({
|
|
|
55513
55547
|
*/
|
|
55514
55548
|
function ProgressUpdatesSettingsSection(props) {
|
|
55515
55549
|
const { openPanel, close, settings, t } = props;
|
|
55516
|
-
const translate = (key) => t === void 0 ? fallbackTranslate(key) : t(key);
|
|
55550
|
+
const translate = (key) => t === void 0 ? fallbackTranslate$1(key) : t(key);
|
|
55517
55551
|
const snapshot = (0, react.useSyncExternalStore)(settings?.subscribe ?? NO_SETTINGS_SUBSCRIBE, settings?.getSnapshot ?? NO_SETTINGS_READ, settings?.getSnapshot ?? NO_SETTINGS_READ);
|
|
55518
55552
|
/** 写入被拒/失败时落在哪一行、说什么。 */
|
|
55519
55553
|
const [failure, setFailure] = (0, react.useState)(void 0);
|
|
@@ -59138,6 +59172,1312 @@ window.__ModuleLoader__.load({
|
|
|
59138
59172
|
return installPluginStyle(STYLE_NAME, SUBAGENT_CSS);
|
|
59139
59173
|
}
|
|
59140
59174
|
//#endregion
|
|
59175
|
+
//#region src/client/codemode/highlight.ts
|
|
59176
|
+
/** 宿主 `ui-theme/src/styles/shiki.css` 定义的标准变量表(带合理回退色以兼容测试环境)。 */
|
|
59177
|
+
const SHIKI_TOKEN_COLORS = {
|
|
59178
|
+
plain: void 0,
|
|
59179
|
+
keyword: "var(--shiki-token-keyword, #d6336c)",
|
|
59180
|
+
string: "var(--shiki-token-string, #2f9e44)",
|
|
59181
|
+
"string-expression": "var(--shiki-token-string-expression, #2b8a3e)",
|
|
59182
|
+
comment: "var(--shiki-token-comment, #868e96)",
|
|
59183
|
+
constant: "var(--shiki-token-constant, #1c7ed6)",
|
|
59184
|
+
function: "var(--shiki-token-function, #6741d9)",
|
|
59185
|
+
parameter: "var(--shiki-token-parameter, #e8590c)",
|
|
59186
|
+
punctuation: "var(--shiki-token-punctuation, #495057)"
|
|
59187
|
+
};
|
|
59188
|
+
/** 单字符数超长保护上限(与宿主 `TOKENIZE_MAX_LINE_LENGTH` 对齐,防止超长单行卡顿)。 */
|
|
59189
|
+
const MAX_HIGHLIGHT_CHARS = 1e5;
|
|
59190
|
+
const TS_KEYWORDS = /* @__PURE__ */ new Set([
|
|
59191
|
+
"as",
|
|
59192
|
+
"async",
|
|
59193
|
+
"await",
|
|
59194
|
+
"break",
|
|
59195
|
+
"case",
|
|
59196
|
+
"catch",
|
|
59197
|
+
"class",
|
|
59198
|
+
"const",
|
|
59199
|
+
"continue",
|
|
59200
|
+
"debugger",
|
|
59201
|
+
"declare",
|
|
59202
|
+
"default",
|
|
59203
|
+
"delete",
|
|
59204
|
+
"do",
|
|
59205
|
+
"else",
|
|
59206
|
+
"enum",
|
|
59207
|
+
"export",
|
|
59208
|
+
"extends",
|
|
59209
|
+
"finally",
|
|
59210
|
+
"for",
|
|
59211
|
+
"from",
|
|
59212
|
+
"function",
|
|
59213
|
+
"get",
|
|
59214
|
+
"if",
|
|
59215
|
+
"implements",
|
|
59216
|
+
"import",
|
|
59217
|
+
"in",
|
|
59218
|
+
"infer",
|
|
59219
|
+
"instanceof",
|
|
59220
|
+
"interface",
|
|
59221
|
+
"is",
|
|
59222
|
+
"keyof",
|
|
59223
|
+
"let",
|
|
59224
|
+
"module",
|
|
59225
|
+
"namespace",
|
|
59226
|
+
"new",
|
|
59227
|
+
"of",
|
|
59228
|
+
"override",
|
|
59229
|
+
"package",
|
|
59230
|
+
"private",
|
|
59231
|
+
"protected",
|
|
59232
|
+
"public",
|
|
59233
|
+
"readonly",
|
|
59234
|
+
"return",
|
|
59235
|
+
"satisfies",
|
|
59236
|
+
"set",
|
|
59237
|
+
"static",
|
|
59238
|
+
"super",
|
|
59239
|
+
"switch",
|
|
59240
|
+
"throw",
|
|
59241
|
+
"try",
|
|
59242
|
+
"type",
|
|
59243
|
+
"typeof",
|
|
59244
|
+
"using",
|
|
59245
|
+
"var",
|
|
59246
|
+
"void",
|
|
59247
|
+
"while",
|
|
59248
|
+
"with",
|
|
59249
|
+
"yield"
|
|
59250
|
+
]);
|
|
59251
|
+
const TS_CONSTANTS = /* @__PURE__ */ new Set([
|
|
59252
|
+
"true",
|
|
59253
|
+
"false",
|
|
59254
|
+
"null",
|
|
59255
|
+
"undefined",
|
|
59256
|
+
"NaN",
|
|
59257
|
+
"Infinity",
|
|
59258
|
+
"this",
|
|
59259
|
+
"globalThis",
|
|
59260
|
+
"console",
|
|
59261
|
+
"Promise",
|
|
59262
|
+
"Math",
|
|
59263
|
+
"JSON",
|
|
59264
|
+
"Object",
|
|
59265
|
+
"Array",
|
|
59266
|
+
"Map",
|
|
59267
|
+
"Set",
|
|
59268
|
+
"RegExp",
|
|
59269
|
+
"Error",
|
|
59270
|
+
"String",
|
|
59271
|
+
"Number",
|
|
59272
|
+
"Boolean",
|
|
59273
|
+
"Buffer",
|
|
59274
|
+
"process"
|
|
59275
|
+
]);
|
|
59276
|
+
const PY_KEYWORDS = /* @__PURE__ */ new Set([
|
|
59277
|
+
"and",
|
|
59278
|
+
"as",
|
|
59279
|
+
"assert",
|
|
59280
|
+
"async",
|
|
59281
|
+
"await",
|
|
59282
|
+
"break",
|
|
59283
|
+
"class",
|
|
59284
|
+
"continue",
|
|
59285
|
+
"def",
|
|
59286
|
+
"del",
|
|
59287
|
+
"elif",
|
|
59288
|
+
"else",
|
|
59289
|
+
"except",
|
|
59290
|
+
"finally",
|
|
59291
|
+
"for",
|
|
59292
|
+
"from",
|
|
59293
|
+
"global",
|
|
59294
|
+
"if",
|
|
59295
|
+
"import",
|
|
59296
|
+
"in",
|
|
59297
|
+
"is",
|
|
59298
|
+
"lambda",
|
|
59299
|
+
"match",
|
|
59300
|
+
"nonlocal",
|
|
59301
|
+
"not",
|
|
59302
|
+
"or",
|
|
59303
|
+
"pass",
|
|
59304
|
+
"raise",
|
|
59305
|
+
"return",
|
|
59306
|
+
"try",
|
|
59307
|
+
"while",
|
|
59308
|
+
"with",
|
|
59309
|
+
"yield"
|
|
59310
|
+
]);
|
|
59311
|
+
const PY_CONSTANTS = /* @__PURE__ */ new Set([
|
|
59312
|
+
"True",
|
|
59313
|
+
"False",
|
|
59314
|
+
"None",
|
|
59315
|
+
"self",
|
|
59316
|
+
"cls",
|
|
59317
|
+
"Ellipsis",
|
|
59318
|
+
"NotImplemented"
|
|
59319
|
+
]);
|
|
59320
|
+
/** 允许紧跟正则表达式字面量的前置关键字。 */
|
|
59321
|
+
const REGEX_PRECEDING_KEYWORDS = /* @__PURE__ */ new Set([
|
|
59322
|
+
"return",
|
|
59323
|
+
"throw",
|
|
59324
|
+
"case",
|
|
59325
|
+
"in",
|
|
59326
|
+
"of",
|
|
59327
|
+
"typeof",
|
|
59328
|
+
"instanceof",
|
|
59329
|
+
"void",
|
|
59330
|
+
"delete",
|
|
59331
|
+
"new",
|
|
59332
|
+
"yield",
|
|
59333
|
+
"await"
|
|
59334
|
+
]);
|
|
59335
|
+
/** 允许紧跟正则表达式字面量的末尾标点字符。 */
|
|
59336
|
+
const REGEX_PRECEDING_PUNCT = /* @__PURE__ */ new Set([
|
|
59337
|
+
"(",
|
|
59338
|
+
"[",
|
|
59339
|
+
"{",
|
|
59340
|
+
",",
|
|
59341
|
+
";",
|
|
59342
|
+
":",
|
|
59343
|
+
"=",
|
|
59344
|
+
"!",
|
|
59345
|
+
"?",
|
|
59346
|
+
"&",
|
|
59347
|
+
"|",
|
|
59348
|
+
"^",
|
|
59349
|
+
"~",
|
|
59350
|
+
"+",
|
|
59351
|
+
"-",
|
|
59352
|
+
"*",
|
|
59353
|
+
"%",
|
|
59354
|
+
"<",
|
|
59355
|
+
">"
|
|
59356
|
+
]);
|
|
59357
|
+
/**
|
|
59358
|
+
* 将完整源码切分为带颜色类别的跨行数组(每个子数组代表源码的一行)。
|
|
59359
|
+
*/
|
|
59360
|
+
function tokenizeCodeLines(code, language = "typescript") {
|
|
59361
|
+
const normalized = code.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
59362
|
+
const trimmed = normalized.endsWith("\n") ? normalized.slice(0, -1) : normalized;
|
|
59363
|
+
if (trimmed.length === 0) return [[{
|
|
59364
|
+
text: "",
|
|
59365
|
+
kind: "plain"
|
|
59366
|
+
}]];
|
|
59367
|
+
if (trimmed.length > MAX_HIGHLIGHT_CHARS) return trimmed.split("\n").map((line) => [{
|
|
59368
|
+
text: line,
|
|
59369
|
+
kind: "plain"
|
|
59370
|
+
}]);
|
|
59371
|
+
return splitTokensIntoLines(language === "python" ? scanPython(trimmed) : scanTypeScript(trimmed));
|
|
59372
|
+
}
|
|
59373
|
+
function pushToken(out, text, kind) {
|
|
59374
|
+
if (text.length === 0) return;
|
|
59375
|
+
const prev = out[out.length - 1];
|
|
59376
|
+
if (prev !== void 0 && prev.kind === kind) {
|
|
59377
|
+
out[out.length - 1] = {
|
|
59378
|
+
text: prev.text + text,
|
|
59379
|
+
kind
|
|
59380
|
+
};
|
|
59381
|
+
return;
|
|
59382
|
+
}
|
|
59383
|
+
out.push({
|
|
59384
|
+
text,
|
|
59385
|
+
kind
|
|
59386
|
+
});
|
|
59387
|
+
}
|
|
59388
|
+
function splitTokensIntoLines(tokens) {
|
|
59389
|
+
const lines = [[]];
|
|
59390
|
+
for (const token of tokens) {
|
|
59391
|
+
const parts = token.text.split("\n");
|
|
59392
|
+
for (let index = 0; index < parts.length; index += 1) {
|
|
59393
|
+
if (index > 0) lines.push([]);
|
|
59394
|
+
const part = parts[index];
|
|
59395
|
+
if (part.length > 0) lines[lines.length - 1].push({
|
|
59396
|
+
text: part,
|
|
59397
|
+
kind: token.kind
|
|
59398
|
+
});
|
|
59399
|
+
}
|
|
59400
|
+
}
|
|
59401
|
+
return lines;
|
|
59402
|
+
}
|
|
59403
|
+
function isIdentStart(ch) {
|
|
59404
|
+
return ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch === 95 || ch === 36 || ch > 127;
|
|
59405
|
+
}
|
|
59406
|
+
function isIdentPart(ch) {
|
|
59407
|
+
return isIdentStart(ch) || ch >= 48 && ch <= 57;
|
|
59408
|
+
}
|
|
59409
|
+
function isDigit(ch) {
|
|
59410
|
+
return ch >= 48 && ch <= 57;
|
|
59411
|
+
}
|
|
59412
|
+
function skipWhitespaceLookahead(src, from) {
|
|
59413
|
+
let pos = from;
|
|
59414
|
+
while (pos < src.length) {
|
|
59415
|
+
const ch = src.charCodeAt(pos);
|
|
59416
|
+
if (ch === 32 || ch === 9) pos += 1;
|
|
59417
|
+
else break;
|
|
59418
|
+
}
|
|
59419
|
+
return pos;
|
|
59420
|
+
}
|
|
59421
|
+
function scanNumber(src, start) {
|
|
59422
|
+
let i = start;
|
|
59423
|
+
if (src[i] === "0" && i + 1 < src.length && /[xXbBoO]/.test(src[i + 1])) {
|
|
59424
|
+
i += 2;
|
|
59425
|
+
while (i < src.length && /[0-9a-fA-F_]/.test(src[i])) i += 1;
|
|
59426
|
+
if (src[i] === "n") i += 1;
|
|
59427
|
+
return i;
|
|
59428
|
+
}
|
|
59429
|
+
while (i < src.length && (isDigit(src.charCodeAt(i)) || src[i] === "_")) i += 1;
|
|
59430
|
+
if (src[i] === "." && i + 1 < src.length && isDigit(src.charCodeAt(i + 1))) {
|
|
59431
|
+
i += 1;
|
|
59432
|
+
while (i < src.length && (isDigit(src.charCodeAt(i)) || src[i] === "_")) i += 1;
|
|
59433
|
+
}
|
|
59434
|
+
if (i < src.length && (src[i] === "e" || src[i] === "E")) {
|
|
59435
|
+
let next = i + 1;
|
|
59436
|
+
if (src[next] === "+" || src[next] === "-") next += 1;
|
|
59437
|
+
if (next < src.length && isDigit(src.charCodeAt(next))) {
|
|
59438
|
+
i = next + 1;
|
|
59439
|
+
while (i < src.length && (isDigit(src.charCodeAt(i)) || src[i] === "_")) i += 1;
|
|
59440
|
+
}
|
|
59441
|
+
}
|
|
59442
|
+
if (src[i] === "n") i += 1;
|
|
59443
|
+
return i;
|
|
59444
|
+
}
|
|
59445
|
+
/**
|
|
59446
|
+
* 尝试从 `start`(`src[start] === '/'`)扫描单行正则表达式字面量;不合法时返回 -1。
|
|
59447
|
+
*/
|
|
59448
|
+
function tryScanRegexLiteral(src, start) {
|
|
59449
|
+
let i = start + 1;
|
|
59450
|
+
let inCharClass = false;
|
|
59451
|
+
if (i >= src.length || src[i] === "\n") return -1;
|
|
59452
|
+
while (i < src.length) {
|
|
59453
|
+
const ch = src[i];
|
|
59454
|
+
if (ch === "\n") return -1;
|
|
59455
|
+
if (ch === "\\") {
|
|
59456
|
+
if (i + 1 >= src.length || src[i + 1] === "\n") return -1;
|
|
59457
|
+
i += 2;
|
|
59458
|
+
continue;
|
|
59459
|
+
}
|
|
59460
|
+
if (ch === "[") {
|
|
59461
|
+
inCharClass = true;
|
|
59462
|
+
i += 1;
|
|
59463
|
+
continue;
|
|
59464
|
+
}
|
|
59465
|
+
if (ch === "]") {
|
|
59466
|
+
inCharClass = false;
|
|
59467
|
+
i += 1;
|
|
59468
|
+
continue;
|
|
59469
|
+
}
|
|
59470
|
+
if (ch === "/" && !inCharClass) {
|
|
59471
|
+
i += 1;
|
|
59472
|
+
while (i < src.length && /[dgimsuvy]/.test(src[i])) i += 1;
|
|
59473
|
+
return i;
|
|
59474
|
+
}
|
|
59475
|
+
i += 1;
|
|
59476
|
+
}
|
|
59477
|
+
return -1;
|
|
59478
|
+
}
|
|
59479
|
+
function scanTypeScript(src) {
|
|
59480
|
+
const tokens = [];
|
|
59481
|
+
/** 模板字符串 `${ ... }` 嵌套栈:记录每一层尚未闭合的左花括号深度。 */
|
|
59482
|
+
const templateBraceStack = [];
|
|
59483
|
+
let canStartRegex = true;
|
|
59484
|
+
let i = 0;
|
|
59485
|
+
const scanTemplateBody = (from) => {
|
|
59486
|
+
let pos = from;
|
|
59487
|
+
let segStart = pos;
|
|
59488
|
+
while (pos < src.length) {
|
|
59489
|
+
const ch = src[pos];
|
|
59490
|
+
if (ch === "\\") {
|
|
59491
|
+
pos = Math.min(src.length, pos + 2);
|
|
59492
|
+
continue;
|
|
59493
|
+
}
|
|
59494
|
+
if (ch === "`") {
|
|
59495
|
+
pushToken(tokens, src.slice(segStart, pos + 1), "string");
|
|
59496
|
+
canStartRegex = false;
|
|
59497
|
+
return pos + 1;
|
|
59498
|
+
}
|
|
59499
|
+
if (ch === "$" && src[pos + 1] === "{") {
|
|
59500
|
+
if (pos > segStart) pushToken(tokens, src.slice(segStart, pos), "string");
|
|
59501
|
+
pushToken(tokens, "${", "punctuation");
|
|
59502
|
+
templateBraceStack.push(0);
|
|
59503
|
+
canStartRegex = true;
|
|
59504
|
+
return pos + 2;
|
|
59505
|
+
}
|
|
59506
|
+
pos += 1;
|
|
59507
|
+
}
|
|
59508
|
+
pushToken(tokens, src.slice(segStart), "string");
|
|
59509
|
+
canStartRegex = false;
|
|
59510
|
+
return pos;
|
|
59511
|
+
};
|
|
59512
|
+
while (i < src.length) {
|
|
59513
|
+
const ch = src[i];
|
|
59514
|
+
const code = src.charCodeAt(i);
|
|
59515
|
+
if (ch === " " || ch === " " || ch === "\n") {
|
|
59516
|
+
let end = i + 1;
|
|
59517
|
+
while (end < src.length && (src[end] === " " || src[end] === " " || src[end] === "\n")) end += 1;
|
|
59518
|
+
pushToken(tokens, src.slice(i, end), "plain");
|
|
59519
|
+
i = end;
|
|
59520
|
+
continue;
|
|
59521
|
+
}
|
|
59522
|
+
if (ch === "/" && src[i + 1] === "/") {
|
|
59523
|
+
const nl = src.indexOf("\n", i + 2);
|
|
59524
|
+
const end = nl === -1 ? src.length : nl;
|
|
59525
|
+
pushToken(tokens, src.slice(i, end), "comment");
|
|
59526
|
+
i = end;
|
|
59527
|
+
continue;
|
|
59528
|
+
}
|
|
59529
|
+
if (ch === "/" && src[i + 1] === "*") {
|
|
59530
|
+
const close = src.indexOf("*/", i + 2);
|
|
59531
|
+
const end = close === -1 ? src.length : close + 2;
|
|
59532
|
+
pushToken(tokens, src.slice(i, end), "comment");
|
|
59533
|
+
i = end;
|
|
59534
|
+
continue;
|
|
59535
|
+
}
|
|
59536
|
+
if (ch === "/" && canStartRegex) {
|
|
59537
|
+
const regexEnd = tryScanRegexLiteral(src, i);
|
|
59538
|
+
if (regexEnd > i) {
|
|
59539
|
+
pushToken(tokens, src.slice(i, regexEnd), "string-expression");
|
|
59540
|
+
canStartRegex = false;
|
|
59541
|
+
i = regexEnd;
|
|
59542
|
+
continue;
|
|
59543
|
+
}
|
|
59544
|
+
}
|
|
59545
|
+
if (ch === "\"" || ch === "'") {
|
|
59546
|
+
let end = i + 1;
|
|
59547
|
+
while (end < src.length) {
|
|
59548
|
+
const c = src[end];
|
|
59549
|
+
if (c === "\\") {
|
|
59550
|
+
end = Math.min(src.length, end + 2);
|
|
59551
|
+
continue;
|
|
59552
|
+
}
|
|
59553
|
+
end += 1;
|
|
59554
|
+
if (c === ch || c === "\n") break;
|
|
59555
|
+
}
|
|
59556
|
+
pushToken(tokens, src.slice(i, end), "string");
|
|
59557
|
+
canStartRegex = false;
|
|
59558
|
+
i = end;
|
|
59559
|
+
continue;
|
|
59560
|
+
}
|
|
59561
|
+
if (ch === "`") {
|
|
59562
|
+
pushToken(tokens, "`", "string");
|
|
59563
|
+
i = scanTemplateBody(i + 1);
|
|
59564
|
+
continue;
|
|
59565
|
+
}
|
|
59566
|
+
if (ch === "{" && templateBraceStack.length > 0) {
|
|
59567
|
+
templateBraceStack[templateBraceStack.length - 1] += 1;
|
|
59568
|
+
pushToken(tokens, "{", "punctuation");
|
|
59569
|
+
canStartRegex = true;
|
|
59570
|
+
i += 1;
|
|
59571
|
+
continue;
|
|
59572
|
+
}
|
|
59573
|
+
if (ch === "}" && templateBraceStack.length > 0) {
|
|
59574
|
+
const top = templateBraceStack[templateBraceStack.length - 1];
|
|
59575
|
+
if (top === 0) {
|
|
59576
|
+
templateBraceStack.pop();
|
|
59577
|
+
pushToken(tokens, "}", "punctuation");
|
|
59578
|
+
i = scanTemplateBody(i + 1);
|
|
59579
|
+
continue;
|
|
59580
|
+
}
|
|
59581
|
+
templateBraceStack[templateBraceStack.length - 1] = top - 1;
|
|
59582
|
+
pushToken(tokens, "}", "punctuation");
|
|
59583
|
+
canStartRegex = false;
|
|
59584
|
+
i += 1;
|
|
59585
|
+
continue;
|
|
59586
|
+
}
|
|
59587
|
+
if (isDigit(code) || ch === "." && i + 1 < src.length && isDigit(src.charCodeAt(i + 1))) {
|
|
59588
|
+
const end = scanNumber(src, i);
|
|
59589
|
+
pushToken(tokens, src.slice(i, end), "constant");
|
|
59590
|
+
canStartRegex = false;
|
|
59591
|
+
i = end;
|
|
59592
|
+
continue;
|
|
59593
|
+
}
|
|
59594
|
+
if (isIdentStart(code)) {
|
|
59595
|
+
let end = i + 1;
|
|
59596
|
+
while (end < src.length && isIdentPart(src.charCodeAt(end))) end += 1;
|
|
59597
|
+
const word = src.slice(i, end);
|
|
59598
|
+
let prevNonSpace = i - 1;
|
|
59599
|
+
while (prevNonSpace >= 0 && (src[prevNonSpace] === " " || src[prevNonSpace] === " ")) prevNonSpace -= 1;
|
|
59600
|
+
const afterDot = prevNonSpace >= 0 && (src[prevNonSpace] === "." || src[prevNonSpace] === "?");
|
|
59601
|
+
const beforeCall = src[skipWhitespaceLookahead(src, end)] === "(";
|
|
59602
|
+
if (!afterDot && TS_KEYWORDS.has(word)) {
|
|
59603
|
+
pushToken(tokens, word, "keyword");
|
|
59604
|
+
canStartRegex = REGEX_PRECEDING_KEYWORDS.has(word);
|
|
59605
|
+
} else if (!afterDot && TS_CONSTANTS.has(word)) {
|
|
59606
|
+
pushToken(tokens, word, "constant");
|
|
59607
|
+
canStartRegex = false;
|
|
59608
|
+
} else if (beforeCall) {
|
|
59609
|
+
pushToken(tokens, word, "function");
|
|
59610
|
+
canStartRegex = false;
|
|
59611
|
+
} else if (/^[A-Z][A-Z0-9_]{2,}$/.test(word)) {
|
|
59612
|
+
pushToken(tokens, word, "constant");
|
|
59613
|
+
canStartRegex = false;
|
|
59614
|
+
} else {
|
|
59615
|
+
pushToken(tokens, word, "plain");
|
|
59616
|
+
canStartRegex = false;
|
|
59617
|
+
}
|
|
59618
|
+
i = end;
|
|
59619
|
+
continue;
|
|
59620
|
+
}
|
|
59621
|
+
if (ch === "@" && i + 1 < src.length && isIdentStart(src.charCodeAt(i + 1))) {
|
|
59622
|
+
let end = i + 2;
|
|
59623
|
+
while (end < src.length && isIdentPart(src.charCodeAt(end))) end += 1;
|
|
59624
|
+
pushToken(tokens, src.slice(i, end), "function");
|
|
59625
|
+
canStartRegex = false;
|
|
59626
|
+
i = end;
|
|
59627
|
+
continue;
|
|
59628
|
+
}
|
|
59629
|
+
pushToken(tokens, ch, "punctuation");
|
|
59630
|
+
canStartRegex = REGEX_PRECEDING_PUNCT.has(ch);
|
|
59631
|
+
i += 1;
|
|
59632
|
+
}
|
|
59633
|
+
return tokens;
|
|
59634
|
+
}
|
|
59635
|
+
function scanPython(src) {
|
|
59636
|
+
const tokens = [];
|
|
59637
|
+
let i = 0;
|
|
59638
|
+
while (i < src.length) {
|
|
59639
|
+
const ch = src[i];
|
|
59640
|
+
const code = src.charCodeAt(i);
|
|
59641
|
+
if (ch === " " || ch === " " || ch === "\n") {
|
|
59642
|
+
let end = i + 1;
|
|
59643
|
+
while (end < src.length && (src[end] === " " || src[end] === " " || src[end] === "\n")) end += 1;
|
|
59644
|
+
pushToken(tokens, src.slice(i, end), "plain");
|
|
59645
|
+
i = end;
|
|
59646
|
+
continue;
|
|
59647
|
+
}
|
|
59648
|
+
if (ch === "#") {
|
|
59649
|
+
const nl = src.indexOf("\n", i + 1);
|
|
59650
|
+
const end = nl === -1 ? src.length : nl;
|
|
59651
|
+
pushToken(tokens, src.slice(i, end), "comment");
|
|
59652
|
+
i = end;
|
|
59653
|
+
continue;
|
|
59654
|
+
}
|
|
59655
|
+
let strStart = i;
|
|
59656
|
+
if (/[rRfFbBuU]/.test(ch)) {
|
|
59657
|
+
let p = i + 1;
|
|
59658
|
+
if (p < src.length && /[rRfFbBuU]/.test(src[p])) p += 1;
|
|
59659
|
+
if (src[p] === "\"" || src[p] === "'") strStart = p;
|
|
59660
|
+
}
|
|
59661
|
+
if (src[strStart] === "\"" || src[strStart] === "'") {
|
|
59662
|
+
const quote = src[strStart];
|
|
59663
|
+
const triple = src[strStart + 1] === quote && src[strStart + 2] === quote;
|
|
59664
|
+
const delim = triple ? quote.repeat(3) : quote;
|
|
59665
|
+
let end = strStart + delim.length;
|
|
59666
|
+
while (end < src.length) {
|
|
59667
|
+
if (src[end] === "\\") {
|
|
59668
|
+
end = Math.min(src.length, end + 2);
|
|
59669
|
+
continue;
|
|
59670
|
+
}
|
|
59671
|
+
if (triple && src.startsWith(delim, end)) {
|
|
59672
|
+
end += 3;
|
|
59673
|
+
break;
|
|
59674
|
+
}
|
|
59675
|
+
if (!triple && (src[end] === quote || src[end] === "\n")) {
|
|
59676
|
+
if (src[end] === quote) end += 1;
|
|
59677
|
+
break;
|
|
59678
|
+
}
|
|
59679
|
+
end += 1;
|
|
59680
|
+
}
|
|
59681
|
+
pushToken(tokens, src.slice(i, end), "string");
|
|
59682
|
+
i = end;
|
|
59683
|
+
continue;
|
|
59684
|
+
}
|
|
59685
|
+
if (isDigit(code) || ch === "." && i + 1 < src.length && isDigit(src.charCodeAt(i + 1))) {
|
|
59686
|
+
const end = scanNumber(src, i);
|
|
59687
|
+
pushToken(tokens, src.slice(i, end), "constant");
|
|
59688
|
+
i = end;
|
|
59689
|
+
continue;
|
|
59690
|
+
}
|
|
59691
|
+
if (isIdentStart(code)) {
|
|
59692
|
+
let end = i + 1;
|
|
59693
|
+
while (end < src.length && isIdentPart(src.charCodeAt(end))) end += 1;
|
|
59694
|
+
const word = src.slice(i, end);
|
|
59695
|
+
let prevNonSpace = i - 1;
|
|
59696
|
+
while (prevNonSpace >= 0 && (src[prevNonSpace] === " " || src[prevNonSpace] === " ")) prevNonSpace -= 1;
|
|
59697
|
+
const afterDot = prevNonSpace >= 0 && src[prevNonSpace] === ".";
|
|
59698
|
+
const beforeCall = src[skipWhitespaceLookahead(src, end)] === "(";
|
|
59699
|
+
if (!afterDot && PY_KEYWORDS.has(word)) pushToken(tokens, word, "keyword");
|
|
59700
|
+
else if (!afterDot && PY_CONSTANTS.has(word)) pushToken(tokens, word, "constant");
|
|
59701
|
+
else if (beforeCall) pushToken(tokens, word, "function");
|
|
59702
|
+
else pushToken(tokens, word, "plain");
|
|
59703
|
+
i = end;
|
|
59704
|
+
continue;
|
|
59705
|
+
}
|
|
59706
|
+
if (ch === "@" && i + 1 < src.length && isIdentStart(src.charCodeAt(i + 1))) {
|
|
59707
|
+
let end = i + 2;
|
|
59708
|
+
while (end < src.length && isIdentPart(src.charCodeAt(end))) end += 1;
|
|
59709
|
+
pushToken(tokens, src.slice(i, end), "function");
|
|
59710
|
+
i = end;
|
|
59711
|
+
continue;
|
|
59712
|
+
}
|
|
59713
|
+
pushToken(tokens, ch, "punctuation");
|
|
59714
|
+
i += 1;
|
|
59715
|
+
}
|
|
59716
|
+
return tokens;
|
|
59717
|
+
}
|
|
59718
|
+
//#endregion
|
|
59719
|
+
//#region src/client/codemode/CodeRunToolView.tsx
|
|
59720
|
+
/**
|
|
59721
|
+
* `code_run` 在对话流中的语法高亮工具行组件 —— 对齐宿主内置 PTC `run_code` 的呈现体验。
|
|
59722
|
+
*
|
|
59723
|
+
* ## 与宿主 `run_code` 一致的四点设计
|
|
59724
|
+
*
|
|
59725
|
+
* 1. **标题行**:代码图标 `</>` + 本地化标题「代码 / Code」+ `description` 摘要(不再出现
|
|
59726
|
+
* `工具 · code_run · ...`),直接接入框架传入的 `useDisclosure` 控制展开/收起;
|
|
59727
|
+
* 2. **源码区**:提取 `args.code` 纯源码文本(剥离外层 JSON 参数包装),提供语言标识
|
|
59728
|
+
* (`typescript` / `python`)、自动换行切换与一键复制源码按钮,并使用宿主 `--shiki-*`
|
|
59729
|
+
* 主题色进行语法高亮;
|
|
59730
|
+
* 3. **输出区**:已结算结果独立展示在下方 `输出` 卡片中(无结果文本时不画空卡片),子调用由外层
|
|
59731
|
+
* `ToolCallTree` 通过 `tool/ptc-dispatch` 自动挂载在本行下方;
|
|
59732
|
+
* 4. **三阶段支持**:覆盖 `preparing`(流式生成参数)、`start`(执行中)与 `result`(成功/失败/停止)。
|
|
59733
|
+
*
|
|
59734
|
+
* @module @eddyskywalker/dsh-chatgpt-subscription/client/codemode/CodeRunToolView
|
|
59735
|
+
*/
|
|
59736
|
+
function fallbackTranslate(key) {
|
|
59737
|
+
return zh$2[key] ?? key;
|
|
59738
|
+
}
|
|
59739
|
+
function firstLine(text) {
|
|
59740
|
+
const nl = text.indexOf("\n");
|
|
59741
|
+
return nl === -1 ? text : text.slice(0, nl);
|
|
59742
|
+
}
|
|
59743
|
+
function rawArgsOf(block) {
|
|
59744
|
+
if (typeof block.argsRaw === "string" && block.argsRaw !== "") return block.argsRaw;
|
|
59745
|
+
if (typeof block.call?.argsRaw === "string" && block.call.argsRaw !== "") return block.call.argsRaw;
|
|
59746
|
+
}
|
|
59747
|
+
function parseArgsObject(raw) {
|
|
59748
|
+
if (raw === void 0 || raw === "") return void 0;
|
|
59749
|
+
try {
|
|
59750
|
+
const parsed = JSON.parse(raw);
|
|
59751
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) return parsed;
|
|
59752
|
+
return;
|
|
59753
|
+
} catch {
|
|
59754
|
+
return;
|
|
59755
|
+
}
|
|
59756
|
+
}
|
|
59757
|
+
/** 从流式参数视图或完整 JSON 中读取字段(与 `ProgressRow` / `MinimaxVideoToolView` 一致)。 */
|
|
59758
|
+
function extractCodeRunArgs(block) {
|
|
59759
|
+
let streamCode;
|
|
59760
|
+
let streamDesc;
|
|
59761
|
+
const readText = block.args?.text;
|
|
59762
|
+
if (typeof readText === "function") {
|
|
59763
|
+
try {
|
|
59764
|
+
const c = readText.call(block.args, "code");
|
|
59765
|
+
if (typeof c === "string" && c !== "") streamCode = c;
|
|
59766
|
+
} catch {}
|
|
59767
|
+
try {
|
|
59768
|
+
const d = readText.call(block.args, "description");
|
|
59769
|
+
if (typeof d === "string" && d !== "") streamDesc = d;
|
|
59770
|
+
} catch {}
|
|
59771
|
+
}
|
|
59772
|
+
const raw = rawArgsOf(block);
|
|
59773
|
+
const parsed = parseArgsObject(raw);
|
|
59774
|
+
const jsonCode = typeof parsed?.["code"] === "string" && parsed["code"] !== "" ? parsed["code"] : void 0;
|
|
59775
|
+
const jsonDesc = typeof parsed?.["description"] === "string" && parsed["description"] !== "" ? parsed["description"] : void 0;
|
|
59776
|
+
const code = jsonCode ?? streamCode ?? null;
|
|
59777
|
+
return {
|
|
59778
|
+
code,
|
|
59779
|
+
description: firstLine(jsonDesc ?? streamDesc ?? ""),
|
|
59780
|
+
rawFallback: code === null && raw !== void 0 ? raw : null
|
|
59781
|
+
};
|
|
59782
|
+
}
|
|
59783
|
+
/** 展平已结算结果的内容块(对齐宿主 `resultText`)。 */
|
|
59784
|
+
function flattenCodeRunOutput(block) {
|
|
59785
|
+
if (block.kind === void 0) return null;
|
|
59786
|
+
const parts = [];
|
|
59787
|
+
for (const item of block.content ?? []) if (item.type === "text" && typeof item.text === "string") parts.push(item.text);
|
|
59788
|
+
else try {
|
|
59789
|
+
parts.push(JSON.stringify(item, null, 2));
|
|
59790
|
+
} catch {
|
|
59791
|
+
parts.push(String(item));
|
|
59792
|
+
}
|
|
59793
|
+
if (parts.length === 0 && block.error !== void 0) {
|
|
59794
|
+
const errName = block.error.name ?? "Error";
|
|
59795
|
+
const errCode = block.error.code ?? "UNKNOWN";
|
|
59796
|
+
parts.push(`${errName}: ${errCode}`);
|
|
59797
|
+
}
|
|
59798
|
+
const joined = parts.join("\n");
|
|
59799
|
+
return joined === "" ? null : joined;
|
|
59800
|
+
}
|
|
59801
|
+
function resolveLanguage(meta) {
|
|
59802
|
+
if (typeof meta === "object" && meta !== null && !Array.isArray(meta)) {
|
|
59803
|
+
if (meta["language"] === "python") return "python";
|
|
59804
|
+
}
|
|
59805
|
+
return "typescript";
|
|
59806
|
+
}
|
|
59807
|
+
function resolveState(phase, block) {
|
|
59808
|
+
if (!(block.kind !== void 0 || phase === "result")) return block.phase === "preparing" || phase === "preparing" ? "preparing" : "running";
|
|
59809
|
+
if (block.error?.code === "interrupted") return "stopped";
|
|
59810
|
+
const stopped = typeof block.meta === "object" && block.meta !== null && !Array.isArray(block.meta) && block.meta["stopped"] === true;
|
|
59811
|
+
if (block.isError === true || stopped) return "error";
|
|
59812
|
+
return "ok";
|
|
59813
|
+
}
|
|
59814
|
+
async function copyTextToClipboard(text) {
|
|
59815
|
+
try {
|
|
59816
|
+
if (typeof navigator !== "undefined" && typeof navigator.clipboard?.writeText === "function") {
|
|
59817
|
+
await navigator.clipboard.writeText(text);
|
|
59818
|
+
return true;
|
|
59819
|
+
}
|
|
59820
|
+
} catch {}
|
|
59821
|
+
if (typeof document === "undefined") return false;
|
|
59822
|
+
try {
|
|
59823
|
+
const textarea = document.createElement("textarea");
|
|
59824
|
+
textarea.value = text;
|
|
59825
|
+
textarea.setAttribute("readonly", "true");
|
|
59826
|
+
textarea.style.position = "fixed";
|
|
59827
|
+
textarea.style.opacity = "0";
|
|
59828
|
+
document.body.appendChild(textarea);
|
|
59829
|
+
textarea.select();
|
|
59830
|
+
const ok = document.execCommand("copy");
|
|
59831
|
+
document.body.removeChild(textarea);
|
|
59832
|
+
return ok;
|
|
59833
|
+
} catch {
|
|
59834
|
+
return false;
|
|
59835
|
+
}
|
|
59836
|
+
}
|
|
59837
|
+
function useFallbackDisclosure() {
|
|
59838
|
+
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
59839
|
+
return {
|
|
59840
|
+
expanded,
|
|
59841
|
+
toggle: (0, react.useCallback)(() => {
|
|
59842
|
+
setExpanded((prev) => !prev);
|
|
59843
|
+
}, [])
|
|
59844
|
+
};
|
|
59845
|
+
}
|
|
59846
|
+
function CodeRunToolView(props) {
|
|
59847
|
+
const { block, phase, inspect, useDisclosure } = props;
|
|
59848
|
+
const t = props.t ?? fallbackTranslate;
|
|
59849
|
+
const { expanded, toggle } = (useDisclosure ?? useFallbackDisclosure)();
|
|
59850
|
+
const [wrapped, setWrapped] = (0, react.useState)(true);
|
|
59851
|
+
const [copied, setCopied] = (0, react.useState)(false);
|
|
59852
|
+
const state = resolveState(phase, block);
|
|
59853
|
+
const { code, description, rawFallback } = (0, react.useMemo)(() => extractCodeRunArgs(block), [block]);
|
|
59854
|
+
const outputText = (0, react.useMemo)(() => flattenCodeRunOutput(block), [block]);
|
|
59855
|
+
const language = (0, react.useMemo)(() => resolveLanguage(block.meta), [block.meta]);
|
|
59856
|
+
const sourceText = code ?? rawFallback;
|
|
59857
|
+
const expandable = state !== "preparing" && (sourceText !== null || outputText !== null);
|
|
59858
|
+
const open = expanded && expandable;
|
|
59859
|
+
const running = state === "preparing" || state === "running";
|
|
59860
|
+
const summaryText = (state === "error" && outputText !== null ? firstLine(outputText) : null) ?? (description !== "" ? description : block.callId ?? "");
|
|
59861
|
+
const highlightedLines = (0, react.useMemo)(() => open && sourceText !== null ? tokenizeCodeLines(sourceText, language) : null, [
|
|
59862
|
+
open,
|
|
59863
|
+
sourceText,
|
|
59864
|
+
language
|
|
59865
|
+
]);
|
|
59866
|
+
const onCopy = (0, react.useCallback)(() => {
|
|
59867
|
+
if (copied || sourceText === null) return;
|
|
59868
|
+
copyTextToClipboard(sourceText.endsWith("\n") ? sourceText.slice(0, -1) : sourceText).then((ok) => {
|
|
59869
|
+
if (!ok) return;
|
|
59870
|
+
setCopied(true);
|
|
59871
|
+
setTimeout(() => {
|
|
59872
|
+
setCopied(false);
|
|
59873
|
+
}, 1e3);
|
|
59874
|
+
});
|
|
59875
|
+
}, [copied, sourceText]);
|
|
59876
|
+
const onRowKeyDown = (0, react.useCallback)((event) => {
|
|
59877
|
+
if (!expandable || event.key !== "Enter" && event.key !== " ") return;
|
|
59878
|
+
event.preventDefault();
|
|
59879
|
+
toggle();
|
|
59880
|
+
}, [expandable, toggle]);
|
|
59881
|
+
const a11yStatus = state === "preparing" ? t("codeRunPreparing") : state === "running" ? t("codeRunRunning") : state === "error" ? t("codeRunFailed") : state === "stopped" ? t("codeRunStopped") : null;
|
|
59882
|
+
const wrapLabel = wrapped ? t("codeRunUnwrap") : t("codeRunWrap");
|
|
59883
|
+
const copyLabel = copied ? t("codeRunCopied") : t("codeRunCopy");
|
|
59884
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
59885
|
+
className: "dshc-code-root",
|
|
59886
|
+
"data-variant": "code",
|
|
59887
|
+
"data-tool": props.toolName ?? "code_run",
|
|
59888
|
+
"data-state": state,
|
|
59889
|
+
children: [
|
|
59890
|
+
a11yStatus !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
59891
|
+
className: "dshc-code-visually-hidden",
|
|
59892
|
+
children: a11yStatus
|
|
59893
|
+
}),
|
|
59894
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
59895
|
+
className: "dshc-code-header",
|
|
59896
|
+
"data-disclosure-header": true,
|
|
59897
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
59898
|
+
className: "dshc-code-row",
|
|
59899
|
+
"data-disclosure-row": true,
|
|
59900
|
+
"data-expandable": expandable ? "true" : void 0,
|
|
59901
|
+
role: expandable ? "button" : void 0,
|
|
59902
|
+
tabIndex: expandable ? 0 : void 0,
|
|
59903
|
+
"aria-expanded": expandable ? open : void 0,
|
|
59904
|
+
onClick: expandable ? toggle : void 0,
|
|
59905
|
+
onKeyDown: expandable ? onRowKeyDown : void 0,
|
|
59906
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
59907
|
+
className: "dshc-code-leading",
|
|
59908
|
+
"aria-hidden": "true",
|
|
59909
|
+
children: open ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronUpIcon, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
59910
|
+
className: "dshc-code-icon-idle",
|
|
59911
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeGlyphIcon, {})
|
|
59912
|
+
}), expandable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
59913
|
+
className: "dshc-code-chevron-hover",
|
|
59914
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronDownIcon, {})
|
|
59915
|
+
})] })
|
|
59916
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
59917
|
+
className: "dshc-code-text-flow",
|
|
59918
|
+
"data-running": running ? "true" : void 0,
|
|
59919
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
59920
|
+
className: "dshc-code-title",
|
|
59921
|
+
children: t("codeRunTitle")
|
|
59922
|
+
}), summaryText !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
59923
|
+
className: "dshc-code-sep",
|
|
59924
|
+
"aria-hidden": "true"
|
|
59925
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
59926
|
+
className: "dshc-code-summary",
|
|
59927
|
+
"data-state": state === "error" || state === "stopped" ? state : void 0,
|
|
59928
|
+
children: summaryText
|
|
59929
|
+
})] })]
|
|
59930
|
+
})]
|
|
59931
|
+
})
|
|
59932
|
+
}),
|
|
59933
|
+
open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
59934
|
+
className: "dshc-code-body-wrap",
|
|
59935
|
+
children: [
|
|
59936
|
+
sourceText !== null && highlightedLines !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
59937
|
+
className: "dshc-code-body-scroll",
|
|
59938
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
59939
|
+
className: "dshc-code-card md-code-block",
|
|
59940
|
+
"data-code-wrap": wrapped ? "true" : "false",
|
|
59941
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
59942
|
+
className: "dshc-code-toolbar",
|
|
59943
|
+
"data-code-block-banner": true,
|
|
59944
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
59945
|
+
className: "dshc-code-lang",
|
|
59946
|
+
children: language
|
|
59947
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
59948
|
+
className: "dshc-code-actions",
|
|
59949
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
59950
|
+
type: "button",
|
|
59951
|
+
className: "dshc-code-action",
|
|
59952
|
+
title: wrapLabel,
|
|
59953
|
+
"aria-label": t("codeRunWrap"),
|
|
59954
|
+
"aria-pressed": wrapped,
|
|
59955
|
+
onClick: () => {
|
|
59956
|
+
setWrapped((prev) => !prev);
|
|
59957
|
+
},
|
|
59958
|
+
children: wrapped ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NowrapIcon, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WrapIcon, {})
|
|
59959
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
59960
|
+
type: "button",
|
|
59961
|
+
className: "dshc-code-action",
|
|
59962
|
+
title: copyLabel,
|
|
59963
|
+
"aria-label": copyLabel,
|
|
59964
|
+
onClick: onCopy,
|
|
59965
|
+
children: copied ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckIcon, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopyIcon, {})
|
|
59966
|
+
})]
|
|
59967
|
+
})]
|
|
59968
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
59969
|
+
className: "shiki css-variables dshc-code-pre",
|
|
59970
|
+
tabIndex: 0,
|
|
59971
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: highlightedLines.map((line, lineIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [lineIndex > 0 && "\n", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
59972
|
+
className: "line",
|
|
59973
|
+
children: line.map((span, spanIndex) => {
|
|
59974
|
+
const color = SHIKI_TOKEN_COLORS[span.kind];
|
|
59975
|
+
return color === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: span.text }, spanIndex) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
59976
|
+
style: { color },
|
|
59977
|
+
children: span.text
|
|
59978
|
+
}, spanIndex);
|
|
59979
|
+
})
|
|
59980
|
+
})] }, lineIndex)) })
|
|
59981
|
+
})]
|
|
59982
|
+
})
|
|
59983
|
+
}),
|
|
59984
|
+
outputText !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
59985
|
+
className: "dshc-code-io-card",
|
|
59986
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
59987
|
+
className: "dshc-code-io-section",
|
|
59988
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
59989
|
+
className: "dshc-code-io-label",
|
|
59990
|
+
children: t("codeRunOutput")
|
|
59991
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
59992
|
+
className: "dshc-code-io-text",
|
|
59993
|
+
"data-error": state === "error" ? "true" : void 0,
|
|
59994
|
+
children: outputText
|
|
59995
|
+
})]
|
|
59996
|
+
})
|
|
59997
|
+
}),
|
|
59998
|
+
inspect !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
59999
|
+
type: "button",
|
|
60000
|
+
className: "dshc-code-inspect-btn",
|
|
60001
|
+
onClick: inspect,
|
|
60002
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(InspectIcon, {}), t("codeRunInspect")]
|
|
60003
|
+
})
|
|
60004
|
+
]
|
|
60005
|
+
})
|
|
60006
|
+
]
|
|
60007
|
+
});
|
|
60008
|
+
}
|
|
60009
|
+
function CodeGlyphIcon() {
|
|
60010
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
60011
|
+
viewBox: "0 0 16 16",
|
|
60012
|
+
fill: "none",
|
|
60013
|
+
stroke: "currentColor",
|
|
60014
|
+
strokeWidth: "1.4",
|
|
60015
|
+
strokeLinecap: "round",
|
|
60016
|
+
strokeLinejoin: "round",
|
|
60017
|
+
children: [
|
|
60018
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M5.2 4.5L1.8 8l3.4 3.5" }),
|
|
60019
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M10.8 4.5L14.2 8l-3.4 3.5" }),
|
|
60020
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M9.2 3L6.8 13" })
|
|
60021
|
+
]
|
|
60022
|
+
});
|
|
60023
|
+
}
|
|
60024
|
+
function ChevronDownIcon() {
|
|
60025
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
60026
|
+
viewBox: "0 0 16 16",
|
|
60027
|
+
fill: "none",
|
|
60028
|
+
stroke: "currentColor",
|
|
60029
|
+
strokeWidth: "1.5",
|
|
60030
|
+
strokeLinecap: "round",
|
|
60031
|
+
strokeLinejoin: "round",
|
|
60032
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M4 6l4 4 4-4" })
|
|
60033
|
+
});
|
|
60034
|
+
}
|
|
60035
|
+
function ChevronUpIcon() {
|
|
60036
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
60037
|
+
viewBox: "0 0 16 16",
|
|
60038
|
+
fill: "none",
|
|
60039
|
+
stroke: "currentColor",
|
|
60040
|
+
strokeWidth: "1.5",
|
|
60041
|
+
strokeLinecap: "round",
|
|
60042
|
+
strokeLinejoin: "round",
|
|
60043
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M4 10l4-4 4 4" })
|
|
60044
|
+
});
|
|
60045
|
+
}
|
|
60046
|
+
function CopyIcon() {
|
|
60047
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
60048
|
+
width: "14",
|
|
60049
|
+
height: "14",
|
|
60050
|
+
viewBox: "0 0 16 16",
|
|
60051
|
+
fill: "none",
|
|
60052
|
+
stroke: "currentColor",
|
|
60053
|
+
strokeWidth: "1.35",
|
|
60054
|
+
strokeLinecap: "round",
|
|
60055
|
+
strokeLinejoin: "round",
|
|
60056
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
60057
|
+
x: "5.5",
|
|
60058
|
+
y: "5.5",
|
|
60059
|
+
width: "8",
|
|
60060
|
+
height: "8",
|
|
60061
|
+
rx: "1.5"
|
|
60062
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M10.5 5.5V3.8A1.3 1.3 0 0 0 9.2 2.5H3.8A1.3 1.3 0 0 0 2.5 3.8v5.4a1.3 1.3 0 0 0 1.3 1.3h1.7" })]
|
|
60063
|
+
});
|
|
60064
|
+
}
|
|
60065
|
+
function CheckIcon() {
|
|
60066
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
60067
|
+
width: "14",
|
|
60068
|
+
height: "14",
|
|
60069
|
+
viewBox: "0 0 16 16",
|
|
60070
|
+
fill: "none",
|
|
60071
|
+
stroke: "currentColor",
|
|
60072
|
+
strokeWidth: "1.6",
|
|
60073
|
+
strokeLinecap: "round",
|
|
60074
|
+
strokeLinejoin: "round",
|
|
60075
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M3.2 8.4l3.1 3.1 6.5-6.5" })
|
|
60076
|
+
});
|
|
60077
|
+
}
|
|
60078
|
+
function WrapIcon() {
|
|
60079
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
60080
|
+
width: "14",
|
|
60081
|
+
height: "14",
|
|
60082
|
+
viewBox: "0 0 16 16",
|
|
60083
|
+
fill: "none",
|
|
60084
|
+
stroke: "currentColor",
|
|
60085
|
+
strokeWidth: "1.35",
|
|
60086
|
+
strokeLinecap: "round",
|
|
60087
|
+
strokeLinejoin: "round",
|
|
60088
|
+
children: [
|
|
60089
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2.5 4h11" }),
|
|
60090
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2.5 8h8.5a2.2 2.2 0 1 1 0 4.4H8.2" }),
|
|
60091
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M9.8 10.8L8 12.4l1.8 1.6" }),
|
|
60092
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2.5 12.4h3" })
|
|
60093
|
+
]
|
|
60094
|
+
});
|
|
60095
|
+
}
|
|
60096
|
+
function NowrapIcon() {
|
|
60097
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
60098
|
+
width: "14",
|
|
60099
|
+
height: "14",
|
|
60100
|
+
viewBox: "0 0 16 16",
|
|
60101
|
+
fill: "none",
|
|
60102
|
+
stroke: "currentColor",
|
|
60103
|
+
strokeWidth: "1.35",
|
|
60104
|
+
strokeLinecap: "round",
|
|
60105
|
+
strokeLinejoin: "round",
|
|
60106
|
+
children: [
|
|
60107
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2.5 4h11" }),
|
|
60108
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2.5 8h11" }),
|
|
60109
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M11.5 6.2L13.5 8l-2 1.8" }),
|
|
60110
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2.5 12h7" })
|
|
60111
|
+
]
|
|
60112
|
+
});
|
|
60113
|
+
}
|
|
60114
|
+
function InspectIcon() {
|
|
60115
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
60116
|
+
width: "12",
|
|
60117
|
+
height: "12",
|
|
60118
|
+
viewBox: "0 0 16 16",
|
|
60119
|
+
fill: "none",
|
|
60120
|
+
stroke: "currentColor",
|
|
60121
|
+
strokeWidth: "1.4",
|
|
60122
|
+
strokeLinecap: "round",
|
|
60123
|
+
strokeLinejoin: "round",
|
|
60124
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
60125
|
+
cx: "7.2",
|
|
60126
|
+
cy: "7.2",
|
|
60127
|
+
r: "4.5"
|
|
60128
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M10.6 10.6L13.8 13.8" })]
|
|
60129
|
+
});
|
|
60130
|
+
}
|
|
60131
|
+
//#endregion
|
|
60132
|
+
//#region src/client/codemode/styles.ts
|
|
60133
|
+
/**
|
|
60134
|
+
* `code_run` 工具行样式表 —— 对齐宿主内置 `run_code`(`DisclosureRow` + `ToolRow` +
|
|
60135
|
+
* `CodeBlock` + `CodeToolbar`)的视觉令牌与排版节奏。
|
|
60136
|
+
*
|
|
60137
|
+
* 所有颜色、字号与圆角均直接引用宿主 `--dsw-*` / `--dsh-*` / `--shiki-*` CSS 变量。
|
|
60138
|
+
*
|
|
60139
|
+
* @module @eddyskywalker/dsh-chatgpt-subscription/client/codemode/styles
|
|
60140
|
+
*/
|
|
60141
|
+
const CODEMODE_CSS = `
|
|
60142
|
+
.dshc-code-root {
|
|
60143
|
+
display: flex;
|
|
60144
|
+
flex-direction: column;
|
|
60145
|
+
width: 100%;
|
|
60146
|
+
min-width: 0;
|
|
60147
|
+
}
|
|
60148
|
+
|
|
60149
|
+
.dshc-code-visually-hidden {
|
|
60150
|
+
position: absolute;
|
|
60151
|
+
width: 1px;
|
|
60152
|
+
height: 1px;
|
|
60153
|
+
overflow: hidden;
|
|
60154
|
+
clip: rect(0 0 0 0);
|
|
60155
|
+
white-space: nowrap;
|
|
60156
|
+
}
|
|
60157
|
+
|
|
60158
|
+
.dshc-code-header {
|
|
60159
|
+
display: flex;
|
|
60160
|
+
align-items: center;
|
|
60161
|
+
min-width: 0;
|
|
60162
|
+
}
|
|
60163
|
+
|
|
60164
|
+
.dshc-code-row {
|
|
60165
|
+
flex: 1 1 auto;
|
|
60166
|
+
position: relative;
|
|
60167
|
+
overflow: hidden;
|
|
60168
|
+
display: flex;
|
|
60169
|
+
align-items: center;
|
|
60170
|
+
height: calc(24px + var(--dsh-content-font-delta, 0px));
|
|
60171
|
+
min-width: 0;
|
|
60172
|
+
color: var(--dsw-alias-label-tertiary, #8a9099);
|
|
60173
|
+
transition: color 100ms ease;
|
|
60174
|
+
user-select: none;
|
|
60175
|
+
}
|
|
60176
|
+
|
|
60177
|
+
.dshc-code-row[data-expandable='true'] {
|
|
60178
|
+
cursor: pointer;
|
|
60179
|
+
}
|
|
60180
|
+
|
|
60181
|
+
@media (hover: hover) {
|
|
60182
|
+
.dshc-code-row:hover {
|
|
60183
|
+
color: var(--dsw-alias-label-secondary, #5b6270);
|
|
60184
|
+
}
|
|
60185
|
+
}
|
|
60186
|
+
|
|
60187
|
+
.dshc-code-row:focus-visible {
|
|
60188
|
+
outline: 1px solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary, #4d6bfe));
|
|
60189
|
+
outline-offset: 2px;
|
|
60190
|
+
border-radius: var(--dsw-radius-sm, 4px);
|
|
60191
|
+
}
|
|
60192
|
+
|
|
60193
|
+
.dshc-code-leading {
|
|
60194
|
+
position: relative;
|
|
60195
|
+
flex: none;
|
|
60196
|
+
width: calc(16px + var(--dsh-content-font-delta, 0px));
|
|
60197
|
+
height: calc(16px + var(--dsh-content-font-delta, 0px));
|
|
60198
|
+
display: inline-flex;
|
|
60199
|
+
align-items: center;
|
|
60200
|
+
justify-content: center;
|
|
60201
|
+
margin-right: 6px;
|
|
60202
|
+
color: inherit;
|
|
60203
|
+
}
|
|
60204
|
+
|
|
60205
|
+
.dshc-code-leading svg {
|
|
60206
|
+
width: calc(14px + var(--dsh-content-font-delta, 0px));
|
|
60207
|
+
height: calc(14px + var(--dsh-content-font-delta, 0px));
|
|
60208
|
+
}
|
|
60209
|
+
|
|
60210
|
+
.dshc-code-icon-idle {
|
|
60211
|
+
display: inline-flex;
|
|
60212
|
+
opacity: 1;
|
|
60213
|
+
transition: opacity 100ms ease;
|
|
60214
|
+
}
|
|
60215
|
+
|
|
60216
|
+
.dshc-code-chevron-hover {
|
|
60217
|
+
position: absolute;
|
|
60218
|
+
inset: 0;
|
|
60219
|
+
margin: auto;
|
|
60220
|
+
opacity: 0;
|
|
60221
|
+
transition: opacity 100ms ease;
|
|
60222
|
+
}
|
|
60223
|
+
|
|
60224
|
+
@media (hover: hover) {
|
|
60225
|
+
.dshc-code-row[data-expandable='true']:hover .dshc-code-icon-idle {
|
|
60226
|
+
opacity: 0;
|
|
60227
|
+
}
|
|
60228
|
+
.dshc-code-row[data-expandable='true']:hover .dshc-code-chevron-hover {
|
|
60229
|
+
opacity: 1;
|
|
60230
|
+
}
|
|
60231
|
+
}
|
|
60232
|
+
|
|
60233
|
+
.dshc-code-text-flow {
|
|
60234
|
+
display: flex;
|
|
60235
|
+
align-items: center;
|
|
60236
|
+
flex: 1 1 auto;
|
|
60237
|
+
min-width: 0;
|
|
60238
|
+
overflow: hidden;
|
|
60239
|
+
}
|
|
60240
|
+
|
|
60241
|
+
@keyframes dshc-shimmer-pulse {
|
|
60242
|
+
0%, 100% { opacity: 1; }
|
|
60243
|
+
50% { opacity: 0.55; }
|
|
60244
|
+
}
|
|
60245
|
+
|
|
60246
|
+
.dshc-code-text-flow[data-running='true'] {
|
|
60247
|
+
animation: dshc-shimmer-pulse 1.6s ease-in-out infinite;
|
|
60248
|
+
}
|
|
60249
|
+
|
|
60250
|
+
.dshc-code-title {
|
|
60251
|
+
flex: none;
|
|
60252
|
+
font-weight: 400;
|
|
60253
|
+
font-size: var(--dsh-content-font-size-secondary, 13px);
|
|
60254
|
+
line-height: calc(24px + var(--dsh-content-font-delta, 0px));
|
|
60255
|
+
color: inherit;
|
|
60256
|
+
}
|
|
60257
|
+
|
|
60258
|
+
.dshc-code-sep {
|
|
60259
|
+
flex: none;
|
|
60260
|
+
width: 2px;
|
|
60261
|
+
height: 2px;
|
|
60262
|
+
border-radius: 1px;
|
|
60263
|
+
margin: 0 8px;
|
|
60264
|
+
background: var(--dsw-alias-label-caption, #8a9099);
|
|
60265
|
+
}
|
|
60266
|
+
|
|
60267
|
+
.dshc-code-summary {
|
|
60268
|
+
flex: 1 1 auto;
|
|
60269
|
+
min-width: 0;
|
|
60270
|
+
overflow: hidden;
|
|
60271
|
+
text-overflow: ellipsis;
|
|
60272
|
+
white-space: nowrap;
|
|
60273
|
+
font-size: var(--dsh-content-font-size-secondary, 13px);
|
|
60274
|
+
line-height: calc(24px + var(--dsh-content-font-delta, 0px));
|
|
60275
|
+
}
|
|
60276
|
+
|
|
60277
|
+
.dshc-code-summary[data-state='error'] {
|
|
60278
|
+
color: var(--dsw-alias-state-error-primary, #d54941);
|
|
60279
|
+
}
|
|
60280
|
+
|
|
60281
|
+
.dshc-code-summary[data-state='stopped'] {
|
|
60282
|
+
color: var(--dsw-alias-state-warn-label, #d97706);
|
|
60283
|
+
}
|
|
60284
|
+
|
|
60285
|
+
.dshc-code-body-wrap {
|
|
60286
|
+
display: flex;
|
|
60287
|
+
flex-direction: column;
|
|
60288
|
+
}
|
|
60289
|
+
|
|
60290
|
+
.dshc-code-body-scroll {
|
|
60291
|
+
max-height: 260px;
|
|
60292
|
+
overflow-y: auto;
|
|
60293
|
+
margin: 4px 0 4px 4px;
|
|
60294
|
+
border-radius: var(--dsw-radius-lg, 10px);
|
|
60295
|
+
border: 0.5px solid var(--dsw-alias-border-l1, rgba(128, 128, 128, 0.18));
|
|
60296
|
+
background: var(--dsw-alias-markdown-code-block, rgba(128, 128, 128, 0.08));
|
|
60297
|
+
}
|
|
60298
|
+
|
|
60299
|
+
.dshc-code-card {
|
|
60300
|
+
position: relative;
|
|
60301
|
+
color: var(--dsw-alias-label-primary, inherit);
|
|
60302
|
+
background: transparent;
|
|
60303
|
+
font: var(--dsw-font-markdown-code-block, 13px/20px var(--ds-font-family-code, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace));
|
|
60304
|
+
}
|
|
60305
|
+
|
|
60306
|
+
.dshc-code-toolbar {
|
|
60307
|
+
position: sticky;
|
|
60308
|
+
top: 0;
|
|
60309
|
+
z-index: 6;
|
|
60310
|
+
display: flex;
|
|
60311
|
+
align-items: center;
|
|
60312
|
+
justify-content: space-between;
|
|
60313
|
+
gap: 12px;
|
|
60314
|
+
padding: 10px 18px 8px 22px;
|
|
60315
|
+
background: var(--dsw-alias-markdown-code-block, #1e222a);
|
|
60316
|
+
color: var(--dsw-alias-label-secondary, #8a9099);
|
|
60317
|
+
font: 11px/18px var(--dsw-font-family, system-ui, sans-serif);
|
|
60318
|
+
}
|
|
60319
|
+
|
|
60320
|
+
.dshc-code-lang {
|
|
60321
|
+
color: var(--dsw-alias-label-tertiary, #8a9099);
|
|
60322
|
+
flex: none;
|
|
60323
|
+
font-family: var(--ds-font-family-code, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
|
|
60324
|
+
}
|
|
60325
|
+
|
|
60326
|
+
.dshc-code-actions {
|
|
60327
|
+
display: flex;
|
|
60328
|
+
align-items: center;
|
|
60329
|
+
gap: 4px;
|
|
60330
|
+
flex: none;
|
|
60331
|
+
}
|
|
60332
|
+
|
|
60333
|
+
.dshc-code-action {
|
|
60334
|
+
display: inline-flex;
|
|
60335
|
+
align-items: center;
|
|
60336
|
+
justify-content: center;
|
|
60337
|
+
width: 24px;
|
|
60338
|
+
height: 24px;
|
|
60339
|
+
padding: 0;
|
|
60340
|
+
border: 0;
|
|
60341
|
+
border-radius: var(--dsw-radius-sm, 4px);
|
|
60342
|
+
color: var(--dsw-alias-label-secondary, #8a9099);
|
|
60343
|
+
background: transparent;
|
|
60344
|
+
cursor: pointer;
|
|
60345
|
+
}
|
|
60346
|
+
|
|
60347
|
+
@media (hover: hover) {
|
|
60348
|
+
.dshc-code-action:hover {
|
|
60349
|
+
background: var(--dsw-alias-interactive-bg-hover, rgba(128, 128, 128, 0.14));
|
|
60350
|
+
color: var(--dsw-alias-label-primary, inherit);
|
|
60351
|
+
}
|
|
60352
|
+
}
|
|
60353
|
+
|
|
60354
|
+
.dshc-code-action:focus-visible {
|
|
60355
|
+
outline: 1px solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary, #4d6bfe));
|
|
60356
|
+
outline-offset: 2px;
|
|
60357
|
+
}
|
|
60358
|
+
|
|
60359
|
+
.dshc-code-pre {
|
|
60360
|
+
margin: 0 !important;
|
|
60361
|
+
padding: 6px 22px 20px;
|
|
60362
|
+
font: var(--dsw-font-markdown-code-block, 13px/20px var(--ds-font-family-code, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace));
|
|
60363
|
+
background: transparent !important;
|
|
60364
|
+
color: var(--shiki-foreground, var(--dsw-alias-label-primary, inherit));
|
|
60365
|
+
overflow-x: auto;
|
|
60366
|
+
white-space: pre-wrap;
|
|
60367
|
+
word-break: normal;
|
|
60368
|
+
overflow-wrap: anywhere;
|
|
60369
|
+
}
|
|
60370
|
+
|
|
60371
|
+
.dshc-code-card[data-code-wrap='false'] .dshc-code-pre {
|
|
60372
|
+
white-space: pre;
|
|
60373
|
+
overflow-wrap: normal;
|
|
60374
|
+
}
|
|
60375
|
+
|
|
60376
|
+
.dshc-code-pre code {
|
|
60377
|
+
font: inherit;
|
|
60378
|
+
background: none;
|
|
60379
|
+
padding: 0;
|
|
60380
|
+
}
|
|
60381
|
+
|
|
60382
|
+
.dshc-code-io-card {
|
|
60383
|
+
display: flex;
|
|
60384
|
+
flex-direction: column;
|
|
60385
|
+
margin: 4px 0 4px 4px;
|
|
60386
|
+
border: 0.5px solid var(--dsw-alias-border-l1, rgba(128, 128, 128, 0.18));
|
|
60387
|
+
border-radius: var(--dsw-radius-lg, 10px);
|
|
60388
|
+
background: var(--dsw-alias-markdown-code-block, rgba(128, 128, 128, 0.08));
|
|
60389
|
+
font: var(--dsw-font-markdown-code-block-small, 12px/18px var(--ds-font-family-code, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace));
|
|
60390
|
+
}
|
|
60391
|
+
|
|
60392
|
+
.dshc-code-io-section {
|
|
60393
|
+
display: grid;
|
|
60394
|
+
grid-template-columns: max-content 1fr;
|
|
60395
|
+
column-gap: 14px;
|
|
60396
|
+
align-items: baseline;
|
|
60397
|
+
padding: 12px 16px;
|
|
60398
|
+
max-height: 150px;
|
|
60399
|
+
overflow-y: auto;
|
|
60400
|
+
}
|
|
60401
|
+
|
|
60402
|
+
.dshc-code-io-label {
|
|
60403
|
+
position: sticky;
|
|
60404
|
+
top: 0;
|
|
60405
|
+
align-self: start;
|
|
60406
|
+
color: var(--dsw-alias-label-caption, #8a9099);
|
|
60407
|
+
}
|
|
60408
|
+
|
|
60409
|
+
.dshc-code-io-text {
|
|
60410
|
+
min-width: 0;
|
|
60411
|
+
white-space: pre-wrap;
|
|
60412
|
+
word-break: break-word;
|
|
60413
|
+
color: var(--dsw-alias-label-secondary, #8a9099);
|
|
60414
|
+
}
|
|
60415
|
+
|
|
60416
|
+
.dshc-code-io-text[data-error='true'] {
|
|
60417
|
+
color: var(--dsw-alias-state-error-primary, #d54941);
|
|
60418
|
+
}
|
|
60419
|
+
|
|
60420
|
+
.dshc-code-inspect-btn {
|
|
60421
|
+
display: inline-flex;
|
|
60422
|
+
align-self: flex-start;
|
|
60423
|
+
align-items: center;
|
|
60424
|
+
gap: 4px;
|
|
60425
|
+
margin: 4px 0 2px 4px;
|
|
60426
|
+
padding: 2px 8px;
|
|
60427
|
+
border: 0.5px solid var(--dsw-alias-border-l3, rgba(128, 128, 128, 0.25));
|
|
60428
|
+
border-radius: 999px;
|
|
60429
|
+
background: var(--dsw-alias-bg-base, transparent);
|
|
60430
|
+
color: var(--dsw-alias-label-secondary, #8a9099);
|
|
60431
|
+
font-size: 11px;
|
|
60432
|
+
line-height: 16px;
|
|
60433
|
+
cursor: pointer;
|
|
60434
|
+
opacity: 0;
|
|
60435
|
+
transition: opacity 100ms ease;
|
|
60436
|
+
}
|
|
60437
|
+
|
|
60438
|
+
.dshc-code-inspect-btn:focus-visible {
|
|
60439
|
+
opacity: 1;
|
|
60440
|
+
}
|
|
60441
|
+
|
|
60442
|
+
@media (hover: hover) {
|
|
60443
|
+
.dshc-code-root:hover .dshc-code-inspect-btn {
|
|
60444
|
+
opacity: 1;
|
|
60445
|
+
}
|
|
60446
|
+
.dshc-code-inspect-btn:hover {
|
|
60447
|
+
background: var(--dsw-alias-interactive-bg-hover-solid, rgba(128, 128, 128, 0.18));
|
|
60448
|
+
color: var(--dsw-alias-label-primary, inherit);
|
|
60449
|
+
}
|
|
60450
|
+
}
|
|
60451
|
+
|
|
60452
|
+
@media (hover: none) {
|
|
60453
|
+
.dshc-code-inspect-btn {
|
|
60454
|
+
opacity: 1;
|
|
60455
|
+
}
|
|
60456
|
+
}
|
|
60457
|
+
|
|
60458
|
+
@media (prefers-reduced-motion: reduce) {
|
|
60459
|
+
.dshc-code-row,
|
|
60460
|
+
.dshc-code-text-flow[data-running='true'] {
|
|
60461
|
+
transition: none;
|
|
60462
|
+
animation: none;
|
|
60463
|
+
}
|
|
60464
|
+
}
|
|
60465
|
+
`;
|
|
60466
|
+
function installCodemodeStyles() {
|
|
60467
|
+
return installPluginStyle("codemode", CODEMODE_CSS);
|
|
60468
|
+
}
|
|
60469
|
+
//#endregion
|
|
60470
|
+
//#region src/client/codemode/tool-name.ts
|
|
60471
|
+
/**
|
|
60472
|
+
* 客户端半边的 `code_run` 工具名常量。
|
|
60473
|
+
*
|
|
60474
|
+
* 独立于 `../../host/codemode/transport.ts`,避免浏览器 bundle 引入 Node 端模块;
|
|
60475
|
+
* 单测会校验两边字面量逐字一致。
|
|
60476
|
+
*
|
|
60477
|
+
* @module @eddyskywalker/dsh-chatgpt-subscription/client/codemode/tool-name
|
|
60478
|
+
*/
|
|
60479
|
+
const CODE_RUN_TOOL_NAME = "code_run";
|
|
60480
|
+
//#endregion
|
|
59141
60481
|
//#region src/client/index.tsx
|
|
59142
60482
|
const inject = [
|
|
59143
60483
|
"slots",
|
|
@@ -59223,6 +60563,7 @@ window.__ModuleLoader__.load({
|
|
|
59223
60563
|
}, "dsh-subagent-settings: styles");
|
|
59224
60564
|
ctx.effect(() => {
|
|
59225
60565
|
installPoolStyles();
|
|
60566
|
+
installCodemodeStyles();
|
|
59226
60567
|
return () => {};
|
|
59227
60568
|
}, "dsh-chatgpt-subscription: pool styles");
|
|
59228
60569
|
ctx.effect(() => setupMermaidObserver(), "dsh-mermaid: observer");
|
|
@@ -59352,6 +60693,11 @@ window.__ModuleLoader__.load({
|
|
|
59352
60693
|
readVideo: videoBytesLoader(ctx)
|
|
59353
60694
|
})
|
|
59354
60695
|
}, MinimaxVideoToolView));
|
|
60696
|
+
ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
|
|
60697
|
+
name: "tool.call.toolview",
|
|
60698
|
+
key: CODE_RUN_TOOL_NAME,
|
|
60699
|
+
locale: NS
|
|
60700
|
+
}, CodeRunToolView));
|
|
59355
60701
|
installVideoDocumentPreview(ctx);
|
|
59356
60702
|
installSubagentSettingsCard(ctx);
|
|
59357
60703
|
installProgressUpdatesClient(ctx);
|